# Replay — every snapshot in a window (up to 15 minutes, 5 symbols)

`GET https://api.skylit.ai/v1/historical/range`

API: Heatseeker. Credits: 25.

Every snapshot between `from` and `to` (inclusive) for up to 5
symbols, at the stored resolution — one per second where 1-second
history exists (`meta.resolution: "1s"`), otherwise one per minute.
Each frame's `values[i]` is the net exposure at
`axes[frame.axis].strikes[i]`, summed over that axis's expirations —
the same number `/v1/historical` reports as `strikes[i].value` for
that instant. Axes are listed once and referenced by id; a new axis
appears only when the visible strikes or expirations change (the
strike window follows spot). Plain JSON numbers; responses are
gzip-compressed when the request sends `Accept-Encoding: gzip`.

**Cost:** 25 credits per call.

## Authentication

Send your Skylit API key as a bearer token: `Authorization: Bearer <key>`. No other header is accepted.

## Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `symbols` | query | string | yes | One ticker, or a comma-separated list for a single cross-asset call (e.g. `SPY` or `SPY,SPX,QQQ`). Each is returned as an element of `data.symbols`. At most 10 distinct symbols (more → `400` `invalid_parameter`). Unknown symbols in a list are omitted; if none is available → `404` `symbol_not_found`. |
| `from` | query | string (date-time) | yes | RFC3339 start of the window (inclusive). Up to 365 days back. |
| `to` | query | string (date-time) | yes | RFC3339 end of the window (inclusive). At most 15 minutes after `from`, not in the future. |
| `metric` | query | string | no | Which Greek exposure to return per strike. (one of `gamma`, `vanna`; default `gamma`) |
| `maxStrikes` | query |  | no | Maximum number of strikes around spot to return: an integer from 1 to 1000, or `all` for every strike the snapshot lists (SPXW lists about 730). Values above 1000 return `400 invalid_parameter`; they are never silently reduced. Values below 1 are treated as 1. The single-symbol stream (`/v1/stream?symbol=`) accepts at most 400 and no `all`. (default `92`) |
| `maxExpirations` | query |  | no | How many of the nearest expirations to net into each strike's `value`: an integer from 1 to 60, or `all`. Values above 60 return `400 invalid_parameter`. Ignored when `expirations` is set. (default `5`) |
| `expirations` | query | string | no | Net each strike over exactly these expirations (`YYYY-MM-DD`, comma-separated) — one for a single-expiration heatmap (`2026-05-22`) or several for a custom set (`2026-05-22,2026-06-19`). Supersedes `maxExpirations`, and reaches any expiration the snapshot has, not just the nearest ones. Requested dates the symbol does not have are ignored; the `expirations` array in the response lists what was actually used. If none of them match, the response is `404` with `code: expiration_not_found` and the available dates in the message. On `/v1/heatmap`, expirations that have already expired are not available (they are trimmed from the live snapshot) — replay them with `/v1/historical` instead. |

## Example request

```bash
curl "https://api.skylit.ai/v1/historical/range?symbols=SPY,SPX,QQQ&from=<from>&to=<to>" \
  -H "Authorization: Bearer $SKYLIT_API_KEY"
```

## Responses

### 200

Every snapshot in the window, per symbol.

SPY, two seconds (truncated):

```json
{
  "data": {
    "from": "2026-03-05T14:30:00Z",
    "to": "2026-03-05T14:30:01Z",
    "symbols": [
      {
        "symbol": "SPY",
        "axes": [
          {
            "id": 0,
            "strikes": [
              510,
              512,
              515
            ],
            "expirations": [
              "2026-03-05",
              "2026-03-06"
            ]
          }
        ],
        "frames": [
          {
            "asOf": "2026-03-05T14:30:00.000Z",
            "axis": 0,
            "spot": 512.4,
            "previousClose": 510.02,
            "values": [
              88010,
              1500200,
              410000
            ]
          },
          {
            "asOf": "2026-03-05T14:30:01.000Z",
            "axis": 0,
            "spot": 512.43,
            "previousClose": 510.02,
            "values": [
              87120.5,
              1502113.2,
              409877.1
            ]
          }
        ]
      }
    ]
  },
  "meta": {
    "metric": "gamma",
    "resolution": "1s",
    "mode": "historical",
    "cached": false
  }
}
```

### 400

Request validation failed.

### 401

Missing API key (`unauthorized`), sent by the gateway.

### 403

Unknown, revoked or expired key (`forbidden`, from the gateway), or an
admin-suspended account (`account_suspended`).

### 404

Unknown symbol, no data available, or none of the requested
`expirations` exist for the symbol (`code: expiration_not_found`).

### 429

Per-minute rate limit exceeded.

Headers: `Retry-After`.

### 503

Heatmap data is temporarily unavailable.
