Image upload

Upload JPEG images and receive scores for the faces in each one.

The image upload endpoint measures emotional expression on faces in one or more JPEG images. Send the images in one request, and the response has one result per image, listing the faces found in it. A realtime session returns the same measurements for the same images.

EndpointPOST https://api.cloud.hume.ai/v1/expression/video/file
ReferenceUpload images
Content typemultipart/form-data
RunRecorded under the run_id. See Runs.

Request

The request body has one or more file parts and an optional config part. Authenticate with a credential header, as described in Authentication.

Required

One JPEG image per part, sent with the content type image/jpeg. Repeat the part to send several images.

Settings as a JSON object, sent with the content type application/json. See Configuration. Omit it to use the defaults.

The request below uploads two images, lowers the detection threshold, and asks for a face_state to continue face tracking in a later request.

curl https://api.cloud.hume.ai/v1/expression/video/file \
-H "X-Hume-Api-Key: $HUME_API_KEY" \
-F "[email protected];type=image/jpeg" \
-F "[email protected];type=image/jpeg" \
-F 'config={
"face": {
"threshold": 0.8,
"return_face_state": true
}
};type=application/json'

Images

Each file part holds one complete JPEG image.

LimitValue
FormatJPEG
Image size2 MB
Pixels per image8,294,400 (3840x2160)
Request size25 MB for the whole multipart body
Faces measured per image2 by default, the largest. Contact support to raise it.
Faces listed per image32

The server checks every image before measuring any. An image that is not a JPEG, or that exceeds the size or pixel limit, fails the request with unsupported_media_type or image_too_large. After earlier images are measured, an image that cannot be decoded can still fail the request with image_decode_failed. A request that fails in any of these ways returns no result for any image and is recorded as an errored run.

Detection

The server scans each image for faces and excludes any whose detection confidence is below face.threshold or whose bounding box is shorter than face.min_size pixels on its shorter side. It measures the largest of the remaining faces, up to 2 by default, and lists them first in faces, largest first. The faces that were not measured follow, most confident first, up to 32 faces in all.

A face that was not measured carries its bbox and confidence, with face_id, expressions, and descriptions set to null. The limit on measured faces is set for your organization and does not appear in responses. To raise it, contact support.

Response

The response below is for two images. Three faces appear in the first, and the two largest are measured. One of the measured faces remains in the second.

200 OK
{
"request_id": "8b27e4d1c05f4a93b6e0d7a2c91f3e58",
"run_id": "01926f3e-397d-7ceb-9f52-a864c0102a44",
"received": {
"frames": 2
},
"measurements": [
{
"frame_id": 0,
"faces": [
{
"face_id": 0,
"bbox": [412.5, 118, 604.25, 371.75],
"confidence": 0.96875,
"expressions": [
{
"name": "amusement",
"probability": 0.6231
},
{
"name": "joy",
"probability": 0.4418
}
],
"descriptions": [
{
"name": "smile",
"probability": 0.8125
}
]
},
{
"face_id": 1,
"bbox": [98, 140.25, 251.5, 348.75],
"confidence": 0.9375,
"expressions": [
{
"name": "concentration",
"probability": 0.5108
}
],
"descriptions": [
{
"name": "jaw drop",
"probability": 0.2266
}
]
},
{
"face_id": null,
"bbox": [702, 160.5, 790.25, 276],
"confidence": 0.90625,
"expressions": null,
"descriptions": null
}
]
},
{
"frame_id": 1,
"faces": [
{
"face_id": 0,
"bbox": [420.75, 121.5, 611, 374.25],
"confidence": 0.953125,
"expressions": [
{
"name": "amusement",
"probability": 0.5742
},
{
"name": "joy",
"probability": 0.4016
}
],
"descriptions": [
{
"name": "smile",
"probability": 0.7695
}
]
}
]
}
],
"face_state": "v1.Qm9keSBvZiB0aGUgc2VhbGVkIGlkZW50aXR5IGNhY2hlLCBiYXNlNjR1cmwgd2l0aG91dCBwYWRkaW5n"
}
request_id

