Tapeab
SPX 7,431.46 ▲0.5%VIX 17.7 ▼1.8XLB +1.9% ▲ DAY LEADERSPX CALL WALL 7525 · PUT WALL 7350BREADTH 62% > 200DNH−NL +35PANW STRADDLE ±138.8%BDX STRADDLE ±36.2%DVN STRADDLE ±31.9%REGIME RISK-ONXLB +3.1% ▲ WEEK LEADERDEALERS SHORT GAMMADARK POOL SVR (MKT) 46%PULLBACK SCREEN 90 CANDIDATESKNIFE SCREEN 53 WATCHING
The Wireprivate beta

Levels API

The same levels this site runs on, as an API: gamma walls, zero-gamma, pin candidates, expected moves and dark-pool levels for ES, NQ, SPX, NDX, SPY and QQQ. Futures levels are converted first-party from the index chains. JSON and CSV, refreshed after each US close and again pre-open.

Base URL https://api.tapelab.io · data last published 2026-06-13 00:20 UTC

Quick start

Authenticate with `X-API-Key` or `Authorization: Bearer` on every levels request. Keys are hand-issued during the beta — see keys & limits.

curl -s -H "X-API-Key: $TAPELAB_KEY" \
  https://api.tapelab.io/v1/levels/ES | jq '.zeroGamma.price'

Endpoints

RouteAuthReturns
GET /v1/healthnoneLiveness + the timestamp of the last data publish.
GET /v1/levels/{INSTRUMENT}keyThe instrument's full levels document (schema below).
GET /v1/levels/{INSTRUMENT}.csvkeyThe same levels as one flat CSV — one row per level.
InstrumentKindDerived fromUnits
ESfuturesSPX chain + ES=F basisES points
NQfuturesNDX chain + NQ=F basisNQ points
SPXcash indexSPX chainindex points
NDXcash indexNDX chainindex points
SPYETFSPY chaindollars · + dark-pool levels
QQQETFQQQ chaindollars · + dark-pool levels

Response schema

Every level carries two values: `native` (the source chain's units) and `price` (the instrument's units — for ES/NQ that's native + basis). Levels are served unsnapped; snap to your instrument's tick on the client. `distPct` is distance from spot.

{
  "version": 1,
  "instrument": "ES",
  "kind": "futures",
  "units": "ES futures points",
  "sourceSymbol": "SPX",            // the option chain the levels derive from
  "asOf": "2026-06-12",             // market session
  "generatedAt": "2026-06-12T22:41:24Z",
  "freshness": "eod",

  "conversion": {                   // futures only — null basis fields on cash/ETF
    "method": "additive_basis",
    "formula": "ES = SPX + basis",
    "basis": 5.04,                  // same-session ES=F close − ^GSPC close
    "basisDate": "2026-06-12",
    "futuresSymbol": "ES=F",
    "cashSymbol": "^GSPC"
  },

  "spot":      { "native": 7431.46, "price": 7436.50 },
  "zeroGamma": { "native": 7434.97, "price": 7440.01, "distPct": 0.05 },
  "callWall":  { "native": 7430.00, "price": 7435.04, "distPct": -0.02 },
  "putWall":   { "native": 7430.00, "price": 7435.04, "distPct": -0.02 },
  "pinCandidates": [                // top strikes by |net GEX|, nearest expiry
    { "rank": 1, "native": 7430.0, "price": 7435.04, "netGexM": 312.4 }
  ],

  "netGexM": 449.7,                 // $M, full chain
  "netGexNearM": 197.2,             // $M, nearest expiry
  "gammaRegime": "long_gamma",      // sign of net GEX: long_gamma | short_gamma
  "gexHhi": 0.0175,                 // strike concentration (Herfindahl)

  "expectedMove": {                 // ATM straddle, no haircut — each horizon:
    "monthly": {
      "expiry": "2026-06-18",
      "straddleNative": 120.55,
      "pct": 1.62,
      "lower": { "native": 7310.91, "price": 7315.95 },
      "upper": { "native": 7552.01, "price": 7557.05 }
    }
    // ... "nearest" and "quarterly" have the same shape
  },

  "darkpool": null                  // SPY/QQQ only: top-5 FINRA off-exchange
                                    // volume-at-price levels since 2018
}

The CSV twin flattens the same document — one row per level, `type` column keys the level kind:

instrument,as_of,type,rank,native,price,net_gex_m,dollars_b,date,pct
ES,2026-06-12,basis,,,5.04,,,2026-06-12,
ES,2026-06-12,spot,,7431.46,7436.5,,,,
ES,2026-06-12,zero_gamma,,7434.97,7440.01,,,,0.05
ES,2026-06-12,call_wall,,7430.0,7435.04,,,,-0.02
ES,2026-06-12,put_wall,,7430.0,7435.04,,,,-0.02
ES,2026-06-12,em_monthly_lower,,7310.91,7315.95,,,2026-06-18,1.62
ES,2026-06-12,em_monthly_upper,,7552.01,7557.05,,,2026-06-18,1.62

Client snippets

Python:

import os, requests

KEY = os.environ["TAPELAB_KEY"]
r = requests.get(
    "https://api.tapelab.io/v1/levels/NQ",
    headers={"X-API-Key": KEY},
    timeout=10,
)
r.raise_for_status()
levels = r.json()

print(levels["asOf"], levels["gammaRegime"])
print("zero-gamma:", levels["zeroGamma"]["price"])   # NQ futures points
print("call wall: ", levels["callWall"]["price"])
print("EM monthly:", levels["expectedMove"]["monthly"]["lower"]["price"],
      "-", levels["expectedMove"]["monthly"]["upper"]["price"])

NinjaTrader 8 (C#) — fetch once per session, not per tick:

// NinjaTrader 8 add-on / indicator (System.Net.Http)
using var http = new HttpClient();
http.DefaultRequestHeaders.Add("X-API-Key",
    Environment.GetEnvironmentVariable("TAPELAB_KEY"));

var json = await http.GetStringAsync(
    "https://api.tapelab.io/v1/levels/ES");

// Newtonsoft ships with NT8:
var levels = Newtonsoft.Json.Linq.JObject.Parse(json);
double zeroGamma = (double)levels["zeroGamma"]["price"];
double callWall  = (double)levels["callWall"]["price"];
// levels are UNSNAPPED — snap to the instrument's tick before drawing:
double tick = 0.25;
zeroGamma = Math.Round(zeroGamma / tick) * tick;

Freshness & schedule

Errors

All errors share one envelope: {"error": {"code": "...", "message": "..."}}

StatusCodeMeaning
401missing_key / invalid_keyNo key supplied, or the key is unknown.
403key_revokedThe key exists but has been deactivated.
404unknown_instrumentNot one of ES, NQ, SPX, NDX, SPY, QQQ.
429rate_limitedPer-key request budget exceeded (default 60/min).
503data_unavailableThe instrument's file isn't published yet — retry after the next pipeline run.

Keys & limits

The API is in private beta: keys are hand-issued, free while the beta lasts, and rate-limited at 60 requests/minute (the data changes twice a day — you won't need more). Billing and self-serve keys come with the public release.

Walls, zero-gamma and pins are heuristics over delayed option chains, labeled as such; expected moves are market-implied straddle ranges, not forecasts; dark-pool levels are daily-resolution approximations of FINRA off-exchange volume. Research data — not investment advice.