Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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:

URLReceives
wss://cryptolisting.wsAll exchanges
wss://cryptolisting.ws?cex=binanceBinance only
wss://cryptolisting.ws?cex=binance,upbitBinance + Upbit

Effective filter

Key allowsYou requestYou receive
*binanceBinance
*noneAll
binance,upbitbinanceBinance
binance,upbitupbitUpbit
binance,upbitnoneBinance + Upbit
binanceupbitnothing (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.