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.
| Symbol | Asset | Markets collected |
|---|---|---|
BTCUSDT | Bitcoin | spot + perpetual |
ETHUSDT | Ethereum | spot + perpetual |
SOLUSDT | Solana | spot + perpetual |
XRPUSDT | XRP | spot + perpetual |
DOGEUSDT | Dogecoin | spot + perpetual |
BNBUSDT | BNB | spot + perpetual |
TRXUSDT | TRON | spot + perpetual |
SUIUSDT | Sui | spot + perpetual |
HYPEUSDT | HYPE | spot + perpetual |
XLMUSDT | Stellar | spot + perpetual |
XMRUSDT | Monero | spot + perpetual |
LINKUSDT | Chainlink | spot + perpetual |
ADAUSDT | Cardano | spot + perpetual |
LTCUSDT | Litecoin | spot + perpetual |
UNIUSDT | Uniswap | spot + perpetual |
GRAMUSDT | Gram (formerly Toncoin) | spot + perpetual |
AVAXUSDT | Avalanche | spot + perpetual |
HBARUSDT | Hedera | spot + perpetual |
NEARUSDT | NEAR Protocol | spot + perpetual |
TAOUSDT | Bittensor | spot + perpetual |
ZECUSDT | Zcash | spot + perpetual |
BCHUSDT | Bitcoin Cash | spot + perpetual |
CCUSDT | Canton | spot + perpetual |
QNTUSDT | Quant | spot + perpetual |
ENAUSDT | Ethena | spot + perpetual |
AAVEUSDT | Aave | spot + perpetual |
ONDOUSDT | Ondo | spot + perpetual |
PUMPUSDT | Pump.fun | spot + perpetual |
WLDUSDT | Worldcoin | spot + perpetual |
ASTERUSDT | Aster | spot + perpetual |
DOTUSDT | Polkadot | spot + perpetual |
WLFIUSDT | World Liberty Financial | spot + perpetual |
MORPHOUSDT | Morpho | spot + perpetual |
SKYUSDT | Sky (formerly Maker) | spot + perpetual |
ETCUSDT | Ethereum Classic | spot + perpetual |
ICPUSDT | Internet Computer | spot + perpetual |
ARBUSDT | Arbitrum | spot + perpetual |
VVVUSDT | Venice Token | spot + perpetual |
JSTUSDT | JUST | spot + perpetual |
ALGOUSDT | Algorand | spot + perpetual |
KASUSDT | Kaspa | spot + perpetual |
POLUSDT | Polygon (formerly MATIC) | spot + perpetual |
JUPUSDT | Jupiter | spot + perpetual |
RENDERUSDT | Render | spot + perpetual |
ATOMUSDT | Cosmos | spot + perpetual |
FILUSDT | Filecoin | spot + perpetual |
INJUSDT | Injective | spot + perpetual |
AEROUSDT | Aerodrome Finance | spot + perpetual |
LITUSDT | Lighter | spot + perpetual |
ZROUSDT | LayerZero | spot + perpetual |
APTUSDT | Aptos | spot + perpetual |
CAKEUSDT | PancakeSwap | spot + perpetual |
STXUSDT | Stacks | spot + perpetual |
STABLEUSDT | Stable | spot + perpetual |
AKEUSDT | Akedo | spot + perpetual |
NIGHTUSDT | Midnight | spot + perpetual |
DASHUSDT | Dash | spot + perpetual |
TIAUSDT | Celestia | spot + perpetual |
PYTHUSDT | Pyth Network | spot + perpetual |
VETUSDT | VeChain | spot + perpetual |
CRVUSDT | Curve DAO | spot + perpetual |
TRUMPUSDT | Official Trump | spot + perpetual |
STRKUSDT | Starknet | spot + perpetual |
PENGUUSDT | Pudgy Penguins | spot + perpetual |
FETUSDT | Artificial Superintelligence Alliance | spot + perpetual |
VIRTUALUSDT | Virtuals Protocol | spot + perpetual |
GRASSUSDT | Grass | spot + perpetual |
SEIUSDT | Sei | spot + perpetual |
BSVUSDT | Bitcoin SV | spot + perpetual |
XPLUSDT | Plasma | spot + perpetual |
PENDLEUSDT | Pendle | spot + perpetual |
FFUSDT | Falcon Finance | spot + perpetual |
SPXUSDT | SPX6900 | spot + perpetual |
XTZUSDT | Tezos | spot + perpetual |
LDOUSDT | Lido DAO | spot + perpetual |
USDCUSDT | USDC | spot |
USDTUSDC | USDT | spot |
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:
| Nature | Type | Description |
|---|---|---|
sum | additive | Volumes, open interest, trade counts, liquidations, order book depth. A missing venue mechanically makes the figure too low. |
open-interest-weighted average | rates and prices | Funding and basis. The venue that carries the most positions weighs the most, and that is what makes the composite representative. |
volume-weighted average | average prices | Average 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.
| Value | Type | Description |
|---|---|---|
true | boolean | The 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. |
false | boolean | The 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:
# 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/spotand/futuresvariants),/v1/funding/rateand/v1/spread/interexchange; anywhere else it is an unknown parameter (422). The/historyroutes 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:
| Suffix | Type | Description |
|---|---|---|
…_pct | percentage | A percentage: 58.5 means 58.5 %. basis_pct, oi_change_pct, rate_pct, apr_pct. |
…_ratio | quotient | A 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. |
…_bps | basis points | Basis 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
Zsuffix and three fixed digits of milliseconds:2026-08-29T11:38:00.000Z.timeis ALWAYS in this format, daily series included (a day is dated at midnight UTC) and there is no separatedatekey; a date alone (2026-08-29) appears only in keys that name a business day, such asfiled_dateoroldest_input_date.timefollows 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 givesoldest_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 requiretimeframe). The envelope of/v1/options/max-pain/historyrepeatsexpiryas the expiry day (YYYY-MM-DD), whatever form you sent. - The request bounds (
since_ms,until_msandbefore_ms) are in milliseconds since the Unix epoch.since_msanduntil_msare inclusive (to the millisecond),before_msis exclusive.since_ms=0means the start of the data. A negative bound, asince_msgreater thanuntil_ms(equal reads that one millisecond) or greater than or equal tobefore_ms,until_msandbefore_mstogether, a bound given in seconds, in microseconds or in nanoseconds, or any other bound earlier than 2009-01-03 (the first Bitcoin block) returns422before 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.