Error Codes
All API errors return a consistent JSON structure with an error code, message, and request ID.
Error Response Format
{
"code": "VALIDATION_ERROR",
"message": "Validation failed",
"request_id": "req_abc123",
"details": [
{
"field": "name",
"message": "required field"
}
]
}
General Errors
| Code | HTTP Status | Description | Recovery |
|---|---|---|---|
BAD_REQUEST | 400 | Invalid request parameters | Check request body and headers |
VALIDATION_ERROR | 400 | Field validation failed | See details array for specific field errors |
UNAUTHORIZED | 401 | Missing or invalid API key | Check your Authorization header |
FORBIDDEN | 403 | Insufficient permissions | Verify API key scopes and tenant access |
NOT_FOUND | 404 | Resource not found | Check the resource ID in your URL |
CONFLICT | 409 | Resource conflict | Resource already exists or is in conflicting state |
RATE_LIMITED | 429 | Rate limit exceeded | Back off and retry; check X-RateLimit-Reset header |
INTERNAL_ERROR | 500 | Unexpected server error | Retry with exponential backoff; contact support if persistent |
SERVICE_UNAVAILABLE | 503 | Service temporarily unavailable | Retry after a short delay |
Screening Errors
| Code | HTTP Status | Description | Recovery |
|---|---|---|---|
SCREENING_FAILED | 500 | Screening process failed | Retry the screening; switch to ASYNC mode for complex subjects |
SCREENING_TIMEOUT | 503 | Screening exceeded 30-second timeout | Use ASYNC mode instead of SYNC |
INVALID_SUBJECT | 400 | Subject data is invalid | Check required fields: type, name |
Case Errors
| Code | HTTP Status | Description | Recovery |
|---|---|---|---|
CASE_NOT_FOUND | 404 | Case does not exist | Verify the case ID |
CASE_ALREADY_CLOSED | 409 | Cannot modify a closed case | Reopen the case first if changes are needed |
INVALID_DISPOSITION | 400 | Invalid disposition value | Use: TRUE_POSITIVE, FALSE_POSITIVE, ESCALATED, or NO_ACTION_REQUIRED |
Dataset Errors
| Code | HTTP Status | Description | Recovery |
|---|---|---|---|
DATASET_NOT_FOUND | 404 | Watchlist dataset not found | Check the dataset source code |
Identity Verification Errors
| Code | HTTP Status | Description | Recovery |
|---|---|---|---|
VERIFICATION_FAILED | 500 | Identity verification process failed | Retry the verification |
DOCUMENT_INVALID | 400 | Document failed validation | Ensure document image is clear and the type is supported |
FACE_MATCH_FAILED | 500 | Face comparison failed | Retry with a clearer selfie image |
LIVENESS_FAILED | 500 | Liveness check failed | Retry the liveness check |
Handling Errors
Rate Limit (429)
async function screenWithRetry(payload, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
const response = await fetch(`${BASE_URL}/screenings`, {
method: "POST",
headers: {
Authorization: `Bearer ${API_KEY}`,
"X-Tenant-ID": TENANT_ID,
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
});
if (response.status === 429) {
const resetTime = response.headers.get("X-RateLimit-Reset");
const waitMs = new Date(resetTime) - Date.now();
await new Promise((resolve) => setTimeout(resolve, Math.max(waitMs, 1000)));
continue;
}
return response.json();
}
throw new Error("Rate limit exceeded after retries");
}
Validation Error (400)
const response = await fetch(`${BASE_URL}/screenings`, { ... });
if (response.status === 400) {
const error = await response.json();
if (error.code === "VALIDATION_ERROR") {
for (const detail of error.details) {
console.error(`Field '${detail.field}': ${detail.message}`);
}
}
}
Timeout → Switch to Async
If a sync screening times out, retry with async mode:
const response = await fetch(`${BASE_URL}/screenings`, {
method: "POST",
headers: { ... },
body: JSON.stringify({ mode: "SYNC", ... }),
});
if (response.status === 503) {
const error = await response.json();
if (error.code === "SCREENING_TIMEOUT") {
// Retry with async mode
const asyncResponse = await fetch(`${BASE_URL}/screenings`, {
method: "POST",
headers: { ... },
body: JSON.stringify({
mode: "ASYNC",
callback_url: "https://your-server.com/webhooks",
...originalPayload,
}),
});
}
}