Sandbox and magic values
Force any outcome deterministically so you can build and test result handling with no real faces
A sandbox key puts every request into sandbox mode. No real checks run and nothing is metered, but the API still receives whatever applicant fields you send, so use synthetic data only and never send production identity data. You decide the outcome by passing a magic value on the applicant, which makes integration tests deterministic and repeatable.
Magic applicant values
TrustWix looks at applicant.reference_id first, then at the local part of applicant.email, and
matches it against the table below. The match is case-insensitive.
| Magic value | Resulting verdict | Resulting status |
|---|---|---|
approved, approve | approve | approved |
rejected, reject | reject | rejected |
review, manual_review | review | manual_review |
pending | none yet | pending |
Anything else behaves like pending: the checks are created but left unresolved, exactly as a live
session behaves before the user has submitted anything.
curl https://api.trustwix.com/v1/verifications \
-H "Authorization: Bearer TWK_..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: sandbox-approval-1" \
-d '{ "applicant": { "reference_id": "approved" } }'curl https://api.trustwix.com/v1/verifications \
-H "Authorization: Bearer TWK_..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: sandbox-decline-1" \
-d '{ "applicant": { "email": "rejected@example.com" } }'These verification-create requests carry an Idempotency-Key. Reuse the same key when retrying the
same logical request and a retry can never create a second verification.
See Idempotency.
What a forced outcome produces
The verdict is applied to every check in the flow, and each check that is not approved carries a
representative reason code for its type. That means a forced reject on a flow containing a
document check produces a document reason code, a forced reject on a liveness check produces a
liveness one, and so on. This lets you test the exact copy you show users for each failure without
guessing at the shape.
Reason codes are stable, upper snake case strings. See Reason codes for the published vocabulary.
Webhooks in sandbox
Sandbox verifications fire the same events as live ones, with the same envelope and the same signature scheme, so a handler built against sandbox traffic works unchanged in production.
They go to your sandbox endpoints, though, not your live ones. An endpoint belongs to the environment of the key that registered it, so register one in each and a sandbox event can never reach the handler that grants real access.
Test the terminal path first
The single most common integration bug is treating a non-terminal status as final. Force
pending at least once and confirm your handler does nothing until the status is approved,
rejected or manual_review.
Moving to live
Nothing about your code needs to change. Swap the sandbox key for a live one, remove the magic applicant values, and the same calls run against real checks. Work through Go live before you do.
One thing does change, and it is not the code: a live key starts with a narrower permission set than a sandbox one, so a few reads that worked in your tests return 403 in production. See Permissions for which ones and why.