Skip to content
Sendozi

Getting started

Sandbox testing

Sandbox is the same API with the same validation, reached with a sk_test_ key. The send is recorded, no provider is called and nothing is debited. It is not a separate environment and needs no separate base URL.

By SendoziUpdated 3 min read

What sandbox mode is

Sandbox is a property of the API key, not of the environment. Send a request with a sk_test_ key and Sendozi validates it exactly as it would a live one, records the message, and stops short of calling a provider or debiting the wallet.

This matters because the usual failure of a mock environment is that it diverges from production. Here there is nothing to diverge: same host, same routes, same validation code. Switching to production is a change of environment variable, not a change of code.

What sandbox does and does not check

CheckSandboxProduction
Platform maintenance modeYesYes
Recipient valid for the channelYesYes
Content policyYesYes
Recipient suppressionYesYes
API key activeNoYes
Workspace activeNoYes
KYC and production accessNoYes
Channel active for the workspaceNoYes
Sender ID approvedNoYes
Wallet balanceNoYes
Provider dispatchNoYes
Wallet debitNoYes

Using it

The only difference is the key
Shell
# Development
export SENDOZI_API_KEY="sk_test_..."

# Production
export SENDOZI_API_KEY="sk_live_..."
Request
curl -X POST https://api.sendozi.com/v1/sms/send \
  -H "Authorization: Bearer $SENDOZI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "sender": "Sendozi",
    "recipient": "+2348012345678",
    "message": "Sandbox test.",
    "sms_type": "transactional"
  }'

The response reports mode: "sandbox" and a customer_price_kobo figure, so you can assert on what a send would have cost without paying it. Sandbox messages appear in GET /v1/messages alongside live ones and are distinguished by mode.

What to test in sandbox

  • Recipient normalisation - assert that a local 0-prefixed number is rejected before it reaches production.
  • Page counting - send your longest merge-field expansion and check customer_price_kobo matches your estimate.
  • Error handling - assert your client branches on error.code rather than on the message text.
  • Idempotency - send twice with the same key and confirm you get one message, not two.
  • Webhook receivers - use POST /v1/webhooks/endpoints/{id}/test to exercise signature verification.
  • Rate-limit backoff - confirm your client honours the delay in the resolution rather than hammering.

Before you switch keys

  1. 1

    KYC approved

    Otherwise every live send returns kyc_required.

  2. 2

    Sender ID registered and approved

    Otherwise sender_id_not_approved. Registration depends on the networks, so start early.

  3. 3

    Wallet funded

    For the whole first campaign, not the first few messages.

  4. 4

    Webhook endpoint registered and verified

    Test it before real deliveries depend on it.

  5. 5

    One real message to your own phone

    The only test that exercises the last mile.

Frequently asked questions

Is there a separate sandbox URL?
No. Sandbox uses the same base URL and the same endpoints. The sk_test_ key prefix is what selects the behaviour.
Does sandbox cost anything?
No. A sandbox send is recorded and priced in the response, but no provider is called and nothing is debited from the wallet.
Will a sandbox message reach a real phone?
No. Sandbox stops before provider dispatch, so nothing is transmitted to a network.
Why did my send work in sandbox and fail in production?
Sandbox skips the account gates. The usual causes are KYC not approved, the sender ID not registered, or an unfunded wallet - none of which sandbox checks.

Get a sandbox key

Create an account and issue a sk_test_ key from the Console.