Getting started
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.
How do I authenticate?
Send your API key in the Authorization header as a bearer token. An X-API-Key header is accepted as an alternative.
curl https://api.sendozi.com/v1/me \
-H "Authorization: Bearer $SENDOZI_API_KEY"curl https://api.sendozi.com/v1/me \
-H "X-API-Key: $SENDOZI_API_KEY"GET /v1/me (scope account:read) confirms a key works. It returns the workspace, the key's redacted details and its mode, and sends nothing.
Sandbox and production keys
| Prefix | Mode | What a send does |
|---|---|---|
| sk_test_ | Sandbox | Validates and records the message. Nothing is sent to a network and nothing is charged. See sandbox testing for exactly which checks run. |
| sk_live_ | Production | Runs every check, reserves the cost from the wallet, and sends to the network. |
The same base URL and endpoints serve both modes. The key decides which mode a request runs in; there is no mode field in the request.
Creating a key
- Keys are created in the Console under Developers > API keys, by the workspace owner, an administrator or a developer.
- Your business verification (KYC) must be approved before any key, sandbox or production, can be created.
- The secret is shown once. Sendozi stores a SHA-256 hash of it, so nobody, including Sendozi support, can read it back.
- Creating, rotating and revoking a key emails the workspace and is recorded in the workspace audit log.
Scopes
A key can call only the endpoints its scopes allow. A new key gets every scope unless you choose a narrower set when you create it. A request outside the key's scopes returns 403 insufficient_scope.
| Scope | Endpoints |
|---|---|
| messages:send | POST /v1/sms/send, POST /v1/sms/bulk, POST /v1/message-batches/{id}/cancel |
| messages:read | GET /v1/messages, GET /v1/messages/{id}, GET /v1/message-batches, GET /v1/message-batches/{id}, GET /v1/message-batches/{id}/recipients |
| senders:read | GET /v1/sms/sender-ids, GET /v1/sms/sender-ids/{id} |
| account:read | GET /v1/me, GET /v1/account/balance, GET /v1/account/usage, GET /v1/api-keys |
| webhooks:read | GET /v1/webhooks/endpoints |
| webhooks:manage | POST, PATCH and DELETE /v1/webhooks/endpoints, POST /v1/webhooks/endpoints/{id}/test |
Scopes cannot be widened on an existing key. To give a system more access, create a key with the scopes it needs. Keys created before 20 September 2026 predate scope enforcement and keep full access.
Rotating and revoking
- Rotate
- Issues a new secret for the same key id, name, mode and scopes. The old secret stops working the moment the new one is issued, so deploy the new secret immediately.
- Replace without a gap
- Create a second key with the same scopes, deploy it, confirm in GET /v1/api-keys that the old key's last_used_at has stopped moving, then revoke the old key.
- Revoke
- Permanent. A revoked key is refused at once with 403 api_key_blocked. If a key has leaked, revoke first and accept the brief outage.
GET /v1/api-keys lists the workspace's keys with id, name, mode, prefix, status (active, blocked, revoked or expired), scopes and last_used_at. It never returns a secret.
Handling keys safely
- Keep keys in environment variables or a secrets manager, never in source control.
- Call Sendozi only from your own servers. A key can send messages and spend your balance; it has no place in a browser, a mobile app or anything a user can inspect.
- Use one key per system, with only the scopes it needs, so a leak is contained and last_used_at tells you which system it was.
- Restrict your live keys to your servers' IP addresses, so a leaked live key is useless anywhere else.
Restricting live keys to your servers
In the Console under Developers > API keys > IP allowlist, list the addresses your servers call Sendozi from. With at least one address listed, a request with a live key from anywhere else is refused with 403 ip_not_allowed. With the list empty, the default, live keys work from any address.
- Up to 50 entries: IPv4 or IPv6 addresses, or IPv4 ranges no wider than /16.
- Sandbox keys (sk_test_) are never restricted, so you can test from anywhere.
- It applies to every endpoint, not only sends, and takes effect on your next request after you save.
- The address checked is the one Sendozi received the request from; a header cannot change it. If it cannot be determined while a list is set, the request is refused.
- The Console shows the address each live key was last used from, and warns before you save a list that leaves one of them out.
- The ip_not_allowed message names the address the request came from, so you can add it if it is yours.
Authentication errors
| Code | Status | Meaning |
|---|---|---|
| unauthorized | 401 | No key was sent, or the key is not recognised |
| insufficient_scope | 403 | The key does not have the scope this endpoint needs |
| api_key_blocked | 403 | The key is revoked, expired or blocked |
| ip_not_allowed | 403 | A live key used from an address that is not on your IP allowlist |
| workspace_suspended | 403 | The key's workspace is unavailable |
Frequently asked questions
- Where do I get a Sendozi API key?
- In the Sendozi Console under Developers > API keys, once your KYC is approved. The secret is displayed once at creation and cannot be shown again.
- What is the difference between sk_test_ and sk_live_?
- sk_test_ is sandbox: the message is validated and recorded but never sent or charged. sk_live_ is production: the cost is reserved from the wallet and the message is sent. The endpoints and base URL are the same.
- Why does a request return insufficient_scope?
- The key was created without the scope that endpoint needs. Scopes cannot be added to an existing key, so create a key with the right scopes and use it instead.
- Can I limit my Sendozi API keys to my own servers?
- Yes, for live keys. Add your servers' IP addresses under Developers > API keys > IP allowlist in the Console. Live requests from any other address are then refused with ip_not_allowed. Sandbox keys stay unrestricted.
- I lost my API key. Can support recover it?
- No. Keys are stored as SHA-256 hashes, so nobody at Sendozi can read one. Rotate it or create a new key, deploy it, and revoke the old one.
Related reading
Getting started
Quickstart: send your first SMS
Create a sandbox key, send your first SMS, read the queued batch it returns, follow the message to delivery, and switch to production. A complete first integration.
Getting started
Sandbox testing
How Sendozi sandbox mode works, exactly which checks it runs and which it skips, what a sandbox message looks like, and what to test before switching to a live key.
Reliability
Errors and the response envelope
The Sendozi response envelope, every error code the API returns with its HTTP status and fix, which errors are safe to retry, Retry-After, and how request_id traces a request.
Reference
Account, balance, usage and Sender IDs
The read-only account endpoints: who a key belongs to, the wallet balance, lifetime usage, the workspace's Sender IDs and their approval on each route, and the service health check.