Keepable docs
Sender API

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..." }'
201 Created
{
  "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:

ConcernLiveSandbox
Identity / KYB verificationReal vendor lookupDeterministic from the test document number (see below)
Email + deliveryReal recipient inboxSynthetic recipients; nothing is sent to a real person
SealsProduction KMS keyNon-production key, tagged sandbox- and reported as not legally valid
Per-send chargesDebits your walletFree and unlimited
DataYour real tenant dataA 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 digitOutcome
0Rejected (verification fails)
9Provider unavailable (use this to test your retry/pending handling)
anything elseApproved, 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