Docs · Reference
Test mode
Every organisation gets a sk_test_... key with no card required. Test-mode sessions never touch a real face/document/card provider and are never billed — build and rehearse your whole integration for free before you flip to live.
Test vs. live keys
Which provider set a session uses is decided entirely by which key created it — there is no separate “mode” request field. A sk_test_... key always resolves to the deterministic simulated providers below; a sk_live_... key always resolves to the real ones. The session’s mode field in every API response and webhook event reflects this, so you can tell which produced a given result.
Simulated verifications are unlimited and free — they’re excluded from usage and billing entirely, not just discounted.
Credit card check
The only method with an on-screen simulated-outcome picker today. In test mode, the hosted flow’s card step shows two buttons instead of a real card form:
| Field | Type | Description |
|---|---|---|
Simulate a credit card (pass) | seti_simulated_pass | Resolves pass, confidence medium. |
Simulate a non-credit card (fail) | seti_simulated_fail | Resolves fail, confidence medium, reason not_credit_card. |
Any other setupIntentId resolves fail with reason unrecognized_simulation. As in live mode, the card check is only offered when the session’s required_age is 18 — it never applies to a 16+ check, test or live.
Facial estimation and ID document checks
These two don’t have on-screen simulate buttons yet — the hosted flow always captures a real photo (from your camera or a file upload) and uploads it under a freshly-generated, random key. Internally, the simulated provider looks for specific substrings in that upload key to decide the outcome:
| Field | Type | Description |
|---|---|---|
face_estimation | upload key contains "pass" | Resolves pass, confidence high. |
face_estimation | upload key contains "inconclusive" | Resolves inconclusive, confidence low — triggers the escalation waterfall to the next method in the session, same as live. |
face_estimation | upload key contains "fail" | Resolves fail, confidence high, reason age_below_threshold. |
id_document | selfie key contains "mismatch" | Checked first — resolves fail, confidence high, reason face_mismatch, regardless of the document key. |
id_document | document key contains "pass" | Resolves pass, confidence high (when the selfie key doesn't say mismatch). |
id_document | document key contains "fail" | Resolves fail, confidence high, reason age_below_threshold. |
Because the hosted flow generates that upload key itself (it’s never something you or your user types), none of these substrings are reachable from an ordinary capture today — any real selfie or document photo you submit in test mode falls through to the default, fail with reason unrecognized_simulation. In practice: use the credit card check above to rehearse a pass end-to-end (webhook, redirect, SDK callback all fire identically regardless of which method produced the result), and treat a face/document capture in test mode as always resolving to a deterministic fail. If your integration needs a scripted pass/inconclusive path for these two methods specifically, get in touch — this is a known gap in the test-mode UI, not a design decision.