# Level history of a day

> One day's price, flip, call wall, put wall and net gamma as columns and rows: SPX and ES one row per 10 seconds, tickers, NQ and RTY one per five-minute book.

Source: https://firmtape.com/docs/developers/live/history

One day's price, flip, call wall, put wall and net gamma as columns and rows: SPX and ES one row per 10 seconds, tickers, NQ and RTY one per five-minute book.

`GET /api/v1/history`

Plan LIVE · Key scope live · Limit 120 a minute per key; the last 90 days, older with DATASET · Version 1.0.0 · Since 2026-09-30

**This endpoint serves:** [LIVE: Levels API](https://firmtape.com/docs/live#levels-api), [DATASET: Older days in the levels API](https://firmtape.com/docs/dataset#deep-history). **Plan:** [LIVE](https://firmtape.com/features/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.

## Parameters

| Name | What it does | Default | Error |
| --- | --- | --- | --- |
| `sym` (required) query, string | One symbol: SPX, ES, NQ, RTY (or MES, MNQ, M2K), a dated contract such as `ESH27`, or a ticker from `/api/v1/symbols`. |  | missing_sym |
| `day` query, string | `YYYY-MM-DD`, within the last 90 days; older with the DATASET licence. | the running or most recent session | bad_day, history_too_old |
| `contract` query, string | Futures: a dated contract in the two weeks before a roll, e.g. `ESH27`. The levels move by that contract's own basis. | the front quarterly | contract_not_live |
| `errors` query, 200 | `200`: an error answers 200 with the same body and the real status in `X-FirmTape-Status`, for clients that cannot read a status. |  |  |
| `key` query, string | Legacy: the key in the address, for platforms that cannot send headers. Prefer the header. |  |  |

## Response

Columns and rows.

| Field | Meaning | Unit |
| --- | --- | --- |
| `sym` (string) | The symbol. |  |
| `day` (string) | The ET trading day. |  |
| `book` ("volume") | Always `volume`. |  |
| `step` (10s \| 5m) | `10s` or `5m`. |  |
| `unit` (string) | Net gamma's unit. |  |
| `unit_text` (string) | The unit in words. |  |
| `columns` (array) | `t`, `price`, `flip`, `call_wall`, `put_wall`, `net_gamma`. |  |
| `rows` (array) | One row per step: the ET time, then the columns' values (index points; net gamma in `unit`). |  |
| `contract` (string \| null) | Futures: the contract. |  |
| `basis` (object) | Futures: the basis as it stood at each row. |  |
| `basis.index` (string) | The index. |  |
| `basis.rule` (string) | How the basis is made. |  |
| `basis.first` (number \| null) | Basis at the first row. | index points |
| `basis.last` (number \| null) | Basis at the last row. | index points |
| `basis.note` (string) | In words. |  |

## Errors

| Status | Code | What to do |
| --- | --- | --- |
| 400 | `missing_sym`, `bad_day` | A parameter is wrong. Pass `sym`, one symbol or a comma list. |
| 401 | `no_key`, `bad_key` | No key, or an unknown or revoked one. Send `Authorization: Bearer <key>` with a key of the product's scope. |
| 403 | `live_required`, `history_too_old` | No LIVE plan, or a day older than 90 days without DATASET. Start or renew LIVE; `pricing` names the page. |
| 404 | `unknown_symbol`, `no_data`, `no_basis`, `contract_not_live` | No such symbol, or no series for that day. Pick one from `GET /api/v1/symbols`. |
| 429 | `rate_limited`, `too_many_places` | Over a limit. Wait `Retry-After` seconds; poll with `If-None-Match`, a 304 is free. |

## 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.

## Request

```sh
curl \
  -H "Authorization: Bearer $FIRMTAPE_LIVE_KEY" \
  "https://firmtape.com/api/v1/history?sym=SPX"
```

```python
import os, requests

H = {"Authorization": f"Bearer {os.environ['FIRMTAPE_LIVE_KEY']}"}
r = requests.get("https://firmtape.com/api/v1/history?sym=SPX", headers=H)
print(r.status_code, r.text[:500])
```

```js
const r = await fetch("https://firmtape.com/api/v1/history?sym=SPX", {
  method: "GET",
  headers: { Authorization: `Bearer ${process.env.FIRMTAPE_LIVE_KEY}` },
});
console.log(r.status, await r.text());
```

## Example response

```json
{
  "sym": "SPX",
  "day": "2026-09-30",
  "book": "volume",
  "step": "10s",
  "unit": "usd_m_per_point",
  "unit_text": "millions of USD of dealer gamma per 1 index point",
  "columns": [
    "t",
    "price",
    "flip",
    "call_wall",
    "put_wall",
    "net_gamma"
  ],
  "rows": [
    [
      "09:30:09",
      6712.4,
      6692,
      6742,
      6662,
      -812.4
    ],
    [
      "09:30:19",
      6713.1,
      6692,
      6742,
      6662,
      -790.2
    ]
  ]
}
```

## Changes

- 2026-10-05: The last 90 days for an account key; older days answer `history_too_old` unless the account holds DATASET.
- 2026-09-30: Added.
