API: Market data
CVD
Cumulative volume delta: aggressor buy volume, sell volume, per-bucket delta and the running cumulative.
GET
/
market
/
cvd
Cumulative volume delta
curl --request GET \
--url https://api.example.com/market/cvd \
--header 'X-API-Key: <api-key>'import requests
url = "https://api.example.com/market/cvd"
headers = {"X-API-Key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-Key': '<api-key>'}};
fetch('https://api.example.com/market/cvd', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/market/cvd",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/market/cvd"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-Key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.example.com/market/cvd")
.header("X-API-Key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/market/cvd")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-Key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"success": false,
"error": {
"code": "UNAUTHORIZED",
"message": "Invalid API key"
},
"meta": {
"version": "2.0",
"timestamp": "2026-04-29T12:00:00Z"
}
}{
"success": false,
"error": {
"code": "NOT_FOUND",
"message": "No data for BTCUSDT"
},
"meta": {
"version": "2.0",
"timestamp": "2026-04-29T12:00:00Z"
}
}{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid request parameters",
"details": {
"errors": []
}
},
"meta": {
"version": "2.0",
"timestamp": "2026-04-29T12:00:00Z"
}
}{
"success": false,
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded. Try again later."
},
"meta": {
"version": "2.0",
"timestamp": "2026-04-29T12:00:00Z"
}
}Aggressor buy volume, sell volume, their per-bucket difference, and the running
cumulative across the window.
Derived from the same buy/sell columns
/market/candles already carries, so requesting
candles and CVD over one window costs a single underlying read rather than
two.
On OHLC
delta is exact: buy minus sell for that bucket.
open and close are the running cumulative at the bucket’s boundaries, also
exact.
high and low are returned as null, with ohlc_complete: false.They would require the path the cumulative took inside the bucket, and bucket
totals do not carry that. We return nulls rather than interpolating, because a
fabricated wick looks exactly like data and isn’t.If you need true intra-bucket extremes, request a finer interval and
aggregate client-side.Reading the cumulative
The cumulative is relative to the start of the window, not an all-time figure. It begins at zero on the first bucket returned. Compare shapes across windows, not levels: two requests with differenthours
will not produce the same absolute values, and neither is wrong.
See also
Candles
Market bundle
Authorizations
Your BackQuant API key (same key as v1)
Headers
Query Parameters
Trading symbol: BTCUSDT, ETHUSDT, SOLUSDT, or HYPEUSDT.
Available options:
BTCUSDT, ETHUSDT, SOLUSDT, HYPEUSDT perp for the perpetual aggregate, spot for spot.
Available options:
perp, spot Series interval.
Available options:
1m, 5m, 15m, 30m, 1h, 4h, 1d Lookback window in hours.
Required range:
1 <= x <= 8760Response
Successful Response
⌘I
Cumulative volume delta
curl --request GET \
--url https://api.example.com/market/cvd \
--header 'X-API-Key: <api-key>'import requests
url = "https://api.example.com/market/cvd"
headers = {"X-API-Key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-Key': '<api-key>'}};
fetch('https://api.example.com/market/cvd', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/market/cvd",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/market/cvd"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-Key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.example.com/market/cvd")
.header("X-API-Key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/market/cvd")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-Key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"success": false,
"error": {
"code": "UNAUTHORIZED",
"message": "Invalid API key"
},
"meta": {
"version": "2.0",
"timestamp": "2026-04-29T12:00:00Z"
}
}{
"success": false,
"error": {
"code": "NOT_FOUND",
"message": "No data for BTCUSDT"
},
"meta": {
"version": "2.0",
"timestamp": "2026-04-29T12:00:00Z"
}
}{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid request parameters",
"details": {
"errors": []
}
},
"meta": {
"version": "2.0",
"timestamp": "2026-04-29T12:00:00Z"
}
}{
"success": false,
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded. Try again later."
},
"meta": {
"version": "2.0",
"timestamp": "2026-04-29T12:00:00Z"
}
}