Skip to main content

Dealer Hedge Flow API

The Dealer Hedge Flow API returns how options dealers are positioned in Deribit BTC options and what their hedging would do if the price moved: for every price level, how many US dollars of BTC dealers would buy or sell to stay delta-hedged on the way there, and whether that flow amplifies or dampens the move. It also returns net gamma exposure (GEX), the zero gamma level and a few legacy options statistics. A new snapshot is computed every hour.

How dealer positions are rebuilt, the formulas and the assumptions: Dealer Hedge Flow Methodology.

Not a trading signal

The Dealer Hedge Flow is a descriptive model of dealer positioning, not a price target or a trading signal.

Endpoints​

MethodPathDescription
GET/v1/options/gexDaily series: one row per day (the 00:00 UTC snapshot)
GET/v1/options/gex/hourlyEvery hourly snapshot (Pro)
GET/v1/options/gex/profileHedge flow by price for one snapshot (default: the latest)
GET/v1/options/gex/heatmapTime × price matrix of impact for a heatmap

Base URL: https://api.blocklens.co. All responses are JSON in the envelope {"success": true, "data": …}: for the series data is a list of rows (with count, access and message next to it), for /profile and /heatmap it is an object that contains access. Errors use {"success": false, "message": {…}, "timestamp": "…"} (see Errors).

Authentication​

All requests require an API key:

Authorization: Bearer YOUR_API_KEY

See Authentication for API keys and Rate Limits & Tiers for which plans include API access and the request limits.

Signs and units​

  • All amounts are in USD. GEX values (net_gex, gex[], strikes[].call_gex / put_gex) are USD per 1% move; hedge flow and impact are USD for the whole move from the current price to the level.
  • hedge_flow > 0 — dealers buy BTC on the way to the level; < 0 — they sell.
  • impact = hedge_flow × sign(level − spot): > 0 — amplify (the flow pushes the move further), < 0 — dampen (it leans against the move).
  • net_gex > 0 — dealers are net long gamma (dampening regime); < 0 — net short gamma (amplifying regime).
  • spot is the BTC index price of the snapshot; levels lie on an absolute $500 grid within ±30% of it.
  • zero_gamma is searched within ±50% of spot, so it can lie outside the level grid; null when the GEX curve keeps one sign there.

Tiers and history​

The tier rules are enforced by the API itself, not only by the Lab interface:

FreePro, Enterprise
/v1/options/gex (daily)the last 30 daysfull history since 2026-03-16
/v1/options/gex/hourly— (403)yes
/v1/options/gex/profilethe latest snapshot only, without strikesany snapshot, with strikes
/v1/options/gex/heatmapresolution=1d, the last 30 days1h, 6h, 1d, full history

Every response carries an access block:

"access": {"tier": "free", "grade": 0, "full_history": false, "history_from": "2026-09-24",
"resolutions": ["1d"], "profile_history": false, "strikes": false, "hourly": false,
"required_grade": 1, "clipped": false}
  • history_from — the first day the caller may see (null for the full history).
  • resolutions, profile_history, strikes, hourly — what the caller's tier allows.
  • clipped — true when the daily series or the heatmap was asked for days before history_from and they were cut off. These two endpoints never return 403 for that reason: they return the allowed part.
  • A past snapshot from /profile (anything but the latest), /hourly, and a 6h / 1h heatmap return 403 on Free (see Errors).

Snapshots and time​

  • One snapshot of the Deribit BTC options board per hour, a few seconds after the full hour. History starts on 2026-03-16; 2026-06-08 … 2026-07-07 is missing (collection outage), and single hours are skipped when the board was incomplete. Data are refreshed every hour at about :20 UTC.
  • Times are UTC, ISO 8601. Snapshot times carry microseconds when the snapshot has them ("2026-10-24T09:00:02.418731Z"): pass a ts / times[] value back to /profile?ts= unchanged and it selects exactly that snapshot. A ts without fractional seconds matches any snapshot within that second.
  • A day (the daily series, /profile?date=, the 1d heatmap) is the 00:00 UTC snapshot of that day — the first snapshot of the day if 00:00 is missing. It lies away from the 08:00 UTC daily expiry, so the row of a day does not change once it appears.

GET /v1/options/gex​

Daily series, newest first.

