Fetching Notifications
Section titled “Fetching Notifications”The notification server exposes endpoints for retrieving, streaming, dismissing, and clearing notifications generated by applications running inside a display container. Use the GET endpoint to fetch historical notifications, the WebSocket endpoint for real-time push, and the POST/DELETE endpoints to manage dismissal state.
All endpoints are scoped to a single notification container and are reachable at https://{projectId}-{containerId}-n-1.{server}.containers.hoody.com.
Get Notifications for Displays
Section titled “Get Notifications for Displays”GET /api/v1/notifications/{display}
Section titled “GET /api/v1/notifications/{display}”Retrieves notifications for one or more specified displays. The display parameter accepts a single ID (for example "1" or ":1"), a comma-separated list (for example "1,:2,3"), 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 |
This endpoint takes no request body.
Response
Section titled “Response”{ "success": true, "data": { "count": 1, "displays": ["1"], "notifications": [ { "id": 10, "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", "display_id": 1, "timestamp": 1749024932903, "expire_time": 5000, "has_icon": true, "icon_url": "/api/v1/notifications/icons/6_10_1749024932903.png" } ] }}The request was malformed (for example, an unparsable display selector or invalid query parameters). The notification server returns a Bad Request error without further detail.
The notification server encountered an internal error and could not read the notification store.
SDK Usage
Section titled “SDK Usage”curl -G "https://67e89abc123def456789abcd-890abcdef12345678901cdef-n-1.node-us.containers.hoody.com/api/v1/notifications/1" \ -H "Authorization: Bearer <token>" \ --data-urlencode "limit=50" \ --data-urlencode "since=1749024000000"The listIterator accessor returns an AsyncIterableIterator. Consume it with for await rather than collecting into a single value.
import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://67e89abc123def456789abcd-890abcdef12345678901cdef-n-1.node-us.containers.hoody.com', token: process.env.HOODY_TOKEN });
for await (const n of client.notifications.listIterator("1", { limit: 50, since: 1749024000000 })) { console.log(n);}Real-time Notification Stream
Section titled “Real-time Notification Stream”GET /api/v1/notifications/stream
Section titled “GET /api/v1/notifications/stream”Establishes a WebSocket connection for real-time notification updates. Clients subscribe to one or more displays and receive immediate notifications as they fire, along with periodic heartbeats.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
displays | query | string | Yes | Comma-separated display IDs to subscribe to (e.g., “1,:2,3”), or “all” to receive notifications from every display. |
This endpoint takes no request body.
Response
Section titled “Response”The server responds with HTTP 101 Switching Protocols to indicate the WebSocket handshake succeeded. No JSON body is returned on the upgrade response; subsequent frames carry notification, heartbeat, and disconnect messages.
The request was malformed (for example, a missing or invalid displays query parameter). The notification server returns a Bad Request error without further detail.
{ "type": "error", "error": "Connection limit exceeded"}SDK Usage
Section titled “SDK Usage”WebSocket endpoints cannot be exercised from cURL. Use the SDK below to attach the typed event handlers and then call connect().
connectStream returns a WebSocket wrapper. Wire the typed callbacks first, then call connect(). There is no onMessage, onClose, or Node-style stream.on(...) surface.
import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://67e89abc123def456789abcd-890abcdef12345678901cdef-n-1.node-us.containers.hoody.com', token: process.env.HOODY_TOKEN });
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();Dismiss Notifications
Section titled “Dismiss Notifications”POST /api/v1/notifications/dismiss
Section titled “POST /api/v1/notifications/dismiss”Marks notifications as dismissed. Dismissed notifications are filtered from subsequent GET responses. Use the optional displayId field to scope the dismissal to a single display.
This endpoint takes no path, query, or header parameters.
Request Body
Section titled “Request Body”| Field | Type | Required | Description |
|---|---|---|---|
notificationIds | array | Yes | Array of notification IDs to dismiss |
displayId | string | No | Optional display ID to scope the dismissal |
{ "notificationIds": [10, 11, 12], "displayId": "1"}Response
Section titled “Response”{ "success": true, "message": "3 notification(s) dismissed"}The request body was missing, malformed, or omitted the required notificationIds field.
The notification server could not persist the dismissal state.
SDK Usage
Section titled “SDK Usage”curl -X POST "https://67e89abc123def456789abcd-890abcdef12345678901cdef-n-1.node-us.containers.hoody.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 inside a { data: { ... } } envelope.
import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://67e89abc123def456789abcd-890abcdef12345678901cdef-n-1.node-us.containers.hoody.com', token: process.env.HOODY_TOKEN });
await client.notifications.dismiss({ notificationIds: [10, 11, 12], displayId: "1" });Clear Dismissed Notifications
Section titled “Clear Dismissed Notifications”DELETE /api/v1/notifications/dismiss
Section titled “DELETE /api/v1/notifications/dismiss”Clears the dismissed state, making previously dismissed notifications visible again. Optionally scope the clear to a single display with the displayId query parameter.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
displayId | query | string | No | Optional display ID to scope the clear operation |
This endpoint takes no request body.
Response
Section titled “Response”{ "success": true, "message": "Dismissed notifications cleared"}SDK Usage
Section titled “SDK Usage”curl -X DELETE "https://67e89abc123def456789abcd-890abcdef12345678901cdef-n-1.node-us.containers.hoody.com/api/v1/notifications/dismiss?displayId=1" \ -H "Authorization: Bearer <token>"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://67e89abc123def456789abcd-890abcdef12345678901cdef-n-1.node-us.containers.hoody.com', token: process.env.HOODY_TOKEN });
await client.notifications.clearDismissed({ displayId: "1" });