Realtime updates
Erdo’s organization WebSocket tells an external app when its canonical data has changed. Events are small invalidation signals rather than copies of datasets or messages: when one arrives, re-read the affected view through/v1 so current
permissions, dataset filters, and response contracts still apply.
Keep the API key on your server
The browser never needs your Erdo API key. Add a same-origin route to your app’s server that calls the ticket endpoint with the browser application’s exact origin:X-Organization-ID header. A caller cannot request a ticket for a
different channel or organization. The ticket expires after five minutes, is
consumed by the first successful connection, and accepts only the exact origin
supplied above.
Connect and subscribe
Return the ticket—not the API key—from your server route to your browser. Convert the API base URL to WebSocket protocol and include the authorized organization in the connection query:subscribed control message before showing a live status. A ticket is
one-time, so request a fresh ticket before every reconnect. Use exponential backoff
and keep a visibility-aware periodic refresh as recovery for missed events. While
the socket is open and the tab is visible, send {"type":"ping"} every 30 seconds;
Erdo answers with type: "pong" and keeps the connection alive.
Handle events
Broadcast messages have a top-leveltype, channel, and timestamp. payload
is a JSON-encoded string whose fields depend on the event type:
record_captured is emitted only after a successful record-capture pipeline run.
It names the pipeline, execution, and written dataset references but never includes
the submitted record. Page views and widget telemetry do not emit this event, so
normal traffic cannot create an app-wide refresh loop. thread_activity likewise
contains conversation identity and activity type, not message content.
The WebSocket is a prompt to re-read, not a durable event log. Debounce bursts of
events, refresh only while the tab is visible, reconnect with a new ticket after a
disconnect, and retain a slower periodic refresh so the UI converges even if a
producer has no realtime event yet.
