Developers menu

Get levels

The volume book's flip, call wall, put wall and net gamma for up to 20 symbols in one call, with the open-interest book alongside under oi.

GET/api/v1/levels
Plan LIVEKey scope liveLimit 120 a minute per key; a 304 is freeVersion 1.0.0Since 2026-09-30

This endpoint serves

Plan: LIVE. LIVE: today's session every second, alerts, ASK, the levels API and the platform integrations, and 5 LAB credits a month. Every finished session is free in REPLAY. Pricing.

Parameters

NameWhat it doesDefaultError
symrequiredquery · stringComma list, up to 20: SPX,ES,NQ,QQQ. MES, MNQ and M2K answer as ES, NQ and RTY; a dated contract (ESH27) names that contract.missing_sym, too_many_symbols
includequery · gammagamma adds each symbol's gamma by strike: one request per chart.
bookquery · vol | oiWith include=gamma: which book's strikes.volbad_book
contractquery · stringFutures: a dated contract in the two weeks before a roll, e.g. ESH27. The levels move by that contract's own basis.the front quarterlycontract_not_live
errorsquery · 200200: an error answers 200 with the same body and the real status in X-FirmTape-Status, for clients that cannot read a status.
keyquery · stringLegacy: the key in the address, for platforms that cannot send headers. Prefer the header.

Response

One entry per symbol asked, in order. A symbol that fails carries its own error; the rest still answer.

FieldMeaningUnit
book"volume"Always volume.
next_update_sintegerThe smallest next_update_s of the symbols.seconds
levelsarrayThe readings.
levels[].symstringThe symbol answered: SPX, ES, NQ, RTY or a ticker. A micro (MES, MNQ, M2K) answers as its future.
levels[].requestedstringPresent when the symbol asked differs from sym (MES answered as ES).
levels[].namestringThe symbol's name.
levels[].classstringindex, future, etf or stock.
levels[].contractstringFutures: the contract the levels are moved to, e.g. ESZ26.
levels[].sessionopen | closed | staleopen while the book is current, closed outside market hours, stale when market hours are on but the book has not moved for a while.
levels[].daystringThe ET trading day of the reading, YYYY-MM-DD.
levels[].book"volume"Always volume: every level is the volume book, the one the terminal draws.
levels[].pricenumber | nullThe price at the reading.index points
levels[].price_as_ofstringWhen that price was taken, ISO 8601 in New York time.
levels[].flipnumber | nullZero-gamma flip of the volume book. On a finished day, read at the levels minute (levels_at).index points
levels[].call_wallnumber | nullCall wall: the strike with the largest call gamma. On a finished day, read at the levels minute.index points
levels[].put_wallnumber | nullPut wall: the strike with the largest put gamma. On a finished day, read at the levels minute.index points
levels[].net_gammaobjectNet dealer gamma of the book: its value, its sign and its unit, named on every answer.
levels[].net_gamma.valuenumber | nullNet dealer gamma, in unit.
levels[].net_gamma.signpositive | negative | nullThe sign of value.
levels[].net_gamma.unitusd_m_per_point | usd_per_1pctusd_m_per_point (millions of USD per index point: SPX, ES) or usd_per_1pct (USD per 1% move: tickers, NQ, RTY).
levels[].at_flipbooleanSPX and ES: the price is within 5 points of the flip, where the side is not a reliable reading.
levels[].dealer_gammalong | short | nullSPX and ES: the side of net gamma; null at the flip.
levels[].gamma_pctlnumber | nullSPX and ES: the volume book's gamma at spot against the same minute of the last 20 sessions, a decile from -11 to +11. A measurement, with no measured forward edge.
levels[].as_ofstringWhen the book was built, ISO 8601 in New York time.
levels[].as_of_unixintegerThe same instant, Unix seconds.
levels[].age_sintegerSeconds since the book was built.seconds
levels[].cadenceobjectHow often the book and the price are rebuilt.
levels[].cadence.bookstring1s (SPX, ES) or 5m (tickers, NQ, RTY).
levels[].cadence.pricestring1s.
levels[].gradestring | nullTickers, NQ, RTY: the chain's trust grade (A best). Null for SPX and ES.
levels[].flip_statusstring | nullTickers: whether the flip was found inside the strike grid.
levels[].oiobject | nullThe open-interest book's levels, the same fields; null when the symbol has none.
levels[].oi.flipnumber | nullZero-gamma flip of the open-interest book.index points
levels[].oi.call_wallnumber | nullCall wall of the open-interest book.index points
levels[].oi.put_wallnumber | nullPut wall of the open-interest book.index points
levels[].oi.net_gammaobjectNet dealer gamma of the book: its value, its sign and its unit, named on every answer.
levels[].oi.flip_statusstring | nullTickers: whether the flip was found inside the strike grid (ok) or not.
levels[].basisobjectES, NQ, RTY: the day's basis that moved the index levels.
levels[].basis.valuenumber | nullFuture minus index.index points
levels[].basis.indexstringThe index the book is measured on: SPX, NDX or RUT.
levels[].basis.passesintegerBasis passes measured so far today.
levels[].basis.rulestringHow the basis is made: the running median of the day's passes, rounded to the future's tick.
levels[].sourcestringFutures: which index book and which basis.
levels[].levels_at15:45 | 12:45A finished day only: the levels minute (ET) flip, call_wall and put_wall were read at. Absent while the session runs.
levels[].last_secondobjectA finished day only: the replaced fields as the session's last second had them.
levels[].last_second.flipnumber | nullFlip at the last second.index points
levels[].last_second.call_wallnumber | nullCall wall at the last second.index points
levels[].last_second.put_wallnumber | nullPut wall at the last second.index points
levels[].last_second.at_flipbooleanAt the flip, at the last second.
levels[].last_second.dealer_gammalong | short | nullThe side, at the last second.
levels[].next_update_sintegerWhen a new reading is worth asking for: 3 for SPX and ES, up to 300 for a five-minute book, 60 when the session is not open.seconds
levels[].gammaobjectWith include=gamma: the symbol's gamma by strike (the fields of GET /api/v1/gamma), or an error.
levels[].errorobjectThis symbol failed; the others in the call still answer.
levels[].error.codestringunknown_symbol, no_data, no_basis or contract_not_live.
levels[].error.messagestringWhat happened, in words.
levels[].error.livearrayWith contract_not_live: the contracts measured that day.

Errors

StatusCodeWhat to do
400missing_sym, too_many_symbols, bad_bookA parameter is wrong. Pass sym, one symbol or a comma list.
401no_key, bad_keyNo key, or an unknown or revoked one. Send Authorization: Bearer <key> with a key of the product's scope.
403live_requiredThe account holds no LIVE plan. Start or renew LIVE; pricing names the page.
429rate_limited, too_many_placesOver the minute's limit, or the key is in use from a fourth address this hour. Wait Retry-After seconds; poll with If-None-Match, a 304 is free.

Every code: Errors.

Caching

Answers carry an ETag: send it back as If-None-Match and an unchanged reading answers 304 with no body, not counted against the limit.

Changes

  • 2026-10-11 A finished day answers with its closing levels, read at 15:45 ET; levels_at and last_second added.
  • 2026-10-11 RTY and M2K.
  • 2026-09-30 Added.

OpenAPI operation getLevels in /docs/developers/openapi.json.

Measurements of dealer positioning, never a forecast or a trade call. This page is built from FirmTape's public contract, the same files the OpenAPI document is built from; the tests hold them against the route code. Markdown: /docs/developers/live/levels.md.