REST API for photo compliance validation.
Authorization: Bearer <api_key> Content-Type: application/json
| Field | Type | Required | Description |
|---|---|---|---|
image_base64 | string | required | Base64-encoded JPG or PNG, up to 25MB. Send the photo as the camera took it: the server frames and compresses it once itself. |
media_type | string | optional | image/jpeg or image/png (default: image/jpeg). The server measures the photo's size and shape itself. |
applicant_id | string | optional | Your reference for the person, up to 256 characters. Returned in the response, saved on the audit record, shown on the dashboard, and sent with identity match webhooks. Use an internal reference rather than a licence number. |
session_id | string | optional | Your ID for this check, up to 256 characters. It becomes the record's request_id. Retakes can share one. If left out, the server makes one. |
filename | string | optional | Shown on the dashboard, up to 256 characters. |
return_processed | boolean | optional | true to get the stored photo back in the response as processed: framed on the face like a passport photo, 1200 × 1600, 300 DPI, about 155KB. The phone SDKs ask for it, to show on their result screen. |
{
"request_id": "b7f3c1e2-4d5a-4c2b-9e1f-2a6c8d9e0f13",
"applicant_id": "CASE-004812",
"overall": "WARN",
"score": 95,
"summary": "This photo can be used, but it could be better. There is a faint shadow on the wall behind you.",
"checks": [
{ "label": "File size", "status": "PASS", "source": "local", "note": null, "conf": null, "meta": "212KB" },
{ "label": "Resolution", "status": "PASS", "source": "local", "note": null, "conf": null, "meta": "1200×1600px" },
{ "label": "No glasses", "status": "PASS", "source": "rekognition", "note": null, "conf": 99, "code": null },
{ "label": "Direct gaze", "status": "PASS", "source": "rekognition", "note": null, "conf": 92, "meta": "Yaw 3°, Pitch -2°", "code": null },
{ "label": "Background", "status": "WARN", "note": "There is a faint shadow on the wall behind you." }
],
"duration_ms": 2341
}
| Field | Meaning |
|---|---|
request_id | This check's ID: your session_id, or one the server made. Always present. Keep it to find the check on the dashboard. |
applicant_id | Your applicant_id, only present if you sent one. |
overall | PASS, WARN (usable, with minor issues) or FAIL. Any single FAIL check makes the result FAIL. |
score | 0 to 100. Starts at 100, less 15 for each FAIL check and 5 for each WARN. |
summary | Plain sentences for the person, safe to show as they are. For a WARN or FAIL it opens with the result, says what to fix (for example "remove your glasses and look straight into the camera lens") and adds anything the photo checks found. Never a list of check names. |
checks | Every check made. Each has label, status (PASS, WARN or FAIL) and note (the reason, or null for a PASS). Some also have source (local for size checks, rekognition for face checks), conf (confidence, 0 to 100), meta (the measured value: the size for size checks, the angles for Direct gaze and Head position, for staff and troubleshooting), and code, a fixed code for certain problems: GLASSES_DETECTED, SUNGLASSES_DETECTED, SMILE_DETECTED, MOUTH_OPEN, EYES_CLOSED, GAZE_OFFCENTER, RESOLUTION_TOO_LOW, WRONG_ASPECT_RATIO, and CHECK_UNAVAILABLE when part of the assessment could not run (reported as a WARN asking the person to try again, so a photo never passes with checks missing). |
processed | Only when you sent return_processed: true. The stored photo: base64 (JPEG), sizeKB, width, height and framing (face, or centre if no face was found). |
duration_ms | How long the check took on the server. |
A photo that is far too small, or nowhere near portrait shape, fails on the size checks alone, and the face and photo checks are skipped.
For a backend (for example a BFF) that hands tokens to an app, so the app never holds a long-lived API key. Send a client ID and secret set up in the server's CLIENT_CREDENTIALS; no API key is needed for this call.
POST /api/auth/token
Content-Type: application/json
{ "client_id": "bff", "client_secret": "..." }
200 { "token": "...", "expires_in": 300, "token_type": "Bearer" }
Use the token as Authorization: Bearer <token> on one compliance check. Each token works once and lasts TOKEN_TTL_SECS (5 minutes by default). A wrong client ID or secret gets 401.
| Code | Meaning |
|---|---|
200 | Success: result may be PASS, WARN or FAIL |
400 | Bad request: missing image_base64, or an ID longer than 256 characters |
401 | Unauthorised: invalid or missing API key |
429 | Compliance check only: more than 120 requests a minute from one IP address |
500 | Server error |