# Versioning

What /v1 guarantees, how additive changes are signalled

The public API lives under `/v1`. Anything outside that prefix is internal — the
dashboard's own cookie-session routes, tracking redirects, hosted pages — and is not a
contract. It is left out of the reference precisely so it cannot be mistaken for
one.

## What `/v1` guarantees

While `/v1` exists, none of the following will change:

- A path or HTTP method is not removed or repurposed.
- A field is not removed from a response, nor its type narrowed.
- A request field that was optional does not become required.
- An `operationId` does not change. These are the stable identifiers for issues,
  changelogs and reference pages, so renaming one breaks inbound links.
- An error `code` does not change meaning, and a code is not removed.
- The response envelope (`data` / `meta` / `error`) does not change shape.
- Pagination stays cursor-based.

## What can change without notice

These are **additive** and a client must tolerate them:

- **New endpoints and new tags.**
- **New fields in responses.** Do not use strict deserialization that fails on unknown
  fields — this is the single most common way an SDK breaks on a routine release.
- **New optional request fields.**
- **New values in an enum**, including new error codes. Handle an unrecognised `code` by
  falling back to a generic error carrying the raw string rather than throwing.
- **New webhook event types**, which a `*` subscription will begin receiving.
- **Wording of `message` fields and documentation prose.** Branch on `code`, never on
  `message`.

Rate limits, and the exact numbers behind them, are deployment configuration rather than
contract. Read `Retry-After`.

## Explicitly not contract

- The **cursor format**. Opaque; see [Pagination](/docs/api/pagination).
- The **key format** beyond the `kirora_` prefix.
- Field **ordering** in JSON objects.
- Anything reachable only outside `/v1`.

## How a breaking change would happen

By introducing `/v2` alongside `/v1`, not by changing `/v1` underneath its users. Both
would run during a migration window announced in advance, following the approach Segment
took when their Public API superseded the Config API — the old surface stopped taking new
users rather than changing behaviour for existing ones.

Per-endpoint stability labels (stable / beta / alpha), so that a new endpoint can evolve
without waiting for a whole major version, are planned but not yet in the reference. Until they
appear, treat every published operation as stable.

## Building a client that survives releases

1. **Deserialize permissively.** Ignore unknown fields; never fail on them.
2. **Treat enums as open.** A future `status` or `code` value must not crash a client.
3. **Take API changes deliberately.** Read the changelog before upgrading a client, so a
   contract change is something you review.
4. **Do not depend on field order, cursor contents, or message wording.**
5. **Make the base URL configurable**, so tests can point at a mock server.

## Next steps

- [Errors](/docs/api/errors) — treat unknown codes as open
- [Pagination](/docs/api/pagination) — cursors are opaque
- [Webhooks](/docs/api/webhooks) — event payloads and what may be added
- [SDK conformance](/docs/api/sdk-conformance) — the checklist for a client that survives releases