Портал розробників

Public WebSocket#

General Push Rules#

Connection url#

EnvironmentPublic channel URL
Productionwss://{public-host}/ws/v5/public

Public channels do not require login.

Connection and Heartbeat Rules#

Each IP address is limited to 3 WebSocket connection attempts per second.

WebSocket Operation Request Rate Limits#

WebSocket operation requests use a token-bucket mechanism. Rate limiting is applied per WebSocket connection, specifically per Netty Channel.

RuleLimit
Rate-limit scopeSingle WebSocket connection
Token-bucket capacity480 tokens
Initial tokens when the connection is established480 tokens
Token recovery rate480 tokens per hour, approximately 1 token every 7.5 seconds
Cost per request1 token
Requests included in the limitClient operation requests such as login, subscribe, and unsubscribe
Separate calculation by channelNo. All channels on the same connection share one token bucket.
Shared by IPNo. Different connections established from the same IP have independent token buckets.
ReconnectionA newly established connection receives a new token bucket with the full initial capacity of 480 tokens.

Each complete WebSocket operation request consumes 1 token. If a subscribe or unsubscribe request contains multiple channels or products in args[], it is still counted as one request and consumes only 1 token.

Tokens are continuously replenished at a rate of 480 per hour. The bucket is capped at 480 tokens and does not reset at the beginning of each hour. A single connection can therefore send up to 480 operation requests in a burst after it is established, after which approximately one token is restored every 7.5 seconds.

All subscribe and unsubscribe operations on the same connection share the same token bucket. They are not calculated separately for business channels such as tickers or trades.

Idle Disconnect and Heartbeat#

The server automatically disconnects a connection if no subscription is created within 30 seconds after the connection is established, or if the server does not push any data for 30 consecutive seconds after a subscription is created.

After receiving each message, the client should start a timer with a duration shorter than 30 seconds. If no new message is received before the timer expires, the client should send the text string ping and expect the server to return the text string pong. If pong is not received within the expected period, the client should report an error or establish a new connection.

Data Type Conventions#

Only three data types are used for parameters:

  • String: used for most parameters.
  • Boolean: used for Boolean values.
  • Integer: used only for exceptions such as sequence numbers.

All numeric values, including prices, quantities, and timestamps, are returned as String. Timestamps use Unix epoch milliseconds and are represented as String.

Scientific notation is not used for numeric values. For example, use 0.000001 instead of 1E-6. Decimal values do not include insignificant trailing zeros; use 5 instead of 5.0.

Subscribe#

Request Format

json
{
  "id": "1512",
  "op": "subscribe",
  "args": [
    {
      "channel": "exchangeos-tickers",
      "assetId": "1"
    }
  ]
}

A single request can subscribe to one or more channels. The total size of the channel objects in args must not exceed 64 KB.

Request Parameters

ParameterTypeRequiredDescription
idStringNoA unique message identifier aligned with V5. The client provides this value, and the server returns it unchanged so the request can be matched. It must contain only letters and numbers and be 1–32 characters long.
opStringYesOperation type, fixed as subscribe.
argsArray of ObjectsYesList of channels to subscribe to.
> channelStringYesChannel name.
> assetIdStringNoProduct ID.

Successful Response Example

json
{
  "event": "subscribe",
  "arg": {
    "channel": "exchangeos-tickers",
    "assetId": "1234"
  },
  "connId": "accb8e21"
}

Response Parameters

ParameterTypeRequiredDescription
eventStringYesEvent type. The value is subscribe or error.
argObjectNoSubscription channel information.
> channelStringYesChannel name.
> assetIdStringNoProduct ID.
codeStringNoError code returned when the request fails.
msgStringNoError message returned when the request fails.
connIdStringYesWebSocket connection ID.

Unsubscribe#

Request Example

json
{
  "op": "unsubscribe",
  "args": [
    {
      "channel": "exchangeos-tickers",
      "assetId": "1234"
    }
  ]
}

Request Parameters

ParameterTypeRequiredDescription
opStringYesOperation type, fixed as unsubscribe.
argsArray of ObjectsYesList of channels to unsubscribe from.
> channelStringYesChannel name.
> assetIdStringNoProduct ID.

