Exchange Wire Formats

Bybit Futures wire format

How Bybit derivatives, linear contracts (USDT and USDC perpetuals and futures) messages become rows in our Parquet files. Each data type below shows a real message next to the rows we publish for it, with the source and the rule for every column. Hover a line or a column to see how they connect.

Checked against our pipeline

These messages were captured from Bybit derivatives, linear contracts (USDT and USDC perpetuals and futures) on 2026-10-05. Our test suite replays each one through the production collector parser and postprocessor, and fails if the published rows differ from the rows on this page. Files written before a change to the pipeline can differ; see Known Gaps & Corrections.

The collector subscribes to orderbook.50.<symbol>, publicTrade.<symbol>, tickers.<symbol> and allLiquidation.<symbol> for every trading linear contract. Ticker, mark price and open interest rows all come from the tickers topic.

  • Public WebSocket: wss://stream.bybit.com/v5/public/linear
  • REST (trade backfill): https://api.bybit.com

Exchange API reference: bybit-exchange.github.io. Conventions shared by every exchange are on the wire formats overview.

Trades

One row per trade from the publicTrade.<symbol> topic, plus trades recovered from REST after a reconnect.

  • WebSocket publicTrade.<symbol>
  • REST GET /v5/market/recent-trade

Trade message

Bybit batches trades: this message carries 2, and each becomes its own row.

WebSocket message · publicTrade.<symbol>received 2026-10-05 19:13:40.218439 UTC
{
"topic": "publicTrade.BTCUSDT",
"type": "snapshot",
"ts": 1791227620120,
"data": [
{
"T": 1791227620119,
"s": "BTCUSDT",
"S": "Buy",
"v": "0.001",
"p": "85629.30",
"L": "PlusTick",
"i": "caa63c3c-3c80-540f-8364-ea18a6824a70",
"BT": false,
"RPI": false,
"seq": 820927598403
},
{
"T": 1791227620119,
"s": "BTCUSDT",
"S": "Buy",
"v": "0.038",
"p": "85629.30",
"L": "ZeroPlusTick",
"i": "e629c952-d70a-5354-8ace-495767ec2770",
"BT": false,
"RPI": false,
"seq": 820927598404
}
]
}

Published rows · 2

received_time1791227620218439000—Our collector's clock when the message arrived, in nanoseconds since the Unix epoch. Not sent by Bybit.
event_time1791227620120tsCopied from the message ts, when Bybit generated the push. Milliseconds. Shared by every trade in the message.
symbolBTCUSDTdata[].sCopied.
trade_id2580710057459900140data[].iBybit sends a UUID, which is not published. The column holds a stable 64-bit hash of the UUID string: FNV-1a over its bytes with multiplier 0x1000001b3 instead of the standard FNV prime, then the sign bit cleared. The same UUID always gives the same ID.
price85629.30data[].pCopied as the exact decimal string Bybit sent.
quantity0.001data[].vCopied as the exact decimal string. Base asset units.
trade_time1791227620119data[].TCopied. When the trade was filled, milliseconds.
is_buyer_makerfalsedata[].Strue when the taker side S is Sell, false when it is Buy.
order_typeMarket—Always Market. A placeholder: Bybit sends no order type.

REST trade backfill

Bybit does not replay trades on subscribe. After every trade connection (re)opens, the collector fetches the latest trades from GET /v5/market/recent-trade and publishes those it did not receive over the WebSocket. A backfilled trade whose trade_time falls outside the hour of the file is not published.

Abridged: Requested with limit=1 to keep the example short; the collector requests limit=1000, the most Bybit returns.

REST responsereceived 2026-10-05 19:18:35.852907 UTC
GET https://api.bybit.com/v5/market/recent-trade?category=linear&symbol=BTCUSDT&limit=1
{
"retCode": 0,
"retMsg": "OK",
"result": {
"category": "linear",
"list": [
{
"execId": "996d7ec5-7333-5567-a813-a4db019fcec2",
"symbol": "BTCUSDT",
"price": "85743.50",
"size": "0.002",
"side": "Buy",
"time": "1791227915662",
"isBlockTrade": false,
"isRPITrade": false,
"seq": "820929204227"
}
]
},
"retExtInfo": {},
"time": 1791227915757
}

