Skip to main content

Detect Faces

faceDetect runs face detection on an image and returns every face it finds, each with a bounding box and a quality score. Faces that also match a known enrolled identity — above the engine's recognition threshold — additionally carry a faceId, personId, and confidence.

This is a read-only operation: it never enrolls anything. To enroll a face, use faceEnroll; to compare two specific images 1:1, use faceCompare.

API Endpoint

  • HTTP Method: POST
  • Endpoint: /api/v1/faces/faceDetect
  • Base URL (Cloud): https://customername.econnectcloud.com/identities
  • Base URL (On-prem): https://<server-host-or-ip>:5009

Authentication

Requires a JWT bearer token in the Authorization header. See Authentication.

Minimum Permission

The permission name and category below are what you'll see in the Identities web app under System → System settings → Roles.

PermissionCategory
Face DetectionFacial Recognition Services

Request Body

Content-Type: application/json. The image field is sent as a base64-encoded string. Every field except image is optional and defaults to the endpoint's original behavior, so existing callers are unaffected.

Required

FieldTypeDescription
imagebyte[] (base64)The image to detect faces in. May contain zero, one, or many faces.

Processing Options

FieldTypeDefaultDescription
largestFaceOnlyboolfalseIf true, only the largest face (by bounding-box area) is returned. See below.
matchThresholddouble(system default)Overrides the gallery-match confidence threshold. Must be within 0.71.0; out-of-range values return 400. See below.
timeoutMsint5000Fail-fast budget in milliseconds. Exceeding it returns 504 Gateway Timeout. Clamped to 25030000; zero or negative values fall back to the default. See below.

Person Inclusion Options

By default the response contains only face-level detection data. Set includePerson: true to enrich every matched face with a person object — the same shape returned by publishWithResponse. The individual include* switches choose which sections of the person record to return.

FieldTypeDefaultDescription
includePersonboolfalseMaster switch. When true, matched faces include a person object.
includeNamesboolfalseInclude the person's names / aliases.
includeAddressesboolfalseInclude the person's addresses.
includeTagsboolfalseInclude the person's tags.
includeFieldsboolfalseInclude the person's entity-field attributes.
excludeDisabledTagsbooltrueWhen true (default), tags whose definition is disabled are omitted, so downstream systems never trigger off a disabled tag. Set false to receive disabled tags too.
Each section is permission-gated

A section is returned only when it is requested AND the caller holds at least one of the permissions below. A requested section the caller isn't permitted to see is simply omitted (no error). includePerson only adds person data for faces that matched a known person — unknown faces are returned with face data only.

SwitchReturnsNeeds any one of these permissions
includeNamesperson.aliasesRead All Identity, Mutate All Identity, Read Aliases
includeAddressesperson.addressesRead All Identity, Mutate All Identity, Read Addresses
includeTagsperson.personTagsRead All Identity, Mutate All Identity, Mutate Tags, Read Tags
includeFieldsperson.entityFieldsRead All Identity, Mutate All Identity, Mutate Entity Fields, Read Entity Fields

These are in addition to the Face Detection permission required by the endpoint itself.

Matched vs. Unmatched Faces

A detected face is only considered a match when its recognition confidence meets the engine's minimum threshold:

  • MatchfaceId, personId, and confidence are populated (plus boundingBox and quality).
  • Below thresholdfaceId, personId, and confidence come back null; you still get the boundingBox and quality so you know a face was located, just not recognized.

personId can also be null for a matched faceId when that face isn't linked to a person record.

Large images are downscaled

Images are resized to fit within 2048×2048 before detection, but the returned boundingBox coordinates are scaled back to the original image's pixel dimensions — so you can draw boxes directly onto the image you sent.

Largest Face Only

Set largestFaceOnly: true to return only the largest detected face (by bounding-box area) instead of every face in the frame. This is what most integrations want when they expect a single dominant subject — the person at the door, the customer at the counter. When includePerson is also set, only that one face is enriched.

Match-Threshold Override

By default a detected face counts as a match only when its recognition confidence meets the server-configured minimum. Set matchThreshold to override that cutoff for a single call — raise it to demand a stronger match, or lower it (down to the floor) to accept weaker ones. A face below the effective threshold comes back unmatched (null faceId / personId / confidence).

The floor is 0.7

matchThreshold must be within 0.71.0. A value below 0.7 (or above 1.0) is rejected with 400 Bad Request — the floor prevents surfacing identities on genuinely weak matches. Omit the field to use the system default.

Fail-Fast Timeout

The whole call is bounded by timeoutMs (default 5000 ms). The budget starts once the request payload is on the server (upload time is excluded); if detection can't finish inside it, the call fails fast with 504 Gateway Timeout instead of hanging your integration. Raise it (up to 30000) for slower batch callers, or lower it (down to 250) if you'd rather retry than wait.

