API tokens
An API token is the key programs use to work with Notifly on behalf of your
account. The same token is presented by the Go and Python SDKs,
the CLI and the MCP server for AI assistants. The
prefix is M, and it is issued in the admin UI on the API tokens page.
Which token is for what
Section titled “Which token is for what”| Token | Prefix | What it is for |
|---|---|---|
| API token | M | Everything account-level: channels, heartbeats, monitors, scans, history, message administration. With a channel and tag scope, an access level and an expiry |
| Channel token | A | Sending into one channel only: POST /message, POST /ask. This is what notifly push, the GitHub Action and any script that “just sends notifications” use |
| Device token | C | A session of an app or a browser. The server accepts it on the same routes as an API token, but it is not an integration key — see below |
| Access token | S | Delegated access to someone else’s channel: reading and, with the send permission, sending. Issued by the channel owner |
How to issue one
Section titled “How to issue one”- Admin UI → Management → API tokens → Issue API token.
- Give it a name (only you see it), an access level, channels and, if you need one, an expiry.
- Copy the value from the dialog — it is shown only once.
Access and scope
Section titled “Access and scope”Access level:
read— reading only (GET, lists, search). Any modifying endpoint answers403.write— full CRUD within the scope.
The channel scope is set in two ways, and they add up:
- a list of channels — a static enumeration. The list is flat: ticking a group opens access to its current child channels, but not to the ones created later;
- tags — a dynamic scope. The token sees every channel carrying any of the listed tags, including channels created after the token was issued.
An empty scope (neither channels nor tags) means “every channel of the account”.
A channel created by the token itself always lands in its scope: an unrestricted
token sees it automatically, and for a restricted one the server appends the new
channel id to the list. Otherwise notifly create-app and CreateChannel from
the SDK would create a channel their own creator could not see.
Expiry
Section titled “Expiry”An optional field: past the given moment the token is rejected at
authentication as invalid (401), while the row itself stays and shows in the
list marked “expired”. The expiry can be extended by editing the token, and
rotation keeps the previous expiry.
Rotation and deletion
Section titled “Rotation and deletion”Rotate — give the token a new value while keeping its name, access level, scope and expiry. The previous value stops working immediately. This is the standard answer to a lost or leaked secret: the scope does not have to be set up again.
Delete — switch the token off for good. API tokens are not cached, so deletion, rotation and a narrowed scope all take effect on every server at once.
Every API token of an account is deleted automatically on a password reset through the link from the email — that is the recovery-after-takeover scenario — and also when an administrator changes the user’s password. An ordinary password change from the settings leaves them alone (see Account security for details).
Where to put it
Section titled “Where to put it”Go SDK
client := notifly.New(notifly.WithAPIToken("M<api-token>"))monitors, err := client.ListMonitors(ctx)Python SDK
from notifly import Notifly
nf = Notifly("M<api-token>")nf.list_channels()More about both SDKs on the Go & Python SDKs page.
CLI — the apiToken field in cli.json or an environment variable; needed
by the create-app and list commands (see CLI client):
export NOTIFLY_API_TOKEN=M<api-token>notifly list -n 10MCP server — the NOTIFLY_API_TOKEN variable in your AI client’s config
(see MCP server).
REST directly — the X-Notifly-Key header:
curl -H "X-Notifly-Key: M<api-token>" https://api.notifly.ru/applicationWhat an API token cannot do
Section titled “What an API token cannot do”The privilege ceiling is deliberate: a leaked key must not turn into full access to the account.
- Manage devices —
/client*is closed to it. - Manage API tokens — a token neither issues, edits, rotates nor deletes itself or its neighbours.
- Change the password, set up 2FA or confirm sensitive actions — those need a live device token and a sudo window.
- Be an administrator — admin endpoints answer
403no matter whose account it is. - Connect over WebSocket —
/wsaccepts a device token (C…) and a channel token with read access (A…,S…); see the WebSocket protocol. - Read a device’s subscriptions — an API token has no device behind it, so
those endpoints answer
401.
Managing tokens is available with a device token only — an API token is not allowed near these endpoints.
| Method and path | Description |
|---|---|
GET /api-token | List the tokens. The token field is the M…ab3d hint, not the secret |
POST /api-token | Issue one. The only response carrying the full value |
PUT /api-token/{id} | Change the name, access, scope or expiry |
POST /api-token/{id}/rotate | Rotate: a new value, the previous settings |
DELETE /api-token/{id} | Delete |
Body fields: name, access (read/write), appIds (an array of channel
ids), appTags (an array of tags), expiresAt (RFC3339). On an update, a
missing appTags or expiresAt means “leave unchanged”, and an empty
appTags array means “clear”.