Published row

received_time1791227915852907593—Our collector's clock when the REST response arrived, in nanoseconds since the Unix epoch. Later than the trade, often by seconds.
event_time1791227915662result.list[].timeThe trade time: REST responses have no push time, so event_time equals trade_time on backfilled rows. Milliseconds.
symbolBTCUSDTresult.list[].symbolCopied.
trade_id5105926908505611849result.list[].execIdBybit sends a UUID, which is not published. The column holds a stable 64-bit hash of the UUID string: FNV-1a over its bytes with multiplier 0x1000001b3 instead of the standard FNV prime, then the sign bit cleared. The same UUID always gives the same ID.
price85743.50result.list[].priceCopied as the exact decimal string.
quantity0.002result.list[].sizeCopied as the exact decimal string. Base asset units.
trade_time1791227915662result.list[].timeParsed from the string. Milliseconds.
is_buyer_makerfalseresult.list[].sidetrue when the taker side side is Sell, false when it is Buy.
order_typeMarket—Always Market. A placeholder: Bybit sends no order type.

Notes

  • Rows are sorted by trade_time, then Bybit's cross sequence seq.
  • The block-trade flag BT, the RPI flag RPI, the tick direction L and seq are not published. Block trades and RPI trades are published as ordinary rows.
  • A trade received over both the WebSocket and the REST backfill is published once, with the WebSocket values. On a backfilled row event_time equals trade_time, and received_time can be seconds after the trade.
  • Bybit's REST endpoint returns at most the latest 1,000 trades, so a long reconnect gap on a busy contract is only partly recovered.

Column types and descriptions: Trades schema.

Order Book

One row per price level from the orderbook.50.<symbol> topic, published as Bybit sent it.

  • WebSocket orderbook.50.<symbol>

Book snapshot

Bybit sends a snapshot of the 50-level book when the subscription starts, and again after a problem on its side or a service restart (u = 1). Each level becomes a snapshot row.

Abridged: Bybit sent 50 bid and 50 ask levels; the best three of each are shown.

WebSocket message · orderbook.50.<symbol>received 2026-10-05 19:13:33.813598 UTC
{
"topic": "orderbook.50.BTCUSDT",
"type": "snapshot",
"ts": 1791227613628,
"data": {
"s": "BTCUSDT",
"b": [
["85626.10", "6.857"],
["85626.00", "0.004"],
["85625.90", "0.415"]
],
"a": [
["85626.20", "1.565"],
["85626.30", "0.392"],
["85626.50", "0.001"]
],
"u": 211266072,
"seq": 820927562650
},
"cts": 1791227613626
}

Published rows · 6

received_time1791227613813598000—Our collector's clock when the message arrived, in nanoseconds since the Unix epoch. Not sent by Bybit.
event_time1791227613628tsCopied. When Bybit generated the push, milliseconds.
transaction_time1791227613626ctsCopied. Matching engine time, milliseconds.
symbolBTCUSDTtopicThe symbol part of the topic (orderbook.50.BTCUSDT). Equals data.s.
event_typesnapshottypesnapshot for type: "snapshot": every level of the 50-level book. A message with u = 1 (Bybit service restart) is also a snapshot.
first_update_idnull—Null for snapshots.
final_update_id211266072data.uCopied. Starts a new chain: the next delta has u + 1.
prev_final_update_idnull—Null. Bybit sends no previous update ID.
last_update_id820927562650data.seqCopied: Bybit's cross sequence seq. It orders messages but is not contiguous.
sidebiddata.bdata.abid for levels in b, ask for levels in a. One row per level.
price85626.10data.b[][0]data.a[][0]Copied as the exact decimal string.
quantity6.857data.b[][1]data.a[][1]Copied as the exact decimal string.
order_countnull—Null. Bybit does not report order counts.

Book delta