ParameterDefaultDescription
from_datefirst allowed dayYYYY-MM-DD (UTC); earlier than the tier window → cut off, access.clipped = true
to_datelatest dayYYYY-MM-DD (UTC, inclusive)
limit100Number of days (1–10,000), newest first
fieldsallComma-separated field names (date is always kept)
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://api.blocklens.co/v1/options/gex?from_date=2026-10-01&fields=btc_price,net_gex,zero_gamma,flow_up5,flow_dn5"
{
"success": true,
"data": [
{"date": "2026-10-23", "snapshot_ts": "2026-10-23T00:00:02Z", "btc_price": 80712.4,
"legacy_total_gex": 30112000.0, "legacy_call_gex": 41870000.0, "legacy_put_gex": -11758000.0,
"top_support_strike": 80000.0, "top_support_gex": 9120000.0,
"top_resist_strike": 76000.0, "top_resist_gex": -3410000.0, "legacy_flip_point": 80551.2,
"pc_ratio_oi": 0.62, "pc_ratio_vol_24h": 0.81, "max_pain": 82000.0, "max_pain_expiry": "24OCT26",
"hedge_snapshot_ts": "2026-10-23T00:00:02Z", "spot": 80712.4, "net_gex": 35700000.0, "zero_gamma": 59300.0,
"flow_up5": -219000000.0, "flow_dn5": 288000000.0, "flow_up10": -402000000.0, "flow_dn10": 515000000.0}
],
"count": 1,
"access": {"tier": "pro", "grade": 1, "full_history": true, "history_from": null, "resolutions": ["1h", "6h", "1d"],
"profile_history": true, "strikes": true, "hourly": true, "required_grade": 1, "clipped": false},
"message": "Options GEX and dealer hedge flow, daily (Deribit BTC)"
}
FieldMeaning
dateUTC day
hedge_snapshot_ts, spotThe snapshot of the day used for the hedge-flow fields and its BTC index price
net_gexNet dealer GEX at spot, Black-Scholes, USD per 1% move — the published net GEX
zero_gammaThe sign change of the recomputed GEX curve nearest to spot (±50%); null if none
flow_up5, flow_dn5, flow_up10, flow_dn10Hedge flow in USD if the price moved +5% / −5% / +10% / −10% from spot, exact at spot × 1.05 / 0.95 / 1.10 / 0.90
snapshot_ts, btc_priceThe snapshot of the legacy fields and its BTC price
top_support_strike, top_support_gexThe strike with the largest positive GEX (Deribit gamma; strikes with |GEX| below $1,000 are left out)
top_resist_strike, top_resist_gexThe strike with the most negative GEX (same rules)
pc_ratio_oi, pc_ratio_vol_24hPut/call ratio by open interest and by 24h volume
max_pain, max_pain_expiryMax pain strike of the nearest expiry, and that expiry
legacy_total_gex, legacy_call_gex, legacy_put_gexGEX on Deribit's published gamma (rounded to 1e-5 — biased against Black-Scholes); use net_gex
legacy_flip_pointSign change of strike GEX between the two strikes around the price — not a gamma flip; use zero_gamma

The daily net_gex, zero_gamma, flow_* and top_*_strike columns are also catalog metrics (options_*, category options) available through /v1/metrics and the MCP tool get_metric.

GET /v1/options/gex/hourly​

Every hourly snapshot, newest first (Pro). Same fields as the daily series, keyed by timestamp (the snapshot time) instead of date; the legacy and the hedge-flow values of the same snapshot share one row.

ParameterDefaultDescription
from_date, to_date—YYYY-MM-DD (UTC, to_date inclusive)
limit168Number of snapshots (1–10,000); the default is one week
fieldsallComma-separated field names (timestamp is always kept)
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://api.blocklens.co/v1/options/gex/hourly?limit=24&fields=spot,net_gex,zero_gamma"

GET /v1/options/gex/profile​

Hedge flow by price for one snapshot.

ParameterDefaultDescription
tslatestSnapshot time (ISO 8601, UTC if no offset): the latest snapshot at or before it. Not with date
date—YYYY-MM-DD (UTC): the 00:00 UTC snapshot of that day (the first of the day). Not with ts

Free callers get the latest snapshot only: omit ts / date (a ts / date that resolves to the latest snapshot is also accepted).

curl -H "Authorization: Bearer YOUR_API_KEY" https://api.blocklens.co/v1/options/gex/profile
{
"success": true,
"data": {
"ts": "2026-10-24T09:00:02Z", "spot": 80712.4, "step": 500.0,
"levels": [80000.0, 80500.0, 81000.0, 81500.0],
"hedge_flow": [21400000.0, 4900000.0, -6800000.0, -27300000.0],
"impact": [-21400000.0, -4900000.0, -6800000.0, -27300000.0],
"gex": [36900000.0, 35900000.0, 35200000.0, 34100000.0],
"net_gex": 35700000.0, "zero_gamma": 59300.0, "flips": [59300.0],
"flow": {"up5": -219000000.0, "dn5": 288000000.0, "up10": -402000000.0, "dn10": 515000000.0},
"max_amplify_level": null, "max_dampen_level": 74000.0, "method_version": 1,
"legacy": {"flip_point": 80551.2, "top_support_strike": 80000.0, "top_resist_strike": 76000.0,
"total_gex": 30112000.0},
"strikes": [{"strike": 80000.0, "call_gex": 6200000.0, "put_gex": 2920000.0}],
"access": {"tier": "pro", "grade": 1, "full_history": true, "history_from": null, "resolutions": ["1h", "6h", "1d"],
"profile_history": true, "strikes": true, "hourly": true, "required_grade": 1, "clipped": false}
}
}

The example is shortened: a real profile has about a hundred levels.

