Nurama Developers
Guides

Real-time events

How to connect to the Socket.IO server, which channel to join, and how notifications are shaped.

The WebSocket server is a separate Socket.IO deployment. If a server you run needs to react to changes without holding a connection open, use webhooks instead. Connect with a Socket.IO client (the SDK's socket namespace, or socket.io-client directly), never with a raw WebSocket.

Channels

A channel is a Socket.IO namespace named after the resource you want to watch:

AddressDelivers
/user/{userId}Everything addressed to one user: mentions, member chats, task assignments. You may only join your own.
/workspace/{workspaceId}Workspace-level changes.
/project/{projectId}Project-level changes for the default audience.
/project/{projectId}/{visibility}Changes scoped to creator, reviewer or public. Join both creator and reviewer if your role spans both.
/chat/{chatId}One chat's stream, plus the collab relay (cursors, drawing, presenter control).
/asset/{assetId}, /task/{taskId}, /submission/{submissionId}One resource's stream.
/public/{token}A public release, authenticated by the token in the address.

Joining requires the matching canGet…Notifications permission, direct or inherited; a refused handshake surfaces as connect_error with the message forbidden.

Handshake

Pass your credential as token in the handshake query: a personal access token against ws.nurama.com, or a bot API key against bot-ws.nurama.com. Public channels need no token.

import { io } from 'socket.io-client';

const socket = io(`https://ws.nurama.com/project/${projectId}/creator`, {
  query: { token: process.env.NURAMA_TOKEN },
});
socket.on('notification', (event) => console.log(event.type, event));

When a credential is revoked the server emits tokenEvent and disconnects shortly after.

The notification envelope

Almost everything arrives as a single event named notification. Its type field names one of the notification types; tokens carries the identifiers the type documents, and changes lists created, updated and deleted resources:

{
  "type": "chatCreateMessage",
  "initiatorId": "…",
  "tokens": { "chatId": "…", "messageId": "…" },
  "changes": { "create": [{ "resourceType": "chatMessage", "resource": { "…": "…" } }] }
}

Switch on type and read the documented payload. Fields marked deprecated in a type's schema will disappear; prefer the changes array over legacy token fields.

Other events

Typing indicators (typing:start, typing:stop) are emitted by clients and relayed by the server, ws:probe checks liveness, and the collab:* family relays live-collaboration state on /chat/{chatId} namespaces. Each is documented under Events with its direction and payload.

The complete machine-readable description is the AsyncAPI document at /asyncapi.json.

On this page