---
title: "Put/call ratio history (20-year stitched series)"
method: GET
path: "/api/v1/cboe/put-call-ratio/history"
tags: ["Finance"]
---

# Put/call ratio history (20-year stitched series)

`GET /api/v1/cboe/put-call-ratio/history`

EXCHANGE-WIDE daily put/call series per family (total, index, equity, etp, vix, spx), stitched from the frozen ratio archives (from 2006; spx from 2010) and the daily statistics feed (2019-10-07 onward). Dated definition edges are declared in definition_changes; response coverage (incl. any live-tail gap) is machine-readable in 'coverage'. Open-interest legs exist from 2019-10-07 only - the archive era is volume-only, declared null. Rules: rows filtered by [start, end]; dates after the committed dataset come from a bounded live tail; 'limit' keeps the NEWEST rows and sets truncated=true.

## Query parameters

- `family` string, required — Series family.
- `start` string, nullable — First date (YYYY-MM-DD), inclusive.
- `end` string, nullable — Last date (YYYY-MM-DD), inclusive.
- `limit` integer, nullable — Keep only the newest N rows after filtering.

## Response `200`

Ascending daily put/call rows for one family.

- EnvelopePutCallHistoryData
  - `data` PutCallHistoryData, required
    - `family` string, required — Series family: total, index, equity, etp, vix, spx.
    - `available_from` string, nullable — First date this family's series carries (measured archive start).
    - `dataset_end` string, nullable — Last date in the committed dataset.
    - `definition_changes` PutCallDefinitionChangeV1[] — Dated series-definition edges (category splits, source stitch) - the series is continuous in dates but not necessarily in definition across these.
      - `date` string, required — Effective date of the series definition change (YYYY-MM-DD).
      - `note` string, required — What changed in the series definition on that date.
    - `coverage` PutCallCoverageV1
      - `dataset_end` string, nullable — Last date served from the committed dataset; later rows come from the bounded live tail.
      - `gap_from` string, nullable — First trading day NOT served because the live-tail budget was exceeded (null when the series is complete).
      - `gap_to` string, nullable — Last trading day not served (see gap_from).
      - `tail_error` boolean — True when the live tail aborted on an upstream failure; rows end at the last healthy day.
    - `truncated` boolean — True when 'limit' cut earlier rows off the response.
    - `count` integer, required — Rows returned.
    - `rows` PutCallHistoryRowV1[] — Ascending daily rows.
      - `date` string, required — Trading session (YYYY-MM-DD).
      - `ratio` number, nullable — Published put/call ratio. Null when undefined (no volume, or no call leg).
      - `call_volume` integer, nullable — Call-leg session volume.
      - `put_volume` integer, nullable — Put-leg session volume.
      - `total_volume` integer, nullable — Total session volume.
      - `call_open_interest` integer, nullable — Call-leg open interest. Null across the archive era (pre 2019-10-07) - the frozen archives carry volume only.
      - `put_open_interest` integer, nullable — Put-leg open interest (see call_open_interest).
      - `total_open_interest` integer, nullable — Total open interest (see call_open_interest).
  - `meta` SugraMeta, required — Metadata attached to every /api/v1/* response envelope.
    - `endpoint` string, required — Requested endpoint path.
    - `data_time` string, required — ISO 8601 UTC timestamp of the source data, not of the request.
    - `response_time` string, required — ISO 8601 UTC timestamp when this response was produced.
    - `provider` string, required — API name and version.
    - `source` string, nullable — Identifier of the primary upstream source used for this response.
    - `attribution` string, nullable — Human-readable attribution mandated by an upstream source (e.g. a securities regulator or self-regulatory organization). Present only on responses whose source requires the owner and source to be clearly identified. Do not remove or alter it when using the response.
    - `fallback_used` boolean, nullable — True when the primary source failed and a fallback produced the data.
    - `fallback_chain` string[], nullable — Ordered list of sources attempted, in the order they were tried.
    - `cached` boolean, nullable — True when this response was served from the internal cache.
    - `stale` boolean, nullable — True when the cached response was returned after the upstream rate-limited or errored. Clients can use this to detect degraded data.

## Other responses

- `401` — Missing or invalid `x-api-key` header. JSON body with a stable `code` distinguishing `missing_api_key` (no header sent) from `invalid_api_key` (header sent, key not accepted); any other 401 source carries the generic `unauthorized` with its detail as `reason`. Plus `hint`. `plan` is always null on 401 - an unauthenticated request has no plan; quota exhaustion is 429, not 401.
- `422` — Validation Error
- `429` — Daily rate limit exceeded. Check `X-RateLimit-Reset` for the next window.
- `503` — Upstream source is temporarily unavailable. Retry after a short delay.

---

[API](https://skmtc.net/sugra/apis/sugra-api.md) · [All operations](https://skmtc.net/sugra/apis/sugra-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/sugra/sugra-api/revisions/a83e6a561bf2/schema)
