# Versioning & deprecation

> How the REST API and MCP server are versioned, and how we signal deprecation.

## URL path versioning
Every REST endpoint lives under a major version prefix: `https://api.statshawk.ai/v1/…`.
The `/v1` contract is stable: within a major version we only make **additive** changes:

* new endpoints, new optional query parameters, new response fields
* new competitions, stat keys, or capability flags
* new error codes (existing codes keep their meaning)

Clients should ignore fields they do not recognize. Removing or renaming a field, changing a
type, or changing the meaning of a status code is a breaking change and only ships as a new
major version (`/v2/…`), served alongside `/v1` for the whole deprecation window.

> **Documented /v1 exception**
>
> The 2026-09-11 paid self-serve quota hard-stop changed at-cap metered `/v1` responses
>   from `200` to `429 QUOTA_EXCEEDED` without a new major version. See the
>   [changelog](/docs/changelog). Handle `QUOTA_EXCEEDED` on every metered route.

The MCP server follows the same rule: tool names and input schemas are stable; new tools
and optional arguments may be added at any time.

## Deprecation signals
When an endpoint, parameter, or tool is scheduled for removal we announce it three ways:

1. **Response headers** on the affected endpoint:
   * `Deprecation: @<unix-timestamp>`: the date the deprecation was announced (RFC 9745)
   * `Sunset: `: the earliest date the endpoint may stop responding (RFC 8594)
   * `Link: <https://statshawk.ai/docs/changelog>; rel="deprecation"`
2. **The [changelog](/docs/changelog)**: every deprecation has a dated entry naming the
   replacement.
3. **The OpenAPI description** at [`/openapi.json`](/openapi.json): deprecated operations
   and parameters carry `deprecated: true`.

## Timeline
| Change                                             | Minimum notice                                                                  |
| -------------------------------------------------- | ------------------------------------------------------------------------------- |
| Deprecating an endpoint, parameter, or MCP tool    | 90 days before `Sunset`                                                         |
| Retiring a major version (`/v1` after `/v2` ships) | 12 months, with `Sunset` on every `/v1` response                                |
| Security-driven changes                            | As fast as needed, announced in the changelog and by email to affected accounts |

During a deprecation window the old surface keeps working unchanged. Agents should watch
for the `Sunset` header and treat its presence as a prompt to migrate.

## Discovering the current spec
* OpenAPI 3.1: [`https://statshawk.ai/openapi.json`](/openapi.json) (also at
  `https://api.statshawk.ai/api-docs/openapi.json`)
* RFC 9727 API catalog: [`/.well-known/api-catalog`](/.well-known/api-catalog)
* MCP server card: [`/.well-known/mcp/server-card.json`](/.well-known/mcp/server-card.json)
