Mode is carried by the key
API keys encode their mode in the prefix:| Prefix | Mode | Rails |
|---|---|---|
pk_test_… | test | Sandbox payment instance — KYB/KYC auto-approve, no real money. |
pk_live_… | live | Production payment instance — real rails, real settlement. |
testMode boolean, derived from the
prefix:
Dashboard sessions switch; keys don’t
Dashboard Bearer JWTs also carry a mode, and start in test. The dashboard re-mints the token to switch:400 ProductionAccessNotApproved. Live KYB is
completed afterwards, on the Payout page, before the org can transact.
API-key callers cannot use this endpoint — they already carry their mode in
the key prefix. Calling it with an API key returns:
Data isolation
Test and live are separate datasets. The same scoping that isolates one organization from another (see Authentication → Tenancy) also isolates test from live within your organization:- Invoices and payment intents are tagged with the mode they were created in; list and read endpoints only return the active mode’s records.
- Buyers are scoped per mode — the same buyer email is a distinct record in test and in live, and KYC completed in one does not carry to the other.
- Webhook deliveries reflect only the mode of the invoice that generated them.
Onboarding status
To check whether the caller’s active mode is ready to transact:mode— the active mode of the credential.needsOnboarding—trueuntil this mode’s environment is activated. Test activates as soon as its sandbox KYB clears (auto-approved); live activates only on real KYB approval (after production access has been granted).tosAccepted— whether the payment-provider Terms have been accepted for this mode.kybStatus— the latest KYB submission status for this mode, ornullif none has been started.
Behavior parity
Test mode runs the same code path as live against a sandbox payment instance — the same intent transitions, the same webhook event types, the same response shapes. The only differences are that the sandbox auto-approves compliance and never moves real funds. Build and test againstpk_test_, then flip to pk_live_ for
production.