Response Example

json
{
  "event": "unsubscribe",
  "arg": {
    "channel": "exchangeos-tickers",
    "assetId": "1234"
  },
  "connId": "d0b44253"
}

Response Parameters

ParameterTypeRequiredDescription
eventStringYesEvent type. The value is unsubscribe or error.
argObjectNoUnsubscription channel information.
> channelStringYesChannel name.
> assetIdStringNoProduct ID.
codeStringNoError code.
msgStringNoError message.
connIdStringYesWebSocket connection ID.

Notice Message (event = notice)#

Approximately 60 seconds before a scheduled service upgrade, the server sends a notice message instructing the client to reconnect.

json
{
  "event": "notice",
  "code": "64008",
  "msg": "The connection will soon be closed for a service upgrade. Please reconnect.",
  "connId": "a4d3ae55"
}

Ticker Channel exchangeos-tickers#

Pushes last trade, best bid/ask, and 24-hour market statistics for one spot or perp product whenever data changes.

Subscribe with:

json
{
  "op": "subscribe",
  "args": [
    {
      "channel": "exchangeos-tickers",
      "assetId": "1234"
    }
  ]
}
FieldTypeDescription
assetIdStringProduct ID.
lastPxStringLatest trade price.
lastSzStringLatest trade quantity.
askPxStringBest ask price.
askSzStringBest ask quantity.
bidPxStringBest bid price.
bidSzStringBest bid quantity.
open24hString24-hour opening price.
high24hString24-hour highest price.
low24hString24-hour lowest price.
volCcy24hString24-hour trading amount denominated in the quote currency.
vol24hString24-hour trading volume denominated in the base currency.
sodUtc0StringOpening price for the day in the UTC+0 time zone.
sodUtc8StringOpening price for the day in the UTC+8 time zone.
tsStringData update timestamp in Unix milliseconds.
lastPxUsdStringUSD value of the latest trade price.

Push Example

json
{
  "arg": { "channel": "exchangeos-tickers", "assetId": "1234" },
  "data": [
    {
      "assetId": "1234",
      "lastPx": "97520.5",
      "lastPxUsd": "97320.5",
      "lastSz": "0.0012",
      "askPx": "97521.0",
      "askSz": "1.5234",
      "bidPx": "97520.0",
      "bidSz": "2.3041",
      "open24h": "96800.0",
      "high24h": "98100.3",
      "low24h": "96210.5",
      "volCcy24h": "582310412.56",
      "vol24h": "5980.23",
      "sodUtc0": "96950.0",
      "sodUtc8": "97010.2",
      "ts": "1710249600000"
    }
  ]
}

Trade Channel exchangeos-trades#

Channel Description

Pushes the latest trades for a specified product.

Trade Aggregation Logic

exchangeos-trades processes trade data independently for each assetId.

Consecutive trades are merged into a single aggregated record only when all of the following conditions are met:

  • The trade price is the same.
  • The buy/sell direction is the same.
  • The timestamp is the same to millisecond precision.
  • The price precision and quantity precision are the same.

The trade quantity is accumulated after aggregation. If any condition differs, the system creates a new record.

Push Rules

  • The system normally checks trade data every 100 milliseconds.
  • Each push returns at most the latest 20 aggregated records.
  • Records in the data array are ordered from newest to oldest, with the most recently received trade first.
  • Each record in data may represent one original trade or the aggregated result of multiple adjacent trades that meet all of the conditions above.
  • assetId appears only in the first element of the data array. All trades in the same message frame belong to the same assetId, which is identified by the outer arg.assetId.