WebSocket message · orderbook.50.<symbol>received 2026-10-05 19:13:33.814335 UTC
{
"topic": "orderbook.50.BTCUSDT",
"type": "delta",
"ts": 1791227613708,
"data": {
"s": "BTCUSDT",
"b": [
["85619.20", "0.023"],
["85618.80", "0"]
],
"a": [
["85626.20", "1.155"],
["85635.70", "0.005"],
["85636.20", "0.003"]
],
"u": 211266074,
"seq": 820927562975
},
"cts": 1791227613706
}

Published rows · 5

received_time1791227613814335000—Our collector's clock when the message arrived, in nanoseconds since the Unix epoch. Not sent by Bybit.
event_time1791227613708tsCopied. When Bybit generated the push, milliseconds.
transaction_time1791227613706ctsCopied. Matching engine time, milliseconds.
symbolBTCUSDTtopicThe symbol part of the topic (orderbook.50.BTCUSDT). Equals data.s.
event_typeupdatetypeupdate for type: "delta".
first_update_id211266074data.uCopied from u. Each delta covers exactly one update ID, so first_update_id = final_update_id.
final_update_id211266074data.uCopied. One more than the previous message's u; a larger step is a gap.
prev_final_update_idnull—Null. Bybit sends no previous update ID.
last_update_id820927562975data.seqCopied: Bybit's cross sequence seq. It orders messages but is not contiguous.
sidebiddata.bdata.abid for levels in b, ask for levels in a. One row per level.
price85619.20data.b[][0]data.a[][0]Copied as the exact decimal string.
quantity0.023data.b[][1]data.a[][1]Copied as the exact decimal string: the new total at that price. 0 removes the level.
order_countnull—Null. Bybit does not report order counts.

Notes

  • The collector subscribes to the 50-level book only, and WebSocket snapshots anchor it. Bybit's REST depth snapshots carry the update IDs of its 1,000-level stream, so they cannot anchor this book and are not published.
  • The collector checks that each delta's u is one more than the previous message's before it writes. After a gap it reconnects and starts again from a new WebSocket snapshot.
  • A delta with no levels is published as one row with side = noop and price and quantity 0, so the update-ID chain has no holes. Skip these rows when rebuilding the book.
  • Files can start with a checkpoint snapshot of the book carried over from the previous hour: its received_time is the hour start, transaction_time is null, final_update_id is the last u applied and last_update_id its seq.
  • Quantities are in base asset units (BTC for BTCUSDT). Bybit does not include Retail Price Improvement (RPI) orders in the book stream.
  • Files written before the October 2026 pipeline update can also contain snapshot rows built from REST depth snapshots. Their update IDs belong to Bybit's 1,000-level stream and do not continue the 50-level chain; skip them when replaying.

Column types and descriptions: Order Book schema.

Ticker

One row per tickers.<symbol> message that carries a field of the ticker row (lastPrice, prevPrice24h, price24hPcnt, highPrice24h, lowPrice24h, volume24h or turnover24h), holding the merged full state.

  • WebSocket tickers.<symbol>

Ticker snapshot

Bybit sends one snapshot with every field when the subscription starts. It publishes a ticker, a mark price and an open interest row. In our captures the first snapshot was up to 2 seconds old on arrival, and the deltas since then followed at once.

WebSocket message · tickers.<symbol>received 2026-10-05 19:19:52.187738 UTC
{
"topic": "tickers.BTCUSDT",
"type": "snapshot",
"data": {
"symbol": "BTCUSDT",
"tickDirection": "ZeroPlusTick",
"price24hPcnt": "0.004251",
"lastPrice": "85721.40",
"prevPrice24h": "85358.50",
"highPrice24h": "86986.50",
"lowPrice24h": "84907.70",
"prevPrice1h": "85436.60",
"markPrice": "85730.36",
"indexPrice": "85768.04",
"openInterest": "57163.259",
"openInterestValue": "4900626772.84",
"turnover24h": "5739447395.0800",
"volume24h": "66763.0850",
"fundingIntervalHour": "8",
"fundingCap": "0.00333",
"singleOpenInterest": "28581.63",
"singleOpenInterestValue": "2450313429.29",
"nextFundingTime": "1791244800000",
"fundingRate": "0.00001336",
"bid1Price": "85721.30",
"bid1Size": "2.542",
"ask1Price": "85721.40",
"ask1Size": "10.152",
"preOpenPrice": "",
"preQty": "",
"curPreListingPhase": ""
},
"cs": 820929695495,
"ts": 1791227990283
}

