Notes: Real-time & Sync
Section titled “Notes: Real-time & Sync”Use these endpoints to establish identity for the current user, initialize and open WebSocket sessions for real-time collaboration, and batch-synchronize client-side mutations back to the server.
Base URL for all operations on this page:
https://{projectId}-{containerId}-notes-1.{server}.containers.hoody.icuIdentity
Section titled “Identity”GET /api/v1/notes/me
Section titled “GET /api/v1/notes/me”Returns the current user identity, including userId, username, role, and notebookId. Auto-provisions the user and notebook on first call.
This endpoint takes no parameters.
curl https://{projectId}-{containerId}-notes-1.{server}.containers.hoody.icu/api/v1/notes/me \ -H "Authorization: Bearer <token>"const identity = await client.notes.identity.get();{}WebSocket sessions
Section titled “WebSocket sessions”Real-time collaboration uses a two-step handshake: first initialize a session to receive a socket ID, then open the WebSocket using that ID.
POST /api/v1/notes/sockets
Section titled “POST /api/v1/notes/sockets”Creates a new socket session and returns the socket ID required to upgrade the HTTP connection to a WebSocket.
This endpoint takes no parameters.
curl -X POST https://{projectId}-{containerId}-notes-1.{server}.containers.hoody.icu/api/v1/notes/sockets \ -H "Authorization: Bearer <token>"const { id } = await client.notes.sockets.init();{ "id": "sock_9f8e7d6c5b4a3210"}{ "message": "Invalid request", "code": "BAD_REQUEST", "details": [ { "path": "headers.authorization", "message": "Missing or malformed authorization header" } ]}{ "message": "Internal server error", "code": "INTERNAL_ERROR", "details": []}GET /api/v1/notes/sockets/{socketId}
Section titled “GET /api/v1/notes/sockets/{socketId}”Upgrades an HTTP connection to a WebSocket using a previously initialized socket ID. After a successful upgrade the server pushes live notebook events to the client over the open socket.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
socketId | path | string | Yes | The socket ID returned from POST /api/v1/notes/sockets. |
curl https://{projectId}-{containerId}-notes-1.{server}.containers.hoody.icu/api/v1/notes/sockets/sock_9f8e7d6c5b4a3210 \ -H "Authorization: Bearer <token>" \ -H "Upgrade: websocket" \ -H "Connection: Upgrade" \ -H "Sec-WebSocket-Version: 13" \ -H "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ=="const socket = await client.notes.sockets.open("sock_9f8e7d6c5b4a3210");{ "message": "Invalid socket ID", "code": "INVALID_SOCKET_ID", "details": [ { "path": "params.socketId", "message": "Socket ID does not match an active session" } ]}{ "message": "WebSocket upgrade failed", "code": "UPGRADE_FAILED", "details": []}Mutation sync
Section titled “Mutation sync”POST /api/v1/notes/notebooks/{notebookId}/mutations
Section titled “POST /api/v1/notes/notebooks/{notebookId}/mutations”Processes a batch of client-side mutations — node CRUD, reactions, interactions, and document updates — and returns per-mutation status results. Each mutation carries a client-generated id, a createdAt timestamp, a type discriminator, and a data payload that varies by type.
A single batch can include up to 500 mutations.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
notebookId | path | string | Yes | The notebook to which the mutations apply. |
Request body
Section titled “Request body”| Field | Type | Required | Description |
|---|---|---|---|
mutations | array | Yes | Batch of mutations to apply. Maximum 500 items per request. |
Each mutation item is a discriminated union with the common shape:
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Client-generated mutation ID, echoed in the result list. |
createdAt | string | Yes | ISO 8601 timestamp of when the mutation was produced locally. |
type | string | Yes | One of node.create, node.update, node.delete, node.reaction.create, node.reaction.delete, node.interaction.seen, node.interaction.opened, document.update. |
data | object | Yes | Type-specific payload. See the examples below. |
curl -X POST https://{projectId}-{containerId}-notes-1.{server}.containers.hoody.icu/api/v1/notes/notebooks/nbk_x9y8z7w6v5u4/mutations \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '{ "mutations": [ { "id": "mut_01HQ7G3K5P8X", "createdAt": "2024-01-15T10:30:00.000Z", "type": "node.create", "data": { "nodeId": "node_abc123", "updateId": "upd_001", "createdAt": "2024-01-15T10:30:00.000Z", "data": "{\"type\":\"paragraph\",\"content\":[{\"type\":\"text\",\"text\":\"Hello world\"}]}" } }, { "id": "mut_01HQ7G3K5P8Y", "createdAt": "2024-01-15T10:30:01.000Z", "type": "node.update", "data": { "nodeId": "node_abc123", "updateId": "upd_002", "data": "{\"type\":\"paragraph\",\"content\":[{\"type\":\"text\",\"text\":\"Hello, world!\"}]}", "createdAt": "2024-01-15T10:30:01.000Z" } }, { "id": "mut_01HQ7G3K5P8Z", "createdAt": "2024-01-15T10:30:02.000Z", "type": "node.reaction.create", "data": { "nodeId": "node_abc123", "reaction": "\uD83D\uDC4D", "rootId": "node_root_001", "createdAt": "2024-01-15T10:30:02.000Z" } }, { "id": "mut_01HQ7G3K5P90", "createdAt": "2024-01-15T10:30:03.000Z", "type": "node.interaction.seen", "data": { "nodeId": "node_abc123", "collaboratorId": "usr_a1b2c3d4e5f6", "seenAt": "2024-01-15T10:30:03.000Z" } }, { "id": "mut_01HQ7G3K5P91", "createdAt": "2024-01-15T10:30:04.000Z", "type": "document.update", "data": { "documentId": "doc_xyz789", "updateId": "upd_doc_001", "data": "{\"ops\":[{\"insert\":\"Updated content \"}]}", "createdAt": "2024-01-15T10:30:04.000Z" } } ] }'await client.notes.mutations.sync("nbk_x9y8z7w6v5u4", { mutations: [ { id: "mut_01HQ7G3K5P8X", createdAt: "2024-01-15T10:30:00.000Z", type: "node.create", data: { nodeId: "node_abc123", updateId: "upd_001", createdAt: "2024-01-15T10:30:00.000Z", data: "{\"type\":\"paragraph\",\"content\":[{\"type\":\"text\",\"text\":\"Hello world\"}]}" } }, { id: "mut_01HQ7G3K5P8Z", createdAt: "2024-01-15T10:30:02.000Z", type: "node.reaction.create", data: { nodeId: "node_abc123", reaction: "\uD83D\uDC4D", rootId: "node_root_001", createdAt: "2024-01-15T10:30:02.000Z" } } ]});{}