Identifies the request in Hume’s records. Quote it when contacting support.

run_id

Identifies the run the request was recorded as. Pass it to the run endpoints to look the run up.

received.frames

The number of images measured.

frame_id

The position of the image’s file part in the request, starting at 0.

face_id

Identifies the same face from image to image within the request, and across requests when you pass back face_state. null for a face that was not measured. See Face tracking.

bbox

The face’s location in the submitted image as [x0, y0, x1, y1]: the top-left and bottom-right corners in pixels, measured from the top-left of the image. Coordinates are in the pixels as stored in the file: EXIF orientation is not applied.

confidence

The detector’s confidence that the box contains a face, from 0 to 1. Never below face.threshold. Unrelated to the expression scores.

expressions

The 48 expression names are listed in Video measurements. null for a face that was not measured.

descriptions

Visible facial actions such as smile or jaw drop. The 27 names are listed in Video measurements. null for a face that was not measured.

face_state

Present when face.return_face_state was set. Pass it back in a later request to continue face_id numbering. See Face tracking.

Matching results to images

measurements holds one result per image, in the order the file parts were sent. Each result’s frame_id is the position of its image’s file part, starting at 0. An image with no faces still has a result, with an empty faces array.

Face tracking

face_id links the same face across the images of one request. IDs are assigned from 0 in the order faces are first measured, largest first within an image. A face normally keeps its ID while it is measured, and can get it back after it leaves the view or is no longer among the largest faces. The server remembers up to 32 faces, so a face that returns after many others have been measured may receive a new ID. IDs do not identify a person.

IDs restart at 0 in every request. To continue numbering across requests, set face.return_face_state to true, and pass the face_state from the response as face_state in the next request’s config.

config (next request)
{
"face": {
"return_face_state": true
},
"face_state": "v1.Qm9keSBvZiB0aGUgc2VhbGVkIGlkZW50aXR5IGNhY2hlLCBiYXNlNjR1cmwgd2l0aG91dCBwYWRkaW5n"
}
  1. Treat face_state as opaque. Pass it back unchanged.
  2. A state is accepted for 24 hours after it was issued. A state that has expired, was altered, or was issued to another organization is ignored, and numbering starts again from 0.

Configuration

To change the detection settings, send a config part. Fields you omit keep their defaults.

config
{
"face": {
"threshold": 0.8,
"min_size": 40
}
}
Defaults to 0.9

The minimum detection confidence for a face to be measured, from 0 to 1. Lower values include more faces at the risk of false detections. The scale is specific to this API, so thresholds tuned for other face detection APIs do not carry over. Reported rounded to four decimal places.

Defaults to 60

The smallest face to measure, as the shorter side of its bounding box in pixels of the submitted image. At least 1.

Defaults to false

Return a face_state with the response, so a later request can continue face_id numbering.

The face_state from an earlier response, so face_id continues from the faces that request saw.

Errors

A failed request returns an error body with a code, a message, and a request_id. A 401 carries only a message, and a request_id when an API key was rejected. HTTP errors describes the format.

StatusCodeDescription
400message_invalidThe multipart body could not be read, has no file part, or has a part with another name.
400config_invalidThe config part is not valid JSON, names an unrecognized field, holds a value outside its range, or appears more than once.
400image_decode_failedAn image could not be decoded.
401NoneThe request carried no valid API key or access token.
403forbiddenYour organization is not permitted to use this endpoint. Contact support.
405method_not_allowedThe endpoint does not accept this HTTP method. The Allow header lists the methods it does accept.
413image_too_largeThe request body is over 25 MB, an image is over 2 MB, or an image has more than 8,294,400 pixels.
415unsupported_media_typeAn image is not a JPEG.
500internal_errorThe server failed while serving the request. Retry it. If the failure recurs, contact Hume with the request_id.
503server_busyThe service is too busy to serve the request now. Wait the number of seconds in the Retry-After header, then retry.

Next steps