Authentication

Every request is authenticated with an API key in the Authorization header:

bash
Authorization: Bearer ssms_sk_test_...

Test and live keys

PrefixModeBehavior
ssms_sk_test_SandboxInstant, free, simulated delivery; no real SMS ever leaves the sandbox.
ssms_sk_live_LiveReal 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.

ScopeAllows
messages:sendPOST /v1/messages, POST /v1/test/inbound
messages:readGET /v1/messages, GET /v1/messages/{id}, GET /v1/deliverability
numbers:readGET /v1/numbers, GET /v1/numbers/available
numbers:writePOST /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
lookupGET /v1/lookup/{phone}
webhooksGET /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
billingGET/PATCH /v1/spend-limit
automationsPOST /v1/track, /v1/automations and everything under it
audit_logs:readGET /v1/audit-logs, GET /v1/exports/audit_log

A restricted key calling outside its scopes gets:

json
{
  "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

StatusCodeMeaning
401invalid_api_keyMissing, malformed, revoked, or unknown key.
403live_access_requiredLive key used before live access was granted, or a live-only endpoint hit with a test key.
403insufficient_scopeA restricted key called an endpoint outside its scopes; required_scope names the one it needs.
403tenant_suspendedThe account is suspended.