MEXC API WebSocket Python: Real-Time Trading Guide
Learn how to connect to MEXC WebSocket API using Python, stream live price data, handle authentication, and build real-time crypto trading tools.
Learn how to connect to MEXC WebSocket API using Python, stream live price data, handle authentication, and build real-time crypto trading tools.
Real-time data is the backbone of serious crypto trading. REST APIs are fine for historical data or placing orders, but if you want live price feeds — tick by tick, millisecond by millisecond — WebSockets are the only tool that makes sense. MEXC offers one of the most developer-friendly WebSocket APIs in the space, and Python makes it surprisingly easy to work with. Whether you're building a signal scanner, a custom dashboard, or a fully automated bot, this guide walks you through everything from first connection to production-ready error handling.
A WebSocket API is a persistent, two-way communication channel between your client and a server. Unlike a standard REST API — where you send a request and wait for a response — a WebSocket connection stays open. The server pushes data to you the moment something changes. No polling, no wasted requests, no latency overhead from repeatedly opening TCP connections.
The difference between WebSocket and API (REST) comes down to communication model. REST is like sending a letter and waiting for a reply. WebSocket is like a phone call that stays connected. For trading, this distinction is critical: price moves happen in milliseconds, and polling a REST endpoint every second means you're always a step behind. Platforms like Binance, Bybit, and OKX all offer WebSocket feeds precisely because traders demanded them.
| Feature | REST API | WebSocket API |
|---|---|---|
| Connection | Opens and closes per request | Stays open persistently |
| Data delivery | Pull (you ask, server answers) | Push (server sends when data changes) |
| Latency | Higher — new TCP handshake each time | Lower — no reconnect overhead |
| Best for | Order placement, account queries | Live prices, order book updates, trades |
| Server load | Higher on high-frequency use | Lower — one connection, many updates |
Before writing a single line of code, get your environment clean. You'll need Python 3.8 or higher and a few libraries. The main one is `websockets` — an async-native library that handles the WebSocket protocol cleanly. You'll also want `asyncio` (built into Python) and `json` for parsing the messages MEXC sends back.
# Install required packages
pip install websockets requests python-dotenv
# Verify websockets version (need 10.x or higher)
python -c "import websockets; print(websockets.__version__)"
MEXC's public WebSocket endpoint for spot trading is `wss://wbs.mexc.com/ws`. For futures it's a different base URL, but the subscription pattern is the same. No API key is required for public market data streams — price tickers, trade history, order book snapshots. You only need authentication for private streams like order updates or account balance changes.
Store your MEXC API key and secret in a .env file and load them with python-dotenv. Never hardcode credentials in your scripts — even for personal use. One accidental git push can expose your keys to anyone.
MEXC uses a JSON subscription model. You send a subscription message after connecting, and MEXC starts streaming that data channel to you. Here's a complete, working example that subscribes to the BTC/USDT mini-ticker stream and prints live price updates.
import asyncio
import json
import websockets
MEXC_WS_URL = "wss://wbs.mexc.com/ws"
async def stream_btc_price():
async with websockets.connect(MEXC_WS_URL) as ws:
# Subscribe to BTC/USDT mini ticker
subscribe_msg = {
"method": "SUBSCRIPTION",
"params": ["[email protected]@BTC_USDT"]
}
await ws.send(json.dumps(subscribe_msg))
print("Subscribed to BTC/USDT ticker")
async for message in ws:
data = json.loads(message)
# Skip subscription confirmation messages
if "code" in data:
print(f"Server response: {data}")
continue
# Parse ticker payload
if "d" in data:
ticker = data["d"]
print(f"Symbol: {ticker.get('s')} | "
f"Last Price: {ticker.get('c')} | "
f"24h Change: {ticker.get('P')}%")
asyncio.run(stream_btc_price())
Run this script and you'll see BTC/USDT prices printing to your terminal in real time. The `d` key contains the data payload, `s` is the symbol, `c` is the last price, and `P` is the 24-hour percentage change. MEXC's field names follow a compact convention — check their official docs for the full field map per stream type.
Public streams need no authentication. But if you want to receive order updates, execution reports, or account balance changes — that's private data and MEXC requires you to sign a listen key or use HMAC authentication. The pattern is similar to what Binance and Bitget use: generate a signature, send it with your subscription, and MEXC validates your identity before streaming private data.
import asyncio
import hashlib
import hmac
import json
import time
import websockets
import os
from dotenv import load_dotenv
load_dotenv()
API_KEY = os.getenv("MEXC_API_KEY")
API_SECRET = os.getenv("MEXC_API_SECRET")
MEXC_WS_URL = "wss://wbs.mexc.com/ws"
def generate_signature(secret: str, timestamp: int) -> str:
message = f"{API_KEY}{timestamp}"
return hmac.new(
secret.encode("utf-8"),
message.encode("utf-8"),
hashlib.sha256
).hexdigest()
async def stream_private_orders():
async with websockets.connect(MEXC_WS_URL) as ws:
timestamp = int(time.time() * 1000)
signature = generate_signature(API_SECRET, timestamp)
# Authenticate
auth_msg = {
"method": "LOGIN",
"params": [
API_KEY,
timestamp,
signature
]
}
await ws.send(json.dumps(auth_msg))
# Subscribe to private order updates
await ws.send(json.dumps({
"method": "SUBSCRIPTION",
"params": ["[email protected]"]
}))
async for message in ws:
data = json.loads(message)
print(json.dumps(data, indent=2))
asyncio.run(stream_private_orders())
MEXC timestamps must be within 5 seconds of server time. If you get authentication errors, check your system clock — even a small drift causes signature failures. Use an NTP sync or fetch server time from the REST API before signing.
Testing a WebSocket API is different from testing a REST endpoint. You can't just paste a URL into a browser. Here are three reliable ways to validate your connection before plugging it into a live trading system.
# Quick test with websocat (install first: brew install websocat)
websocat wss://wbs.mexc.com/ws
# Then type and press Enter:
{"method":"SUBSCRIPTION","params":["[email protected]@ETH_USDT"]}
# You should start seeing ETH price updates immediately
Comparing behavior across exchanges is also useful for calibration. On Binance, the WebSocket feed structure uses slightly different field names than MEXC. OKX uses a channel-based subscription model. Understanding these differences helps you write normalizing adapters if you're building a multi-exchange system — which is exactly what platforms like VoiceOfChain do to aggregate signals from multiple feeds into unified trading alerts.
A WebSocket that connects once and never handles disconnections is a toy. Production systems need to handle dropped connections, server-side timeouts, network blips, and MEXC's own maintenance windows. Here's a production-grade wrapper that reconnects automatically and handles common failure modes.
import asyncio
import json
import logging
import websockets
from websockets.exceptions import ConnectionClosedError, ConnectionClosedOK
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
MEXC_WS_URL = "wss://wbs.mexc.com/ws"
RECONNECT_DELAY = 5 # seconds
PING_INTERVAL = 20 # MEXC requires keepalive pings
async def on_message(data: dict):
"""Handle incoming messages — plug your logic here."""
if "d" in data:
ticker = data["d"]
logger.info(f"{ticker.get('s')}: {ticker.get('c')} USDT")
async def run_with_reconnect(symbols: list[str]):
subscriptions = [
f"[email protected]@{sym}" for sym in symbols
]
while True:
try:
async with websockets.connect(
MEXC_WS_URL,
ping_interval=PING_INTERVAL,
ping_timeout=10
) as ws:
logger.info("Connected to MEXC WebSocket")
await ws.send(json.dumps({
"method": "SUBSCRIPTION",
"params": subscriptions
}))
async for raw in ws:
try:
data = json.loads(raw)
await on_message(data)
except json.JSONDecodeError:
logger.warning(f"Failed to parse message: {raw}")
except ConnectionClosedOK:
logger.info("Connection closed cleanly — reconnecting")
except ConnectionClosedError as e:
logger.warning(f"Connection dropped (code {e.code}): {e.reason}")
except Exception as e:
logger.error(f"Unexpected error: {e}")
finally:
logger.info(f"Reconnecting in {RECONNECT_DELAY}s...")
await asyncio.sleep(RECONNECT_DELAY)
# Watch BTC, ETH, and SOL simultaneously
asyncio.run(run_with_reconnect(["BTC_USDT", "ETH_USDT", "SOL_USDT"]))
This pattern — infinite retry loop with exponential or fixed delay, separate error handling for clean vs. dirty closes — is used in production bots across Gate.io, KuCoin, and MEXC integrations alike. The `ping_interval` parameter is particularly important: MEXC will close idle connections after roughly 60 seconds, so you need the client to send periodic pings. The `websockets` library handles this automatically when you set `ping_interval`.
If you're aggregating data from multiple exchanges simultaneously — say, MEXC and Bybit feeds running side by side — use `asyncio.gather()` to run multiple WebSocket coroutines concurrently. Each connection runs in its own async task, and Python's event loop handles the scheduling. This is the architecture behind real-time signal aggregators like VoiceOfChain, which combines order flow data, price feeds, and on-chain signals to surface high-probability trade setups as they happen.
WebSocket connectivity is the difference between a dashboard that lags and a trading system that reacts. MEXC's WebSocket API is well-structured, reliable for high-frequency data needs, and Python's `asyncio` + `websockets` stack makes implementation straightforward once you understand the subscription model. Start with a single public ticker stream, add reconnect logic, then layer in authentication for private channels as your use case demands. From there, the architecture scales naturally — multiple symbols, multiple exchanges, feeding into signal logic or automated order placement. If you want to skip the infrastructure build and focus on trade decisions, platforms like VoiceOfChain already aggregate real-time signals across exchanges, giving you the market intelligence layer without having to maintain the WebSocket plumbing yourself.