Every API key is bound to one region (us or eu) and one mode (test or live). The prefix encodes both, and the SDK uses it to pick the right endpoint. You cannot move data between regions, and a key issued in one region does not work against the other.
Test vs live mode
Section titled “Test vs live mode”Test mode is isolated from live mode. Verifications, applicants, checks, and webhook deliveries created in test mode never touch live data and never bill against your wallet.
Test-mode emails are suppressed: no real delivery occurs. They still appear in the email log so you can inspect what would have been sent.
You can wipe all test-mode data for an organization at any time from Developers → Test data. The purge is irreversible: see Test data.
Test mode is a zero-friction, fully synthetic sandbox
Section titled “Test mode is a zero-friction, fully synthetic sandbox”Test mode is free and provably synthetic, and it is the safe place to build your integration end to end before going live:
- Free, no billing. Every check runs free. Test mode has no wallet and no subscription, so you do not need to fund anything to run a test verification. Billing applies to live mode only. (Your activity still meters into the dashboard so you can see counts.)
- No real checks, no real data. A test verification runs no real checks: document capture, selfie, and liveness are simulated in the browser, with no real data, camera, or biometrics used. Every result is synthetic.
- You pick the outcome. When you start a test verification you choose an Expected outcome (Pass, Needs review, Fail, or Document quality issue), and that one choice drives a coherent synthetic verdict across every check in the verification (document, face match, and liveness). The default is Pass. This replaces guessing at magic identifiers: one picker, one outcome.
Switch to live mode when you are ready to verify real applicants, at which point checks run for real and bill against your wallet.
Forcing an outcome in test mode
Section titled “Forcing an outcome in test mode”There are exactly four reserved values, and nothing else is accepted.
| Value | Console label | What it produces |
|---|---|---|
pass |
Pass | Clears every check. |
review |
Needs review | A borderline result that routes the verification to manual review. |
fail |
Fail | A result that does not clear verification. |
doc_quality |
Document quality issue | A document that cannot be fully read, which routes the verification to manual review. |
You enter the value in one of three places, and they are the only three:
| Where | Field |
|---|---|
| Console | The Expected outcome picker on the new-verification form. It appears in test mode only. |
POST /v1/sessions |
expected_outcome, in the JSON body. |
POST /v1/id-verification |
expected_outcome, as a multipart form field. |
The value is fixed when the verification is created and applies to every check in it. There is no per-step or per-request override, and no reserved name, date of birth, document number, or email address changes a result: what the applicant types never influences the synthetic outcome. So the question of which input wins does not arise. One value, chosen once, drives the whole verification.
Omitting the value on a test-mode POST /v1/sessions is the same as sending pass. On a live-mode POST /v1/sessions the field is dropped, so a forged expected_outcome can never stamp a synthetic result on a real verification. POST /v1/id-verification is stricter and rejects a live-mode request that carries the field at all: see the standalone ID-scan endpoint below.
A check reads the value in the way that makes sense for what it does. Identity verification synthesizes the document, face-match, and liveness results from it. A check that replays a recorded file, such as credit history, uses it to pick which recorded file is replayed.
The standalone ID-scan endpoint
Section titled “The standalone ID-scan endpoint”POST /v1/id-verification is a separate, stateless scan API: it extracts identity fields from an uploaded document image without creating a verification. Test mode applies to it the same way it applies to a verification: a test-mode key returns a synthetic extraction result rather than reading your document.
To be precise about what happens to the image you upload, because test mode does not change the request you make: you still send it to this endpoint, and we still validate it (format and size). In test mode we then discard it. It is never stored, and it is never passed on for extraction.
The same four outcomes are available as an optional expected_outcome multipart field, test mode only, defaulting to pass when omitted. pass and review return 200. Fail and Document quality issue both return 422 document_unreadable and are indistinguishable in the response - the two are told apart only in your organization’s audit trail, never on the wire.
Every upload validation rule still runs in test mode: the image format check, the 10 MiB per-image and 21 MiB total size limits, and the full error taxonomy. A test key still exercises your multipart encoding and error handling; it does not exercise how a real document reads.
A live-mode request that includes expected_outcome is rejected with 422, unlike POST /v1/sessions, which silently drops the field on a live request - this endpoint treats every unrecognized multipart field as a security concern and rejects it outright. Every response reports which mode produced it, so a synthetic result is never mistaken for a real one. Where you read it depends on the status: a 200 carries it as data.mode, and a 422 document_unreadable carries it as error.details.mode. No other error response carries it.
US vs EU regions
Section titled “US vs EU regions”Customer data is pinned to the region of the organization that owns it. We do not replicate tenant data across regions. EU verifications run entirely within the EU region against an EU-approved configuration for any organization in the EU region.
| Region | API endpoint | Console |
|---|---|---|
| US | https://api.us.checktiv.com |
https://console.us.checktiv.com |
| EU | https://api.eu.checktiv.com |
https://console.eu.checktiv.com |
How keys encode region and mode
Section titled “How keys encode region and mode”Every API key has the form ah_{type}_{region}_{mode}_{secret} where type is sk (secret) or pk (publishable); region is us or eu; and mode is live or test. Example: ah_sk_us_test_<your-key>.
Picking the right endpoint
Section titled “Picking the right endpoint”Send each request to the API endpoint that matches the key’s region. A ah_sk_us_… key against api.eu.checktiv.com returns region_mismatch.
Switching mode in the console
Section titled “Switching mode in the console”The sidebar’s mode toggle switches between test and live across every page. The current mode persists in your session.
Cross-region rules
Section titled “Cross-region rules”You cannot share an applicant, verification, or webhook endpoint between US and EU. To run identical configuration in both, create one organization per region.