Fetching Notifications
Section titled “Fetching Notifications”Retrieve, dismiss, and clear notifications for one or more displays, and open a real-time WebSocket stream for live notification delivery. Use these endpoints when building notification dashboards, alert sinks, or background consumers that need to stay in sync with the notification server.
Get notifications for specified display(s)
Section titled “Get notifications for specified display(s)”GET /api/v1/notifications/{display}
Retrieves notifications for one or more specified displays. The display path parameter accepts a single ID, a comma-separated list, or all to fetch from every display.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
display | path | string | Yes | A single display ID (e.g., 1 or :1), a comma-separated list (e.g., 1,:2,3), or all to fetch from all displays |
limit | query | integer | No | Maximum number of notifications to return. Default: 100 |
since | query | integer | No | Unix timestamp in milliseconds to get notifications after this time |
username | query | string | No | Filter notifications by username |
session | query | string | No | Filter notifications by session ID |
curl -X GET "https://your-instance.com/api/v1/notifications/all?limit=50&since=1749024000000" \ -H "Authorization: Bearer <token>"// Async iteration over matching notificationsfor await (const n of client.notifications.listIterator("all", { limit: 50, since: 1749024000000,})) { console.log(n);}{ "success": true, "data": { "count": 1, "displays": ["1"], "notifications": [ { "id": 10, "display_id": 1, "appname": "Google Chrome", "summary": "Focus or Open a Window", "body": "Click to focus the window", "message": "Focus or Open a Window: Click to focus the window", "category": "system", "urgency": "normal", "has_icon": true, "icon_url": "/api/v1/notifications/icons/6_10_1749024932903.png", "expire_time": 5000, "timestamp": 1749024932903 } ] }}{ "statusCode": 400, "error": "Bad Request", "message": "Invalid display parameter"}{ "statusCode": 500, "error": "Internal Server Error", "message": "Failed to load notifications"}Real-time notification stream via WebSocket
Section titled “Real-time notification stream via WebSocket”GET /api/v1/notifications/stream
Establishes a WebSocket connection for real-time notification updates. Subscribe to one or more displays and receive messages as they are produced by the notification server.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
displays | query | string | Yes | Comma-separated display IDs to subscribe to (e.g., 0,:1,2), or all to receive notifications from every display. |
curl -X GET "https://your-instance.com/api/v1/notifications/stream?displays=all" \ -H "Upgrade: websocket" \ -H "Connection: Upgrade" \ -H "Sec-WebSocket-Version: 13" \ -H "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ=="// Wire typed callbacks first, then connect.const stream = await client.notifications.connectStream({ displays: "all" });
stream.onNotification((msg) => console.log("new:", msg.data));stream.onHeartbeat(() => {});stream.onDisconnect((code, reason) => {});stream.onError((err) => console.error(err));
await stream.connect();
// later:stream.close();The WebSocket handshake succeeds and the connection upgrades to 101 Switching Protocols. The server then begins pushing notification, heartbeat, and disconnect frames over the open socket.
{ "statusCode": 400, "error": "Bad Request", "message": "Missing or invalid `displays` query parameter"}{ "type": "error", "error": "Connection limit exceeded"}Dismiss notifications
Section titled “Dismiss notifications”POST /api/v1/notifications/dismiss
Marks notifications as dismissed. Dismissed notifications are filtered from subsequent GET responses until they are cleared with the DELETE endpoint below.
Request Body
Section titled “Request Body”| Field | Type | Required | Description |
|---|---|---|---|
notificationIds | array of integer | Yes | Array of notification IDs to dismiss |
displayId | string | No | Optional display ID to scope the dismissal |
This endpoint takes no path, query, or header parameters.
curl -X POST "https://your-instance.com/api/v1/notifications/dismiss" \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '{ "notificationIds": [10, 11, 12], "displayId": "1" }'// Pass the body object directly — do not wrap it in a `data` property.await client.notifications.dismiss({ notificationIds: [10, 11, 12], displayId: "1",});{ "success": true, "message": "3 notification(s) dismissed"}{ "statusCode": 400, "error": "Bad Request", "message": "`notificationIds` must be a non-empty array of integers"}{ "statusCode": 500, "error": "Internal Server Error", "message": "Failed to dismiss notifications"}Clear dismissed notifications
Section titled “Clear dismissed notifications”DELETE /api/v1/notifications/dismiss
Clears the dismissed state, making previously dismissed notifications visible to subsequent GET calls again. Optionally scope the clear to a single display.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
displayId | query | string | No | Optional display ID to scope the clear operation |
curl -X DELETE "https://your-instance.com/api/v1/notifications/dismiss?displayId=1" \ -H "Authorization: Bearer <token>"await client.notifications.clearDismissed({ displayId: "1" });{ "success": true, "message": "Dismissed notifications cleared"}