Code Examples

API_URL="https://customername.econnectcloud.com/identities"
TOKEN="your_jwt" # from POST /api/v1/authenticate
IMG_B64=$(base64 -w 0 photo.jpg)

# Basic detect - returns one entry per detected face.
# Recognized faces carry faceId/personId/confidence; unrecognized faces return null for those.
curl -sk -X POST "$API_URL/api/v1/faces/faceDetect" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "{\"image\": \"$IMG_B64\"}" | jq

# With options: only the largest face, enrich matched faces with the person (names + tags),
# override the match threshold (0.7-1.0), and fail fast after 3s.
# excludeDisabledTags defaults true, so disabled tags are omitted.
curl -sk -X POST "$API_URL/api/v1/faces/faceDetect" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "{
\"image\": \"$IMG_B64\",
\"largestFaceOnly\": true,
\"matchThreshold\": 0.85,
\"timeoutMs\": 3000,
\"includePerson\": true,
\"includeNames\": true,
\"includeTags\": true
}" | jq

Raw Sample

Request

POST https://customername.econnectcloud.com/identities/api/v1/faces/faceDetect
Authorization: Bearer <your_jwt_token>
Content-Type: application/json
{ "image": "base64_encoded_image" }

Response

200 OK — a FacesDetected object whose detections array has one entry per detected face:

{
"detections": [
{
"faceId": "5f9c2b7a-3e41-4d8a-9b6c-1a2b3c4d5e6f",
"personId": "0a1b2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d",
"confidence": 0.981,
"quality": 0.93,
"boundingBox": { "x": 320, "y": 145, "width": 96, "height": 96 }
},
{
"faceId": null,
"personId": null,
"confidence": null,
"quality": 0.74,
"boundingBox": { "x": 512, "y": 210, "width": 64, "height": 64 }
}
]
}

The first entry is a recognized face; the second is a face that was located but didn't match above the threshold.

With includePerson

When includePerson: true is requested, each matched face additionally carries a person object populated with the requested, permitted sections (unknown faces are returned with face data only):

{
"detections": [
{
"faceId": "5f9c2b7a-3e41-4d8a-9b6c-1a2b3c4d5e6f",
"personId": "0a1b2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d",
"confidence": 0.981,
"quality": 0.93,
"boundingBox": { "x": 320, "y": 145, "width": 96, "height": 96 },
"person": {
"personId": "0a1b2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d",
"friendlyName": "Doe, Jane",
"aliases": [ { "firstName": "Jane", "lastName": "Doe" } ],
"personTags": [ { "tag": { "name": "VIP", "disabled": false } } ]
}
}
]
}

By default (excludeDisabledTags: true) any disabled tag is omitted from person.personTags. Set excludeDisabledTags: false to receive disabled tags too (each carries its own disabled flag).

Response Fields

FieldTypeDescription
detections[].faceIdstringMatched face's identifier. null for a below-threshold (unrecognized) face.
detections[].personIdstring (GUID)Matched person's identifier. null when unrecognized, or when the face isn't linked to a person.
detections[].confidencefloatRecognition confidence, 0.01.0. null for a below-threshold face.
detections[].qualityfloatFace quality score, 0.01.0. Always present.
detections[].boundingBoxobject{ x, y, width, height } pixel coordinates in the original image. Always present.
detections[].personobjectPerson record (including personId). Present only with includePerson on a matched face; contains only the requested, permitted sections. Omitted when null.

Response Codes

CodeMeaning
200 OKDetection ran; detections contains the results (empty array if no faces were found).
400 Bad RequestInvalid request — for example, matchThreshold is outside the 0.71.0 range.
401 UnauthorizedMissing or invalid JWT.
403 ForbiddenThe user lacks the Face Detection permission.
500 Internal Server ErrorA server-side error occurred.
504 Gateway TimeoutDetection did not complete within the timeoutMs budget. Safe to retry.

Notes

  • An unrecognized face returns null faceId / personId / confidence but still gives you boundingBox and quality.
  • boundingBox coordinates are in the original image's pixel space, not the downscaled detection space.
  • All options are opt-in — omit them and the response is exactly the original face-level shape.
  • includePerson adds person data inline only for matched faces; a requested section the caller isn't permitted to see is omitted silently (not an error). Disabled tags are excluded unless excludeDisabledTags: false.
  • Set matchThreshold only within 0.71.0; use largestFaceOnly when you expect a single dominant subject.
  • A 504 means the timeoutMs budget was exceeded — retry, or raise the budget if your integration can tolerate the wait.
  • To turn a detected face into an enrolled identity, feed the image to faceEnroll.