json
{
  "op": "subscribe",
  "args": [
    {
      "channel": "exchangeos-trades",
      "assetId": "1234"
    }
  ]
}
FieldTypeDescription
assetIdStringProduct ID. Appears only in the first element of the data array.
fIdStringTrade ID of the first original trade in the aggregation segment, inclusive.
lIdStringTrade ID of the last original trade in the aggregation segment, inclusive. The first character is a lowercase l. Trade IDs within the aggregation segment are guaranteed to be consecutive from fId to lId.
pxStringCommon execution price of all trades in the aggregation segment.
szStringTotal trade quantity of the aggregation segment.
sideStringTrade direction. Possible values: buy or sell.
tsStringTrade timestamp in Unix milliseconds. All trades in the same aggregated record have the same ts; trades with different ts values are not aggregated.
json
{
  "arg": {
    "channel": "exchangeos-trades",
    "assetId": "1802"
  },
  "data": [
    {
      "assetId": "1802",
      "fId": "161999",
      "lId": "161999",
      "px": "94.546",
      "sz": "1.05",
      "side": "buy",
      "ts": "1793087643641"
    },
    {
      "fId": "161998",
      "lId": "161998",
      "px": "94.54",
      "sz": "1.17",
      "side": "buy",
      "ts": "1793087643641"
    }
  ]
}

Trade Candle Channel exchangeos-candle{bar}#

Pushes trade candlestick data whenever the data changes. Replace {bar} with the desired interval.

Supported intervals

1m, 5m, 15m, 1H, 4H, 1D

json
{
  "op": "subscribe",
  "args": [
    {
      "channel": "exchangeos-candle1H",
      "assetId": "1234"
    }
  ]
}

Each element in data[] is a fixed-length array containing nine string values:

IndexFieldDescription
0tsCandle start time in Unix epoch milliseconds.
1openOpening price.
2highHighest price.
3lowLowest price.
4closeClosing price.
5volTrading volume.
6volCcyVolume denominated in the volume currency.
7volCcyQuoteTrading amount denominated in the quote currency.
8confirm0: candle is not closed; 1: candle is closed.
json
{
  "arg": {
    "channel": "exchangeos-candle1H",
    "assetId": "1234"
  },
  "data": [
    [
      "1710000000000",
      "50000",
      "51000",
      "49500",
      "50500",
      "1234.5",
      "617250000",
      "617250000",
      "0"
    ]
  ]
}

Mark Price Candle Channel exchangeos-mark-price-candle{bar}#

Channel Description

Pushes mark-price candlesticks for a specified product. Candlestick prices are derived from the mark price and do not include trading volume.

Channel Name

The channel name consists of exchangeos-mark-price-candle followed by the candle interval. Examples:

  • exchangeos-mark-price-candle1s
  • exchangeos-mark-price-candle1m
  • exchangeos-mark-price-candle15m
  • exchangeos-mark-price-candle1H

Supported Intervals (bar)

1s, 1m, 5m, 15m, 1H, 4H, 1D

Subscription Parameters

ParameterTypeRequiredDescription
channelStringYesChannel name in the format exchangeos-mark-price-candle{bar}, where {bar} is the candle interval.
assetIdStringYesProduct ID. Only perp products are supported.

Subscription Examples

Subscribe to 1-second mark-price candlesticks for assetId=2:

json
{
  "op": "subscribe",
  "args": [
    {
      "channel": "exchangeos-mark-price-candle1s",
      "assetId": "2"
    }
  ]
}

Subscribe to 15-minute mark-price candlesticks for assetId=2:

json
{
  "op": "subscribe",
  "args": [
    {
      "channel": "exchangeos-mark-price-candle15m",
      "assetId": "2"
    }
  ]
}

Push Structure

FieldTypeDescription
argObjectSubscription channel information.
arg.channelStringChannel name, including the candle interval.
arg.assetIdStringProduct ID.
dataArray<Array<String>>Mark-price candlestick data. Each record contains exactly 6 elements.

data[] Element Description

Each candlestick is returned in the following fixed order:

text
[ts, open, high, low, close, confirm]
IndexFieldTypeDescription
0tsStringCandlestick start time in Unix milliseconds.
1openStringOpening mark price.
2highStringHighest mark price.
3lowStringLowest mark price.
4closeStringClosing mark price. For an unclosed candlestick, this is the latest mark price.
5confirmStringCandlestick status: 0 means unclosed; 1 means closed.

This channel does not return trading volume, trading amount, or trade count.

Push Example

