Getting started

Conventions

The rules that hold across every family. They explain why two calls to the same endpoint can differ, why one figure does not compare with another, and what the absence of a trading venue from an aggregate means.

#Symbols

Twenty-two assets are tracked: twenty USDT-M perpetuals and two stablecoins, the latter in spot only. The live list is served by /v1/symbols, and that one is authoritative.

SymbolAssetMarkets collected
BTCUSDTBitcoinspot + perpetual
ETHUSDTEthereumspot + perpetual
SOLUSDTSolanaspot + perpetual
XRPUSDTXRPspot + perpetual
DOGEUSDTDogecoinspot + perpetual
BNBUSDTBNBspot + perpetual
TRXUSDTTRONspot + perpetual
SUIUSDTSuispot + perpetual
HYPEUSDTHYPEspot + perpetual
XLMUSDTStellarspot + perpetual
XMRUSDTMonerospot + perpetual
LINKUSDTChainlinkspot + perpetual
ADAUSDTCardanospot + perpetual
LTCUSDTLitecoinspot + perpetual
UNIUSDTUniswapspot + perpetual
GRAMUSDTGram (formerly Toncoin)spot + perpetual
AVAXUSDTAvalanchespot + perpetual
HBARUSDTHederaspot + perpetual
NEARUSDTNEAR Protocolspot + perpetual
TAOUSDTBittensorspot + perpetual
ZECUSDTZcashspot + perpetual
BCHUSDTBitcoin Cashspot + perpetual
CCUSDTCantonspot + perpetual
QNTUSDTQuantspot + perpetual
ENAUSDTEthenaspot + perpetual
AAVEUSDTAavespot + perpetual
ONDOUSDTOndospot + perpetual
PUMPUSDTPump.funspot + perpetual
WLDUSDTWorldcoinspot + perpetual
ASTERUSDTAsterspot + perpetual
DOTUSDTPolkadotspot + perpetual
WLFIUSDTWorld Liberty Financialspot + perpetual
MORPHOUSDTMorphospot + perpetual
SKYUSDTSky (formerly Maker)spot + perpetual
ETCUSDTEthereum Classicspot + perpetual
ICPUSDTInternet Computerspot + perpetual
ARBUSDTArbitrumspot + perpetual
VVVUSDTVenice Tokenspot + perpetual
JSTUSDTJUSTspot + perpetual
ALGOUSDTAlgorandspot + perpetual
KASUSDTKaspaspot + perpetual
POLUSDTPolygon (formerly MATIC)spot + perpetual
JUPUSDTJupiterspot + perpetual
RENDERUSDTRenderspot + perpetual
ATOMUSDTCosmosspot + perpetual
FILUSDTFilecoinspot + perpetual
INJUSDTInjectivespot + perpetual
AEROUSDTAerodrome Financespot + perpetual
LITUSDTLighterspot + perpetual
ZROUSDTLayerZerospot + perpetual
APTUSDTAptosspot + perpetual
CAKEUSDTPancakeSwapspot + perpetual
STXUSDTStacksspot + perpetual
STABLEUSDTStablespot + perpetual
AKEUSDTAkedospot + perpetual
NIGHTUSDTMidnightspot + perpetual
DASHUSDTDashspot + perpetual
TIAUSDTCelestiaspot + perpetual
PYTHUSDTPyth Networkspot + perpetual
VETUSDTVeChainspot + perpetual
CRVUSDTCurve DAOspot + perpetual
TRUMPUSDTOfficial Trumpspot + perpetual
STRKUSDTStarknetspot + perpetual
PENGUUSDTPudgy Penguinsspot + perpetual
FETUSDTArtificial Superintelligence Alliancespot + perpetual
VIRTUALUSDTVirtuals Protocolspot + perpetual
GRASSUSDTGrassspot + perpetual
SEIUSDTSeispot + perpetual
BSVUSDTBitcoin SVspot + perpetual
XPLUSDTPlasmaspot + perpetual
PENDLEUSDTPendlespot + perpetual
FFUSDTFalcon Financespot + perpetual
SPXUSDTSPX6900spot + perpetual
XTZUSDTTezosspot + perpetual
LDOUSDTLido DAOspot + perpetual
USDCUSDTUSDCspot
USDTUSDCUSDTspot

symbol is mandatory

On every route specific to an asset, in any case (btcusdt works; the envelope gives the canonical BTCUSDT, and asset and series follow the same rule). Missing, the request returns 422; unknown or disabled, 422 with the list of accepted values. There is no default symbol and no fallback: serving Bitcoin to someone who asked for nothing would produce a correct figure attributed to the wrong asset.

Whole-market data, on the contrary, accepts no symbol: Fear & Greed, global market, macro, ETF, Bitcoin network, BTC and ETH on-chain. Options are targeted with ?asset=BTC or ?asset=ETH.

#Timeframes

On most bucketed routes, seven values:

1m5m15m30m1h4h1d

Candles (/v1/klines) and technical indicators accept an eighth one, the week (starting Monday 00:00 UTC), because they are built directly from the candles:

1m5m15m30m1h4h1d1w

The exceptions: options routes refuse 1m (their snapshots come about once a minute), intraday macro instruments refuse 30m, and the optional step of /v1/btc/fees/history and /v1/global/history is 1h, 4h or 1d. The contract gives each route its exact list (an enum), and the family catalogue (/v1/macro/intraday/series) the timeframes of each instrument.

A value outside the list returns 422 invalid_timeframe with the accepted values, never a silent fallback to another timeframe. Every validation error is a 422, the body of POST /v1/indicators and the options histories included. Branch on error.code, it says which parameter is at fault. Like symbol, timeframe and order ignore case (1H is 1h), except 1M: elsewhere a month, it is refused here, 1m being one minute.

