Error Codes
All API errors return a consistent JSON structure:
{
"code": "VALIDATION_ERROR",
"error": "Missing required field 'externalId'",
"details": {
"field": "externalId",
"constraint": "required"
}
}
HTTP Status Codes
| Status | Title | Description | Recovery |
|---|---|---|---|
400 | Bad Request | The request body is invalid or missing required fields | Check the request body against the API schema. Ensure all required fields are present and correctly typed. |
401 | Unauthorized | The API key is missing, invalid, or expired | Verify your API key is correct and active. Check that the Authorization header uses the Bearer prefix. |
403 | Forbidden | The API key doesn't have permission for this operation | Check that your API key has the required scope. Sandbox keys cannot access production endpoints. |
404 | Not Found | The requested resource doesn't exist | Verify the resource ID is correct. The verification may have been deleted or belong to a different tenant. |
409 | Conflict | The request conflicts with the current resource state | Check the verification status. Some operations are only valid in certain states (e.g., document upload requires pending status). |
429 | Rate Limited | Too many requests — you've exceeded the rate limit | Implement exponential backoff. Check the Retry-After header for when to retry. See Rate Limits. |
500 | Internal Server Error | An unexpected error occurred on the server | Retry the request with exponential backoff. If the error persists, contact support. |
Error Codes
| Code | Description | Example message | HTTP Status |
|---|---|---|---|
VALIDATION_ERROR | Request body validation failed | Missing required field 'externalId' | 400 |
VERIFICATION_NOT_FOUND | Verification does not exist | No verification found with ID 'ver_xyz' | 404 |
INVALID_STATE | Operation not valid in current state | Cannot upload selfie before document | 409 |
RATE_LIMIT_EXCEEDED | Too many requests | Maximum verification attempts exceeded for today | 429 |
DOCUMENT_REQUIRED | Document must be uploaded first | Document must be uploaded before selfie | 400 |
SESSION_EXPIRED | Verification session has expired | Verification session expired after 24 hours | 409 |
DUPLICATE_DETECTED | Duplicate document or image detected | Duplicate document image detected | 409 |
TENANT_NOT_FOUND | Tenant ID is invalid | No tenant found with the provided ID | 401 |
Common error scenarios
Missing X-Tenant-ID header
{
"error": "X-Tenant-ID header is required"
}
Fix: Add the X-Tenant-ID header with your tenant UUID to every request.
Invalid verification ID
{
"error": "invalid verification ID"
}
Fix: Ensure the verification ID is a valid UUID. Verification IDs are returned when you create a session.
Wrong verification state
{
"code": "INVALID_STATE",
"error": "Cannot upload selfie before document"
}
Fix: Follow the verification flow in order: create → document → selfie → complete. Check the current status with GET /verifications/{id}.
Invalid image type
{
"error": "invalid image type: photo"
}
Fix: Use one of the valid image types: document_front, document_back, selfie, liveness_frame.
Best practices
- Retry with backoff — For
429and5xxerrors, implement exponential backoff starting at 1 second - Check status before operations — Call
GET /verifications/{id}to check the current state before performing actions - Handle idempotently — Use the
externalIdto track verifications. Re-creating with the sameexternalIdis safe. - Validate webhook signatures — Always verify the HMAC-SHA256 signature before processing webhook payloads
- Use sandbox for testing — Use
test-approve-*,test-reject-*, etc. as external IDs in sandbox for deterministic results