An API key lets another piece of software (a CRM, a website, a script, an automation tool) call your gateway without using a dashboard account. Each key is independent: it has its own name, its own permissions and its own limits, and it can be revoked without touching the others.
Keys are managed on the API keys page of the dashboard (menu System > API keys, or the Manage API keys button of the API reference page).
Who can do what
| Role | On the API keys page |
|---|---|
| Superadmin | Create, edit, revoke and delete keys |
| Operator, Read only | See the list, read-only. The actions are not shown |
A key with the admin scope can also manage keys through the API (/api-keys). No other key can:
a key allowed to send must not be able to grant itself more rights.
Create a key
- Open API keys, then New API key.
- Fill in the options below. Only the name and the scope are required.
- Click Create key.
- The key is shown once, with a Copy key button and a ready-to-run
curlcommand that reads the latest message (it sends nothing, whatever the scope). Copy the key into your application or your secrets manager. - Click I have copied the key. The window cannot be closed any other way, so that the key is not lost by a stray click.
After that, nobody can read the key again: not you, not the API, not support. The gateway only keeps a fingerprint of it, which is enough to recognise it and useless to rebuild it. A lost key is replaced by a new one.
What stays visible is the prefix: sk_ followed by the first eight characters, for example
sk_A1b2C3d. It lets you recognise a key in the list, or in your application's configuration,
without exposing it.
Options
| Option | Where | Default | Allowed values | Effect |
|---|---|---|---|---|
| Name | Creation and edit | required | 1 to 80 characters, unique (capitals ignored) | A label only. Name the key after the application that uses it, so you know which one to revoke |
| Scope | Creation and edit | Read | Read (read), Send (send), Admin (admin) |
What the key may call. See Scopes |
| Allowed IP addresses | Creation and edit | empty: any address | Up to 16 entries, each an IPv4 or IPv6 address or a CIDR range (203.0.113.7, 10.0.0.0/8, 2001:db8::/32), one per line |
A call from any other address is refused with 403 IP_NOT_ALLOWED. See Allowed addresses |
| Calls per day | Creation and edit | empty: no limit | 0 to 1,000,000. Empty or 0 means no limit | Beyond it, calls are refused with 429 RATE_LIMITED until midnight UTC. The counter survives a restart of the gateway |
| Calls per minute | Creation and edit | empty: no limit | 0 to 10,000. Empty or 0 means no limit | Beyond it, calls are refused with 429 RATE_LIMITED and a Retry-After header. When set, every answer carries the X-RateLimit-* headers |
Changes made by Edit apply from the next call. The key itself does not change: the application keeps working with the same value.
Scopes
The three scopes are ordered: each one includes the previous.
| Scope in the dashboard | Value | What the key can do | Typical use |
|---|---|---|---|
| Read | read |
Look up messages, conversations, contacts, groups, devices, campaigns, statistics and the activity log. No sending, no change | A reporting tool, a dashboard of your own |
| Send | send |
Everything Read allows, plus sending an SMS and retrying a failed message. No configuration change | A website sending confirmation codes, a CRM sending reminders |
| Admin | admin |
The whole API: configuration, contacts, templates, rules, campaigns, webhooks, bulk exports, backups, the technical log and the keys themselves | A trusted tool that administers the gateway |
Some reads are reserved to Admin even though they change nothing, because they hand over a large amount of data at once: bulk exports, backups (which contain the whole database), the list of dashboard accounts (it holds email addresses) and the technical log. A Read key is meant to look up a message or a device, not to carry the installation away.
Whatever its scope, a key can never create, change or delete a dashboard account: those actions need a superadmin signed in to the dashboard.
A call outside the key's scope gets 403 FORBIDDEN_SCOPE. Your quota is not used up by a refused
call.
Allowed addresses
Leave the list empty and the key works from anywhere, which is the right choice for a key used from several places whose addresses change. Fill it in as soon as the calling application has a fixed address: a key copied by mistake into a public repository is then useless to whoever finds it.
The address checked is that of the machine that calls the gateway, as the gateway sees it:
- in the standard installation with a domain, the HTTPS front end (Caddy) passes the real address of the caller, and that is the one checked;
- on a local network, it is the address of the calling machine on that network;
- if you put your own reverse proxy in front of the gateway, declare it in
GATEWAY_TRUSTED_PROXIES(see the installation guide). Otherwise every call seems to come from the proxy, and the list either lets everything through or refuses everything. As long as a list exists, a call whose address cannot be read is refused rather than let through.
Limits
The two limits protect against different things:
- Calls per minute stops a burst: a script in a loop, a page reloaded a thousand times. It counts in memory and restarts from zero when the gateway restarts.
- Calls per day caps the total volume of a day. It is stored with your data, so a restart does not hand the quota back. It is counted per UTC day, from midnight to midnight UTC, whatever your time zone.
Every call counts, reads included, not only sends. A refused call (wrong scope, address not allowed) does not use up the daily quota; a call refused for exceeding the per-minute limit still counts towards that minute, so retrying faster does not help.
These limits are per key. They are independent of the daily quota of each SIM set on the Devices page, which limits the SMS actually sent by each card, whatever their origin. A key with no limit still cannot make a SIM exceed its own quota.
The list
| Column | What it shows |
|---|---|
| Name | The name, and the creation date |
| Prefix | sk_ and the first eight characters of the key |
| Scope | Read, Send or Admin |
| Allowed addresses | "Any address", or the first entry and how many others |
| Limits | Per day and per minute, or "No limit" |
| Last used | The time of the last accepted call, or "Never" |
| Status | Active, or Revoked with its date |
Last used is the quickest way to find a key nobody uses any more: a key that has not been used for months is a key to revoke.
Rotate a key
There is no "regenerate" button, on purpose: replacing a key in place would break the application that uses it at the very moment you click. Rotation is done in three steps, without interruption:
- Create a new key with the same scope and options, named for example
CRM 2026-09. - Put the new key in the application and check that it works (its Last used column fills in).
- Revoke the old key.
Rotate a key when someone who knew it leaves, when it may have been exposed (a log, a screenshot, a repository, a support ticket), and otherwise at a regular pace that suits you.
Revoke or delete
| Action | Effect | When to use it |
|---|---|---|
| Revoke | The key is refused from the next call, for good. The row stays in the list, with its date of revocation and last use | The normal way to retire a key |
| Delete | The key is refused, then erased with its counters. Nothing remains in the list | Cleaning up a key already revoked |
Both take effect immediately: nothing is cached, every call checks the key. A revoked key cannot be
edited or reactivated: create a new one instead. A revoked key answers exactly like an unknown key
(403 INVALID_API_KEY), so a caller cannot tell whether a value once existed.
Creation, revocation and deletion of keys appear in the Activity log, with the prefix and never the key.
Good practices
- One key per application. When a tool is removed or compromised, you revoke its key and nothing else stops.
- The narrowest scope. Send for an application that sends, Read for one that reads. Keep Admin for tools you trust as much as a superadmin.
- Allowed addresses whenever the caller has a fixed address.
- A daily limit a little above the normal volume: a runaway script then stops by itself instead of emptying the SIM quotas.
- The key in a secrets manager or an environment variable, never in source code, never in a URL,
never in an email. It always travels in the
X-API-KEYheader. - Over HTTPS. On a network you do not control, call the gateway only through its
https://address: over plainhttp, the key crosses the network in clear text. - Review the list from time to time, and revoke keys that are no longer used.
Troubleshooting
| Answer | Likely cause |
|---|---|
401 MISSING_API_KEY |
The X-API-KEY header is missing, or a proxy between you and the gateway removes it |
403 INVALID_API_KEY |
The key is mistyped, truncated, revoked or deleted |
403 IP_NOT_ALLOWED |
The calling address is not in the list. Check the address the gateway really sees |
403 FORBIDDEN_SCOPE |
The operation needs a wider scope |
429 RATE_LIMITED |
Per-minute limit or daily quota reached. Retry-After gives the wait in seconds |
See also Using the API for the error format, and Security.