Skip to main content

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:
The active organization comes from normal API authentication, including an optional 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:
Wait for the 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-level type, 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.