Guides
Guides

WebSocket Streams

Real-time price klines, mark-price klines, and ticker updates over WebSocket. Public — no authentication required.

Symbols use a lowercase, no-slash format here (e.g. btcusdt, ethusdt) - this differs from the <base>/<quote> format used by the REST market-data endpoints.

Connection

Endpoint: wss://trade.mudrex.com/fapi/v1/price/ws/linear

Keepalive

The server closes the connection after 40 seconds of inactivity. Any client message - a PING frame, SUBSCRIBE, UNSUBSCRIBE, or LIST_SUBSCRIPTIONS - resets the inactivity timer. Sending regular PING frames is the recommended way to keep an idle connection open.

  • Recommended ping interval: 20 seconds.
  • Subscriptions are per-connection and are not persisted. If the connection drops, re-subscribe to all streams after reconnecting.

Request format

All client messages share the same envelope:

{
    "id": 1,
    "method": "SUBSCRIBE",
    "params": ["kline@1m@btcusdt"],
    "assets": ["btcusdt"]
}
FieldTypeDescription
idintCorrelation ID; the server echoes it back so you can match responses to requests.
methodstringSUBSCRIBE, UNSUBSCRIBE, or LIST_SUBSCRIPTIONS.
paramsstring[]Stream names to act on.
assetsstring[]Asset symbols. Applied only when a ticker stream (ticker@5s / ticker@1s) is in params; ignored otherwise.

Mixing stream types in one params array is valid. All-or-nothing: if any stream in params is invalid, the entire request is rejected and no state changes.

Response format

Every request receives a response before any stream data is pushed.

Success:

{ "method": "SUBSCRIBE", "id": 1, "result": "success" }

Error:

{ "method": "SUBSCRIBE", "id": 1, "error": { "code": 400, "msg": "invalid stream name: kline@5m@btcusdt" } }

Available streams

StreamName formatNotes
Kline 1-secondkline@1s@<symbol>OHLCV candle
Kline 1-minutekline@1m@<symbol>OHLCV candle
Mark Kline 1-secondmarkKline@1s@<symbol>OHLC, no volume
Mark Kline 1-minutemarkKline@1m@<symbol>OHLC, no volume
Ticker 1-secondticker@1sChanged prices every 1 second
Ticker 5-secondticker@5sChanged prices every 5 seconds

ticker@1s shares all ticker@5s semantics: assets are supplied in assets, a one-time snapshot is sent on subscribe, pushes occur only when a tracked asset's price changes within the window, and it counts as a single subscription regardless of asset count.

Subscribe

Klines:

{
    "id": 1,
    "method": "SUBSCRIBE",
    "params": ["kline@1m@btcusdt", "kline@1s@ethusdt"]
}

Mark klines (linear only):

{
    "id": 2,
    "method": "SUBSCRIBE",
    "params": ["markKline@1m@btcusdt"]
}

Ticker - the stream name goes in params and asset symbols go in assets:

{
    "id": 3,
    "method": "SUBSCRIBE",
    "params": ["ticker@5s"],
    "assets": ["btcusdt", "ethusdt"]
}

On a successful ticker subscribe, the server immediately sends a one-time snapshot with the last known ticker for each newly-added asset. Assets with no data yet are omitted from the snapshot.

Unsubscribe

Klines:

{
    "id": 4,
    "method": "UNSUBSCRIBE",
    "params": ["kline@1m@btcusdt"]
}

Ticker — pass the assets to remove in assets. The ticker stream is automatically removed when no assets remain:

{
    "id": 5,
    "method": "UNSUBSCRIBE",
    "params": ["ticker@5s"],
    "assets": ["btcusdt"]
}

List subscriptions

Request:

{
    "id": 6,
    "method": "LIST_SUBSCRIPTIONS"
}

Response:

{
    "id": 6,
    "method": "LIST_SUBSCRIPTIONS",
    "result": {
        "subscriptions": ["kline@1m@btcusdt", "ticker@5s"],
        "ticker_5s_assets": ["btcusdt", "ethusdt"],
        "ticker_1s_assets": ["solusdt"]
    }
}

Push data formats

All server-initiated pushes use this envelope:

{ "stream": "<stream-name>", "data": <payload> }

Kline — stream kline@1m@btcusdt:

{
    "stream": "kline@1m@btcusdt",
    "data": {
        "s": "btcusdt",
        "t": 1748736060,
        "o": 67000.0,
        "h": 67500.0,
        "l": 66800.0,
        "c": 67200.0,
        "v": 12.5
    }
}
FieldDescription
sSymbol
tCandle open time (Unix seconds)
oOpen
hHigh
lLow
cClose
vVolume

Mark Kline (linear only) — stream markKline@1m@btcusdt. Same envelope as kline; data has no v field:

{
    "stream": "markKline@1m@btcusdt",
    "data": {
        "s": "btcusdt",
        "t": 1748736060,
        "o": 67010.0,
        "h": 67510.0,
        "l": 66810.0,
        "c": 67215.0
    }
}

Ticker — stream ticker@5s (and ticker@1s):

{
    "stream": "ticker@5s",
    "data": [
        { "s": "btcusdt", "p": 67200.0, "mp": 67210.0 },
        { "s": "ethusdt", "p": 3500.0 }
    ]
}
FieldDescription
sSymbol
pLast price
mpMark price (linear endpoint only; field omitted when unavailable)

Only assets whose price changed since the previous window are included in each push. If no subscribed asset changed, no message is sent.

Limits & errors

  • Max 15 active subscriptions per connection. A ticker stream counts as 1 regardless of asset count; ticker asset count is unlimited.
  • New connections: max 10 per minute per IP
CodeMessageCause
400invalid JSONMalformed request body
400unknown methodmethod is not one of the three valid values
400invalid stream name: <x>Unrecognised stream or unsupported interval
400not subscribed: <x>Unsubscribing from a stream not currently active
429subscription limit reachedWould exceed 15 active subscriptions