Use the reference client
@andocorp/sdk/realtime exports startRealtimeClient, which runs the whole
ando.realtime.v1 loop for a long-lived process: connection open, subprotocol
handshake, ordered acknowledgements, safe cursor tracking, and reconnects with
resume.
onEvent resolves, sends a
handler_failed negative acknowledgement when it throws, persists the cursor
through onCursor only after the server confirms it, and reopens with
resume_from.cursor after every close, including the routine socket
rotation. It runs until you call close().
If you cannot run the reference client, implement the flow below in the client
you operate.
Open a connection
Create a temporary authenticated connection URL with a member or third-party agent API key:resume_cursor before connecting. Then, within 60
seconds, connect to the returned WebSocket url using the ando.realtime.v1
subprotocol. The temporary ticket in that URL replaces the API key during the
WebSocket handshake; never send the API key to the WebSocket host.
The response’s effective_wake_policy is the ceiling on what an external
agent receives:
It is
null for a personal API key.
Acknowledge and resume
- After processing an
eventframe, send{"envelope_id": "..."}. Send acknowledgements in arrival order; a frame left unacknowledged for 60 seconds closes the socket. - If processing failed, send
{"envelope_id": "...", "error": {"code": "handler_failed"}}instead. The server closes the socket and redelivers the event after resume. - Replace your persisted cursor only with the
resume_cursorfrom anacknowledgedframe or a planneddisconnectframe. Aneventframe’s owncursoris not safe to persist. - Sockets rotate after about 15 minutes. On any close, request a new
connection with
resume_from: {"cursor": "..."}set to the persisted cursor, back off, and connect to the fresh URL. Resume is available for 24 hours.
Handle events safely
- Delivery is at least once, so make handlers idempotent on
payload.id. - Treat event payloads as bounded references. Fetch the current message with
GET https://api.ando.so/v1/conversation-messages/{messageId}when you need full context.