VerifEye Face API
Overview
The VerifEye Face API is the single entry point for face onboarding, identification and analysis. One call takes an image, works out who is on it against your own face collection, and — when you ask for it — returns the age, gender, emotions and attention of every face it answers about.
The VerifEye Face API enables you to:
- Onboard faces into a collection — every face is looked up and added when it is not already there
- Identify faces against a collection — every face is looked up and nothing is ever added
- Compare the faces on an image against one face you name — a 1:1 check that answers "is this person here?"
- Enrich each face with optional attributes: age, gender, emotions and attention
- Answer about several faces on one image in a single call
- Manage collections (create, retrieve, update, reset, delete)
- Associate your own external keys (for example a customer or user identifier) with faces and look faces up by them
Base URLs
Choosing the right call
Three calls do the face work. They take the same image, the same optional attributes and the same maxFaces; what separates them is what each face on the image is matched against.
Rule of thumb: Onboard to put a person on file. Then Identify when you do not know who they are, or Compare when you do and only need it confirmed.
The order of calls
A collection starts empty, so Onboard always comes first — there is nothing for Identify or Compare to match against until a face is on file. Onboard is normally a one-off per person; Identify and Compare are the calls you make repeatedly afterwards.
sequenceDiagram
participant A as Your application
participant F as VerifEye Face API
Note over A,F: Once per person
A->>F: POST /v1/face/onboard (image, collectionId)
F-->>A: faceId + faceStatus (New or Existing)
Note over A: Store the faceId against your own user record
Note over A,F: Every time afterwards
alt You do not know who this is — 1:N
A->>F: POST /v1/face/identify (image, collectionId)
F-->>A: faceId of the match, or faceStatus NotExisting
else You know who they claim to be — 1:1
A->>F: POST /v1/face/compare (image, collectionId, faceId)
F-->>A: similarity + isMatch per face
endKeep the faceId Onboard gives you
Compare needs a faceId, and Onboard is the only call that issues one. Store it against your own user record at sign-up — or attach your own identifier to the face with an
Requests and responses
Images
Supply the image either as a base64-encoded JPEG/PNG (image.bytes) or as a URL (image.url). When both are set, bytes wins. Only http and https URLs are accepted, and the host must resolve to a public address — private, loopback and link-local addresses are rejected with 400.
See Image Requirements for resolution, file size and face-position guidance.
Optional attributes
Every attribute is off by default. Enable only what you need through the include object in the request body. The API returns the requested attributes for every face it answers about.
Billing
Enabling include.emotions or include.attention incurs an additional charge.
Only turn on what you actually use
Every option you enable is additional work per face, so each one adds latency to the request. Asking for everything on several faces is measurably slower than asking for what you need.
Ask for the attributes your flow reads and nothing more. include is per request, not per collection, so a flow that needs age only at sign-up can leave it off everywhere else.
Face detection restrictions
Faces that the API cannot process with sufficient confidence are omitted from the response — they do not appear in faces. This is more common when the image contains multiple faces.
So faces can hold fewer entries than the image holds faces. Those omitted faces are not counted in unprocessedFaceCount; that field counts the faces the call never looked at — the ones maxFaces left out, plus any beyond the detector’s own limit. Do not rely on the position of a face in faces to match the position of a face on the image; match on faces[].face.boundingBox instead.
Multiple faces
maxFaces (default 1, maximum 4) decides how many faces one call answers about. Faces are processed in order of dominance, and every face the limit left out is counted in unprocessedFaceCount.
API Endpoints
Onboard
Onboards the faces on the image into the collection: every face is looked up and, when it is not already there, added.
Endpoint: POST /v1/face/onboard
Authentication: API Key or Bearer Token
Request Body:
{
"image": {
"bytes": "base64-encoded-image-string",
"url": null
},
"collectionId": "my-collection",
"faceMatchThreshold": 80,
"maxFaces": 1,
"include": {
"age": true,
"gender": true,
"emotions": false,
"attention": false
}
}
Request Parameters:
Response Example:
{
"faces": [
{
"face": {
"confidence": 0.9987,
"boundingBox": {
"x": 120,
"y": 80,
"width": 200,
"height": 250
}
},
"faceId": "face_abc123xyz789",
"externalKey": "user-123",
"age": {
"prediction": 31.4,
"uncertainty": 0.42
},
"gender": "Female",
"emotions": null,
"attention": null,
"faceStatus": "Existing"
}
],
"unprocessedFaceCount": 0
}
Response Fields:
Example Request:
curl -X POST "https://verifeye-face-api-eu.realeyes.ai/v1/face/onboard" \
-H "Authorization: ApiKey API-KEY-FROM-DEV-CONSOLE" \
-H "Content-Type: application/json" \
-d '{
"image": {
"bytes": "/9j/4AAQSkZJRgABAQEAYABgAAD..."
},
"collectionId": "my-collection",
"include": {
"age": true,
"gender": true
}
}'
Response Codes:
200- The faces were onboarded400- Validation failure401- Authentication failure404- Collection not found504- The request did not complete within the time budget
Identify
Identifies the faces on the image against the collection: every face is looked up and never added.
Endpoint: POST /v1/face/identify
Authentication: API Key or Bearer Token
The request and the response are identical to faceStatus: NotExisting and no faceId, and nothing is stored. Every attribute that was asked for is still returned for it — only the identity is missing.
Request Body:
{
"image": {
"bytes": "base64-encoded-image-string",
"url": null
},
"collectionId": "my-collection",
"faceMatchThreshold": 80,
"maxFaces": 2,
"include": {
"age": false,
"gender": false,
"emotions": true,
"attention": true
}
}
Response Example:
{
"faces": [
{
"face": {
"confidence": 0.9987,
"boundingBox": {
"x": 120,
"y": 80,
"width": 200,
"height": 250
}
},
"faceId": "face_abc123xyz789",
"externalKey": "user-123",
"age": null,
"gender": null,
"emotions": {
"confusion": false,
"contempt": null,
"disgust": false,
"happy": true,
"empathy": null,
"surprise": false
},
"attention": {
"presence": true,
"eyesOnScreen": true,
"attention": true
},
"faceStatus": "Existing"
},
{
"face": {
"confidence": 0.9721,
"boundingBox": {
"x": 430,
"y": 96,
"width": 180,
"height": 224
}
},
"faceId": null,
"externalKey": null,
"age": null,
"gender": null,
"emotions": {
"confusion": null,
"contempt": null,
"disgust": null,
"happy": false,
"empathy": null,
"surprise": false
},
"attention": {
"presence": true,
"eyesOnScreen": false,
"attention": false
},
"faceStatus": "NotExisting"
}
],
"unprocessedFaceCount": 1
}
Example Request:
curl -X POST "https://verifeye-face-api-eu.realeyes.ai/v1/face/identify" \
-H "Authorization: ApiKey API-KEY-FROM-DEV-CONSOLE" \
-H "Content-Type: application/json" \
-d '{
"image": {
"url": "https://example.com/photo.jpg"
},
"collectionId": "my-collection",
"maxFaces": 2,
"include": {
"emotions": true,
"attention": true
}
}'
Response Codes:
200- The faces were searched for; each one either matched or did not400- Validation failure401- Authentication failure404- Collection not found504- The request did not complete within the time budget
Face status
Every face carries a faceStatus saying what the collection had to say about it.
Onboard only ever returns Existing or New: a face it does not find is added, so it always comes back with a faceId. NotExisting is Identify's alone.
NotExisting means one thing: no match. The collection held nobody who looks like this person. Every requested attribute is still returned — only the identity is missing. This is the ordinary end of an identify.
Compare
Compares the faces on the image against one face already in the collection, and answers how similar each of them is to it. This is the 1:1 check: the collection is never searched and never written to — the face you name by faceId is read directly, and every face on the image is scored against it.
Use it when you already know who the person claims to be. When you do not, use
Endpoint: POST /v1/face/compare
Authentication: API Key or Bearer Token
Request Body:
{
"image": {
"bytes": "base64-encoded-image-string",
"url": null
},
"collectionId": "my-collection",
"faceId": "face_abc123xyz789",
"faceMatchThreshold": 80,
"maxFaces": 1,
"include": {
"age": false,
"gender": false,
"emotions": false,
"attention": false
}
}
Request Parameters:
The parameters are the same as faceId.
Response Example:
{
"faces": [
{
"face": {
"confidence": 0.9987,
"boundingBox": {
"x": 120,
"y": 80,
"width": 200,
"height": 250
}
},
"similarity": 96,
"isMatch": true,
"age": null,
"gender": null,
"emotions": null,
"attention": null
}
],
"unprocessedFaceCount": 0
}
Response Fields:
There is no faceId and no faceStatus on a compare result: you supplied the identity, so the only thing left to answer is how well each face matches it. Whether the person is on the image at all is true for any faces[].isMatch — with maxFaces: 1 that is simply faces[0].isMatch.
Example Request:
curl -X POST "https://verifeye-face-api-eu.realeyes.ai/v1/face/compare" \
-H "Authorization: ApiKey API-KEY-FROM-DEV-CONSOLE" \
-H "Content-Type: application/json" \
-d '{
"image": {
"bytes": "/9j/4AAQSkZJRgABAQEAYABgAAD..."
},
"collectionId": "my-collection",
"faceId": "face_abc123xyz789"
}'
Response Codes:
200- The faces were compared; each one either matched or did not400- Validation failure401- Authentication failure403- The account has reached its face check limit404- Collection not found, or the collection holds no face with thatfaceId504- The request did not complete within the time budget
A 404 means the faceId is gone, not that the person is absent
A face that was deleted, or a faceId belonging to a different collection, comes back as 404. A person who is simply not on the image is a 200 with isMatch: false — the two are different answers and should be handled differently.
Delete Face
Deletes a single face from the collection. Deleting a face also removes any external key association it had.
Endpoint: DELETE /v1/face/delete
Authentication: API Key or Bearer Token
Query Parameters:
Response Example:
{}
Example Request:
curl -X DELETE "https://verifeye-face-api-eu.realeyes.ai/v1/face/delete?collectionId=my-collection&faceId=face_abc123xyz789" \
-H "Authorization: ApiKey API-KEY-FROM-DEV-CONSOLE"
Response Codes:
200- The face was deleted (idempotent)400- Validation failure401- Authentication failure404- Collection not found
Collection Management
A collection is the store of faces that onboard, identify and compare work against. For a conceptual overview of what a face collection is and how it relates to a Verification, see Face collection.
Get Collection
Retrieves a single collection by its identifier.
Endpoint: GET /v1/collection/get
Authentication: API Key or Bearer Token
Query Parameters:
Response Example:
{
"collection": {
"collectionId": "my-collection",
"description": "Collection for employee verification",
"createdAt": "2026-01-15T10:30:00Z",
"updatedAt": "2026-02-10T14:20:00Z"
}
}
Response Fields:
Example Request:
curl -X GET "https://verifeye-face-api-eu.realeyes.ai/v1/collection/get?collectionId=my-collection" \
-H "Authorization: ApiKey API-KEY-FROM-DEV-CONSOLE"
Response Codes:
200- Collection found400- Validation failure401- Authentication failure404- Collection not found
Get All Collections
Lists all collections belonging to the authenticated account.
Endpoint: GET /v1/collection/get-all
Authentication: API Key or Bearer Token
Response Example:
{
"collections": [
{
"collectionId": "my-collection",
"description": "Collection for employee verification",
"createdAt": "2026-01-15T10:30:00Z",
"updatedAt": "2026-02-10T14:20:00Z"
},
{
"collectionId": "employee-faces",
"description": "",
"createdAt": "2026-01-20T08:15:00Z",
"updatedAt": "2026-01-20T08:15:00Z"
}
]
}
Response Fields:
Example Request:
curl -X GET "https://verifeye-face-api-eu.realeyes.ai/v1/collection/get-all" \
-H "Authorization: ApiKey API-KEY-FROM-DEV-CONSOLE"
Response Codes:
200- Collections returned400- Validation failure401- Authentication failure
Create Collection
Creates a new collection.
Endpoint: POST /v1/collection/create
Authentication: API Key or Bearer Token
Request Body:
{
"collectionId": "new-collection",
"description": "Collection for customer verification"
}
Request Parameters:
Response Example:
{
"collectionId": "new-collection"
}
Response Fields:
Example Request:
curl -X POST "https://verifeye-face-api-eu.realeyes.ai/v1/collection/create" \
-H "Authorization: ApiKey API-KEY-FROM-DEV-CONSOLE" \
-H "Content-Type: application/json" \
-d '{
"collectionId": "new-collection",
"description": "Collection for customer verification"
}'
Response Codes:
200- Collection created successfully400- Validation failure401- Authentication failure409- Collection already exists
Update Collection
Updates an existing collection (only description is mutable).
Endpoint: PUT /v1/collection/update
Authentication: API Key or Bearer Token
Request Body:
{
"collectionId": "my-collection",
"description": "Updated description for my collection"
}
Request Parameters:
Response Example:
{
"collectionId": "my-collection"
}
Response Fields:
Example Request:
curl -X PUT "https://verifeye-face-api-eu.realeyes.ai/v1/collection/update" \
-H "Authorization: ApiKey API-KEY-FROM-DEV-CONSOLE" \
-H "Content-Type: application/json" \
-d '{
"collectionId": "my-collection",
"description": "Updated description for my collection"
}'
Response Codes:
200- Collection updated400- Validation failure401- Authentication failure404- Collection not found
Reset Collection
Removes all faces from a collection without deleting the collection itself. The collection (and its description) is preserved and remains usable; only the faces it contains — and any external key associations they had — are removed. This operation is irreversible.
For large collections the reset can take some time to complete. Stop onboarding into the collection before calling reset: faces onboarded after the reset has started are not guaranteed to be removed and may survive the operation. Resume onboarding only once the call has returned.
Endpoint: DELETE /v1/collection/reset
Authentication: API Key or Bearer Token
Query Parameters:
Response Example:
{
"collectionId": "my-collection"
}
Response Fields:
Example Request:
curl -X DELETE "https://verifeye-face-api-eu.realeyes.ai/v1/collection/reset?collectionId=my-collection" \
-H "Authorization: ApiKey API-KEY-FROM-DEV-CONSOLE"
Response Codes:
200- Collection reset (all faces removed)400- Validation failure401- Authentication failure404- Collection not found
Delete Collection
Deletes a collection by its identifier.
Endpoint: DELETE /v1/collection/delete
Authentication: API Key or Bearer Token
Query Parameters:
Response Example:
{}
Example Request:
curl -X DELETE "https://verifeye-face-api-eu.realeyes.ai/v1/collection/delete?collectionId=my-collection" \
-H "Authorization: ApiKey API-KEY-FROM-DEV-CONSOLE"
Response Codes:
200- Collection deleted (idempotent)400- Validation failure401- Authentication failure404- Collection not found
External Key Management
External keys let you attach your own identifier (for example a customer id, user id or reference number) to a face. A face has at most one external key, while an external key maps to a single face by default — or to several faces when duplicates are explicitly allowed.
External keys are managed independently of onboarding: set to associate a key with it. Once associated, the key comes back on every onboard and identify result that matches the face.
Set External Key
Associates an external key with a face. Creates a new association or updates the existing one (a face's key is replaced when set again with a different key).
Endpoint: PUT /v1/external-key/set
Authentication: API Key or Bearer Token
Request Body:
{
"collectionId": "my-collection",
"faceId": "face_abc123xyz789",
"externalKey": "user-123",
"allowDuplicates": false
}
Request Parameters:
Response Example:
{
"faceId": "face_abc123xyz789",
"externalKey": "user-123",
"result": "Created"
}
Response Fields:
Example Request:
curl -X PUT "https://verifeye-face-api-eu.realeyes.ai/v1/external-key/set" \
-H "Authorization: ApiKey API-KEY-FROM-DEV-CONSOLE" \
-H "Content-Type: application/json" \
-d '{
"collectionId": "my-collection",
"faceId": "face_abc123xyz789",
"externalKey": "user-123",
"allowDuplicates": false
}'
Response Codes:
200- Association created or updated400- Validation failure, or the external key is already associated with a different face andallowDuplicatesisfalse401- Authentication failure404- Collection not found
Get Face IDs by External Key
Returns all face ids associated with the specified external key in a collection.
Endpoint: GET /v1/external-key/get-face-ids
Authentication: API Key or Bearer Token
Query Parameters:
Response Example:
{
"faceIds": ["face_abc123xyz789"]
}
Response Fields:
Example Request:
curl -X GET "https://verifeye-face-api-eu.realeyes.ai/v1/external-key/get-face-ids?collectionId=my-collection&externalKey=user-123" \
-H "Authorization: ApiKey API-KEY-FROM-DEV-CONSOLE"
Response Codes:
200- Lookup succeeded400- Validation failure401- Authentication failure404- Collection not found
Delete External Key Association
Removes external key associations. When faceId is omitted, every face associated with the external key is unlinked; otherwise only the single pair is removed. This only removes the key association — it does not delete the face itself (use
Endpoint: DELETE /v1/external-key/delete
Authentication: API Key or Bearer Token
Query Parameters:
Response Example:
{}
Example Request:
curl -X DELETE "https://verifeye-face-api-eu.realeyes.ai/v1/external-key/delete?collectionId=my-collection&externalKey=user-123" \
-H "Authorization: ApiKey API-KEY-FROM-DEV-CONSOLE"
Response Codes:
200- Associations removed (idempotent)400- Validation failure401- Authentication failure404- Collection not found
External Key Format
- Maximum length: 512 characters.
- Allowed characters: printable ASCII only (
0x21–0x7E). Spaces, control characters and Unicode characters are rejected with400. - Recommended encoding: keep keys ASCII. If you need to embed richer identifiers (Unicode names, or values containing spaces or slashes), base64url-encode them on your side and store the encoded value (e.g. matching
^[A-Za-z0-9_-]{1,512}$). - Why ASCII only: external keys are used as lookup keys and may appear in URLs and logs. Restricting to printable ASCII avoids URL-encoding ambiguity and Unicode normalization collisions, where two visually identical keys are not byte-for-byte equal and therefore do not match.
Use Cases
For end-to-end scenarios using this API — including registering a face and checking it later — see the Use Cases page.
Health Check
Check the API health status.
Endpoint: GET /v1/healthz
Authentication: None required
Response Example:
2026-08-04T10:30:45Z
Response Fields:
Example Request:
curl -X GET "https://verifeye-face-api-eu.realeyes.ai/v1/healthz"
Response Codes:
200- API is healthy
Common Response Codes
Model validation failures (400) return a JSON body (ProblemDetails) with an errors object listing the invalid fields. A 401 returns {"message":"Unauthorized"} — no errors object. Some request-level errors — a missing image, an unfetchable image URL — return a plain-text message instead. Do not assume a single error shape; branch on Content-Type and on the status code.
Swagger Documentation
Interactive API documentation is available via Swagger UI:
- EU: https://verifeye-face-api-eu.realeyes.ai/swagger
- US: https://verifeye-face-api-us.realeyes.ai/swagger
The OpenAPI specification is available at:
- EU: https://verifeye-face-api-eu.realeyes.ai/swagger/v1/swagger.json
- US: https://verifeye-face-api-us.realeyes.ai/swagger/v1/swagger.json
Last updated: 2026-08-07