The stream
One WebSocket at wss://api.chartdeck.trade/v1/stream - authentication, subscribe, frames, heartbeats and close codes.
Live data and events arrive over one WebSocket: wss://api.chartdeck.trade/v1/stream. Messages are JSON text frames.
#Authentication
Either send the key on the upgrade request (Authorization: Bearer cdk_..., preferred from servers), or, when your WebSocket library cannot set headers, send it as the first message within 5 seconds:
{"op":"auth","key":"cdk_..."}Never put the key in the URL (the connection is closed with 4000 and the key should be rotated). Browser origins are refused: the stream is for servers. On success the server sends {"op":"hello", ...} with your tier and limits.
#Subscribing
{"op":"subscribe","id":"c1","channels":["candles:binance:BTCUSDT:1","calendar:US"]}The answer is {"op":"ack","id":"c1", ...} listing what was subscribed and what was refused, with a code for each refusal. Also: unsubscribe (same shape), list, and ping (answered with pong). At most 50 channels per message. Opening a connection costs 1 unit and each subscribe 1 unit; data frames cost nothing.
#Frames
{"ch":"candles:binance:BTCUSDT:1","seq":42,"type":"bar","t_ms":1793548800123,"data":{}}seq counts per channel from 1 after each subscribe; a jump is announced by a gap frame. Event channels add event_id (for resuming). Other server messages: ping, error, gap, notice.
#Heartbeats
The server pings every 20 seconds; answer {"op":"pong","ts":<its ts>} (any message also counts). No message from you for 60 seconds closes the connection (4008).
#Close codes
| Code | Meaning | Reconnect |
|---|---|---|
| 1012 | server restarting | at once |
| 1013 | overloaded | after a pause |
| 4000 | bad request, or a key in the URL | after fixing |
| 4001 | unauthorized | no: fix the key |
| 4002 | no auth message in 5 s | yes |
| 4003 | forbidden (scope or tier) | no |
| 4008 | heartbeat timeout | yes |
| 4009 | slow consumer | yes, reading faster or with fewer channels |
| 4010 | key revoked or expired | no |
| 4011 | limits changed | yes, within the new limits |
| 4029 | too many connections | after closing another |
The SDKs reconnect with backoff, re-subscribe and resume for you: see Backpressure and resume.