json
{
  "arg": {
    "channel": "exchangeos-mark-price-candle1s",
    "assetId": "2"
  },
  "data": [
    [
      "1785912897000",
      "1.0298",
      "1.0298",
      "1.0298",
      "1.0298",
      "0"
    ]
  ]
}

Interpretation

  • The candlestick start time is 1785912897000.
  • The opening mark price is 1.0298.
  • The highest mark price is 1.0298.
  • The lowest mark price is 1.0298.
  • The current closing mark price is 1.0298.
  • confirm="0" indicates that the candlestick is not yet closed.

Client Handling Rules

An unclosed candlestick may be pushed repeatedly as the mark price changes. The client should use channel + assetId + ts as the unique key for each candlestick and overwrite the previous record with the latest data.

When confirm="1" is received, the candlestick is considered closed.

Index Ticker Channel exchangeos-index-tickers#

Channel Description

Pushes the latest index price.

  • When the index price changes, updates are pushed at most once per second.
  • If the index price does not change, an update is pushed once per minute.
  • The push includes idxPx, open24h, high24h, low24h, sodUtc0, and sodUtc8.

Subscription Parameters

  • channel: Fixed as exchangeos-index-tickers.
  • assetId: Product ID corresponding to the index, for example 1234.

Subscription Example

json
{
  "op": "subscribe",
  "args": [
    {
      "channel": "exchangeos-index-tickers",
      "assetId": "1234"
    }
  ]
}

Push Fields (data element)

FieldTypeDescription
assetIdStringProduct ID.
idxPxStringLatest index price.
high24hStringHighest index price over the past 24 hours.
low24hStringLowest index price over the past 24 hours.
open24hStringIndex opening price over the past 24 hours.
sodUtc0StringDaily index opening price in the UTC+0 time zone.
sodUtc8StringDaily index opening price in the UTC+8 time zone.
tsStringData update timestamp in Unix milliseconds.

Push Example

json
{
  "arg": {
    "channel": "exchangeos-index-tickers",
    "assetId": "1234"
  },
  "data": [
    {
      "assetId": "1234",
      "idxPx": "64972.1",
      "high24h": "65500.0",
      "low24h": "64200.0",
      "open24h": "64800.0",
      "sodUtc0": "64900.0",
      "sodUtc8": "64950.0",
      "ts": "1781701360808"
    }
  ]
}

Index Candlestick Channel exchangeos-index-candle{bar}#

Channel Description

Pushes index candlestick data. The channel name consists of exchangeos-index-candle followed by the candle interval, for example exchangeos-index-candle1H.

The fields are aligned with the TZ REST index candlestick data. Each record contains OHLC data and the candlestick status, for a total of 6 elements. Trading volume is not included.

Supported Intervals (bar)

1m, 5m, 15m, 1H, 4H, 1D

Subscription Parameters

  • channel: Formatted as exchangeos-index-candle{bar}.
  • assetId: Product ID.

Subscription Example

json
{
  "op": "subscribe",
  "args": [
    {
      "channel": "exchangeos-index-candle1H",
      "assetId": "1234"
    }
  ]
}

Push Fields (data is an array of 6 strings)

IndexDescription
[0]Candlestick start time in Unix milliseconds.
[1]Opening price.
[2]Highest price.
[3]Lowest price.
[4]Closing price.
[5]Candlestick status: 0 means unclosed; 1 means closed.

Push Example

json
{
  "arg": {
    "channel": "exchangeos-index-candle1H",
    "assetId": "1234"
  },
  "data": [
    [
      "1710000000000",
      "50000.0",
      "51000.0",
      "49500.0",
      "50500.0",
      "0"
    ]
  ]
}

Funding Rate Channel exchangeos-funding-rate#

Channel Description

Pushes the current predicted funding rate and the next settlement information for perpetual contracts. Updates are pushed every 5 seconds by default.

The WebSocket response does not include fundingTime. Clients should use nextFundingTime to determine the next settlement time and settlementInterval to determine the settlement period.

To retrieve fundingTime, query the REST endpoint:

http
GET /market/funding-rate

Subscription Parameters

  • channel: Fixed as exchangeos-funding-rate.
  • assetId: Required, for example 1234.

Subscription Example

