Inyo

Sandbox & Test Data

Sandbox is a full copy of the verification pipeline with its own credentials and its own data. Use it to build and prove your integration before any real customer reaches it.


Access

What you needHow you get it
Sandbox base URLIssued by Inyo at onboarding
client_id / client_secretIssued by Inyo at onboarding, separate from production
webhook_secretIssued by Inyo at onboarding, separate from production
Network accessYour egress IP ranges must be allowlisted β€” send them to your Inyo contact
A registered webhook_urlOptional, but needed to exercise webhook delivery. A tunnel works during development

Sandbox and production credentials are never interchangeable, and a sandbox verification is never a valid basis for a real onboarding decision.


Sandbox Runs Real Verification

Sandbox performs real document analysis β€” the same extraction, authenticity, liveness, and face-match pipeline as production. There is no fixed set of test document numbers that produce canned outcomes, the way test card numbers work for payments.

The practical consequence: test with real documents you personally control, or with documents issued for testing. A verification will genuinely fail if the image is blurry, the document is expired, or the selfie does not match β€” which is exactly what makes sandbox useful for proving your error handling.

Every result carries a provider field. "inyo" means real analysis produced it. "inyo-mock" means a simulator did β€” which never happens in production, and tells you unambiguously that a result did not come from real verification.


Driving Each Outcome

TargetHow to produce it
approvedA valid, unexpired document you control, well lit and in frame, with a selfie of the same person
declined β€” expired documentAn expired document. document_not_expired fails
declined β€” face mismatchA document belonging to one person with a selfie of another. face_match fails
declined β€” screen recapturePhotograph the document off a phone or monitor screen. document_authentic and/or screen_pattern fail
declined β€” unreadableA deliberately blurry or partially covered capture. document_readable fails
declined β€” capture attemptsFail capture repeatedly in the widget until the limit is reached, adding a capture_attempts check
in_review β€” soft checkSend data_check: true with a prefill name or date of birth that does not match the document. data_match fails
in_review β€” held rejectionAsk Inyo to enable held rejections on your sandbox tenant, then produce any readable-document decline
in_review β€” borderline passAsk Inyo to set a review threshold on your sandbox tenant above your face-match threshold, then verify with a marginal selfie
expiredCreate a session and leave it unused past the link's 48-hour lifetime
422 responsesRequest a document type you do not have enabled, or send a malformed prefill.document_number
502Not reproducible on demand β€” handle it as a transient retry path in code

Ask for a separate sandbox tenant if you need conflicting configurations. Review routing and held rejections are tenant-level settings, so exercising both a normal decline and a held decline means changing configuration between runs β€” or having two sandbox tenants.


Testing Without a Camera

The document-number format validator needs no credentials and no images, which makes it the fastest thing to integrate against first:

curl --request POST \
  --url https://{FQDN}/v1/validators/document-number \
  --header 'Content-Type: application/json' \
  --data '{"document_type": "drivers_license", "number": "not-a-number", "issuing_state": "PA"}'
{
  "document_type": "drivers_license",
  "number": "not-a-number",
  "issuing_state": "PA",
  "valid": false,
  "rule": "us_dl:PA",
  "detail": "document number does not match the PA license format"
}

Use it to confirm your handling of all three states β€” true, false, and null for an unknown jurisdiction. See Verification Sessions.


Testing Result Delivery

Delivery is worth testing on its own, independently of verification outcomes:

  1. Signature verification β€” capture one real sandbox webhook body and its X-Inyo-Signature, then unit-test your verifier against those exact bytes. Add a case that mutates one byte of the body and asserts rejection, and a case that re-serializes the parsed JSON and asserts rejection. Those two cases catch the mistake that breaks most integrations.
  2. Retry behavior β€” return 500 from your endpoint and confirm you see up to three attempts, then nothing.
  3. Ordering β€” replay two stored notifications for one session out of order and assert your handler keeps the one with the higher notified_at.
  4. Idempotency β€” deliver the same result twice and assert your system does not double-process it.

Steps 1, 3, and 4 need no sandbox call at all once you have captured one real payload.


Before You Go Live

CheckWhy
Signature verification runs against raw bytesThe most common production failure
in_review has a pending state in your modelIt is neither approved nor rejected, and it arrives on redirects too
Concurrent results resolve by notified_atDeliveries can arrive out of order
A completed outcome can be reversedQuality-control overrides re-deliver a changed result
502 retries rather than decliningIt is an infrastructure failure, not a customer outcome
Production credentials are separate and the base URL is switchedSandbox tokens are not valid in production
A reconciliation job polls non-terminal sessionsDelivery is best-effort; GET /v1/sessions/{session_id} is authoritative

Next Steps