Connecting

Open a WebSocket connection to the feed, authenticating with your API key on the upgrade request.

wss://api.esca.finance/v1/rates

Authentication

Send your API key in the X-Api-Key header on the connection upgrade — identical to the REST API. The key is pinned to your account's allowed IP(s), same as REST.

Header Required Description
X-Api-Key Yes Your API key

If the key is missing, invalid, expired, IP-mismatched, or the account is deactivated, the upgrade is rejected with 401.

Server-to-server clients (Node ws, Python websockets, Go gorilla/websocket, etc.) can set the X-Api-Key header on the upgrade directly. Browser WebSocket clients cannot set custom headers and are not supported.

Welcome frame

On a successful connection the server sends:

{
  "type": "welcome",
  "connection_id": "42-1716640000000-a1b2c3",
  "server_time": "2026-05-25T13:28:53.121Z",
  "heartbeat_interval_ms": 25000
}
Field Description
connection_id Identifier for this connection (quote it in support requests)
server_time Server timestamp (ISO 8601)
heartbeat_interval_ms How often the server will ping (see Heartbeats)

Heartbeats

The server sends a heartbeat every heartbeat_interval_ms (25s):

{ "type": "ping", "server_time": "2026-05-25T13:29:18.000Z" }

Your client must reply with a pong so the server knows the connection is alive:

{ "type": "pong" }

A connection that misses a heartbeat (no pong before the next tick) is closed. Replying promptly to every ping keeps the connection open through idle periods.

Reconnection

If the connection drops, reconnect and re-subscribe:

  • Use exponential backoff with jitter, starting around 1s and capped near 30s.
  • On reconnect, open a new connection with the X-Api-Key header and re-send your subscribe request — there is no session to resume.

Server shutdown

During a deploy or dyno cycle the server sends a shutdown frame before closing:

{ "type": "server_shutdown", "reconnect_after_ms": 1840 }

Wait reconnect_after_ms (jittered) before reconnecting to spread reconnection load.

Example (Node, ws)

const WebSocket = require('ws');

const ws = new WebSocket('wss://api.esca.finance/v1/rates', {
  headers: { 'X-Api-Key': process.env.ESCA_API_KEY },
});

ws.on('open', () => {
  ws.send(JSON.stringify({
    method: 'subscribe',
    params: { channel: 'ticker', symbol: ['USD/NGN', 'BTC/USD'], snapshot: true },
    req_id: 1,
  }));
});

ws.on('message', (raw) => {
  const msg = JSON.parse(raw.toString());
  if (msg.type === 'ping') ws.send(JSON.stringify({ type: 'pong' }));
  // handle welcome / subscribe ack / snapshot / update ...
});