Skip to content

Channel delegation (Sharing)

Delegation (sharing) is a way to give another person access to one of your channels without letting them into the rest of the account. A colleague will get either the right to only read messages from that channel, or to read and send new ones — but will not be able to see your other channels, change settings, or manage clients and tokens.

Useful when:

  • you need to show the team only the Prod-алёрты channel without exposing the whole project;
  • a CI bot only needs to send to one channel (the send permission) and nothing else;
  • the on-call person should see incoming notifications for a specific service (view);
  • you want to grant access temporarily — a delegation can be easily revoked without touching the channel’s tokens.

Technically, each delegation is a separate Share token with the S prefix, bound to a channel. The channel owner issues the token, optionally specifying the recipient’s email and the permission level. The recipient uses the token like a regular notifly token (see below How the recipient uses the access).

permissionWhat is allowed
viewSee the channel in the list and read its messages (GET /message).
sendSame as view, plus sending messages (POST /message).

send includes view. Any mutations of the channel itself, clients, tokens, as well as deleting messages using a Share token are forbidden (response 403).

A delegation to a specific email is first created as an invitation which the recipient can accept or decline:

statusWhat it means
pendingThe invitation has been issued; the recipient has not yet reacted.
acceptedThe recipient accepted — the channel has appeared in their list.
declinedThe recipient declined the invitation.

Only a pending invitation can be accepted (POST /share/:id/accept); attempting to accept/decline an already processed one will return 400 share is not pending.

The request is made by the channel owner (or a delegated user — see Re-sharing) using a client token or MCP code with write permission.

Terminal window
curl -X POST "$NOTIFLY_URL/application/42/share" \
-H "Content-Type: application/json" \
-H "X-Notifly-Key: <client-token>" \
-d '{
"recipientEmail": "colleague@example.com",
"permission": "view",
"note": "Дежурному на эту неделю"
}'

Request body fields (ChannelShareParams):

FieldTypeRequiredDescription
permissionstringyesview or send. Any other value → 400.
recipientEmailstringnoRecipient’s email. If empty — becomes an “open share” (see below).
notestringnoArbitrary comment for yourself (e.g. “for CI”, “for colleague X”).

Response — the created ChannelShare object:

{
"id": 1007,
"token": "S9f3k...",
"appid": 42,
"recipientEmail": "colleague@example.com",
"permission": "view",
"status": "pending",
"note": "Дежурному на эту неделю",
"created": "2026-06-23T10:00:00Z",
"lastUsed": null,
"appName": "Prod-алёрты"
}

The token field (prefix S) is the Share token. Give it to the recipient by any channel, or rely on them finding the invitation via incoming.

If recipientEmail is left empty, the delegation becomes an open share — a link/token that anyone who has it can use. In this case the recipient joins via POST /share/join, and a personal copy of the delegation (with its own Share token) is created for them, leaving the original untouched. This is convenient for invitations like “forward the link to the team”.

After the delegation is accepted (accepted), the channel appears in the recipient’s normal list (GET /application). Then the Share token is used like any notifly token:

Terminal window
# Чтение сообщений канала (view и send)
curl "$NOTIFLY_URL/message" -H "X-Notifly-Key: S9f3k..."
# Отправка в канал (только send)
curl -X POST "$NOTIFLY_URL/message" \
-H "X-Notifly-Key: S9f3k..." \
-d 'title=Деплой&message=Готово'

A Share token grants access strictly to a single channel. Attempts to call mutating endpoints (create/modify a channel, delete a message, manage tokens) will return 403 share tokens cannot perform this action.

The recipient sees delegations issued to their email via GET /share/incoming. Both unaccepted (pending) and accepted (accepted) are returned — except for invitations to channels the recipient already owns, and pending duplicates with the same permissions as an already accepted delegation.

Terminal window
curl "$NOTIFLY_URL/share/incoming" -H "X-Notifly-Key: <client-token>"
Terminal window
# Accept — the channel will appear in the recipient's list
curl -X POST "$NOTIFLY_URL/share/1007/accept" -H "X-Notifly-Key: <client-token>"
# Decline
curl -X POST "$NOTIFLY_URL/share/1007/decline" -H "X-Notifly-Key: <client-token>"

Only the user whose email matches the delegation’s recipientEmail can accept/decline; otherwise — 404. Only a pending invitation can be processed.

If the recipient was given the Share token directly (for example, an open share or simply the S... string), they join with a single call:

Terminal window
curl -X POST "$NOTIFLY_URL/share/join" \
-H "Content-Type: application/json" \
-H "X-Notifly-Key: <client-token>" \
-d '{"token": "S9f3k..."}'

Behavior depends on the type of delegation:

  • Named (with recipientEmail): the token joins only if the user’s email matches the delegation’s address (otherwise 403 this share is not for your email). The status is automatically changed to accepted.
  • Open share (without email): a personal copy of the delegation is created for the joiner with status accepted. If they already have a delegation for this channel, it is upgraded to send if necessary and set to accepted.

Invalid token → 404 invalid share token.

Managing issued delegations (for the owner)