Published row

received_time1791227992187738000—Our collector's clock when the message arrived, in nanoseconds since the Unix epoch. Not sent by Bybit.
event_time1791227990283tsCopied. When Bybit generated the push, milliseconds.
symbolBTCUSDTdata.symbolCopied.
price_change362.90data.lastPricedata.prevPrice24hlastPrice − prevPrice24h, computed exactly in decimal.
price_change_percent0.4251data.price24hPcntBybit sends a fraction; multiplied by 100 exactly, so the column is in percent: 0.004251 becomes 0.4251.
weighted_average_pricenull—Null. Bybit sends no weighted average price.
last_price85721.40data.lastPriceCopied.
last_quantitynull—Null. Bybit sends no last trade quantity.
open_price85358.50data.prevPrice24hCopied from prevPrice24h, the price 24 hours ago.
high_price86986.50data.highPrice24hCopied.
low_price84907.70data.lowPrice24hCopied.
base_asset_volume66763.0850data.volume24hCopied. 24h volume in base asset units.
quote_asset_volume5739447395.0800data.turnover24hCopied. 24h turnover in quote asset units.
statistics_open_timenull—Null. Bybit sends no statistics window.
statistics_close_timenull—Null. Bybit sends no statistics window.
first_trade_idnull—Null. Bybit sends no trade IDs in tickers.
last_trade_idnull—Null. Bybit sends no trade IDs in tickers.
total_tradesnull—Null. Bybit sends no trade count.

Ticker delta

A delta holds only the fields that changed. The row is the merged state: changed fields from this delta, the others carried forward. Replayed after the snapshot and the 21 deltas Bybit sent between them; those prepare the state and their rows are not shown.

Replayed after 22 earlier messages (not shown) that set the state this message builds on.

WebSocket message · tickers.<symbol>received 2026-10-05 19:19:52.975586 UTC
{
"topic": "tickers.BTCUSDT",
"type": "delta",
"data": {
"symbol": "BTCUSDT",
"tickDirection": "MinusTick",
"price24hPcnt": "0.00425",
"lastPrice": "85721.30",
"turnover24h": "5739467196.7231",
"volume24h": "66763.3160",
"bid1Price": "85721.30",
"bid1Size": "5.212"
},
"cs": 820929708680,
"ts": 1791227992883
}

Published row

received_time1791227992975586000—Our collector's clock when the message arrived, in nanoseconds since the Unix epoch. Not sent by Bybit.
event_time1791227992883tsCopied. When Bybit generated the push, milliseconds.
symbolBTCUSDTdata.symbolCopied.
price_change362.80data.lastPricelastPrice − prevPrice24h, computed exactly in decimal from the merged state. prevPrice24h is not in this message and is carried forward.
price_change_percent0.425data.price24hPcntBybit sends a fraction; multiplied by 100 exactly, so the column is in percent: 0.00425 becomes 0.425.
weighted_average_pricenull—Null. Bybit sends no weighted average price.
last_price85721.30data.lastPriceCopied.
last_quantitynull—Null. Bybit sends no last trade quantity.
open_price85358.50—Not in this message: carried forward from the snapshot and the deltas before this message.
high_price86986.50—Not in this message: carried forward from the snapshot and the deltas before this message.
low_price84907.70—Not in this message: carried forward from the snapshot and the deltas before this message.
base_asset_volume66763.3160data.volume24hCopied. 24h volume in base asset units.
quote_asset_volume5739467196.7231data.turnover24hCopied. 24h turnover in quote asset units.
statistics_open_timenull—Null. Bybit sends no statistics window.
statistics_close_timenull—Null. Bybit sends no statistics window.
first_trade_idnull—Null. Bybit sends no trade IDs in tickers.
last_trade_idnull—Null. Bybit sends no trade IDs in tickers.
total_tradesnull—Null. Bybit sends no trade count.

