API ReferenceWebSocket Protocol
Live

WebSocket Protocol

One connection, many channels. Open a socket, subscribe to the channels you want, and data flows as it happens on-chain — sub-second from transaction to your handler. This page is the protocol; the Channel Catalog lists every channel you can subscribe to.

Connecting

wss://api.conyr.ai/ws
const ws = new WebSocket("wss://api.conyr.ai/ws?api_key=YOUR_API_KEY");
 
ws.onopen = () => {
  ws.send(JSON.stringify({
    op: "subscribe",
    channels: ["token:EPjFWd...:trades", "token:EPjFWd...:ohlcv:filtered:1m"],
  }));
};
 
ws.onmessage = (event) => {
  const msg = JSON.parse(event.data);
  if (msg.channel) console.log(`[${msg.channel}]`, msg.data);
};

Your API key’s tier governs the connection — pass it as the api_key query param (browser-friendly), or as an Authorization: Bearer header from a server client. The free tier has 0 WebSocket connections, so streaming needs a Layer 1+ key.

Client → server

MessagePurpose
{"op": "subscribe", "channels": [...]}Subscribe to one or more channels
{"op": "unsubscribe", "channels": [...]}Stop receiving those channels
{"op": "ping"}Liveness check (server replies pong)

Server → client

MessageMeaning
{"channel": "...", "data": { ... }}A data event — the payload shape depends on the channel
{"op": "subscribed", "channels": [...]}Subscription confirmed
{"op": "unsubscribed", "channels": [...]}Unsubscribe confirmed
{"op": "pong"}Reply to your ping
{"op": "error", "message": "..."}Informational error — does not disconnect you

Every data event is wrapped in the same {channel, data} envelope, so one onmessage handler can route by channel.

{ "channel": "token:EPjFWd...:trades", "data": { "...": "the primitive's payload" } }

Limits by tier

TierConnectionsSubscriptions / connection
Free0
Layer 1550
Layer 22050
Layer 35050
EnterpriseUnlimitedUnlimited

Exceeding the subscription cap returns an error message on the socket — it doesn’t drop the connection.

Delivery & heartbeat

⚠️

If your client falls behind, messages are dropped silently rather than backing up and affecting other consumers — so keep your onmessage handler fast. For guaranteed delivery and a dedicated consumer position, use the Enterprise tier.

The server also sends a WebSocket-level ping roughly every 30 seconds to keep the connection alive; most clients answer automatically.

The reliable pattern: backfill current state from REST, then subscribe to the matching channel — events pick up from the moment you connect, with no gap. See the REST + Streaming Model.