SEAM API emits real-time events over Socket.IO so that your frontend can show loading feedback while HTTP operations run and instantly reflect data changes across every open tab or connected user. Every authenticated connection is placed in a private user room, and two event channels drive the UI lifecycle:Documentation Index
Fetch the complete documentation index at: https://mintlify.com/TheSerchCp/SEAM-API/llms.txt
Use this file to discover all available pages before exploring further.
operation:progress for per-operation status updates and data:changed for global data synchronization. This guide walks through the complete client setup.
Prerequisites
Before connecting you need:- A valid JWT token obtained from
POST /api/v1/auth/login. - The
socket.io-clientpackage installed in your frontend project. - The base URL of the SEAM API server (e.g.,
http://localhost:3000).
Connection Setup
Obtain a JWT token
Call the login endpoint and store the returned token. The Socket.IO handshake requires it.
Create the Socket.IO connection
Pass the token in the
auth object of the connection options. SEAM API’s Socket.IO middleware validates the token via jwt.verify before the connection is accepted.Handle connection events
Confirm the connection succeeded and handle authentication errors returned by the server.
In production deployments, replace
http:// with https:// and ensure your reverse proxy (Nginx, Caddy, etc.) is configured to upgrade WebSocket connections. The Socket.IO URL must use wss:// in secure contexts to avoid mixed-content browser errors.Sending X-Socket-ID with Every HTTP Request
SEAM API uses the X-Socket-ID request header to associate an incoming HTTP request with the specific socket that initiated it. This allows the server to emit operation:progress events back to exactly the right browser tab — even when the same user has multiple sessions open.
Build a thin API client wrapper that attaches both the Authorization and X-Socket-ID headers automatically:
X-Socket-ID is absent, the server falls back to broadcasting to all sockets belonging to the authenticated user’s room (user:{userId}). Providing the header gives more precise targeting.
Handling operation:progress Events
The server emits operation:progress directly to the socket that sent the X-Socket-ID header. Use this event to control loading spinners and in-app notifications.
Event Payload
Lifecycle
status | When Emitted | Frontend Action |
|---|---|---|
start | Operation begins in the controller | Show loader with initial message |
processing | Intermediate step (e.g., after DB write, before post-processing) | Update loader message |
success | Operation completed successfully | Hide loader, show success notification |
error | Any error was thrown and caught by errorHandler | Hide loader, display error message |
Full Handler Example
Read-only operations (those ending in
:fetchAll, :fetchOne, :fetchByRole, :fetchByUri, or auth:login) do not emit a data:changed broadcast on success, since they don’t modify data. They still emit operation:progress to the requesting socket.Handling data:changed for Real-Time Table Updates
The server broadcasts data:changed to all connected clients whenever a mutation operation (create, update, delete, assign) completes successfully. Use this event to keep every open session up to date without polling.
Event Payload
Deduplication with initiatorSocketId
The initiatorSocketId field lets you skip redundant updates. The client that triggered the operation already has the latest data from the HTTP response — applying the data:changed payload on top would be a no-op at best and a race condition at worst.
Routing Updates by Operation Name
Operation names follow the convention<resource>:<verb>. Parse the string to decide which slice of your UI to refresh:
User Rooms
Every authenticated socket is automatically placed in the roomuser:{userId} on connection. This means events emitted with emitToUser(userId, ...) reach every session that user has open — desktop browser, mobile tab, and so on — without the client needing to join any room manually.
emitToSocket(socketId, ...) when X-Socket-ID was provided with the request. This is how operation:progress achieves per-tab precision.
Reconnection Behavior
Socket.IO reconnects automatically after a network interruption. On each reconnect attempt the handshakeauth.token is re-evaluated by the server’s JWT middleware. If the token has expired during the disconnection period, the reconnect will be rejected with "Token inválido o expirado".
Handle this in your reconnect logic: