Notifications API
The Notifications API backs the dashboard bell: a per-user feed of in-app alerts — delivery failures, billing events, security sign-ins, port-status changes, agent handoffs, SLA breaches, and more. Read the feed with the list endpoints, mark rows read or dismiss them, and subscribe toGET /api/v1/notifications/stream to receive
new notifications in real time.
Base path: /api/v1/notifications
Authentication: session JWT. Notifications are scoped to the signed-in user and
their tenant, so these endpoints use your dashboard session rather than a workspace
API key. The live stream supports a query-parameter token so browsers can
authenticate EventSource connections (see Live stream).
The notification object
severityis one ofinfo,warning,error— it drives the icon colour.read_atisnulluntil the notification is marked read.source_pillarandcategoryare coarse facets used by the dashboard filter chips.source_pillaris one ofcpaas,ucaas,ccaas,aiaas,cxaas,cspaas,naas,verify,system.categoryis one ofsla_breach,missed_call,campaign_result,agent_state,verification,webhook_failure,billing,security,compliance,system.- Notifications past their
expires_atare filtered out of the list automatically.
List notifications — GET /api/v1/notifications/
Returns your notifications, newest first, in a cursor-paginated page.
pagination.cursor back as the cursor query
parameter. When has_more is false, cursor is null and you have reached the
end of the feed.
Unread count — GET /api/v1/notifications/unread-count
Returns { "count": <n> } — the number backing the bell badge.
Mark read — PUT /api/v1/notifications/{id}/read
Marks a single notification read and returns the updated row. Returns 404 if the
id does not exist or is not yours.
Mark all read — POST /api/v1/notifications/read-all
Marks every unread notification read in one call. Returns
{ "affected": <n> } — the number of rows updated.
Dismiss — DELETE /api/v1/notifications/{id}
Deletes one of your notifications and returns { "deleted": "<id>" }. Returns 404
if the id does not exist or is not user-scoped.
Organization-wide notifications are shared across the workspace and cannot be
dismissed by an individual user — they clear on their own when they expire.
Dismiss applies only to your own user-scoped rows.
Live stream — SSE
GET /api/v1/notifications/stream pushes new notifications to the browser in real
time over Server-Sent Events.
Browsers cannot set request headers on an EventSource, so the stream accepts the
session token as a query parameter. Two authentication paths are supported:
- One-time token (preferred). Call
POST /api/v1/notifications/sse-tokento mint a short-lived token, then open the stream with?ot=<token>. This keeps your long-lived session JWT out of server access logs and browser history. - Legacy JWT (fallback). Open the stream with
?token=<session-jwt>directly. Use this only when a one-time token is unavailable.
Mint a one-time token — POST /api/v1/notifications/sse-token
201 with the token and its lifetime:
200 with { "ot": null, "fallback": "token" } instead of an error. When
you see ot: null, fall back to opening the stream with ?token=<session-jwt>.
Open the stream — GET /api/v1/notifications/stream
connected event, then emits one event per new
notification. The event name reflects the notification type (for example
notification.created); the data: line carries the notification JSON.
: heartbeat comment is sent every 30 seconds to keep the connection alive. If
the stream ends, reconnect — mint a fresh one-time token first if you are using the
?ot= path.
The stream is for browser clients: connections must come from a trusted dashboard
origin with a browser User-Agent. Non-browser clients are rejected — to consume
the same events from a server, use the durable Webhooks push
instead.
See also
- Webhooks — durable, retry-handled push for server-side consumers.
- Events API — the platform-wide live event firehose.