DOCUMENTATION
Send your first SMS in a few minutes
The Sendozi API is plain HTTPS with JSON. There is no SDK to install and no separate sandbox host: the same endpoints serve test and live traffic, and the key prefix decides which.
curl -X POST https://api.sendozi.com/v1/sms/send \
-H "Authorization: Bearer $SENDOZI_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: first-send-001" \
-d '{
"sender": "YourBrand",
"recipient": "08012345678",
"message": "Welcome to Acme. Your account is ready.",
"route": "promotional"
}'- Base URL
- https://api.sendozi.com
- Version
- v1
- Auth
- Bearer API key, or X-API-Key
- Sandbox
- sk_test_ keys, same endpoints
- SMS rate
- ₦7.00 per page
- Send rate limit
- 300/min per workspace
- Max SMS length
- 1000 characters, 469 in Unicode
- Recipients
- Nigerian mobile numbers, 080… or +234…
- Per request
- up to 1,000,000 recipients
Getting started
Quickstart: send your first SMS
Create a sk_test_ key in the Console, POST to /v1/sms/send with a sender, a recipient, a message and a route, and read back the queued batch. Follow the message_id to its delivery status, then swap to a sk_live_ key.
Authentication, API keys and scopes
Send the API key as a bearer token. sk_test_ keys are sandbox and sk_live_ keys are production. Each key carries scopes that decide which endpoints it may call, and a key is shown once, stored as a hash, and replaced rather than recovered.
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.
Sending
Sending SMS
POST /v1/sms/send or /v1/sms/bulk with a sender, one or more recipients, the message and a route. The send is queued and answered with 202 and a batch: invalid, repeated and opted-out numbers are removed and counted, the cost is reserved, and each recipient is charged as it is handed to the network.
Transactional SMS: OTPs, alerts and receipts
Transactional SMS carries one person's own event - an OTP, a payment alert, a receipt. Each request has exactly one recipient and an Idempotency-Key, and the message is your own text: there are no templates to register or match.
Messages, batches and delivery status
A send returns a batch_id. The batch holds one recipient per accepted number, and each recipient becomes a message with its own message_id. Look up either by id, page through recipients to see every number's outcome, and cancel a batch that is still queued or sending.
Reliability
Webhooks
Register an HTTPS endpoint with POST /v1/webhooks/endpoints and Sendozi POSTs each event to it as JSON, signed with HMAC-SHA256 using a secret shown once at creation. A failed delivery is retried for about 46 hours, and an endpoint that keeps failing is paused with its events held until you resume it.
Idempotency and safe retries
Send an Idempotency-Key header on POST /v1/sms/send and /v1/sms/bulk. A repeat with the same key and the identical body returns the original response and sends nothing. Keys belong to your workspace and last 24 hours. Transactional sends require one.
Errors and the response envelope
Every response has success, then data or error, and a request_id. An error carries a stable code, a message and a resolution. 4xx codes are answers about your request and will repeat if resent unchanged; 429 and 5xx are worth retrying with the same Idempotency-Key.
Limits, large sends and pagination
Send endpoints allow 300 requests a minute per workspace, and one request can carry up to 1,000,000 recipients. A send is accepted into a queue and handed to the networks at a steady rate, so a large campaign takes time to go out. Lists use cursor pagination.
Reference
Account, balance, usage and Sender IDs
GET /v1/me identifies the key and its workspace, GET /v1/account/balance returns the wallet in kobo and naira, GET /v1/account/usage counts messages and spend for the key's mode, and GET /v1/sms/sender-ids lists Sender IDs with their route and status. None of them change anything.
Integrations
Send SMS with Node.js
Node 18 and later include fetch, so no package is needed. The client below sends promotional and transactional SMS with an Idempotency-Key, throws a typed error carrying error.code, and pairs with a webhook receiver that verifies the timestamped signature.
Send SMS with Python
There is no Sendozi Python SDK; httpx or requests is enough. The client below serialises each body once, retries network errors, 429 and 5xx with the same Idempotency-Key, and raises an error carrying error.code. The receivers verify the timestamped signature over the raw body.
Send SMS with PHP and Laravel
There is no Sendozi PHP package. Plain PHP posts JSON with cURL; Laravel uses Http::withToken. Encode each body once, retry network errors, 429 and 5xx with the same Idempotency-Key, keep the key in config, and queue anything larger than a single OTP.
Sending SMS over SMPP
Banks, fintechs and aggregators can send to Sendozi over SMPP 3.4 as well as the HTTP API. Sendozi creates the account; you bind from your allowed IPs with the system ID and password, send submit_sm with your approved Sender ID, and receive delivery receipts as deliver_sm on the same connection.
Channel availability
- SMSLive
- Bulk and transactional SMS to Nigerian numbers is live. Production sending opens once KYC is approved and a sender ID is registered.