API Reference
The Haystack API is simple to use. We made this reference guide to help get you started quickly and easily.
If you have any questions, please do not hesitate to contact us.
All requests must be made to:
https://api.haystack.ai
SSL is optional, but strongly recommended.
Implementation Notes
- All actions MUST contain a valid API key.
- Every response will contain a result parameter.
- The result parameter will always be success or failure.
- A 202 (Accepted) response code will be generated on any error (result = failure)
- All emphasized variables are optional in both the client request and the server response
- Supported values for the output parameter are json, xml, rest.
- We recommend the largest side an image be between 512 and 1024 pixels. (This is a suggestion not a requirement)
Authentication
The Haystack API uses API keys to allow access to the API. You can register a new API key at our developer portal.
Haystack expects the API key to be included in all API requests. The API key can be provided in the query string or in the request payload.
Authorization: https://api.haystack.com/api/ENDPOINT/ACTION?apikey=YOUR_KEY_HERE
API Objects
The Haystack API represents the classification results as objects formatted based on the output parameter. These objects are returned in post API requests.
Gender
{
"gender":"female",
"confidence":0.9936
}
Type | Parameter | Description |
---|---|---|
string | gender | The detected gender of the person male or female. |
float | confidence | The confidence of the detected gender |
Ethnicity
{
"ethnicity":"White_Caucasian",
"confidence":0.8735
}
Type | Parameter | Description |
---|---|---|
string | ethnicity | The detected ethnicity of the person. |
float | confidence | The confidence of the detected ethnicity. |
Location
{
"x":180,
"y":116,
"width":130,
"height":130
}
Type | Parameter | Description |
---|---|---|
int | x | The left coordinate of the face in the image from the top left. |
int | y | The top coordinate of the face in the image from the top left. |
int | width | The width of the bounding rectangle. |
int | height | The height of the bounding rectangle. |
Person
{
"index":0,
"gender":
{
"gender":"female",
"confidence":0.9974
},
"age":24,
"location":
{
"x":156,
"y":180,
"width":190,
"height":187
},
"ethnicity":
{
"ethnicity":"White_Caucasian",
"confidence":0.9312
},
"emotion":
{
"emotions":
{
"neutral":0.3678,
"happy":0.3222,
"judging":0.1347
},
"attributes":
{
"biting_lip":true
}
},
"attractiveness":7.0812
}
Type | Parameter | Description |
---|---|---|
int | index | The unique identifier for this person in this image. |
gender | gender | The Gender information for this person. |
int | age | The predicted age of the person. |
location | location | The bounding rectangle of where the persons face is location in the picture. |
ethnicity | ethnicity | The Ethnicity information for this person. |
emotion | emotion | The Emotion detected on the person face. |
float | attractiveness | The estimated attractiveness for this person. |
Emotion
{
"emotions":
{
"neutral":0.3678,
"happy":0.3222,
"judging":0.1347
},
"attributes":
{
"biting_lip":true
}
}
Type | Parameter | Description |
---|---|---|
array | emotions | The detected emotions on the person’s face with the confidence of each emotion. |
array | attributes | Boolean attributes detected on the person’s face. An attribute will only be included if the value is true. |
AdultContent
{
"isAdultContent":false,
"isAdultContentConfidence":0.7889,
"adultContentType":"",
"adultContentTypeConfidence":0
}
Type | Parameter | Description |
---|---|---|
boolean | isAdultContent | true if adult content was detected in the image, otherwise false |
float | isAdultContentConfidence | The confidence for the adult detection |
string | adultContentType | The type of adult content that was detected |
float | adultContentTypeConfidence | The confidence in the classification of the adult content |
Group
{
"groupHash":"4170f5ee6a5150eaced5d0ad6e02b13bad47ed8d",
"title":"Celebrities"
}
Type | Parameter | Description |
---|---|---|
string | groupHash | The unique identifier for this group |
float | title | The string provided by the user when calling CreateGroup |
Models
These are the models currently available for use on the platform. This list does not include custom models uploaded by third party developers.
Name | Description |
---|---|
AdultType | Determines the type of adult content in an image |
Age | Determines the age of each person detected |
Attractiveness | Determines the attractiveness of each person detected |
Colors | Determines an images color composition |
Ethnicity | Determines the ethnicity of each person detected |
Emotion | Determines the emotion of the face of each person detected |
Gender | Determines the gender of each person detected |
Nudity | Determines if an image contains nudity |
Image Endpoint
Image platform for face detection, scene recognition, face verification, and adult content detection.
Action List
Action | Description |
---|---|
Analyze | Performs gender, age, and ethnicity classification on all detected people. Detects and classifies adult content. |
Verify | Compares two images to see if they contain the same person. |
AnalyzeAdult | Detects and classifies adult content. |
Analyze
curl -X POST --data-binary @testImage.jpg \
"https://api.haystack.ai/api/image/analyze?output=json&apikey=YOUR_KEY_HERE"
using (var client = new System.Net.WebClient())
{
var fileData = System.IO.File.ReadAllBytes("testImage.jpg");
var resData = client.UploadData(
"https://api.haystack.ai/api/image/analyze?output=json&apikey=YOUR_KEY_HERE",
"POST",
fileData);
var response = System.Text.Encoding.UTF8.GetString(resData);
Console.WriteLine(response);
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api.haystack.ai/api/image/analyze?output=json&apikey=YOUR_KEY_HERE");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, file_get_contents("testImage.jpg"));
$result=curl_exec ($ch);
echo $result;
?>
var url = "https://api.haystack.ai/api/image/analyze?output=json&apikey=YOUR_KEY_HERE";
var formData = new FormData();
formData.append("image", **IMAGE_DATA_BLOB**);
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
console.log(this.response);
}
};
xhttp.open("POST", url, true);
xhttp.send(formData);
URL url = new URL("https://api.haystack.ai/api/image/analyze?output=json&apikey=YOUR_KEY_HERE");
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
byte[] imageData = Files.readAllBytes(Paths.get("testImage.jpg"));
OutputStream os = new BufferedOutputStream(conn.getOutputStream());
os.write(imageData);
os.close();
InputStream is = conn.getInputStream();
buffer = new byte[1024];
ByteArrayOutputStream responseBuffer = new ByteArrayOutputStream();
while(true) {
int n = is.read(buffer, 0, buffer.length);
if(n <= 0) break;
responseBuffer.write(buffer, 0, n);
}
String response = responseBuffer.toString("UTF-8");
System.out.println(response);
import requests
r = requests.post(
"https://api.haystack.ai/api/image/analyze?output=json&apikey=YOUR_KEY_HERE",
data=open('testImage.jpg', 'rb'))
print(r.text);
The above code will print the following
{
"result":"success",
"adultContent":
{
"isAdultContent":true,
"isAdultContentConfidence":0.9963,
"adultContentType":"",
"adultContentTypeConfidence":0
},
"people" : [
{
"index":0,
"gender":
{
"gender":"female",
"confidence":0.9727
},
"age":17,
"location":
{
"x":691,
"y":110,
"width":149,
"height":149
},
"ethnicity":
{
"ethnicity":"White_Caucasian",
"confidence":0.8758
}
},
{
"index":1,
"gender":
{
"gender":"male",
"confidence":0.9942
},
"age":17,
"location":
{
"x":188,
"y":161,
"width":125,
"height":124
},
"ethnicity":
{
"ethnicity":"White_Caucasian",
"confidence":0.9547
}
}
],
"containsNudity":false
}
This action detects people in an image and determines the gender, age, and ethnicity of each of the people detected. This action will also determine if the image is considered adult content and will indicate the type if it is.
HTTP Request
POST https://api.haystack.ai/api/image/analyze
Request
Parameter | Description |
---|---|
apikey | A string containing your apikey |
image | The image to process. This may be sent as a Base64 encoded string, multipart/form-data, or as bytes in the post body. |
model | Specifies the specific model to use for the request. There can be multiple occurrences of this parameter in the request |
output | The desired output of the request. |
Response
Type | Parameter | Description |
---|---|---|
string | result | The result of the request. |
adultContent | adultContent | The adult object that indicates if the image contains adult content and the type of content. |
array | people | A list of person objects. |
boolean | containsNudity | true if nudity was detected in the image, otherwise false |
Verify
curl -X POST -F image1=@test1.jpg -F image2=@test2.jpg \
"http://api.haystack.ai/api/image/verify?output=json&apikey=YOUR_KEY_HERE"
var client = new System.Net.Http.HttpClient();
var content = new System.Net.Http.MultipartFormDataContent();
content.Add(new System.Net.Http.ByteArrayContent(
System.IO.File.ReadAllBytes("image1.jpg")), "image1");
content.Add(new System.Net.Http.ByteArrayContent(
System.IO.File.ReadAllBytes("image2.jpg")), "image2");
var result = client.PostAsync(
"https://api.haystack.ai/api/image/verify?output=json&apikey=YOUR_KEY_HERE",
content).Result;
Console.WriteLine(result.Content);
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api.haystack.ai/api/image/verify?output=json&apikey=YOUR_KEY_HERE");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, array(
"image1" => file_get_contents("image1.jpg"),
"image2" => file_get_contents("image2.jpg")
));
$result=curl_exec ($ch);
echo $result;
?>
var url = "https://api.haystack.ai/api/image/verify?output=json&apikey=YOUR_KEY_HERE";
var formData = new FormData();
formData.append("image1", **IMAGE_DATA_BLOB**);
formData.append("image2", **IMAGE_DATA_BLOB**);
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
console.log(this.response);
}
};
xhttp.open("POST", url, true);
xhttp.send(formData);
byte[] imageData1 = Files.readAllBytes(Paths.get("image1.jpg"));
byte[] imageData2 = Files.readAllBytes(Paths.get("image2.jpg"));
URL url = new URL("https://api.haystack.ai/api/image/verify?output=json&apikey=YOUR_KEY_HERE");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
String boundary = "------" + System.currentTimeMillis();
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
String fileHeaderFormat = boundary + "\r\n";
fileHeaderFormat += "Content-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\n";
fileHeaderFormat += "Content-Type: image/jpeg\r\n\r\n";
ByteArrayOutputStream body = new ByteArrayOutputStream();
byte[] buffer = String.format(fileHeaderFormat, "image1", "image1.jpg").getBytes(Charset.forName("UTF-8"));
body.write(buffer);
body.write(imageData1);
body.write("\r\n".getBytes("UTF-8"));
buffer = String.format(fileHeaderFormat, "image2", "image2.jpg").getBytes(Charset.forName("UTF-8"));
body.write(buffer);
body.write(imageData2);
body.write("\r\n".getBytes("UTF-8"));
buffer = (boundary + "--").getBytes(Charset.forName("UTF-8"));
body.write(buffer);
conn.setRequestProperty("Content-Length", ""+body.size());
OutputStream os = new BufferedOutputStream(conn.getOutputStream());
os.write(body.toByteArray());
os.close();
InputStream is = conn.getInputStream();
buffer = new byte[1024];
ByteArrayOutputStream responseBuffer = new ByteArrayOutputStream();
while(true) {
int n = is.read(buffer, 0, buffer.length);
if(n <= 0) break;
responseBuffer.write(buffer, 0, n);
}
String response = responseBuffer.toString("UTF-8");
System.out.println(response);
import requests
r = requests.post("https://api.haystack.ai/api/image/verify?output=json&apikey=YOUR_KEY_HERE", files={
"image1": open("image1.jpg", "rb"),
"image2": open("image2.jpg", "rb"),
})
print(r.text);
The above code will print the following
{
"result":"success",
"isSame":"false"
}
This action compares two images and checks to see if they are the same person. The input is assumed to be two images earch containing one face.
HTTP Request
POST https://api.haystack.ai/api/image/verify
Request
Parameter | Description |
---|---|
apikey | A string contining your apikey |
image1 | The first image to process. This may be sent as a Base64 encoded string or multipart/form-data. |
image2 | The second image to process. This may be sent as a Base64 encoded string or multipart/form-data. |
output | The desired output of the request. |
Response
Type | Parameter | Description |
---|---|---|
string | result | The result of the request. |
boolean | isSame | true if both images contain the same person, otherwise false. |
AnalyzeAdult
curl -X POST --data-binary @testImage.jpg \
"https://api.haystack.ai/api/image/analyzeadult?output=json&apikey=YOUR_KEY_HERE"
using (var client = new System.Net.WebClient())
{
var fileData = System.IO.File.ReadAllBytes("testImage.jpg");
var resData = client.UploadData(
"https://api.haystack.ai/api/image/analyzeadult?output=json&apikey=YOUR_KEY_HERE",
"POST",
fileData);
var response = System.Text.Encoding.UTF8.GetString(resData);
Console.WriteLine(response);
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api.haystack.ai/api/image/analyzeadult?output=json&apikey=YOUR_KEY_HERE");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, file_get_contents("testImage.jpg"));
$result=curl_exec ($ch);
echo $result;
?>
var url = "https://api.haystack.ai/api/image/analyzeadult?output=json&apikey=YOUR_KEY_HERE";
var formData = new FormData();
formData.append("image1", **IMAGE_DATA_BLOB**);
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
console.log(this.response);
}
};
xhttp.open("POST", url, true);
xhttp.send(formData);
URL url = new URL("https://api.haystack.ai/api/image/analyzeadult?output=json&apikey=YOUR_KEY_HERE");
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
byte[] imageData = Files.readAllBytes(Paths.get("testImage.jpg"));
OutputStream os = new BufferedOutputStream(conn.getOutputStream());
os.write(imageData);
os.close();
InputStream is = conn.getInputStream();
buffer = new byte[1024];
ByteArrayOutputStream responseBuffer = new ByteArrayOutputStream();
while(true) {
int n = is.read(buffer, 0, buffer.length);
if(n <= 0) break;
responseBuffer.write(buffer, 0, n);
}
String response = responseBuffer.toString("UTF-8");
System.out.println(response);
import requests
r = requests.post(
"https://api.haystack.ai/api/image/analyzeadult?output=json&apikey=YOUR_KEY_HERE",
data=open('testImage.jpg', 'rb'))
print(r.text);
The above request will return the following
{
"result":"success",
"adultContent":
{
"isAdultContent":true,
"isAdultContentConfidence":0.8551,
"adultContentType":"",
"adultContentTypeConfidence":0
},
"containsNudity":true
}
This action determines if there is adult content in the image and will indicate what type if there is.
HTTP Request
POST https://api.haystack.ai/api/image/analyzeadult
Request
Parameter | Description |
---|---|
apikey | A string containing your apikey |
image | The image to process. This may be sent as a Base64 encoded string, multipart/form-data or as bytes in the POST body. |
output | The desired output of the request. |
Response
Type | Parameter | Description |
---|---|---|
string | result | The result of the request |
adultContent | adultContent | An encoded adultContent object that indicates if the image contains adult content and the type of content |
boolean | containsNudity | true if nudity was detected, otherwise false. |
Custom
This action allows the developer to run a custom model that has been uploaded to the platform by a third party.
HTTP Request
POST https://api.haystack.ai/api/image/custom
Parameter | Description |
---|---|
apikey | A string containing your apikey |
image | The image to process. This may be sent as a Base64 encoded string, multipart/form-data or as bytes in the POST body. |
model | The model to use for this request. |
Response
Type | Parameter | Description |
---|---|---|
string | result | The result of the request |
object | output | The raw result from the model as key value pairs. |
ImageSearch Endpoint
Face search platform
Action List
Action | Description |
---|---|
CreateGroup | Create a new group that can be searched against. |
AddToGroup | Add a new image to an existing group |
Search | Search for a face within a group |
GetGroups | Retrieve a list of groups that have been created. |
AnalyzeSearch | Perform Analyze on an image and then perform a search for each face detected. |
CreateGroup
curl -X POST "http://api.haystack.ai/api/imagesearch/creategroup?apikey=YOUR_KEY_HERE&title=group1&output=json"
URL url = new URL("http://api.haystack.ai/api/imagesearch/creategroup?apikey=YOUR_KEY_HERE&title=group1&output=json");
URLConnection conn = url.openConnection();
InputStream is = conn.getInputStream();
buffer = new byte[1024];
ByteArrayOutputStream responseBuffer = new ByteArrayOutputStream();
while(true) {
int n = is.read(buffer, 0, buffer.length);
if(n <= 0) break;
responseBuffer.write(buffer, 0, n);
}
String response = responseBuffer.toString("UTF-8");
System.out.println(response);
This action creates a searchable group that you can upload photos to using AddToGroup and search using Search.
HTTP Request
POST https://api.haystack.ai/api/imagesearch/creategroup
Request
Parameter | Description |
---|---|
apikey | A string containing your apikey |
title | A title for the group |
output | The desired output of the request. |
Response
Type | Parameter | Description |
---|---|---|
string | result | The result of the request |
string | groupHash | The unique id of the group |
AddToGroup
curl -X POST --data-binary @testImage.jpg \
"http://api.haystack.ai/api/imagesearch/addtogroup?apikey=YOUR_KEY_HERE&groupHash=**groupHash**&uuid=personId&output=json"
URL url = new URL("http://api.haystack.ai/api/imagesearch/addtogroup?apikey=YOUR_KEY_HERE&groupHash=**groupHash**&uuid=personId&output=json");
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
byte[] imageData = Files.readAllBytes(Paths.get("testImage.jpg"));
OutputStream os = new BufferedOutputStream(conn.getOutputStream());
os.write(imageData);
os.close();
InputStream is = conn.getInputStream();
buffer = new byte[1024];
ByteArrayOutputStream responseBuffer = new ByteArrayOutputStream();
while(true) {
int n = is.read(buffer, 0, buffer.length);
if(n <= 0) break;
responseBuffer.write(buffer, 0, n);
}
String response = responseBuffer.toString("UTF-8");
System.out.println(response);
This action adds an image to a group for searching using Search. This endpoint can be used to add new users to the group and to add images to an existing user in the group.
HTTP Request
POST https://api.haystack.ai/api/imagesearch/addtogroup
Request
Parameter | Description |
---|---|
apikey | A string containing your apikey |
groupHash | The hash of the group to add to |
uuid | The unique identifier of the person in the photo, several photos can be uploaded with the same uuid key to add multiple pictures of the same person |
output | The desired output of the request. |
Response
Type | Parameter | Description |
---|---|---|
string | result | The result of the request |
Search
curl -X POST --data-binary @testImage.jpg \
"http://api.haystack.ai/api/imagesearch/search?apikey=YOUR_KEY_HERE&groupHash=**groupHash**&output=json"
URL url = new URL("http://api.haystack.ai/api/imagesearch/search?apikey=YOUR_KEY_HERE&groupHash=**groupHash**&output=json");
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
byte[] imageData = Files.readAllBytes(Paths.get("testImage.jpg"));
OutputStream os = new BufferedOutputStream(conn.getOutputStream());
os.write(imageData);
os.close();
InputStream is = conn.getInputStream();
buffer = new byte[1024];
ByteArrayOutputStream responseBuffer = new ByteArrayOutputStream();
while(true) {
int n = is.read(buffer, 0, buffer.length);
if(n <= 0) break;
responseBuffer.write(buffer, 0, n);
}
String response = responseBuffer.toString("UTF-8");
System.out.println(response);
Perform a search against a group created using CreateGroup. Results will be based on the similary of the face in the uploaded image.
HTTP Request
POST https://api.haystack.ai/api/imagesearch/search
Request
Parameter | Description |
---|---|
apikey | A string containing your apikey |
groupHash | The hash of the group to search against |
image | The image to process. This may be sent as a Base64 encoded string, multipart/form-data, or as bytes in the post body. |
output | The desired output of the request. |
Response
Type | Parameter | Description |
---|---|---|
string | result | The result of the request |
GetGroups
Retrieve a list of groups that have been created.
HTTP Request
POST https://api.haystack.ai/api/imagesearch/GetGroups
Request
Parameter | Description |
---|---|
apikey | A string containing your apikey |
output | The desired output of the request. |
Response
Type | Parameter | Description |
---|---|---|
string | result | The result of the request |
group | groups | A list of groups that can be searched |
AnalyzeSearch
The above code will print the following
{
"result":"success",
"adultContent":
{
"isAdultContent":true,
"isAdultContentConfidence":0.9963,
"adultContentType":"",
"adultContentTypeConfidence":0
},
"people" : [
{
"index":0,
"gender":
{
"gender":"female",
"confidence":0.9727
},
"age":17,
"location":
{
"x":691,
"y":110,
"width":149,
"height":149
},
"ethnicity":
{
"ethnicity":"White_Caucasian",
"confidence":0.8758
},
"searchResults":[
]
},
{
"index":1,
"gender":
{
"gender":"male",
"confidence":0.9942
},
"age":17,
"location":
{
"x":188,
"y":161,
"width":125,
"height":124
},
"ethnicity":
{
"ethnicity":"White_Caucasian",
"confidence":0.9547
},
"searchResults":[
{
"uuid":"person4",
"distance":0.23137212
},
{
"uuid":"person5",
"distance":0.33139654
},
{
"uuid":"person7",
"distance":0.49139212
},
{
"uuid":"person8",
"distance":0.89989221
}
]
}
],
"containsNudity":false
}
Perform Analyze on an image and then perform a search for each face detected.
HTTP Request
POST https://api.haystack.ai/api/imagesearch/AnalyzeSearch
Request
Parameter | Description |
---|---|
apikey | A string containing your apikey |
groupHash | The hash of the group to search against |
image | The image to process. This may be sent as a Base64 encoded string, multipart/form-data, or as bytes in the post body. |
output | The desired output of the request. |
Response
Type | Parameter | Description |
---|---|---|
string | result | The result of the request |
adultContent | adultContent | The adult object that indicates if the image contains adult content and the type of content. |
array | people | A list of person objects. |
boolean | containsNudity | true if nudity was detected in the image, otherwise false |
Errors
The Haystack API uses the following error codes:
Error Code | Meaning |
---|---|
1 | Invalid Api Key – Your API key is invalid |
4 | Invalid Action – No action or invalid action specified |
92 | No Pricing Information – Your key is missing pricing information for this endpoint or action. Contect support |
103 | Please Try Again Later – Your request could not be completed. Contact support if this error persists |
104 | Internal Error – An internal error occurred. Try your request again. Contact support if this error perisists |
105 | No Faces in Picture – No faces were detected in the uploaded image |
106 | Too Many Faces in Picture – Too many faces were detected in the uploaded image |
996 | No Permission – No permission to access service. Contact support |