json
{
  "op": "subscribe",
  "args": [
    {
      "channel": "exchangeos-funding-rate",
      "assetId": "2"
    }
  ]
}

Push Fields (data element)

FieldTypeDescription
assetIdStringProduct ID.
fundingRateStringCurrent funding rate. This field was renamed from the previous TZ on-chain field rate. Returns an empty string "" when upstream data is unavailable, such as when a new trading pair has insufficient liquidity or the funding switch is disabled.
nextFundingTimeStringNext settlement time in milliseconds. Under normal conditions, it equals fundingTime + settlementInterval × 3,600,000.
settlementIntervalStringSettlement interval in hours. Possible values are 1, 2, 4, 8, 12, and 24. The source field is settlement_interval, with a default value of 1 hour.
minFundingRateStringMinimum funding rate for a single settlement.
maxFundingRateStringMaximum funding rate for a single settlement.
fundingSwitchBooleanFunding-fee switch. false means that funding fees are not calculated, collected, or distributed during the current settlement window. When re-enabled, the sampling window is reset, rolling history is cleared, and sampling data is rebuilt according to the cold-start rules.

Push Example

json
{
  "arg": {
    "channel": "exchangeos-funding-rate",
    "assetId": "2"
  },
  "data": [
    {
      "assetId": "2",
      "fundingRate": "-0.004200",
      "nextFundingTime": "1785916800000",
      "settlementInterval": "1",
      "minFundingRate": "-0.015000",
      "maxFundingRate": "0.015000",
      "fundingSwitch": true
    }
  ]
}

Instruments Channel exchangeos-instruments#

Channel Description

Pushes listing, delisting, instrument, and trading-parameter changes.

Incremental push triggers include:

  1. A change to the product state, such as a new contract or trading pair going live, a manual pause or resumption, or delisting due to delivery or exercise.
  2. A change to the trading parameters priceDecimals or sizeDecimals.
  3. A change to the listing or delisting times listTime or expTime.

upcChg is used to announce pending changes to priceDecimals or sizeDecimals. When a parameter is adjusted, the system pushes the parameter name, new value, and effective time:

  1. One push is sent when the parameter-change task is created.
  2. A second push is sent when the parameter becomes effective and is applied.

A delisting notice is pushed 30 minutes before the official delisting time.

Subscription Parameters

ParameterTypeRequiredDescription
channelStringYesFixed as exchangeos-instruments.
instTypeStringYesProduct type. Supported values are SPOT and PERPS. Subscription is performed by product type.

After subscribing, the server returns all products under the specified product type and continues pushing listing, delisting, and parameter changes. When any product changes, the server pushes the complete instrument list for that instType.

Subscription Example

json
{
  "op": "subscribe",
  "args": [
    {
      "channel": "exchangeos-instruments",
      "instType": "SPOT"
    }
  ]
}

Push Fields (data element)

FieldTypeDescription
instTypeStringProduct type. Supported values are SPOT and PERPS.
assetIdStringProduct ID, for example 1234.
baseTokenIdStringTrading asset ID. Applies to Spot products only.
quoteTokenIdStringQuote asset ID. Applies to Spot products only.
settleTokenIdStringPnL settlement and margin asset ID. Applies to Perpetual products only.
priceDecimalsStringPrice precision, representing the minimum price increment for orders. When the precision is reduced, existing order prices may be rounded: sell orders are rounded up and buy orders are rounded down. If the rounded price becomes 0, the order is canceled.
sizeDecimalsStringQuantity precision.
stateStringProduct state: live means available for trading; preopen means pre-listed. After a product is listed in the backend and its data is recorded on-chain, the system pushes the preopen state.
listTimeStringProduct listing time in Unix epoch milliseconds.
expTimeStringProduct delisting time in Unix epoch milliseconds. Pushed when changed.
upcChgArrayList of pending parameter changes. Returns an empty array [] when there are no pending changes.
upcChg[].paramStringParameter scheduled to change. Supported values are priceDecimals and sizeDecimals.
upcChg[].newValueStringNew parameter value to be applied.
upcChg[].effTimeStringParameter effective time in Unix epoch milliseconds.
tsStringEvent push timestamp in Unix epoch milliseconds.