Section titled “Managing issued delegations (for the owner)”

List of delegations for a specific channel (only those you created are shown; the channel owner also sees legacy delegations without a creator):

Terminal window
curl "$NOTIFLY_URL/application/42/share" -H "X-Notifly-Key: <client-token>"

Change the permission level, email, or note — PUT /share/:id (channel owner only):

Terminal window
curl -X PUT "$NOTIFLY_URL/share/1007" \
-H "Content-Type: application/json" \
-H "X-Notifly-Key: <client-token>" \
-d '{"permission": "send", "recipientEmail": "colleague@example.com"}'

Revoke a delegation — DELETE /share/:id. It can be deleted by its creator or the channel owner (for legacy delegations without a creator). After deletion, the token immediately stops working and the channel disappears from the recipient’s list.

Terminal window
curl -X DELETE "$NOTIFLY_URL/share/1007" -H "X-Notifly-Key: <client-token>"

To avoid typing emails manually, the sharing form can suggest addresses you’ve already shared with — GET /share/recipients returns a list of distinct emails from newest to oldest:

Terminal window
curl "$NOTIFLY_URL/share/recipients" -H "X-Notifly-Key: <client-token>"

Leaving and rotating your own token (for the recipient)

Section titled “Leaving and rotating your own token (for the recipient)”

The recipient manages only their own side of the access — with two calls. Both take the channel in the request body (appid) rather than in the path:

Terminal window
# Give up access to the channel (it disappears from the list, the token dies)
curl -X POST "$NOTIFLY_URL/share/leave" \
-H "Content-Type: application/json" \
-H "X-Notifly-Key: <client-token>" \
-d '{"appid": 42}'
# Change the value of your own Share token (for example, if it leaked)
curl -X POST "$NOTIFLY_URL/share/rotate" \
-H "Content-Type: application/json" \
-H "X-Notifly-Key: <client-token>" \
-d '{"appid": 42}'
  • share/leave removes all of your accesses to that channel (there may be several if different people shared it). The delegation is not “returned” to the owner: to come back you need a new invitation or token.
  • share/rotate changes the token value in place, keeping the permissions and the binding; the old value stops working immediately. Only an accepted and valid delegation can be rotated.

If you have no access to the channel, both calls return 404.

Email delegations are about people. For scripts, CI and integrations a channel has machine keys: several keys per channel, each with its own permissions, label, expiry and its own lastUsed.

Terminal window
# Issue a send-only key
curl -X POST "$NOTIFLY_URL/application/42/token" \
-H "Content-Type: application/json" \
-H "X-Notifly-Key: <client-token>" \
-d '{"name": "CI deploy key", "canRead": false, "canWrite": true,
"note": "gitlab runner", "expiresAt": 0}'
FieldMeaning
namehuman-readable label of the key
canReadreading the channel history and subscribing over WebSocket
canWritesending to the channel (POST /message, /ask)
notefree-form comment
expiresAtexpiry, unix milliseconds; 0 — never

A key must allow at least one of canRead/canWrite, otherwise 400. Key management is available only to the channel owner: a delegation recipient does not get it even with write permission.

Revocation has two steps. The first DELETE /token/:id is soft: the key stops authenticating, but the row remains, so you can still see when it was last used and when it was revoked. A repeated DELETE removes the record permanently.

Rotation (POST /token/:id/rotate) changes only the value: the id, the permissions and the channel binding are preserved, so nothing that references the key breaks.

Revocation takes effect from the next request. The exception is an already open WebSocket connection: it was authorised before the upgrade and lives with the old key until it reconnects.

A delegated user can, in turn, share the channel further — but not above their own permission level. If you only have view, attempting to grant send will return:

403 cannot grant 'send' permission — you only have 'view' access

The channel owner is always considered to have maximum access (send). Each user in the GET /application/:id/share list sees only their own delegations (the created_by field), so re-sharing does not expose other users’ delegations for the same channel.

Method and pathAuthorizationPurpose
GET /application/:id/shareclient-tokenlist of channel delegations (only your own)
POST /application/:id/shareclient-token (write)create a delegation (issue a Share token)
PUT /share/:idclient-token (write)change permission / email / note (channel owner)
DELETE /share/:idclient-token (write)revoke a delegation
GET /share/incomingclient-tokenincoming invitations to the user’s email
GET /share/recipientsclient-tokenemail addresses you’ve already shared with (for suggestions)
POST /share/:id/acceptclient-tokenaccept a pending invitation
POST /share/:id/declineclient-tokendecline a pending invitation
POST /share/joinclient-tokenjoin a channel by Share token
POST /share/leaveclient-token (write)give up access to a channel, body {"appid": N}
POST /share/rotateclient-token (write)change your own Share token value, body {"appid": N}
GET /application/:id/tokenclient-tokenmachine keys of the channel (owner only)
POST /application/:id/tokenclient-token (write)issue a machine key
PUT /token/:idclient-token (write)change permissions, label and expiry
DELETE /token/:idclient-token (write)revoke a key (a repeated call deletes it permanently)
POST /token/:id/rotateclient-token (write)change the key value, keeping its permissions