Events Gateway API · ws

WebSocket upgrade endpoint

GET /ws

WebSocket upgrade endpoint: one live connection that carries every change in the organization as it happens.

The upgrade itself is unauthenticated (browsers cannot set headers on it), so the client's FIRST frame must be a JSON auth frame ({"type":"auth","token":"<jwt>","since":{"inventory":0,…}}) within 10 seconds, or the server answers an error frame and closes. On a verified token the server sends {"type":"ready","tenantId":…}, replays each requested service's journal from its since cursor (inclusive) as {"type":"event","service":…,"message":…} frames, then forwards each new change as it is recorded. Delivery is at-least-once around the catch-up boundary, so dedupe by eventId/sequence. A plain GET without an upgrade returns 426.

Access

Public: the socket authenticates its first message with the caller's JWT, and each room checks the scopes it needs

No token: the link, the claim or the first message is the credential, as the description says.

How scopes come from roles: Scopes and roles. Getting a token: Authentication and app tokens.

AI agent tool

No agent tool. A WebSocket upgrade feeding the admin's live screens, not a request and response a tool call can make.

Connecting an agent: AI agents.

Example

Upgrade to a WebSocket, send {"type":"auth","token":"<jwt>","since":{"inventory":0}} first; the server answers with a ready frame like this one, then replays and forwards events.

curl
# A WebSocket (websocat): the auth frame first, then the socket stays open.
(printf '%s\n' "{\"type\":\"auth\",\"token\":\"$MANIFOLD_TOKEN\",\"since\":{\"inventory\":0}}"; cat) \
  | websocat 'wss://events.getmanifold.io/ws'
JavaScript (fetch)
const socket = new WebSocket("wss://events.getmanifold.io/ws");
// Browsers cannot set headers on the upgrade: the token is the first frame.
socket.addEventListener("open", () =>
  socket.send(JSON.stringify({ type: "auth", token: process.env.MANIFOLD_TOKEN, since: { inventory: 0 } })),
);
socket.addEventListener("message", (event) => console.log(JSON.parse(event.data)));
First frame from the server, after the upgrade (101)
{"type":"ready","tenantId":"org_01a15889-fa80-7d83-add6-41f282c51558"}

The panel writes this call in other languages. It does not send it: Manifold's APIs do not take calls from a web page on another site, so run the call from your own code or terminal. The whole API as OpenAPI: events-gateway.openapi.json. Base URL https://events.getmanifold.io.

Errors

This operation declares no refusals.