Delta with no ticker field

Most deltas only move the best bid and ask (bid1Price, ask1Price and sizes), which are not published. A delta that carries no field of a data type publishes no row for it; this one publishes nothing. Replayed after the snapshot and the 17 deltas Bybit sent between them; those prepare the state and their rows are not shown.

Replayed after 18 earlier messages (not shown) that set the state this message builds on.

WebSocket message · tickers.<symbol>received 2026-10-05 19:19:52.375291 UTC
{
"topic": "tickers.BTCUSDT",
"type": "delta",
"data": {
"symbol": "BTCUSDT",
"bid1Price": "85721.30",
"bid1Size": "5.835",
"ask1Price": "85721.40",
"ask1Size": "0.744"
},
"cs": 820929705226,
"ts": 1791227992283
}

Not published

received_time—Not published: this delta carries no field of the ticker row.
event_time—Not published: this delta carries no field of the ticker row.
symbol—Not published: this delta carries no field of the ticker row.
price_change—Not published: this delta carries no field of the ticker row.
price_change_percent—Not published: this delta carries no field of the ticker row.
weighted_average_price—Not published: this delta carries no field of the ticker row.
last_price—Not published: this delta carries no field of the ticker row.
last_quantity—Not published: this delta carries no field of the ticker row.
open_price—Not published: this delta carries no field of the ticker row.
high_price—Not published: this delta carries no field of the ticker row.
low_price—Not published: this delta carries no field of the ticker row.
base_asset_volume—Not published: this delta carries no field of the ticker row.
quote_asset_volume—Not published: this delta carries no field of the ticker row.
statistics_open_time—Not published: this delta carries no field of the ticker row.
statistics_close_time—Not published: this delta carries no field of the ticker row.
first_trade_id—Not published: this delta carries no field of the ticker row.
last_trade_id—Not published: this delta carries no field of the ticker row.
total_trades—Not published: this delta carries no field of the ticker row.

Notes

  • Bybit sends one snapshot and then delta messages that hold only the fields that changed. The pipeline folds every message into the symbol's full state and publishes the merged state, so unchanged fields are filled from earlier messages. A snapshot replaces the state.
  • The state at the end of an hour carries into the next hour. When the previous hour's state is not available (first run, lost state, or an hour without tickers messages), an hour holds only the fields seen in it until the next snapshot. Files before the 2026-09 data-integrity release hold change-only rows with nulls for unchanged fields.
  • price_change_percent is in percent from the 2026-09 data-integrity release; earlier files hold Bybit's fraction.

Column types and descriptions: Ticker schema.

Mark Price

One row per tickers.<symbol> message that carries a mark price, index price or funding field, holding the merged full state.

  • WebSocket tickers.<symbol>

Ticker snapshot

Bybit sends one snapshot with every field when the subscription starts. It publishes a ticker, a mark price and an open interest row. In our captures the first snapshot was up to 2 seconds old on arrival, and the deltas since then followed at once.

WebSocket message · tickers.<symbol>received 2026-10-05 19:19:52.187738 UTC
{
"topic": "tickers.BTCUSDT",
"type": "snapshot",
"data": {
"symbol": "BTCUSDT",
"tickDirection": "ZeroPlusTick",
"price24hPcnt": "0.004251",
"lastPrice": "85721.40",
"prevPrice24h": "85358.50",
"highPrice24h": "86986.50",
"lowPrice24h": "84907.70",
"prevPrice1h": "85436.60",
"markPrice": "85730.36",
"indexPrice": "85768.04",
"openInterest": "57163.259",
"openInterestValue": "4900626772.84",
"turnover24h": "5739447395.0800",
"volume24h": "66763.0850",
"fundingIntervalHour": "8",
"fundingCap": "0.00333",
"singleOpenInterest": "28581.63",
"singleOpenInterestValue": "2450313429.29",
"nextFundingTime": "1791244800000",
"fundingRate": "0.00001336",
"bid1Price": "85721.30",
"bid1Size": "2.542",
"ask1Price": "85721.40",
"ask1Size": "10.152",
"preOpenPrice": "",
"preQty": "",
"curPreListingPhase": ""
},
"cs": 820929695495,
"ts": 1791227990283
}

