Exchange Filtering
Two filter layers narrow the stream you receive. The effective scope is their intersection.
1. Key restriction
Set by the administrator at key creation. Your effective allow-list appears in the welcome message:
{ "type": "welcome", "allowedCex": "binance,upbit", ... }
"*" means all exchanges.
2. ?cex= query parameter
Pass on the WebSocket URL:
| URL | Receives |
|---|---|
wss://cryptolisting.ws | All exchanges |
wss://cryptolisting.ws?cex=binance | Binance only |
wss://cryptolisting.ws?cex=binance,upbit | Binance + Upbit |
Effective filter
| Key allows | You request | You receive |
|---|---|---|
* | binance | Binance |
* | none | All |
binance,upbit | binance | Binance |
binance,upbit | upbit | Upbit |
binance,upbit | none | Binance + Upbit |
binance | upbit | nothing (no overlap) |
If the intersection is empty, the connection still succeeds and stays alive (PING and heartbeat keep flowing) but you receive no announcement messages. Verify your allowedCex against your ?cex= value.
Filtering by event type
?cex= narrows by exchange. To narrow by event class, branch on listingType in your handler:
def on_message(ws, raw):
msg = json.loads(raw)
if msg["type"] != "announcement":
return
lt = msg["listingType"]
if lt == "spot_listing":
snipe(msg["publisher"], msg["ticker"])
elif lt in ("spot_delisting", "futures_delisting"):
unwind(msg["publisher"], msg["ticker"])
elif lt in ("monitoring_tag_extend", "monitoring_tag_remove", "caution_released"):
log_risk_signal(msg["publisher"], msg["ticker"], lt)
The schema is identical across exchanges, so a single match / switch / if-elif chain covers every type. See Listing types for the full list.