Sandbox & test keys
Get a test API key in about a minute, with no contract and no KYB. The sandbox is a full copy of the API against synthetic data, where every costly step is mocked and every send is free.
The sandbox lets an engineer try the entire Sender API before any contract
or know-your-business check. You verify an email, sign in to the portal, mint a
kpk_test_ key, and call the same endpoints you would in production, only
against a separate, synthetic data plane where nothing is billed and no real
person is ever contacted.
A key's prefix selects the data plane. kpk_test_ keys are sandbox;
kpk_live_ keys are live. The two never share data. See
Environments for how the switch works.
Get a test key
Signup is fully self-serve. First, submit your email:
curl -X POST https://api.keepable.co/sandbox/signup \
-H "Content-Type: application/json" \
-d '{ "email": "you@example.com" }'{ "message": "If that email can start a sandbox, a verification link is on its way." }The response is identical whether or not the address is already in use, so it never reveals who has signed up. Open the verification link we email you and POST its token back:
curl -X POST https://api.keepable.co/sandbox/verify \
-H "Content-Type: application/json" \
-d '{ "token": "sbx_9f8e7d..." }'{
"tenant_id": "ten_01HXP",
"session_token": "sess_...",
"session_expires_at": "2026-05-24T09:30:00Z",
"email": "you@example.com",
"mode": "sandbox"
}Verify returns a sandbox session token, not an API key. It signs you in to
the portal (the portal stores it in a sender_session cookie), where you set up
a passkey and mint kpk_test_ API keys from the dashboard. Send a minted key as
Authorization: Bearer on every call; see
Authentication for scoping, rotation, and
revocation.
The link token is single-use and expires 30 minutes after signup. If it lapses,
just call /sandbox/signup again.
What's different in the sandbox
The sandbox runs the same code as production, with every costly or irreversible side-effect mocked:
| Concern | Live | Sandbox |
|---|---|---|
| Identity / KYB verification | Real vendor lookup | Deterministic from the test document number (see below) |
| Email + delivery | Real recipient inbox | Synthetic recipients; nothing is sent to a real person |
| Seals | Production KMS key | Non-production key, tagged sandbox- and reported as not legally valid |
| Per-send charges | Debits your wallet | Free and unlimited |
| Data | Your real tenant data | A separate schema-set; sandbox can never read live data |
You do not need an approved tenant, an accepted agreement, or a funded wallet to use the sandbox. Those are only required to go live.
Magic test data
Verification outcomes are driven by the last digit of the document number you submit (a NIN for a person, a CAC/RC or TIN for a business), so you can exercise every branch on demand without a real identity:
| Last digit | Outcome |
|---|---|
0 | Rejected (verification fails) |
9 | Provider unavailable (use this to test your retry/pending handling) |
| anything else | Approved, with a synthetic Sandbox Tester identity |
An empty document number also approves, so a happy-path test that omits it still
succeeds. For example, a NIN of 12345678901 approves; 12345678900 is
rejected; 12345678909 returns provider-unavailable.
Next steps
- Send your first content with your test key.
- When you're ready for production, follow Going live.
Errors
Every non-2xx response is an RFC 7807 problem document. Here is the full catalogue of problem types, what triggers each, and whether to retry.
Going live
Moving from the sandbox to production means clearing three gates (an approved KYB, an accepted Sender Agreement, and a funded prepaid wallet) before you can mint a live key.