TrustWixDocs

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 valueResulting verdictResulting status
approved, approveapproveapproved
rejected, rejectrejectrejected
review, manual_reviewreviewmanual_review
pendingnone yetpending

Anything else behaves like pending: the checks are created but left unresolved, exactly as a live session behaves before the user has submitted anything.

Force an approval
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" } }'
Force a decline, using the email instead
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.

On this page