Strike ladder
Dealer exposure by strike and expiry for every greek, and the dealer position in contracts.
curl --request GET \
--url https://api.example.com/gex/ladder \
--header 'X-API-Key: <api-key>'import requests
url = "https://api.example.com/gex/ladder"
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/gex/ladder', 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/gex/ladder",
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/gex/ladder"
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/gex/ladder")
.header("X-API-Key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/gex/ladder")
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"
}
}gex, dex,
vanna, charm, vega, oi or pos), with a row per strike and a column
per expiry, plus each strike’s total over every expiry in scope.
pos is the dealer position itself, in contracts: where dealers are longest
and shortest, by strike and by expiry. With positioning=flow (the default
for BTC and ETH) it is measured from the tape; see
How flow is measured.
curl -H "X-API-Key: $KEY" \
"https://api.backquant.com/v2/gex/ladder?symbol=BTCUSDT&metric=pos&expiry=week"
expiry takes all, 0dte, front, week, month, ISO dates or tokens
such as 30OCT26. Every expiry in the response carries both forms.
See also
Dealer positioning
Strike profile
Authorizations
Your BackQuant API key (same key as v1)
Headers
Query Parameters
Trading symbol: BTCUSDT, ETHUSDT, SOLUSDT, or HYPEUSDT.
BTCUSDT, ETHUSDT, SOLUSDT, HYPEUSDT Which exposure: gex, dex, vanna, charm, vega, oi or pos.
gex, dex, vanna, charm, vega, oi, pos Dealer positioning model. flow (default) is BackQuant's measured dealer model, available for BTC/ETH; it falls back to std when it cannot be produced for a symbol. std is the textbook convention (call:+OI / put:-OI). The response reports which model actually ran in meta.extra.positioning.
all, 0dte, front, week, month, or a comma list of ISO dates / tokens (30OCT26).
400How many of the nearest expiries get their own column.
0 <= x <= 24Strikes within spot x (1 +/- span). Default 0.12.
0.005 <= x <= 0.5Merge strikes into buckets about this many strike steps wide.
1 <= x <= 20Response
Successful Response
curl --request GET \
--url https://api.example.com/gex/ladder \
--header 'X-API-Key: <api-key>'import requests
url = "https://api.example.com/gex/ladder"
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/gex/ladder', 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/gex/ladder",
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/gex/ladder"
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/gex/ladder")
.header("X-API-Key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/gex/ladder")
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"
}
}