Skip to content
Sendozi

Getting started

Sandbox testing

A sk_test_ key runs requests through the same endpoints and the same request validation, records the message, and stops before sending or charging. It skips the account checks - Sender ID approval, KYC, wallet and the transactional limits - so a clean sandbox run is not proof a live send will pass.

By SendoziUpdated 3 min read

What sandbox mode is

Sandbox is a property of the API key. A request made with a sk_test_ key goes to the same endpoints as a live one and is validated the same way, then the message is recorded as sent without reaching a network and without touching the wallet.

What sandbox checks, and what it skips

CheckSandboxProduction
API key active and scoped for the endpointYesYes
Route present (transactional or promotional)YesYes
Message present, within length, passes the content policyYesYes
At least one valid Nigerian number; invalid and repeated numbers removedYesYes
Opted-out numbers removedYesYes
Transactional: one recipient and an Idempotency-KeyYesYes
Transactional: the workspace's limits per minute and per dayNoYes
Platform maintenance modeYesYes
Workspace active, KYC approved, production accessNoYes
Sender ID approved for the routeNoYes
Wallet not frozen and balance covers the costNoYes
Promotional hours (08:30 to 19:30 WAT)NoYes
Sent to a networkNoYes
Wallet reserved and chargedNoYes

What a sandbox send returns

  • The send response is the same shape as a live one, with "mode": "sandbox". estimated_cost_kobo shows what the send would cost live; reserved_cost_kobo is 0.
  • Each message moves from queued to accepted and stays there. There is no delivery report in sandbox, so no message becomes delivered, failed or expired.
  • customer_price_kobo on a sandbox message is 0.
  • Sandbox messages appear in GET /v1/messages alongside live ones, told apart by mode.
  • Webhooks fire for sandbox sends: message.sent when each message is recorded, and batch.completed when the batch finishes. message.delivered never fires in sandbox; use the endpoint test to exercise your receiver.

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" \
  -H "Idempotency-Key: sandbox-check-001" \
  -d '{
    "sender": "YourBrand",
    "recipient": "08012345678",
    "message": "Sandbox test.",
    "route": "promotional"
  }'

What to test in sandbox

  • Recipient handling: send a mix of formats (08012345678, 8012345678, +2348012345678), a duplicate and an invalid number, and check accepted_count, duplicates_removed and invalid_count.
  • Page counting: send your longest rendered message and check estimated_cost_kobo matches your estimate. One character outside GSM-7 halves the characters per page.
  • Error handling: branch on error.code, never on the message text.
  • Idempotency: send twice with the same key and body, and confirm the second answer has the same batch_id.
  • Webhook receivers: POST /v1/webhooks/endpoints/{id}/test sends a signed test.ping so you can check signature verification.

Before you switch keys

  1. 1

    Sender ID approved for the route you send on

    Otherwise sender_id_not_approved, or sender_id_route_mismatch for a transactional send on a Sender ID approved for promotional only.

  2. 2

    Wallet funded for the whole send

    The full estimated cost is reserved when a live send is accepted.

  3. 3

    Webhook endpoint registered and tested

    Before real deliveries depend on it.

  4. 4

    One live message to your own phone

    The only test of the last mile.

Frequently asked questions

Is there a separate sandbox URL?
No. Sandbox uses the same base URL and endpoints. The sk_test_ key prefix selects it.
Does sandbox cost anything?
No. The estimated cost is reported in the response, but nothing is reserved or charged.
Will a sandbox message reach a real phone?
No. A sandbox message is never handed to a network.
Why did my send pass in sandbox and fail live?
Sandbox skips the account checks. The usual causes are a Sender ID not approved for the route, or an unfunded wallet.

Get a sandbox key

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