Published row

received_time1791227992187738000—Our collector's clock when the message arrived, in nanoseconds since the Unix epoch. Not sent by Bybit.
event_time1791227990283tsCopied. When Bybit generated the push, milliseconds.
symbolBTCUSDTdata.symbolCopied.
mark_price85730.36data.markPriceCopied.
index_price85768.04data.indexPriceCopied.
estimated_settle_pricenull—Copied from predictedDeliveryPrice, which Bybit documents for dated futures. BTCUSDT is a perpetual and its messages do not carry the field, so it is null.
funding_rate0.00001336data.fundingRateCopied. A fraction per funding interval: 0.0001 is 0.01 %.
next_funding_time1791244800000data.nextFundingTimeParsed from the string. Milliseconds.

Ticker delta with a new index price

Any delta with markPrice, indexPrice, fundingRate, nextFundingTime or predictedDeliveryPrice publishes a mark price row from the merged state. Replayed after the snapshot and the 16 deltas Bybit sent between them; those prepare the state and their rows are not shown.

Replayed after 17 earlier messages (not shown) that set the state this message builds on.

WebSocket message · tickers.<symbol>received 2026-10-05 19:19:52.275513 UTC
{
"topic": "tickers.BTCUSDT",
"type": "delta",
"data": {
"symbol": "BTCUSDT",
"indexPrice": "85768.02",
"turnover24h": "5739466939.5592",
"volume24h": "66763.3130",
"ask1Price": "85721.40",
"ask1Size": "0.740"
},
"cs": 820929704683,
"ts": 1791227992183
}

Published row

received_time1791227992275513000—Our collector's clock when the message arrived, in nanoseconds since the Unix epoch. Not sent by Bybit.
event_time1791227992183tsCopied. When Bybit generated the push, milliseconds.
symbolBTCUSDTdata.symbolCopied.
mark_price85730.22—Not in this message: carried forward from the snapshot and the deltas before this message.
index_price85768.02data.indexPriceCopied.
estimated_settle_pricenull—Copied from predictedDeliveryPrice, which Bybit documents for dated futures. BTCUSDT is a perpetual and its messages do not carry the field, so it is null.
funding_rate0.00001336—Not in this message: carried forward from the snapshot and the deltas before this message.
next_funding_time1791244800000—Not in this message: carried forward from the snapshot and the deltas before this message.

Notes

  • Bybit sends one snapshot and then delta messages that hold only the fields that changed. The pipeline folds every message into the symbol's full state and publishes the merged state, so unchanged fields are filled from earlier messages. A snapshot replaces the state.
  • The state at the end of an hour carries into the next hour. When the previous hour's state is not available (first run, lost state, or an hour without tickers messages), an hour holds only the fields seen in it until the next snapshot. Files before the 2026-09 data-integrity release hold change-only rows with nulls for unchanged fields.
  • Bybit's funding interval differs per contract (fundingIntervalHour, 8 hours for BTCUSDT here). Neither it nor the funding cap fundingCap is published.

Column types and descriptions: Mark Price schema.

Open Interest

One row per tickers.<symbol> message that carries openInterest or openInterestValue, plus one carried-forward row at the start of every hour.

  • WebSocket tickers.<symbol>

Ticker snapshot

Bybit sends one snapshot with every field when the subscription starts. It publishes a ticker, a mark price and an open interest row. In our captures the first snapshot was up to 2 seconds old on arrival, and the deltas since then followed at once.