Parameter-Change Lifecycle Example

The following example shows priceDecimals changing from 1 to 2 at 1710086400000.

1. Pending-Change Push

The top-level field still contains the old value, while upcChg carries the new value and effective time.

json
{
  "arg": {
    "channel": "exchangeos-instruments",
    "instType": "PERPS"
  },
  "data": [
    {
      "instType": "PERPS",
      "assetId": "5678",
      "settleTokenId": "0",
      "priceDecimals": "1",
      "sizeDecimals": "3",
      "state": "live",
      "listTime": "1710000000000",
      "expTime": "",
      "upcChg": [
        {
          "param": "priceDecimals",
          "newValue": "2",
          "effTime": "1710086400000"
        }
      ],
      "ts": "1710000000000"
    }
  ]
}

The client should retain the current value from the top-level field and compare it with upcChg[].newValue. The API does not provide a separate oldValue field.

2. Effective-Change Confirmation Push

When effTime is reached, the top-level field is updated to the new value and upcChg is cleared.

json
{
  "arg": {
    "channel": "exchangeos-instruments",
    "instType": "PERPS"
  },
  "data": [
    {
      "instType": "PERPS",
      "assetId": "5678",
      "settleTokenId": "0",
      "priceDecimals": "2",
      "sizeDecimals": "3",
      "state": "live",
      "listTime": "1710000000000",
      "expTime": "",
      "upcChg": [],
      "ts": "1710086400000"
    }
  ]
}

Open Interest Channel exchangeos-open-interest#

Channel Description

Pushes the total open interest for perpetual contracts. An update is pushed every 3 seconds when the data changes.

Subscription Parameters

  • channel: Fixed as exchangeos-open-interest.
  • assetId: Required, for example 1234.

Subscription Example

json
{
  "op": "subscribe",
  "args": [
    {
      "channel": "exchangeos-open-interest",
      "assetId": "1234"
    }
  ]
}
FieldTypeDescription
assetIdStringProduct ID. Only Perps assetId values are supported. If a Spot assetId is provided, the server returns a successful subscription acknowledgment but does not push any data.
oiCcyStringOpen interest denominated in the underlying currency.
oiUsdStringOpen interest converted to USD.
tsStringData update timestamp in Unix milliseconds.

Push Example

json
{
  "arg": {
    "channel": "exchangeos-open-interest",
    "assetId": "1234"
  },
  "data": [
    {
      "assetId": "1234",
      "oiCcy": "22161.13",
      "oiUsd": "1939251795.54",
      "ts": "1710249600000"
    }
  ]
}

Price Limit Channel exchangeos-price-limit#

The channel pushes the highest allowed buy price, buyLmt, and the lowest allowed sell price, sellLmt.

There is no initial push. When the price-limit band changes, an update is pushed at most once per second. No update is pushed when the band remains unchanged. The initial configuration of a price band triggers a push. If no valid price-limit band exists, the related fields return an empty string instead of "0".

json
{
  "op": "subscribe",
  "args": [
    {
      "channel": "exchangeos-price-limit",
      "assetId": "1234"
    }
  ]
}
FieldTypeDescription
assetIdStringProduct asset ID.
buyLmtStringHighest allowed buy price. Returns an empty string when no value is available.
sellLmtStringLowest allowed sell price. Returns an empty string when no value is available.
tsStringPush timestamp in Unix epoch milliseconds.
json
{
  "arg": {
    "channel": "exchangeos-price-limit",
    "assetId": "1234"
  },
  "data": [
    {
      "assetId": "1234",
      "buyLmt": "52000",
      "sellLmt": "48000",
      "ts": "1710249600000"
    }
  ]
}

Order Book Channels#

exchangeos-books#

The full order book channel. The first push is a complete snapshot with action: "snapshot". Subsequent pushes are incremental updates with action: "update".

json
{
  "op": "subscribe",
  "args": [
    {
      "channel": "exchangeos-books",
      "assetId": "1234"
    }
  ]
}

Each price level is represented as [price, size, orderCount]. In an incremental update, size: "0" indicates that the price level should be removed.

