Learn
Authentication
Every request except the OpenAPI document is authenticated with an API key carrying a fixed set of scopes.
Sending your key
Send the key as a bearer token. This is the form the API is built around and the one you should use.
If a gateway in front of your application strips or rewrites the Authorization header, SMSend also accepts the key in a dedicated header. Authorization is checked first.
A key is never accepted in a query string, and never will be. Query strings are written to web-server access logs by default, which would put a live credential in plain text on disk and in every log aggregator downstream.
What a key looks like
A key is a public prefix and a secret, joined by a dot. The prefix identifies which key is being used; the secret proves you hold it.
SMSend stores the prefix in clear and only a SHA-256 hash of the secret. The full value is shown exactly once, when the key is created, and is unrecoverable afterwards. If you lose it, create a new key and revoke the old one.
Scopes
A key carries a fixed set of scopes chosen when it is created. Give each integration the narrowest set it needs — a key that only reads reports should never be able to spend money.
| Value | Meaning |
|---|---|
MESSAGES_SEND | Submit a batch. This is the only scope that can spend money. |
MESSAGES_READ | Read batches, individual messages, and the catch-up feed. |
ACCOUNT_READ | Read the wallet balance, credit limit and billing mode. |
SENDER_IDS_READ | List the sender IDs registered to the account. |
WEBHOOKS_MANAGE | Create, rotate, enable and disable webhook endpoints. |
Scopes are re-checked on every request
A key's effective scopes are its stored scopes intersected with what the member who created it is permitted to grant today. If that person is demoted or leaves the team, the key loses the corresponding scopes within one request and starts returning INSUFFICIENT_SCOPE.
When authentication fails
Every authentication failure returns the same 401 with the same message — an unknown key, a wrong secret, a revoked key, an expired key and a suspended account are indistinguishable from outside. Which one it was appears only in SMSend's own logs. This is deliberate: a more helpful error would confirm to an attacker which half of a guessed credential was right.
A valid key that lacks the scope for an endpoint is a 403, not a 401. The credential is fine; it is the permission that is missing, and the response names the scope you need.
Rotating a key
An account may hold several active keys at once, and that is the supported state — it is what lets you rotate without a window where nothing works.
- Create a second key with the same scopes.
- Deploy it, and confirm traffic is flowing on the new key.
- Revoke the first key. Revocation is a status change, not a deletion, so the audit trail survives.
If the member who created a key leaves the account, the key is not deleted — its effective scopes become empty and every scoped endpoint starts answering INSUFFICIENT_SCOPE. Re-issue it under a current member.