Free WebSocket Crypto APIs: Real-Time Data for Traders
Learn how to tap into free crypto WebSocket APIs for live price feeds. Practical Python and JavaScript examples for Binance, Bybit, and OKX streams.
Learn how to tap into free crypto WebSocket APIs for live price feeds. Practical Python and JavaScript examples for Binance, Bybit, and OKX streams.
Every millisecond matters when you are trading crypto. REST APIs are fine for checking a balance or placing a manual order, but they are fundamentally polling — you ask, the server answers, you wait, you ask again. WebSockets flip that model. The exchange keeps a persistent connection open and pushes data to you the moment it changes. Price tick, order book update, trade execution — all arrive in real time without you hammering an endpoint. The good news is that most major exchanges offer a free crypto WebSocket API with generous rate limits, no API key required for public market data. This guide walks through exactly how to connect, what to expect, and how to write production-quality code around it.
A REST request involves a full HTTP handshake every time — TCP connection, TLS negotiation, request, response, close. For a price check every second that overhead adds up fast and burns through API rate limits. WebSocket establishes one TCP connection and keeps it alive indefinitely. After the initial HTTP upgrade handshake, raw frames flow in both directions with almost no overhead. Latency drops from hundreds of milliseconds to low single digits. For algo traders, scalpers, or anyone building a dashboard that needs live prices, this is not a nice-to-have — it is the foundation.
Beyond latency, WebSockets also reduce infrastructure cost. Instead of spinning up a polling loop that fires 60 requests per minute, you maintain one socket and let the exchange notify you. Binance, Bybit, OKX, KuCoin, and Gate.io all provide free bitcoin WebSocket streams for public market data — trades, 24h tickers, depth updates — without authentication. Private channels like order updates require a signed API key, but for price feeds you need exactly zero credentials.
Not all WebSocket implementations are equal. Some exchanges push individual trade ticks, others push aggregated book snapshots, and the reconnection policies vary widely. Here is a practical comparison of the most reliable free options:
| Exchange | Base URL | Auth Required (Public) | Max Connections | Heartbeat |
|---|---|---|---|---|
| Binance | wss://stream.binance.com:9443 | No | 1024 streams/conn | Ping every 3 min |
| Bybit | wss://stream.bybit.com/v5/public/spot | No | 10 topics/conn | Ping every 20s |
| OKX | wss://ws.okx.com:8443/ws/v5/public | No | 240 req/hour | Ping every 30s |
| KuCoin | wss://ws-api.kucoin.com (token needed) | Token via REST | 300 topics/conn | Ping every 30s |
| Gate.io | wss://api.gateio.ws/ws/v4/ | No | 100 channels/conn | Ping every 30s |
Binance is the most beginner-friendly free WebSocket: no token negotiation, stable URL, and the widest documentation coverage. Start there, then branch out to Bybit or OKX for additional pairs.
Binance's free bitcoin WebSocket stream for individual trades is at wss://stream.binance.com:9443/ws/{symbol}@trade. No API key, no token — just open the socket and start receiving. Install the websocket-client library with pip install websocket-client, then use the following production-ready example that includes error handling and automatic reconnection:
import websocket
import json
import time
SYMBOL = "btcusdt"
SOCKET_URL = f"wss://stream.binance.com:9443/ws/{SYMBOL}@trade"
def on_message(ws, message):
data = json.loads(message)
price = float(data["p"])
qty = float(data["q"])
side = "BUY" if data["m"] is False else "SELL"
print(f"BTC/USDT | {side} | Price: {price:.2f} | Qty: {qty:.6f}")
def on_error(ws, error):
print(f"[ERROR] {error}")
def on_close(ws, close_status_code, close_msg):
print(f"[CLOSED] Code: {close_status_code} — reconnecting in 5s...")
time.sleep(5)
connect()
def on_open(ws):
print(f"[CONNECTED] Streaming {SYMBOL.upper()} trades from Binance")
def connect():
ws = websocket.WebSocketApp(
SOCKET_URL,
on_open=on_open,
on_message=on_message,
on_error=on_error,
on_close=on_close
)
ws.run_forever(ping_interval=180, ping_timeout=10)
if __name__ == "__main__":
connect()
The m field in the Binance trade stream is the maker side flag — false means the buyer was the maker, true means the seller was. This is how you determine buy vs sell pressure without any additional calls. The ping_interval=180 keeps the connection alive — Binance will close idle connections after 24 hours or if they do not receive a pong within 10 minutes of a ping.
OKX uses a subscription model over their free crypto WebSocket API — you connect, then send a JSON subscribe message specifying which channels and instruments you want. This is slightly different from Binance's URL-based approach but far more flexible when you need multiple symbols or channel types over a single connection. The following Node.js example subscribes to the BTC-USDT ticker and handles reconnection automatically:
const WebSocket = require('ws');
const OKX_WS_URL = 'wss://ws.okx.com:8443/ws/v5/public';
let ws;
function connect() {
ws = new WebSocket(OKX_WS_URL);
ws.on('open', () => {
console.log('[CONNECTED] OKX WebSocket open');
const subscribeMsg = {
op: 'subscribe',
args: [
{ channel: 'tickers', instId: 'BTC-USDT' },
{ channel: 'tickers', instId: 'ETH-USDT' }
]
};
ws.send(JSON.stringify(subscribeMsg));
});
ws.on('message', (raw) => {
const msg = JSON.parse(raw);
// OKX sends pong as plain string
if (msg === 'pong') return;
if (msg.event === 'subscribe') {
console.log(`[SUBSCRIBED] ${msg.arg.channel} — ${msg.arg.instId}`);
return;
}
if (msg.data && msg.data.length > 0) {
const { instId, last, bidPx, askPx, vol24h } = msg.data[0];
console.log(`${instId} | Last: ${last} | Bid: ${bidPx} | Ask: ${askPx} | Vol24h: ${vol24h}`);
}
});
ws.on('error', (err) => {
console.error('[ERROR]', err.message);
});
ws.on('close', () => {
console.log('[CLOSED] Reconnecting in 5s...');
setTimeout(connect, 5000);
});
// OKX requires client-side ping every 30s
setInterval(() => {
if (ws.readyState === WebSocket.OPEN) {
ws.send('ping');
}
}, 25000);
}
connect();
OKX expects a plain-text ping string (not JSON) and responds with a plain-text pong. If you skip this, the connection drops after 30 seconds of silence. The setInterval fires every 25 seconds to stay safely under the 30-second threshold. On Bybit the same principle applies but the keepalive is a JSON object: {"op": "ping"}.
When you need to track multiple trading pairs simultaneously without running multiple processes, Python's asyncio with the websockets library is the cleanest approach. Bybit's v5 public endpoint lets you subscribe to multiple topics over one connection — orderbook, trades, and tickers all at once:
import asyncio
import json
import websockets
from datetime import datetime
BYBIT_URL = "wss://stream.bybit.com/v5/public/spot"
SUBSCRIPTIONS = [
"tickers.BTCUSDT",
"tickers.ETHUSDT",
"publicTrade.BTCUSDT"
]
async def bybit_stream():
while True: # outer loop handles reconnection
try:
async with websockets.connect(BYBIT_URL, ping_interval=20) as ws:
sub_msg = {"op": "subscribe", "args": SUBSCRIPTIONS}
await ws.send(json.dumps(sub_msg))
print(f"[{datetime.now():%H:%M:%S}] Connected to Bybit")
async for raw in ws:
msg = json.loads(raw)
if "success" in msg:
print(f"Subscription: {msg}")
continue
topic = msg.get("topic", "")
data = msg.get("data", {})
if topic.startswith("tickers"):
symbol = data.get("symbol")
price = data.get("lastPrice")
change = data.get("price24hPcnt")
print(f"{symbol}: ${price} ({float(change)*100:.2f}% 24h)")
elif topic.startswith("publicTrade"):
for trade in data:
side = trade["S"]
price = trade["p"]
size = trade["v"]
print(f" TRADE {side}: {size} BTC @ ${price}")
except (websockets.ConnectionClosed, OSError) as e:
print(f"[DISCONNECTED] {e} — retrying in 5s")
await asyncio.sleep(5)
if __name__ == "__main__":
asyncio.run(bybit_stream())
Always wrap your WebSocket event loop in a while True reconnection block. Exchanges drop connections during maintenance windows, network blips, or after hitting rate limits. Production code that does not auto-reconnect will fail silently at 3am.
Raw price ticks are noise. The edge comes from what you do with them. Common patterns traders build on top of free WebSocket crypto streams include: rolling VWAP calculations updated tick-by-tick, order flow imbalance detection using the maker/taker side flag, real-time CVD (Cumulative Volume Delta) for spotting divergences, and aggressive trade clustering to detect large player activity. Platforms like Binance and OKX push enough granularity — individual trade size, side, timestamp — that you can reconstruct a full order flow picture purely from WebSocket data.
If you do not want to build the signal layer yourself, VoiceOfChain aggregates real-time data from multiple exchange WebSocket feeds and turns them into structured trading signals you can act on immediately. The platform processes live streams from Binance, Bybit, and OKX simultaneously, normalizing the data into a unified feed so you are not context-switching between exchange-specific formats. For traders who want the speed of WebSocket data without writing the infrastructure from scratch, it handles the heavy lifting — connection management, reconnection logic, data normalization, and signal generation — and surfaces the result as clean alerts.
After working with free crypto WebSocket APIs across Binance, Bybit, OKX, Bitget, and KuCoin, the failure modes fall into predictable patterns. Knowing them upfront saves hours of debugging.
Free WebSocket crypto APIs from Binance, Bybit, and OKX give you genuine institutional-quality market data at zero cost. The barrier to entry is low — a dozen lines of Python or JavaScript is enough to start receiving live price ticks. The real work is what comes next: building resilient reconnection logic, normalizing data across exchanges, and turning raw streams into signals that actually inform decisions. Start with the Binance free bitcoin WebSocket for its simplicity, add Bybit and OKX as you need cross-exchange coverage, and layer your signal logic on top. Whether you build it all yourself or use a platform like VoiceOfChain to handle the infrastructure, the foundation is the same: a persistent connection, a clean message handler, and an auto-reconnect loop that keeps it all running when things inevitably go wrong.