FieldTypeDescription
asks / bidsArrayAsk-side or bid-side price-level lists.
tsStringPush timestamp in Unix epoch milliseconds.
prevSeqIdIntegerPrevious sequence number.
seqIdIntegerCurrent sequence number.

The client must validate sequence continuity:

  • The prevSeqId of the first update must equal the snapshot seqId.
  • For each subsequent update, update.prevSeqId must equal the previous seqId.
  • If the sequence is discontinuous, the client must resubscribe.
  • If there is no change for 60 seconds, the server may send a heartbeat frame where seqId == prevSeqId.
json
{
  "arg": {
    "channel": "exchangeos-books",
    "assetId": "1234"
  },
  "action": "update",
  "data": [
    {
      "asks": [
        ["8477", "415", "3"]
      ],
      "bids": [
        ["8476", "0", "0"]
      ],
      "ts": "1710249600000",
      "prevSeqId": 123455,
      "seqId": 123456
    }
  ]
}

exchangeos-books5#

Pushes a complete snapshot of the top five order-book levels. Updates are pushed when the order book changes. This channel does not have incremental semantics, so sequence validation is not required.

json
{
  "op": "subscribe",
  "args": [
    {
      "channel": "exchangeos-books5",
      "assetId": "1234"
    }
  ]
}
json
{
  "arg": {
    "channel": "exchangeos-books5",
    "assetId": "1234"
  },
  "data": [
    {
      "asks": [
        ["8477", "415", "3"],
        ["8478", "7", "1"]
      ],
      "bids": [
        ["8476", "256", "4"],
        ["8475", "101", "2"]
      ],
      "assetId": "1234",
      "ts": "1710249600000",
      "seqId": 123456
    }
  ]
}

exchangeos-bbo-tbt#

Pushes a complete BBO snapshot containing one best ask level and one best bid level. This is not an incremental update.

When the BBO changes, updates are pushed at most once every 100 ms. Multiple changes within the same 100 ms window are merged. If the BBO remains unchanged, the server sends a fallback update approximately every 60 seconds.

json
{
  "op": "subscribe",
  "args": [
    {
      "channel": "exchangeos-bbo-tbt",
      "assetId": "1234"
    }
  ]
}
json
{
  "arg": {
    "channel": "exchangeos-bbo-tbt",
    "assetId": "1234"
  },
  "data": [
    {
      "asks": [
        ["8477", "415", "3"]
      ],
      "bids": [
        ["8476", "256", "4"]
      ],
      "assetId": "1234",
      "ts": "1710249600000",
      "seqId": 123457
    }
  ]
}

Estimated Perpetual Settlement Price Channel exchangeos-estimated-price#

This channel pushes the estimated settlement price when a product is scheduled for delisting.

After a successful subscription, the server pushes the current snapshot. Price updates use an aggregation window of approximately 200 ms; within the same window, only the latest value for the same assetId is pushed.

If no valid estimated price is available, settlePx returns an empty string.

No periodic market-data heartbeat is sent when the price does not change. Connection keepalive uses the public WebSocket ping / pong mechanism.

When expTime, settleAt, status, settlePx, settleType, or another public field changes, the server pushes the complete object. The current raw interface example explicitly defines the following fields.

json
{
  "op": "subscribe",
  "args": [
    {
      "channel": "exchangeos-estimated-price",
      "assetId": "9102"
    }
  ]
}
FieldTypeDescription
assetIdStringPerpetual contract asset ID.
nameStringProduct name.
marketTypeStringMarket type, for example perp.
expTimeStringEstimated delisting or expiration time in Unix epoch milliseconds.
settlePxStringEstimated settlement price. Returns an empty string when no valid price is available.
tsStringPush timestamp in Unix epoch milliseconds.
json
{
  "arg": {
    "channel": "exchangeos-estimated-price",
    "assetId": "9102"
  },
  "data": [
    {
      "assetId": "9102",
      "name": "UNI-USD-PERP",
      "marketType": "perp",
      "expTime": "1751990400000",
      "settlePx": "6.4182",
      "ts": "1751988600123"
    }
  ]
}