MOONEUM

WebSockets

Register a config from the WebSockets page in an app you have Developer permissions on, then connect:

wss://developers.mooneum.com/api/v1/ws?id=<config id>&token=<your bearer token>

Any of your tokens works — an sk_… secret key, a pk_… publishable key, or an OAuth access token. Browsers can't set custom headers on a WebSocket handshake, so the token travels in the URL; prefer an sk_… key from a server-side process where practical, since anything in the URL can end up in proxy/access logs.

WebSockets are live-only: there's no replay or backfill on reconnect, so an event published while you're disconnected is simply missed — and never logged, since nothing was there to receive it. If you need a durable record of every event, use webhooks instead — the two can be run side by side against the same event, on the same or different configs.

Events

Configs use the exact same subscription and scoping rules as webhooks: an events list of exact names, prefix.* wildcards, or * for everything, narrowed to one app's scope. The order lifecycle (order.*) carries a domain field and only delivers to the config's own app — see the Webhooks guide for the full naming rules, and the Events reference for the always-current list of every event the platform can emit.

Messages

Every message is a JSON text frame with a type:

{ "type": "connection.ready", "configId": "…", "events": ["order.*"], "scope": "trade" }

Sent once, right after connecting, confirming which config you're attached to.

{ "type": "event", "event": "order.submitted", "at": "2026-01-01T00:00:00.000Z", "data": { … } }

One per matching event — event and data mirror a webhook delivery's event name and JSON body exactly, so the same handler code can parse either.

The server sends a WebSocket protocol ping roughly every 25 seconds and closes the connection if a client doesn't respond; most WebSocket libraries answer these automatically. If yours doesn't expose protocol pings (some browser contexts don't), send {"type":"ping"} as a text frame and you'll get {"type":"pong"} back.

Delivery log

The WebSockets page shows the last 5 events actually sent to each config, expandable per row — useful for confirming an integration is receiving what you expect. A row appears only once an event reaches a live connection; there's no entry for a missed event and no retry, status, or error field the way a webhook delivery has, since there's nothing to retry against a socket that isn't open. The same API response is available from GET /developer/websockets.

Disconnects

The server closes the connection with a specific code when a config stops being valid:

CodeMeaning
4001The config was disabled
4004The config was deleted
1001The server is restarting — reconnect as usual

Use the WebSockets page's "Send test" button to push a synthetic websocket.test event to every connection on that config, regardless of its subscribed events — a quick way to confirm your client is receiving messages before wiring up real event handling.