WebSocket message · tickers.<symbol>received 2026-10-05 19:19:52.187738 UTC
{
"topic": "tickers.BTCUSDT",
"type": "snapshot",
"data": {
"symbol": "BTCUSDT",
"tickDirection": "ZeroPlusTick",
"price24hPcnt": "0.004251",
"lastPrice": "85721.40",
"prevPrice24h": "85358.50",
"highPrice24h": "86986.50",
"lowPrice24h": "84907.70",
"prevPrice1h": "85436.60",
"markPrice": "85730.36",
"indexPrice": "85768.04",
"openInterest": "57163.259",
"openInterestValue": "4900626772.84",
"turnover24h": "5739447395.0800",
"volume24h": "66763.0850",
"fundingIntervalHour": "8",
"fundingCap": "0.00333",
"singleOpenInterest": "28581.63",
"singleOpenInterestValue": "2450313429.29",
"nextFundingTime": "1791244800000",
"fundingRate": "0.00001336",
"bid1Price": "85721.30",
"bid1Size": "2.542",
"ask1Price": "85721.40",
"ask1Size": "10.152",
"preOpenPrice": "",
"preQty": "",
"curPreListingPhase": ""
},
"cs": 820929695495,
"ts": 1791227990283
}

Published row

received_time1791227992187738000—Our collector's clock when the message arrived, in nanoseconds since the Unix epoch. Not sent by Bybit.
symbolBTCUSDTdata.symbolCopied.
sum_open_interest57163.259data.openInterestCopied. Base asset units, counting both sides as Bybit defines openInterest; Bybit's one-sided singleOpenInterest is not published.
sum_open_interest_value4900626772.84data.openInterestValueCopied. Quote currency (USDT for BTCUSDT), both sides.
timestamp1791227990283tsCopied from the message ts. Milliseconds.

Ticker delta with a new open interest value

Any delta with openInterest or openInterestValue publishes an open interest row from the merged state. Here only the value moved (with the mark price), so sum_open_interest is carried forward. Replayed after the snapshot and the 23 deltas Bybit sent between them; those prepare the state and their rows are not shown.

Replayed after 24 earlier messages (not shown) that set the state this message builds on.

WebSocket message · tickers.<symbol>received 2026-10-05 19:19:53.175339 UTC
{
"topic": "tickers.BTCUSDT",
"type": "delta",
"data": {
"symbol": "BTCUSDT",
"tickDirection": "ZeroPlusTick",
"markPrice": "85730.18",
"openInterestValue": "4900616483.46",
"turnover24h": "5739473711.5495",
"volume24h": "66763.3920",
"ask1Price": "85721.40",
"ask1Size": "0.668",
"singleOpenInterestValue": "2450308284.59"
},
"cs": 820929710650,
"ts": 1791227993083
}

Published row

received_time1791227993175339000—Our collector's clock when the message arrived, in nanoseconds since the Unix epoch. Not sent by Bybit.
symbolBTCUSDTdata.symbolCopied.
sum_open_interest57163.259—Not in this message: carried forward from the snapshot and the deltas before this message.
sum_open_interest_value4900616483.46data.openInterestValueCopied. Quote currency (USDT for BTCUSDT), both sides.
timestamp1791227993083tsCopied from the message ts. Milliseconds.

Hour-start carried-forward row

Every hour, each symbol with a known open interest gets a row at the hour start holding the state at the boundary. This snapshot was stamped just before 20:00 UTC and arrived just after, so it lands in the 20:00 file: it publishes its own row (stamped 19:59) and is folded into the hour-start row.

WebSocket message · tickers.<symbol>received 2026-10-05 20:00:00.011956 UTC
{
"topic": "tickers.BTCUSDT",
"type": "snapshot",
"data": {
"symbol": "BTCUSDT",
"tickDirection": "PlusTick",
"price24hPcnt": "0.003552",
"lastPrice": "85688.40",
"prevPrice24h": "85385.10",
"highPrice24h": "86986.50",
"lowPrice24h": "84907.70",
"prevPrice1h": "85604.10",
"markPrice": "85684.30",
"indexPrice": "85720.48",
"openInterest": "57257.185",
"openInterestValue": "4906041816.70",
"turnover24h": "5713818688.2134",
"volume24h": "66461.5850",
"fundingIntervalHour": "8",
"fundingCap": "0.00333",
"singleOpenInterest": "28628.593",
"singleOpenInterestValue": "2453020951.19",
"nextFundingTime": "1791244800000",
"fundingRate": "0.00002009",
"bid1Price": "85688.40",
"bid1Size": "5.141",
"ask1Price": "85688.50",
"ask1Size": "0.261",
"preOpenPrice": "",
"preQty": "",
"curPreListingPhase": ""
},
"cs": 820941027667,
"ts": 1791230398283
}

