TrustWixDocs

Sandbox and magic values

Force any outcome deterministically so you can build and test result handling with no real faces

A test key puts every request into sandbox mode. No real checks run and nothing is charged, 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 webhook events as live ones, to the same endpoints, with the same signature scheme. Build your handler against sandbox traffic and it will work unchanged in production.

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.

Sandbox keys are real keys

Sandbox testing always uses a real test key issued from the console, on any environment. The only exception is the fixed local development key, which works exclusively against an API running on your own machine in development mode. Deployed environments reject it outright with a DEV_KEY_NOT_ALLOWED error rather than treating it as an unknown key, so if you see that error you have shipped the local key somewhere real. Replace it with a test key from the console.

Moving to live

Nothing about your code needs to change. Swap the test 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.

On this page