WebSocket API
Two endpoints share the same API-key namespace.
Endpoints
| URL | Region | Coverage | Use it for |
|---|---|---|---|
wss://cryptolisting.ws | AWS Tokyo (ap-northeast-1a, apne1-az4) | Binance + Upbit + Bithumb | Bots in Tokyo / global |
wss://kr.cryptolisting.ws | AWS Seoul (ap-northeast-2c, apne2-az3) | Upbit only | Korea-based bots trading Upbit |
Pick one per bot — the closest to your trading region. The Seoul endpoint removes the Seoul → Tokyo network hop on Upbit detection. Bithumb is dispatched only from Tokyo. Same key authenticates on both, but rate limits and connection caps are tracked independently.
Frames are binary; payloads are UTF-8 JSON.
Query parameters
| Parameter | Required | Description | Example |
|---|---|---|---|
cex | No | Comma-separated list of exchanges | binance,upbit |
See Exchange Filtering.
Lifecycle
Client Server
| |
|--- WSS handshake + API key -----→ |
|←---- 101 Switching Protocols -----|
| |
|←---- welcome --------------------| (immediate)
|←---- PING (control frame) -------| (every 15 s)
|--- PONG ------------------------→ | (handled by your WS lib)
|←---- heartbeat (JSON) -----------| (every 30 s)
|←---- announcement ---------------| (when detected)
|--- {"type":"test"} -------------→ | (optional)
|←---- test_announcement ---------| (only to you)
|←---- close (1000, key_expired) -| (if key expires)
Handshake
If the key fails validation, the server rejects the upgrade with an HTTP error:
| Code | Cause |
|---|---|
426 | Malformed upgrade request (missing/invalid Sec-WebSocket-Key or Upgrade) |
401 | Missing X-API-Key header |
403 | Invalid, revoked, or expired key |
429 | Rate, per-IP, distinct-IP, or absolute-cap limit hit (or cooldown active) |
See Error Handling for retry strategy.
Welcome
Sent once after a successful handshake. Confirms tier and limits. See welcome.
Keep-alive
The server sends a WebSocket PING control frame every 15 s (with 0–5 s jitter on the first). Your library responds with PONG automatically — Python websockets, Node.js ws, Go gorilla/websocket, Rust tokio-tungstenite all handle it without configuration.
If the server does not receive a PONG within 30 s of the last ping, it closes the connection.
Don’t add an “no-message-for-N-seconds → reconnect” watchdog at the application layer. Listings are sparse; you’ll reconnect in a loop during quiet periods. Use your library’s close/error callbacks instead.
Heartbeat
A JSON heartbeat message every 30 s, every tier. Lets your client confirm the connection is alive without waiting for a rare announcement. See heartbeat.
Announcements
When an event is detected, every subscriber whose filter matches receives an announcement. See announcement.
Disconnection
The server may close the connection with a close frame. The reason field tells you why — see Error Handling.
Client-to-server messages
The only supported client message is the test request:
{"type":"test"}
Returns a fake test_announcement. Limits:
| Limit | Value | Effect on excess |
|---|---|---|
| Message rate | 3 / minute | Connection closed (rate_limit_exceeded) |
| Frame size | 1 KB | Connection closed (frame_too_large) |
| Test rate | 1 / minute | test_rate_limited error response |