Test vs. live
Two isolated environments. Same dashboard, same SDK, different keys.
Why two environments
- Test is for development. Verify with mock passports, iterate on rules and webhooks, never bill credits.
- Live is for production. Real documents, real proofs, real billing.
The environments don’t share data, flows, sessions, or webhook endpoints.
How they’re separated
- API keys are bound to one environment, reflected in their prefix:
sk_test_...vs.sk_live_.... The key is what decides the environment: a session created with a test key is a test session, one created with a live key is a live session. - Flows serve both environments. A deployed configuration has a single
flowIdthat works with either key. You don’t create a separate flow for live. The workspace’s Test and Live tabs show the sameflowIdwith that environment’s credentials and webhooks. - Webhook endpoints are per-environment (set on the Test/Live tab). Set up
https://staging.example.com/webhooks/selffor test andhttps://prod.example.com/webhooks/selffor live, with separate secrets. Test sessions only deliver to test endpoints. - Billing never applies in test. Test verifications consume no credits, and credit balance is for live only.
- On-chain flows map the split to networks: test sessions verify on Celo Sepolia, live sessions on Celo Mainnet, each against its own contract.
Mock passports
In test, you verify with a mock passport created in the Self app, with attributes you control (nationality, age, OFAC status), so you can exercise every branch of your handler without real users or real documents.
Mock credentials are cryptographically distinct from real ones and never verify against a live flow.
See Using mock passports for the steps.
Going live
The same flowId serves both environments, so going live is a key swap, not a re-deploy:
- Generate a live API key under Developer → API keys (the Live tab).
- Register your production webhook endpoint on the Live tab, with its own signing secret.
- Point your backend at the live key (
sk_live_…) and the live webhook secret. TheflowIdstays the same.
For an on-chain flow, confirm the Live tab’s contract shows Deployed: live sessions verify against the Celo Mainnet contract.
Common test-mode patterns
Run an integration test in CI
// In CI environment:
process.env.SELF_API_KEY = 'sk_test_...';
process.env.SELF_FLOW_ID = '<test flow uuid>';
process.env.SELF_WEBHOOK_SECRET = 'whsec_...';
// The test creates a session, simulates a mock-passport completion,
// and asserts the webhook handler fires with the expected payload.
Run a staging environment
Use test keys + a test webhook endpoint, pointing at your staging backend. Real verification flows for your QA team, no production billing exposure.
What to never do
- Don’t put a live key in a test environment. Test environments tend to log requests, screenshot UIs, and store payloads in dev databases. A live key in any of those places is a security incident.
- Don’t reuse a webhook signing secret across environments. Each endpoint gets its own. Mixing them is how you end up running test events against your prod database.
Thanks for your feedback!