#Multi-venue aggregation

No response names its trading venue. Multi-venue metrics arrive already merged: that is the platform’s contract, and the reason why multiple integrations become a single one. Three merge rules, according to the nature of the quantity:

NatureTypeDescription
sumadditiveVolumes, open interest, trade counts, liquidations, order book depth. A missing venue mechanically makes the figure too low.
open-interest-weighted averagerates and pricesFunding and basis. The venue that carries the most positions weighs the most, and that is what makes the composite representative.
volume-weighted averageaverage pricesAverage prices. The natural weight of an average price is the volume that produced it.

One single exception in the whole API: /v1/spread/interexchange names the venues, a spread making no sense without them. Everywhere else the exchange parameter does not exist: passing it returns 422.

#Closed candles and the current period

Every route that serves data cut into windows carries an is_closed boolean on every row, whether you asked for it or not: candles, trade candles, CVD, buy/sell ratio, trade size, big/small liquidations, the order book, inter-venue spreads — and every row of every /history route (basis, open interest, funding, liquidations, macro, on-chain…). Their latest value is the latest CLOSED bucket of timeframe (required). A latest value computed over a ROLLING window (cumulative liquidations, open-interest change, cumulative funding, options open-interest change) is always final and carries no is_closed: time is the end of its window, window_start_at and window_s give its start and length.

ValueTypeDescription
truebooleanThe value is final: BytNode will not recompute it, it can be stored, summed, compared with a chart. A multi-venue window closes as soon as every expected source has delivered it, and at the latest max(20 s, 1 % of its duration) after its end; it is then frozen. The CVD waits longer: it closes 90 s after the end of its window. The order book is a photo taken at the end of each bucket: every row served is already final. A source that revises its own figures (macro, on-chain) can still republish a closed value.
falsebooleanThe value is provisional. Two successive calls can return different figures for the same row.

By default, only closed windows are served. To see the current period, add ?live=1:

curl
# The latest CLOSED hourly candle: its value will not move again.
curl -H "X-API-KEY: $BYTNODE_API_KEY" \
  "https://api.bytnode.com/v1/cvd?symbol=BTCUSDT&timeframe=1h"

# The candle IN PROGRESS: provisional, flagged is_closed: false.
curl -H "X-API-KEY: $BYTNODE_API_KEY" \
  "https://api.bytnode.com/v1/cvd?symbol=BTCUSDT&timeframe=1h&live=1"

What to know about ?live=1

  • It is an option. Without it, the response is strictly the one from before.
  • Only on the latest-value routes that declare it: /v1/klines, /v1/cvd, /v1/trades-kline (and their /spot and /futures variants), /v1/funding/rate and /v1/spread/interexchange; anywhere else it is an unknown parameter (422). The /history routes serve closed windows only, by definition.
  • Never a null. If the current period has received nothing yet (a quiet market), the last closed window is returned instead.
  • The value does not jump at the close. Provisional and final come out of the same definition: when the period closes, the row freezes on the figure it was showing.

Attainable freshness: about two seconds on trades, candles, CVD and spreads. The order book has no period in progress: each row is the photo of a closed minute, so live is not accepted there.

#Units and scales

A proportion is never written in two ways. The suffix of a field gives its scale, and the rule holds in every family, from the market core to the satellites:

SuffixTypeDescription
…_pctpercentageA percentage: 58.5 means 58.5 %. basis_pct, oi_change_pct, rate_pct, apr_pct.
…_ratioquotientA dimensionless quotient. A share of a whole is a fraction: 0.585 means 58.5 % (buy_ratio, staking_ratio). A quotient of two quantities can exceed 1 or be signed: put_call_ratio 1.2 = 1.2 puts per call, imbalance_ratio from −1 to 1.
…_bpsbasis pointsBasis points: 1 bp is 0.01 %. premium_bps, max_spread_bps.

#Timestamps and ordering

  • The timestamps of the data are in ISO 8601, in UTC, with the Z suffix and three fixed digits of milliseconds: 2026-08-29T11:38:00.000Z. time is ALWAYS in this format, daily series included (a day is dated at midnight UTC) and there is no separate date key; a date alone (2026-08-29) appears only in keys that name a business day, such as filed_date or oldest_input_date. time follows one of two rules, and the reference of each route says which: on a bucketed series (candles, CVD, order book per bucket, funding per 8 h period) it is the start of the bucket, never its end; on a point-in-time value (a latest value, a rolling window, a forecast, a composite) it is the instant the value refers to — the end of a rolling window, the settlement a forecast is for, the most recent input of a composite (which also gives oldest_input_date). The latest value of a bucketed route is its latest CLOSED bucket, dated at its start like the first row of its /history: /v1/klines, /v1/cvd, /v1/buy-sell-ratio, /v1/trades/avg-size, /v1/liquidations/big-small-ratio, /v1/orderbook (all of them require timeframe). The envelope of /v1/options/max-pain/history repeats expiry as the expiry day (YYYY-MM-DD), whatever form you sent.
  • The request bounds (since_ms, until_ms and before_ms) are in milliseconds since the Unix epoch. since_ms and until_ms are inclusive (to the millisecond), before_ms is exclusive. since_ms=0 means the start of the data. A negative bound, a since_ms greater than until_ms (equal reads that one millisecond) or greater than or equal to before_ms, until_ms and before_ms together, a bound given in seconds, in microseconds or in nanoseconds, or any other bound earlier than 2009-01-03 (the first Bitcoin block) returns 422 before anything runs.
  • Value arrays (an indicator’s series, the internal series of a CVD) run from oldest to most recent.
  • History lists are returned from most recent to oldest by default — the freshest row comes first — or from oldest to most recent with order=asc.
  • The day starts at midnight UTC: that is the alignment of the daily series.