---
title: "Api V2 Market Spreads Series Get"
method: GET
path: "/api/v2/market/spreads/series"
tags: ["Market Data (v2)", "Beta (v2)"]
---

# Api V2 Market Spreads Series Get

`GET /api/v2/market/spreads/series`

## Request

- Base URL: `https://api.zerogex.io` (the document declares no server; this is the origin it was published from)
- URL: `https://api.zerogex.io/api/v2/market/spreads/series`
- Auth: HTTP bearer

How today's quoted widths moved through the session, puts against calls.

One reading per bucket, taken at the last chain snapshot inside it.
Calls and puts are returned separately and no blended row is computed:
the whole point of the series is the divergence between the two, and a
combined median reports roughly half of it.

**Beta** — contract may change.

## Query parameters

- `symbol` string: Underlying symbol
- `session` string: Trading session
- `bucket_minutes` integer: Bucket size in minutes
- `dte_max` integer
- `moneyness_band_pct` number

## Response `200`

Successful Response

- EnvelopeSpreadSeriesResponse
  - `data` SpreadSeriesResponse, required
    - `symbol` string, required
    - `session` string, required
    - `bucket_minutes` integer, required
    - `dte_max` integer, required
    - `moneyness_band_pct` number, required
    - `basis` string
    - `disclosure` string
    - `bars` SeriesBucket[], required
      - `bucket_start` string, date-time, required
      - `anchor_ts` string, date-time, required
      - `spot` number, required
      - `calls` SpreadAggregateModel: One population's quote quality. Widths are null when nothing is quoted.
        - `contract_count` integer, required
        - `tradable_count` integer, required
        - `two_sided_pct` number, required
        - `zero_bid_pct` number, required
        - `crossed_or_locked_pct` number, required
        - `no_quote_pct` number, required
        - `median_spread` number, nullable
        - `median_relative_spread_pct` number, nullable
        - `p90_relative_spread_pct` number, nullable
        - `median_spread_bps_underlying` number, nullable
        - `p90_spread_bps_underlying` number, nullable
        - `total_open_interest` integer
        - `total_volume` integer
      - `puts` SpreadAggregateModel: One population's quote quality. Widths are null when nothing is quoted.
        - `contract_count` integer, required
        - `tradable_count` integer, required
        - `two_sided_pct` number, required
        - `zero_bid_pct` number, required
        - `crossed_or_locked_pct` number, required
        - `no_quote_pct` number, required
        - `median_spread` number, nullable
        - `median_relative_spread_pct` number, nullable
        - `p90_relative_spread_pct` number, nullable
        - `median_spread_bps_underlying` number, nullable
        - `p90_spread_bps_underlying` number, nullable
        - `total_open_interest` integer
        - `total_volume` integer
  - `freshness` Freshness, required: The v2 freshness envelope. Present on every ``/api/v2/*`` response.
    - `evaluated_at` string, date-time, required: When the API evaluated this response (server wall clock, UTC). Endpoint-health signal: advances on every request even when the underlying data is unchanged.
    - `generated_at` string, date-time, required: When the served data was computed. Equals the snapshot stamp for cycle-backed endpoints, or evaluated_at for endpoints computed on demand for this request.
    - `source_timestamp` string, date-time, nullable: Timestamp of the upstream market observation the payload derives from. This is what freshness_status is measured against. Null when the endpoint has no upstream feed or returned no rows.
    - `latest_event_at` string, date-time, nullable: Newest event timestamp present in the payload (last bar, last trade, last scored row). Best-effort on very large responses, which are sampled rather than fully walked.
    - `age_seconds` number, nullable: evaluated_at - source_timestamp, in seconds. Null when source_timestamp is null.
    - `market_session_status` string, required: pre-market | regular | after-hours | closed (US/Eastern).
    - `expected_update_cadence` string, nullable: ISO-8601 duration for how often this endpoint's data is expected to change right now, e.g. PT60S. Null means no updates are expected (weekend, holiday, or a feed that only runs during the session).
    - `expected_update_cadence_seconds` number, nullable: expected_update_cadence as a number of seconds.
    - `cadence_profile` string, required: Identifier of the cadence class this endpoint belongs to, e.g. analytics_cycle. Stable across releases; the seconds behind it may be retuned.
    - `stale_after` string, date-time, nullable: Instant after which this payload should be treated as stale. Null whenever expected_update_cadence is null.
    - `freshness_status` 'fresh' | 'aging' | 'stale' | 'session_closed' | 'static' | 'unknown', required: The rolled-up freshness verdict for one response. ``fresh`` ``source_timestamp`` is within one expected update cadence. ``aging`` Past one cadence but not yet past ``stale_after`` — the grace band that absorbs normal cycle jitter. Not an error; a client that polls faster than the cadence sees this routinely. ``stale`` Past ``stale_after`` while updates *were* expected. This is the actionable state: the feed behind this endpoint is late. ``session_closed`` A feed-backed endpoint whose feed is not due to produce anything right now (weekend, holiday, or a feed that only runs during the session). The payload is the last good value — deliberately NOT reported as ``stale``, because an overnight consumer polling a closed market is not observing a fault and should not page on it. ``static`` The endpoint is not feed-backed at all: completed history, or a result computed from the caller's own inputs. Age here carries no health meaning and never becomes a fault. ``unknown`` No source timestamp could be resolved from the payload (e.g. a pure calculator, an admin endpoint, or an empty result set). A consumer should fall back to ``evaluated_at`` for endpoint health and make no claim about data age.

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/zerogex/apis/zerogex-api.md) · [All operations](https://skmtc.dev/zerogex/apis/zerogex-api/llms.txt) · [OpenAPI document](https://skmtc.dev/zerogex/apis/zerogex-api/revisions/753b26bf0592?raw)
