VeroID

Errors

Error handling and response codes

VeroID uses standard HTTP status codes and returns detailed error information in JSON format.

HTTP Status Codes

CodeMeaning
200Success
400Bad Request - Invalid parameters
401Unauthorized - Invalid or missing API key
402Payment Required - Insufficient credits
403Forbidden - Your account is not a developer account, or is not approved for this environment
404Not Found - Resource doesn't exist
422Unprocessable Entity - Sandbox screening name not in the test list
429Too Many Requests - API rate limit or document cooldown (DOCUMENT_COOLDOWN)
500Internal Server Error

Error Response Format

{
  "error": "Error Type",
  "code": "ERROR_CODE",
  "message": "Human-readable description",
  "verificationId": "ver_..." 
}

Authentication Errors (401)

{
  "error": "Unauthorized",
  "message": "Missing API key. Include X-API-Key header."
}

Credit Errors (402)

{
  "error": "Payment Required",
  "message": "Insufficient credit balance. Please purchase more credits."
}

Sandbox Screening Errors (422)

Returned when a sandbox screening request uses a name that is not one of the predefined test triggers. The response includes testNames with the valid values. See Sandbox for the full list.

{
  "error": "Unprocessable Entity",
  "code": "SANDBOX_SCREENING_NAME_REQUIRED",
  "message": "Sandbox screening only accepts predefined test names...",
  "testNames": [
    "screenclear",
    "screensanction",
    "screenpep",
    "screenpossible",
    "screenmultiple",
    "screenmedia",
    "screenrca"
  ]
}

Access Errors (403)

Returned when a sk_live_* key is used before the onboarding fee is settled or before VeroID has approved your account for live production verification. This applies to every endpoint, including test-api.veroid.com.au. Use a sk_test_* key on the test endpoint until your account is approved for production.

{
  "error": "Forbidden",
  "message": "Live verification is locked until your account is approved for the production verification hub. Use a test key against the test endpoint in the meantime."
}

If the onboarding fee is the blocker, the message names it instead:

{
  "error": "Forbidden",
  "message": "Live keys are issued once the one-time developer onboarding fee is paid. Use a sandbox key against the test endpoint in the meantime."
}

The API is only available to developer accounts. If the account has been switched to the dashboard track, its keys stop working entirely:

{
  "error": "Forbidden",
  "message": "API keys are not part of a dashboard account. Switch to a developer account to integrate over the API."
}

Expanded verification responses

A successful HTTP 200 from POST /v1/verify can still mean the document did not match. Expanded verification responses (field-level detail in the errors array) are not HTTP errors - they are part of a normal verification outcome when status is failed, invalid_input, or responseCode is D.

{
  "success": true,
  "responseCode": "N",
  "status": "failed",
  "match": false,
  "errors": [
    { "source": "issuer", "field": "BirthDate", "message": "Date of birth does not match." }
  ]
}

See Expanded Responses in the API reference. Do not retry identity no-match (N), validation failures (invalid_input), or D. Only system errors (S, or HTTP 500) are transient. Live credits are not deducted for invalid_input.

Rate Limits

LimitValue
Requests per second10
Requests per minute100
Requests per hour1,000

When the per-key rate limit is exceeded, the API returns HTTP 429 with a Retry-After header (seconds).

API error codes (code field)

Top-level JSON errors use a code string. Verification and session failures may also include error.code on the resource. Legacy codes prefixed with DVS_ may appear as deprecatedCode during a transition period; integrate against the neutral name only.

CodeTypical HTTPMeaning
SANDBOX_SCREENING_NAME_REQUIRED422Sandbox screening name not in test list
DOCUMENT_COOLDOWN429Same document resubmitted too soon
DOCUMENT_LOCKED500Issuer temporarily locked the document
HUB_NOT_CONFIGURED500Verification hub not configured for this environment
HUB_SYSTEM_ERROR500Transient hub or system failure (retry may help)
INTERNAL_ERROR500Unexpected server error
INSUFFICIENT_CREDITS402Prepaid balance too low

Verify session error codes (GET /v1/verify/sessions/:id)

CodeMeaning
SMS_SEND_FAILEDSMS could not be sent for hosted link sessions
FACE_MATCH_FAILEDBiometric face match step failed
NOT_MATCHIssuer did not match submitted details
FINISH_IN_PROGRESSConcurrent finish request; poll session again
DOCUMENT_LOCKEDIssuer temporarily locked the document
HUB_NOT_CONFIGUREDHub unavailable for this check

Embedded form browser errorCode values

The iframe posts veroid-embed messages with type: "error". Common errorCode values include session_expired, session_cancelled, network_error, camera_denied, validation_error, and submit_failed. Treat these as UX signals; authoritative outcomes are on the session API and webhooks.

Verify session statuses

status on the session API reflects server state. The embed complete event uses submitted only as a browser-side signal that the form was submitted; it is not a session API status.

  • created - session record created
  • sms_sent / sms_failed - SMS delivery outcome for link sessions
  • opened - subject opened the hosted page
  • consent_given - consent step completed
  • fields_captured - document fields captured
  • processing - issuer check in progress
  • completed - finished with a result
  • failed - finished with an error
  • expired - past expiresAt
  • cancelled - cancelled via API

Idempotency (create endpoints)

Optional Idempotency-Key headers on POST /v1/verify/sessions, POST /v1/verify/embed-sessions, and POST /v1/screening. Keys are scoped per account, test or live environment, and endpoint. Retention is 24 hours. Without a key, behaviour is unchanged.

OutcomeHTTPCode / headerWhen
Successful create or replay201 (verify sessions) or 200 (screening)Idempotent-Replayed: true on replay onlySame key and same JSON body within 24 hours
Invalid key400INVALID_IDEMPOTENCY_KEYEmpty or whitespace-only key, or longer than 255 characters
Key reused with different body422IDEMPOTENCY_KEY_REUSED_WITH_DIFFERENT_PARAMSSame key within 24 hours but request JSON differs for that endpoint
Embed replay unavailable409IDEMPOTENCY_REPLAY_UNAVAILABLEPOST /v1/verify/embed-sessions only: original session exists but clientSecret cannot be replayed (encryption not configured). Use GET /v1/verify/sessions/:id for the outcome.

Concurrent retries with the same key and body wait on a server-side lock, then return the original create response (201 or 200 with Idempotent-Replayed: true). They do not return 409 for duplicate in-flight creates.

Document cooldown (429)

On live verification, submitting the same document details again too soon returns HTTP 429 with code DOCUMENT_COOLDOWN - before the request reaches the issuer. This protects against issuer lockouts when users retry quickly after a typo or failed check.

{
  "error": "Too Many Requests",
  "code": "DOCUMENT_COOLDOWN",
  "message": "This document was verified recently. Wait before submitting the same document again.",
  "retryAfterSeconds": 45
}

If the issuer or verification hub has already locked the document, the cooldown is longer (about 5 minutes) and the message references a temporary document lock. Honour Retry-After and do not auto-retry with the same payload. See Best Practices.

Document temporary lock (500)

When the verification hub returns "Document Temporarily Locked", the API responds with HTTP 500, code DOCUMENT_LOCKED, and a Retry-After header. Wait before submitting the same document details again - do not treat this like a system error (S) retry loop.

{
  "success": false,
  "error": "Verification Failed",
  "code": "DOCUMENT_LOCKED",
  "deprecatedCode": "DVS_DOCUMENT_LOCKED",
  "message": "Document Temporarily Locked",
  "verificationId": "ver_...",
  "retryAfterSeconds": 300
}