API Reference

REST API for photo compliance validation.

Compliance
POST /api/v1/compliance/check Run photo compliance check
Docs
Try it
Authentication
Authorization: Bearer <api_key>
Content-Type: application/json
Request body
FieldTypeRequiredDescription
image_base64stringrequiredBase64-encoded JPG or PNG, up to 25MB. Send the photo as the camera took it: the server frames and compresses it once itself.
media_typestringoptionalimage/jpeg or image/png (default: image/jpeg). The server measures the photo's size and shape itself.
applicant_idstringoptionalYour 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_idstringoptionalYour 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.
filenamestringoptionalShown on the dashboard, up to 256 characters.
return_processedbooleanoptionaltrue 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.
Example response
{
  "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
}
Response fields
FieldMeaning
request_idThis check's ID: your session_id, or one the server made. Always present. Keep it to find the check on the dashboard.
applicant_idYour applicant_id, only present if you sent one.
overallPASS, WARN (usable, with minor issues) or FAIL. Any single FAIL check makes the result FAIL.
score0 to 100. Starts at 100, less 15 for each FAIL check and 5 for each WARN.
summaryPlain 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.
checksEvery 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).
processedOnly 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_msHow 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.

Try it

Drop photo here or click to browse
Short-lived tokens
POST/api/auth/tokenGet a token for one compliance check

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.

HTTP Status Codes
CodeMeaning
200Success: result may be PASS, WARN or FAIL
400Bad request: missing image_base64, or an ID longer than 256 characters
401Unauthorised: invalid or missing API key
429Compliance check only: more than 120 requests a minute from one IP address
500Server error