Authentication
Every request is authenticated with an API key in the Authorization header:
Authorization: Bearer ssms_sk_test_...Test and live keys
| Prefix | Mode | Behavior |
|---|---|---|
ssms_sk_test_ | Sandbox | Instant, free, simulated delivery; no real SMS ever leaves the sandbox. |
ssms_sk_live_ | Live | Real numbers and real delivery. Mintable once your account has live access. |
Keys issued with an older prefix (dsms_sk_*, resms_sk_*)
are still accepted and will never be revoked for their prefix; new keys mint
as ssms_sk_. See what else kept working
when Delivered became SimpleSMS.
Keys never expire, but you can roll or revoke them anytime from the console. Rolling revokes the old key immediately and mints a replacement.
Storage
Keys are stored hashed (SHA-256), so we can never display a key again after minting it. If you lose one, roll it.
Scopes
A key has full access unless you restrict it. In Console → API keys, choose Restricted and tick the scopes the key needs; a key that leaks can then only do what its job required. Rolling a key keeps its scopes.
| Scope | Allows |
|---|---|
messages:send | POST /v1/messages, POST /v1/test/inbound |
messages:read | GET /v1/messages, GET /v1/messages/{id}, GET /v1/deliverability |
numbers:read | GET /v1/numbers, GET /v1/numbers/available |
numbers:write | POST /v1/numbers, PATCH /v1/numbers/{id}, DELETE /v1/numbers/{id} |
verify | /v1/verify, /v1/verify/check, /v1/verify/{id} |
consent | /v1/consent and everything under it |
lookup | GET /v1/lookup/{phone} |
webhooks | GET /v1/events, POST /v1/events/{id}/replay, GET /v1/webhooks, GET /v1/webhooks/deliveries |
customers | /v1/customers and everything under it |
contacts | /v1/contacts, /v1/segments, /v1/topics and everything under them |
registrations | /v1/registrations and everything under it |
billing | GET/PATCH /v1/spend-limit |
automations | POST /v1/track, /v1/automations and everything under it |
audit_logs:read | GET /v1/audit-logs, GET /v1/exports/audit_log |
A restricted key calling outside its scopes gets:
{
"error": {
"code": "insufficient_scope",
"message": "This API key is missing the `messages:send` scope. Use a key with that scope, or mint one in the console (API keys).",
"required_scope": "messages:send"
}
}Keys minted before scopes existed, and keys minted without choosing any, keep full access.
Errors
| Status | Code | Meaning |
|---|---|---|
| 401 | invalid_api_key | Missing, malformed, revoked, or unknown key. |
| 403 | live_access_required | Live key used before live access was granted, or a live-only endpoint hit with a test key. |
| 403 | insufficient_scope | A restricted key called an endpoint outside its scopes; required_scope names the one it needs. |
| 403 | tenant_suspended | The account is suspended. |