FieldMeaning
ts, spotSnapshot time and BTC index price
step, levelsGrid step ($500) and the price levels, ascending, within ±30% of spot
hedge_flow[i]USD dealers trade if the price moves from spot to levels[i] (> 0 buy, < 0 sell)
impact[i]hedge_flow[i] signed by the direction of the move (> 0 amplify, < 0 dampen)
gex[i]Net dealer GEX recomputed as if the price were at levels[i], USD per 1%
net_gexGEX at spot
zero_gamma, flipsThe sign change of the GEX curve nearest to spot and all sign changes, ascending, within ±50% of spot (null / [] if none)
flowHedge flow exactly at spot × 1.05 / 0.95 / 1.10 / 0.90 (up5, dn5, up10, dn10)
max_amplify_level, max_dampen_levelThe $500 band with the largest amplifying / dampening marginal flow (null if none)
method_versionVersion of the calculation method
legacyLegacy values of the same snapshot (Deribit gamma): flip_point, top_support_strike, top_resist_strike, total_gex
strikesNet GEX by strike, calls and puts separately, summed over expiries (Pro; null on Free)

hedge_flow is cumulative along the price path: to read a band between two levels take the difference, never the sum of several levels.

GET /v1/options/gex/heatmap​

ParameterDefaultDescription
resolution1d1d, 6h or 1h (Pro): one snapshot per bucket — the first one (1d = the 00:00 UTC snapshot)
from1d: the whole history; 6h: the last 180 days; 1h: the last 30 daysISO date or date-time (UTC). Earlier than the tier window → cut off, access.clipped = true
tonowISO date (inclusive) or date-time (exclusive)
price_min, price_maxall levelsTrim the price range, USD (finite, ≥ 0, price_min < price_max)

from / to snap outward to whole buckets of resolution.

curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://api.blocklens.co/v1/options/gex/heatmap?resolution=6h&from=2026-09-01"
{
"success": true,
"data": {
"resolution": "1d", "times": ["2026-10-22T00:00:01Z", "2026-10-23T00:00:02Z"], "step": 500.0,
"levels": [80000.0, 80500.0, 81000.0],
"matrix": [[-18200000, null, -5100000], [-21400000, -4900000, -6800000]],
"overlays": {"price": [80310.0, 80712.4], "zero_gamma": [null, 59300.0]},
"scale": {"p98": 310000000, "max": 612000000},
"access": {"tier": "pro", "grade": 1, "full_history": true, "history_from": null, "resolutions": ["1h", "6h", "1d"],
"profile_history": true, "strikes": true, "hourly": true, "required_grade": 1, "clipped": false}
}
}
  • matrix[t][l] — the impact in whole USD at levels[l] for the snapshot times[t] (> 0 amplify, < 0 dampen). null outside that snapshot's own ±30% range or in a hole of its grid.
  • times are the real snapshot times, ascending; the spacing is irregular around data gaps (no empty rows).
  • levels — one common $500 grid covering every returned snapshot.
  • overlays.price — spot of each row; overlays.zero_gamma — its zero gamma level (null where there is none). The zero gamma level can lie outside levels: clip the line when drawing it.
  • scale — the 98th percentile and the maximum of |impact|; cap a colour scale at p98.

Limits and payload size​

  • resolution=1h covers at most 90 days per request (400 otherwise — use 6h or 1d for longer ranges).
  • A heatmap request may cover at most 2,000,000 cells (snapshots × levels); larger requests return 400 — use a coarser resolution, a shorter period or price_min / price_max.
  • The full hourly history is about 10 MB of uncompressed JSON. Responses are gzip-compressed on the wire. For a first view use 1d or 6h, or a short 1h window.
  • Request limits per API key: Rate Limits & Tiers.

Updates and caching​

  • A new snapshot is computed every hour on our side and published at about :20 UTC; until then the previous hour is the latest.
  • Responses are cached on the server and refreshed when new data arrive.
  • The same URL returns different data for different tiers, so responses are sent with Cache-Control: private, max-age=600 and Vary: Authorization — they are never stored by shared caches.

Errors​

Errors come in the envelope {"success": false, "message": {…}, "timestamp": "…"}; the table shows message.

StatusWhenmessage
400A bad date or time, to_date before from_date, both ts and date, unknown resolution, price_min / price_max not finite, negative or price_min >= price_max, a range that does not overlap the levels, more than 90 days at 1h, a heatmap above 2,000,000 cells{"error": "Invalid parameter", "message": "resolution must be one of 1h, 6h, 1d"}
401Missing or invalid API key
403Free: a past snapshot from /profile, /hourly, a 6h / 1h heatmap{"error": "Insufficient tier", "message": "Profiles of past snapshots requires Pro", "required_grade": 1, "current_tier": "free", "current_grade": 0, "history_from": "2026-09-24", "upgrade_url": "https://blocklens.co/pricing"}
404No snapshot for the requested day or time, or no data in the requested range{"error": "Not found", "message": "no profile on 2026-06-20"}
429Rate limit exceededSee Rate Limits & Tiers