API de order flow cripto
Sigue la presión compradora y vendedora del mercado: CVD, libro de órdenes agregado, ratio de compra/venta y tamaño medio de los trades. Los datos de flujo están normalizados en todos los mercados cubiertos: lees un solo mercado en lugar de unir los libros uno a uno.
Lo que el libro de órdenes y el flujo de órdenes dicen de la relación de fuerzas. Cuatro familias: delta de volumen acumulado, profundidad agregada, presión direccional y zonas de liquidación.
#Order flow cripto para agentes de IA y LLM
«¿Compradores o vendedores: quién controla BTC?», «¿El CVD diverge del precio?», «¿El libro de ETH es más profundo a la compra o a la venta?»: un agente de IA lee el order flow mediante la herramienta MCP get_pair_data, en spot, en perpetuos o en ambos.
{
"name": "get_pair_data",
"arguments": {
"symbol": "BTCUSDT",
"fields": ["cvd", "buy_sell_ratio", "orderbook"],
"timeframe": "15m",
"limit": 48
}
}- Para el LLM: el CVD es una suma acumulada, su nivel por sí solo no significa nada; es su pendiente en la ventana la que dice quién empuja el precio.
- Para desarrolladores:
/v1/cvdy/v1/orderbookson herramientas naturales para tu propio agente de IA (tool calling); por MCP, la herramienta dirige el mercado pedido a la ruta correcta. - Dónde funciona: Claude, ChatGPT, Cursor y cualquier cliente MCP, incluidos los frameworks de agentes compatibles con MCP, como LangChain o n8n.
Conecta tu agente de IA con la guía del servidor MCP, o enséñale BytNode con los Agent Skills de código abierto.
#CVD
Los 9 campos de esta ruta (según el contrato)
time | ISO 8601 UTC, milliseconds (2026-09-28T14:00:00.000Z) | Start of the bucket the row covers: a 1h bucket at 14:00 covers 14:00:00 to 14:59:59.999. |
cvd_series | base asset quantity (BTC for BTCUSDT) | Cumulative volume delta inside the bucket, one point per step of finer candles (1 minute up to `1h`, 5 minutes in `4h`, 15 minutes in `1d`), starting from 0 at the bucket start. `null` when those finer candles do not cover the bucket (before 2026-06-05; in `1d`, before 2023-12; or a collection gap): `buy_volume`, `sell_volume` and `net_volume` then come from the bucket's own candle, as on `/v1/trades-kline`, and `sample_count` is 1. |
net_volume | base asset quantity (BTC for BTCUSDT) | buy_volume - sell_volume over the row, base asset units. Positive = net buying. |
buy_volume | base asset quantity (BTC for BTCUSDT) | Aggressive (taker) buy volume, base asset units, aggregated across venues. |
sell_volume | base asset quantity (BTC for BTCUSDT) | Aggressive (taker) sell volume, base asset units, aggregated across venues. |
sample_count | count | Number of points in `cvd_series`; 1 when `cvd_series` is `null` (the bucket's candle alone). |
buy_sell_coverage_ratio | fraction (0.585 = 58.5 %) | Share of the volume (in USD) whose buy/sell split is known. 1 = every trade is split. Below 1 on part of the history, where some sources did not report the aggressor side: `buy_volume` and `sell_volume` then cover that share only, so `buy_volume + sell_volume` < `volume`; `buy_ratio` and the CVD describe the covered share. `null` when the bucket has no volume. |
is_volume_estimated | `true` when some base-asset quantities of this row were ESTIMATED from USD amounts (history where a source reported amounts but not quantities): a buy or sell amount is converted at that source's own average price when its total quantity is known, otherwise at the candle's typical price (high + low + close) / 3. Every quantity a source measured is kept as is. `false` = all measured. `null` when the volume itself is `null` (not available). | |
is_closed | `true` = the row is final; `false` = provisional: the latest bucket while it still settles (a few seconds after its end, e.g. a candle whose volumes are not final yet), or the period in progress with `?live=1` on the routes that take it. Exception, rare: when a venue delivers trades LATE (seconds to minutes, e.g. during a burst), a closed row built from trades (trade candles, candle volumes, CVD, buy/sell ratio, trades per second) is corrected afterwards to include them, usually within minutes and at most one hour later; the correction only adds the late trades. |
Los 9 campos de esta ruta (según el contrato)
time | ISO 8601 UTC, milliseconds (2026-09-28T14:00:00.000Z) | Start of the bucket the row covers: a 1h bucket at 14:00 covers 14:00:00 to 14:59:59.999. |
cvd_series | base asset quantity (BTC for BTCUSDT) | Cumulative volume delta inside the bucket, one point per step of finer candles (1 minute up to `1h`, 5 minutes in `4h`, 15 minutes in `1d`), starting from 0 at the bucket start. `null` when those finer candles do not cover the bucket (before 2026-06-05; in `1d`, before 2023-12; or a collection gap): `buy_volume`, `sell_volume` and `net_volume` then come from the bucket's own candle, as on `/v1/trades-kline`, and `sample_count` is 1. |
net_volume | base asset quantity (BTC for BTCUSDT) | buy_volume - sell_volume over the row, base asset units. Positive = net buying. |
buy_volume | base asset quantity (BTC for BTCUSDT) | Aggressive (taker) buy volume, base asset units, aggregated across venues. |
sell_volume | base asset quantity (BTC for BTCUSDT) | Aggressive (taker) sell volume, base asset units, aggregated across venues. |
sample_count | count | Number of points in `cvd_series`; 1 when `cvd_series` is `null` (the bucket's candle alone). |
buy_sell_coverage_ratio | fraction (0.585 = 58.5 %) | Share of the volume (in USD) whose buy/sell split is known. 1 = every trade is split. Below 1 on part of the history, where some sources did not report the aggressor side: `buy_volume` and `sell_volume` then cover that share only, so `buy_volume + sell_volume` < `volume`; `buy_ratio` and the CVD describe the covered share. `null` when the bucket has no volume. |
is_volume_estimated | `true` when some base-asset quantities of this row were ESTIMATED from USD amounts (history where a source reported amounts but not quantities): a buy or sell amount is converted at that source's own average price when its total quantity is known, otherwise at the candle's typical price (high + low + close) / 3. Every quantity a source measured is kept as is. `false` = all measured. `null` when the volume itself is `null` (not available). | |
is_closed | `true` = the row is final; `false` = provisional: the latest bucket while it still settles (a few seconds after its end, e.g. a candle whose volumes are not final yet), or the period in progress with `?live=1` on the routes that take it. Exception, rare: when a venue delivers trades LATE (seconds to minutes, e.g. during a burst), a closed row built from trades (trade candles, candle volumes, CVD, buy/sell ratio, trades per second) is corrected afterwards to include them, usually within minutes and at most one hour later; the correction only adds the late trades. |
El delta de volumen acumulado: la suma corriente del volumen comprado a mercado menos el vendido a mercado. Mide quién, compradores o vendedores, tuvo que cruzar el libro de órdenes, es decir, quién empuja realmente el precio.
CVD, ratio comprador, tamaño medio de las operaciones y libro de órdenes llevan el mercado en la RUTA: sin sufijo = todos los mercados (spot + futuros perpetuos), /spot, /futures (/v1/cvd, /v1/cvd/spot, /v1/cvd/futures, igual con /history); el sobre lo repite en market. Las cantidades spot se miden desde el 2026-09-27: antes de esa fecha, en spot y todos los mercados, los volúmenes comprador y vendedor se estiman a partir de los importes en USD, marcados con is_volume_estimated: true. /futures sirve todo el historial de futuros.
| Parámetro | Tipo | Por defecto | Descripción |
|---|---|---|---|
symbol | string | obligatorio | El activo. |
timeframe | string | obligatorio | 1m, 5m, 15m, 30m, 1h, 4h, 1d. |
live | boolean | false | Expone la ventana en curso. |
since_ms / until_ms | integer | — | Solo en el historial. |
limit | integer | 100 | En el historial, de 1 a 1000. |
curl -H "X-API-KEY: $BYTNODE_API_KEY" \
"https://api.bytnode.com/v1/cvd?symbol=BTCUSDT&timeframe=1h"| Campo | Tipo | Descripción |
|---|---|---|
time | string | Inicio de la ventana. |
cvd_series | float[] | La serie acumulada dentro de la ventana, un punto por paso interno, del más antiguo al más reciente. Es su pendiente la que lleva la información. |
net_volume | float | Compra menos venta en toda la ventana. |
buy_volume / sell_volume | float | Los dos volúmenes que componen el delta. |
sample_count | integer | Número de puntos de la serie. |
is_volume_estimated | boolean | true cuando una cantidad spot de la fila se estimó a partir de su importe en USD (datos spot anteriores al 2026-09-27). |
is_closed | boolean | Falso solo con live=1. |
#Libro de órdenes
Los 9 campos de esta ruta (según el contrato)
time | ISO 8601 UTC, milliseconds (2026-09-28T14:00:00.000Z) | Start of the bucket; the depth is the photo of the order book at the END of the bucket. |
is_closed | `true` = the row is final; `false` = provisional: the latest bucket while it still settles (a few seconds after its end, e.g. a candle whose volumes are not final yet), or the period in progress with `?live=1` on the routes that take it. Exception, rare: when a venue delivers trades LATE (seconds to minutes, e.g. during a burst), a closed row built from trades (trade candles, candle volumes, CVD, buy/sell ratio, trades per second) is corrected afterwards to include them, usually within minutes and at most one hour later; the correction only adds the late trades. | |
ranges | One entry per price range around the mid price, from the tightest (±0.25 %) to the widest (±10 %). Each range is cumulative: ±1 % includes everything inside ±0.5 %. | |
ranges.range_pct | percent (58.5 = 58.5 %) | Half-width of the range around each venue's mid price ((best bid + best ask) / 2): `1.0` = bids down to -1 % and asks up to +1 %. |
ranges.bids_quantity | base asset quantity (BTC for BTCUSDT) | Resting BUY orders inside the range (price >= mid × (1 - range_pct/100)), summed across venues. `null` = no venue publishes its book that deep. |
ranges.asks_quantity | base asset quantity (BTC for BTCUSDT) | Resting SELL orders inside the range (price <= mid × (1 + range_pct/100)), summed across venues. `null` = not measured. |
ranges.bids_usd | USD | USD value (Σ price × quantity) of the buy orders inside the range. |
ranges.asks_usd | USD | USD value (Σ price × quantity) of the sell orders inside the range. |
ranges.imbalance_ratio | fraction from -1 to 1 | (bids_usd - asks_usd) / (bids_usd + asks_usd). Positive = more bids than asks. `null` when one side is not measured. |
La última foto cerrada del libro para el timeframe pedido (1m = el último minuto cerrado), sumada entre mercados, por rango de precio: la liquidez situada a ±0,25 %, 0,5 %, 0,75 %, 1 %, 2 %, 3 %, 5 % y 10 % del precio medio. /v1/orderbook suma los libros spot y de futuros perpetuos; /v1/orderbook/spot y /v1/orderbook/futures dan un solo mercado.
| Campo | Tipo | Descripción |
|---|---|---|
time | string | Inicio del minuto fotografiado; los valores son el libro a su final. |
is_closed | boolean | Siempre verdadero: toda foto servida es definitiva. |
ranges | array | Una entrada por rango de precio, del más estrecho al más amplio. |
range_pct / bids_quantity / asks_quantity / bids_usd / asks_usd / imbalance_ratio | float | null | Para cada rango: su amplitud en porcentaje, las cantidades situadas en cada lado (activo base), las mismas en USD, e imbalance_ratio = (bids_usd − asks_usd) / (bids_usd + asks_usd), de −1 a 1, positivo cuando dominan los compradores. null cuando ningún mercado midió ese rango. |
Los 9 campos de esta ruta (según el contrato)
time | ISO 8601 UTC, milliseconds (2026-09-28T14:00:00.000Z) | Start of the bucket; the depth is the photo of the order book at the END of the bucket. |
is_closed | `true` = the row is final; `false` = provisional: the latest bucket while it still settles (a few seconds after its end, e.g. a candle whose volumes are not final yet), or the period in progress with `?live=1` on the routes that take it. Exception, rare: when a venue delivers trades LATE (seconds to minutes, e.g. during a burst), a closed row built from trades (trade candles, candle volumes, CVD, buy/sell ratio, trades per second) is corrected afterwards to include them, usually within minutes and at most one hour later; the correction only adds the late trades. | |
ranges | One entry per price range around the mid price, from the tightest (±0.25 %) to the widest (±10 %). Each range is cumulative: ±1 % includes everything inside ±0.5 %. | |
ranges.range_pct | percent (58.5 = 58.5 %) | Half-width of the range around each venue's mid price ((best bid + best ask) / 2): `1.0` = bids down to -1 % and asks up to +1 %. |
ranges.bids_quantity | base asset quantity (BTC for BTCUSDT) | Resting BUY orders inside the range (price >= mid × (1 - range_pct/100)), summed across venues. `null` = no venue publishes its book that deep. |
ranges.asks_quantity | base asset quantity (BTC for BTCUSDT) | Resting SELL orders inside the range (price <= mid × (1 + range_pct/100)), summed across venues. `null` = not measured. |
ranges.bids_usd | USD | USD value (Σ price × quantity) of the buy orders inside the range. |
ranges.asks_usd | USD | USD value (Σ price × quantity) of the sell orders inside the range. |
ranges.imbalance_ratio | fraction from -1 to 1 | (bids_usd - asks_usd) / (bids_usd + asks_usd). Positive = more bids than asks. `null` when one side is not measured. |
La misma foto por bucket (timeframe obligatorio, tanto en el último valor como en el historial): el libro tal como estaba al FINAL de cada bucket — una foto, no un promedio. Toda fila es definitiva, por eso live no se acepta.
| Campo | Tipo | Descripción |
|---|---|---|
time | string | Inicio del bucket; los valores son el libro a su final. |
ranges | array | Los mismos rangos de precio que arriba. |
is_closed | boolean | Siempre verdadero: un intervalo solo se sirve una vez cerrado (live no se acepta en el libro de órdenes). |
#Presión direccional
Como /v1/cvd, estas rutas exigen timeframe (1m a 1d), y su último valor es el último bucket CERRADO: la primera fila del /history para el mismo timeframe. El mercado va en la ruta: sin sufijo = spot + futuros, /spot, /futures.
Los 8 campos de esta ruta (según el contrato)
time | ISO 8601 UTC, milliseconds (2026-09-28T14:00:00.000Z) | Start of the latest closed bucket of `timeframe` — the first row of `/v1/buy-sell-ratio/history` for the same `timeframe`. |
buy_volume | base asset quantity (BTC for BTCUSDT) | Aggressive (taker) buy volume, base asset units, aggregated across venues. |
sell_volume | base asset quantity (BTC for BTCUSDT) | Aggressive (taker) sell volume, base asset units, aggregated across venues. |
buy_ratio | fraction (0.585 = 58.5 %) | buy_volume / (buy_volume + sell_volume). Above 0.5 = buyers dominate. |
sample_count | count | Number of points of the CVD series behind the bucket — the `sample_count` of `/v1/cvd` for the same bucket. |
buy_sell_coverage_ratio | fraction (0.585 = 58.5 %) | Share of the volume (in USD) whose buy/sell split is known. 1 = every trade is split. Below 1 on part of the history, where some sources did not report the aggressor side: `buy_volume` and `sell_volume` then cover that share only, so `buy_volume + sell_volume` < `volume`; `buy_ratio` and the CVD describe the covered share. `null` when the bucket has no volume. |
is_volume_estimated | `true` when some base-asset quantities of this row were ESTIMATED from USD amounts (history where a source reported amounts but not quantities): a buy or sell amount is converted at that source's own average price when its total quantity is known, otherwise at the candle's typical price (high + low + close) / 3. Every quantity a source measured is kept as is. `false` = all measured. `null` when the volume itself is `null` (not available). | |
is_closed | `true` = the row is final; `false` = provisional: the latest bucket while it still settles (a few seconds after its end, e.g. a candle whose volumes are not final yet), or the period in progress with `?live=1` on the routes that take it. Exception, rare: when a venue delivers trades LATE (seconds to minutes, e.g. during a burst), a closed row built from trades (trade candles, candle volumes, CVD, buy/sell ratio, trades per second) is corrected afterwards to include them, usually within minutes and at most one hour later; the correction only adds the late trades. |
Los 8 campos de esta ruta (según el contrato)
time | ISO 8601 UTC, milliseconds (2026-09-28T14:00:00.000Z) | Start of the bucket. The row covers the WHOLE bucket, from `time` to `time` + the envelope's `step` (excluded). |
buy_volume | base asset quantity (BTC for BTCUSDT) | Aggressive (taker) buy volume, base asset units, aggregated across venues. |
sell_volume | base asset quantity (BTC for BTCUSDT) | Aggressive (taker) sell volume, base asset units, aggregated across venues. |
buy_ratio | fraction (0.585 = 58.5 %) | buy_volume / (buy_volume + sell_volume). Above 0.5 = buyers dominate. |
sample_count | count | Number of points of the CVD series behind the bucket — the `sample_count` of `/v1/cvd/history` for the same bucket. |
buy_sell_coverage_ratio | fraction (0.585 = 58.5 %) | Share of the volume (in USD) whose buy/sell split is known. 1 = every trade is split. Below 1 on part of the history, where some sources did not report the aggressor side: `buy_volume` and `sell_volume` then cover that share only, so `buy_volume + sell_volume` < `volume`; `buy_ratio` and the CVD describe the covered share. `null` when the bucket has no volume. |
is_volume_estimated | `true` when some base-asset quantities of this row were ESTIMATED from USD amounts (history where a source reported amounts but not quantities): a buy or sell amount is converted at that source's own average price when its total quantity is known, otherwise at the candle's typical price (high + low + close) / 3. Every quantity a source measured is kept as is. `false` = all measured. `null` when the volume itself is `null` (not available). | |
is_closed | `true` = the row is final; `false` = provisional: the latest bucket while it still settles (a few seconds after its end, e.g. a candle whose volumes are not final yet), or the period in progress with `?live=1` on the routes that take it. Exception, rare: when a venue delivers trades LATE (seconds to minutes, e.g. during a burst), a closed row built from trades (trade candles, candle volumes, CVD, buy/sell ratio, trades per second) is corrected afterwards to include them, usually within minutes and at most one hour later; the correction only adds the late trades. |
| Campo | Tipo | Descripción |
|---|---|---|
time | string | Inicio del bucket. |
buy_volume | float | Volumen comprador en el bucket (el mismo que /v1/cvd para ese bucket). |
sell_volume | float | Volumen vendedor. |
buy_ratio | float | buy / (buy + sell), de 0 a 1. Por encima de 0,5, dominan los compradores. |
is_volume_estimated | boolean | true cuando una cantidad spot de la fila se estimó a partir de su importe en USD (datos spot anteriores al 2026-09-27). |
sample_count | integer | Número de minutos (puntos) detrás del bucket. |
is_closed | boolean | true: el bucket está cerrado y sus valores son definitivos. |
Los 7 campos de esta ruta (según el contrato)
time | ISO 8601 UTC, milliseconds (2026-09-28T14:00:00.000Z) | Start of the latest closed bucket of `timeframe` — the first row of `/v1/trades/avg-size/history` for the same `timeframe`. |
avg_trade_size | base asset quantity (BTC for BTCUSDT) | Average trade size, base asset units (NOT dollars: multiply by the price for a notional). |
volume | base asset quantity (BTC for BTCUSDT) | Traded volume over the row, base asset units (BTC for BTCUSDT, NOT dollars), aggregated across venues, over the market(s) the route covers: spot + perpetual futures on `/v1/klines` and `/v1/trades-kline`, the path's market alone on a `/spot` or `/futures` route (a name without a market suffix covers every market of its route; `volume_spot` / `volume_futures` restrict). `null` when a market is not available (never a partial sum). |
trade_count | count | Number of trades. `null` when the number is not known: history imported from an outside source carries the buy and sell volumes, not the trade count. |
is_volume_estimated | `true` when some base-asset quantities of this row were ESTIMATED from USD amounts (history where a source reported amounts but not quantities): a buy or sell amount is converted at that source's own average price when its total quantity is known, otherwise at the candle's typical price (high + low + close) / 3. Every quantity a source measured is kept as is. `false` = all measured. `null` when the volume itself is `null` (not available). | |
sample_count | count | Number of source points in the bucket (one-minute points with data). For a state (basis, open interest) the value is the LAST of them — the bucket's close —; for a flow it is their total. |
is_closed | `true` = the row is final; `false` = provisional: the latest bucket while it still settles (a few seconds after its end, e.g. a candle whose volumes are not final yet), or the period in progress with `?live=1` on the routes that take it. Exception, rare: when a venue delivers trades LATE (seconds to minutes, e.g. during a burst), a closed row built from trades (trade candles, candle volumes, CVD, buy/sell ratio, trades per second) is corrected afterwards to include them, usually within minutes and at most one hour later; the correction only adds the late trades. |
Los 7 campos de esta ruta (según el contrato)
time | ISO 8601 UTC, milliseconds (2026-09-28T14:00:00.000Z) | Start of the bucket of `timeframe`, the value aggregating the bucket's minutes; the row covers `time` to `time` + the envelope's `step` (excluded). |
avg_trade_size | base asset quantity (BTC for BTCUSDT) | Average trade size, base asset units (NOT dollars: multiply by the price for a notional). |
volume | base asset quantity (BTC for BTCUSDT) | Traded volume over the row, base asset units (BTC for BTCUSDT, NOT dollars), aggregated across venues, over the market(s) the route covers: spot + perpetual futures on `/v1/klines` and `/v1/trades-kline`, the path's market alone on a `/spot` or `/futures` route (a name without a market suffix covers every market of its route; `volume_spot` / `volume_futures` restrict). `null` when a market is not available (never a partial sum). |
trade_count | count | Number of trades. `null` when the number is not known: history imported from an outside source carries the buy and sell volumes, not the trade count. |
is_volume_estimated | `true` when some base-asset quantities of this row were ESTIMATED from USD amounts (history where a source reported amounts but not quantities): a buy or sell amount is converted at that source's own average price when its total quantity is known, otherwise at the candle's typical price (high + low + close) / 3. Every quantity a source measured is kept as is. `false` = all measured. `null` when the volume itself is `null` (not available). | |
sample_count | count | Number of source points in the bucket (one-minute points with data). For a state (basis, open interest) the value is the LAST of them — the bucket's close —; for a flow it is their total. |
is_closed | `true` = the row is final; `false` = provisional: the latest bucket while it still settles (a few seconds after its end, e.g. a candle whose volumes are not final yet), or the period in progress with `?live=1` on the routes that take it. Exception, rare: when a venue delivers trades LATE (seconds to minutes, e.g. during a burst), a closed row built from trades (trade candles, candle volumes, CVD, buy/sell ratio, trades per second) is corrected afterwards to include them, usually within minutes and at most one hour later; the correction only adds the late trades. |
El tamaño medio de una operación perfila a los participantes: sube cuando entran actores institucionales y se desploma cuando el flujo se convierte en un polvo de órdenes minoristas.
| Campo | Tipo | Descripción |
|---|---|---|
avg_trade_size | float | null | Tamaño medio, ponderado por el número de operaciones de cada mercado. |
volume | float | Volumen total agregado. |
trade_count | integer | Número agregado de operaciones. |
time | string | Inicio del bucket. |
is_volume_estimated | boolean | true cuando una cantidad spot de la fila se estimó a partir de su importe en USD (datos spot anteriores al 2026-09-27). |
sample_count | integer | Número de minutos (puntos) detrás del bucket. |
is_closed | boolean | true: el bucket está cerrado y sus valores son definitivos. |