Published rows · 2

received_time1791230400011956000—Our collector's clock when the message arrived, in nanoseconds. The hour-start row takes the latest receipt among messages stamped before the hour that arrived after it, here this message's. Without such a message it is the hour start.
symbolBTCUSDTdata.symbolCopied.
sum_open_interest57257.185data.openInterestCopied. Base asset units, counting both sides as Bybit defines openInterest; Bybit's one-sided singleOpenInterest is not published.
sum_open_interest_value4906041816.70data.openInterestValueCopied. Quote currency (USDT for BTCUSDT), both sides.
timestamp1791230398283tsCopied from ts for the message's own row, which falls before the hour. The hour start, 1791230400000 (20:00:00 UTC), for the carried-forward row.

Notes

  • Bybit sends one snapshot and then delta messages that hold only the fields that changed. The pipeline folds every message into the symbol's full state and publishes the merged state, so unchanged fields are filled from earlier messages. A snapshot replaces the state.
  • The state at the end of an hour carries into the next hour. When the previous hour's state is not available (first run, lost state, or an hour without tickers messages), an hour holds only the fields seen in it until the next snapshot. Files before the 2026-09 data-integrity release hold change-only rows with nulls for unchanged fields.
  • Bybit documents openInterest and openInterestValue as both sides of the market. The single-side figures singleOpenInterest and singleOpenInterestValue are not published.
  • In every hour with tickers messages, each symbol with a known open interest gets a row at the hour start with timestamp = the hour start. Its received_time is the hour start, or later when a message stamped before the hour arrived after it (see the example). Before the October 2026 pipeline update this row always had received_time = the hour start and left out such late messages.
  • Output of the REST open interest poller (GET /v5/market/open-interest) is not published.

Column types and descriptions: Open Interest schema.

Liquidations

One row per entry of an allLiquidation.<symbol> message.

  • WebSocket allLiquidation.<symbol>

S is the side of the liquidated position. Sell means a short was liquidated, so the published liquidation order side is BUY.

WebSocket message · allLiquidation.<symbol>received 2026-10-05 19:13:56.576211 UTC
{
"topic": "allLiquidation.BTCUSDT",
"type": "snapshot",
"ts": 1791227636482,
"data": [
{
"T": 1791227636066,
"s": "BTCUSDT",
"S": "Sell",
"v": "1.312",
"p": "85914.10"
}
]
}

Published row

received_time1791227636576211000—Our collector's clock when the message arrived, in nanoseconds since the Unix epoch. Not sent by Bybit.
event_time1791227636482tsCopied from the message ts, when Bybit generated the push. Milliseconds.
symbolBTCUSDTdata[].sCopied.
sideBUYdata[].SFlipped to the liquidation order's side: position side Buy (a long was liquidated) becomes SELL, Sell becomes BUY.
order_typeMarket—Constant Market placeholder. Bybit sends no order type.
time_in_forceIOC—Constant IOC placeholder. Bybit sends no time in force.
quantity1.312data[].vCopied. Executed size, base asset units.
price85914.10data[].pCopied. The bankruptcy price, not an execution price.
average_price85914.10data[].pThe bankruptcy price again. Bybit sends no average fill price.
order_statusFILLED—Constant FILLED placeholder. Bybit sends no order status.
last_filled_quantity1.312data[].vCopied from v, same as quantity.
filled_quantity1.312data[].vCopied from v, same as quantity.
trade_time1791227636066data[].TCopied. Milliseconds.

Notes

  • price and average_price both hold the bankruptcy price. order_type, time_in_force and order_status are fixed placeholders, and filled_quantity and last_filled_quantity equal quantity.
  • data is an array; each entry becomes its own row. Rows are sorted by trade_time. Bybit documents a push frequency of 500 ms for this topic and states that it pushes all liquidations.

Column types and descriptions: Liquidations schema.