> ## Documentation Index
> Fetch the complete documentation index at: https://docs.chataigne.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Versioning

> How the Chataigne API uses path-based major versions, what counts as additive vs. breaking, and how breaking changes are rolled out.

The Chataigne API is versioned in the URL path. The current major version is `v1`, and it
applies to both API surfaces:

* **Chataigne API** — `https://server.chataigne.ai/v1`
* **Admin API** — `https://server.chataigne.ai/admin/v1`

We make a clear, enforceable promise: **additive changes ship continuously within a major
version and never break your integration. Breaking changes only ever ship behind a new major
version** (`/v2`, `/v3`, …). You upgrade by changing one segment of the URL — on your schedule,
not ours.

<Note>
  There is no `x-api-version` header and no per-account "API version" pin. The version is the
  path. The URL you call is the contract you get.
</Note>

## The version is in the path

Every request targets an explicit major version. Pin it in your base URL and you are insulated
from breaking changes for the life of that version.

<CodeGroup>
  ```bash curl theme={null}
  curl https://server.chataigne.ai/v1/locations/loc_8sJ2kQ \
    -H "x-api-key: ch_org_live_3kQ9xV..."
  ```

  ```js Node.js theme={null}
  const BASE_URL = "https://server.chataigne.ai/v1";

  const res = await fetch(`${BASE_URL}/locations/loc_8sJ2kQ`, {
    headers: { "x-api-key": process.env.CHATAIGNE_API_KEY },
  });
  const location = await res.json();
  ```
</CodeGroup>

<Warning>
  Always include the version segment. There is no unversioned root and no "latest" alias —
  calling `https://server.chataigne.ai/locations` (without `/v1`) is not a supported endpoint.
</Warning>

## What's additive (non-breaking)

Additive changes can land at any time within `v1` without notice. Your integration must tolerate
them. The following are **non-breaking** and will roll out continuously:

* **Adding new endpoints, resources, or HTTP methods** on existing resources.
* **Adding new optional fields** to a response object (e.g. a new property on a `location`).
* **Adding new optional request parameters** that default to today's behavior when omitted.
* **Adding new values** to an existing field that is documented as open-ended (e.g. a new
  `currency` or `country` becoming supported).
* **Adding new expandable fields** for `expand[]`.
* **Adding new error `code` values** within an existing error `type`.
* **Adding new response headers**, or new properties to the `error` object such as `details`.
* **Making a previously required request parameter optional**, or relaxing a validation rule.

<Note>
  **Write forward-compatible clients.** Ignore fields you don't recognize, don't fail on
  unknown enum values, and don't assume the set of keys in a response is fixed. A client that
  follows these rules will never break on an additive change.
</Note>

This is why, for example, a `location` response may gain fields over time. Today it returns
`id`, `object`, `name`, `currency`, `country`, `timezone`, `default_language`, `address`,
`created_at`, and `updated_at` — but your code should read the fields it needs and pass the rest
through untouched.

```json Example: a location response may grow over time theme={null}
{
  "id": "loc_8sJ2kQ",
  "object": "location",
  "organization_id": "org_4Tn1wD",
  "name": "Pizzeria Centrale",
  "currency": "CHF",
  "country": "CH",
  "timezone": "Europe/Zurich",
  "default_language": "fr",
  "address": {
    "line1": "Bahnhofstrasse 1",
    "line2": null,
    "postal_code": "8001",
    "city": "Zürich",
    "country": "CH",
    "latitude": 47.3769,
    "longitude": 8.5417
  },
  "created_at": "2026-01-12T09:30:00Z",
  "updated_at": "2026-05-20T14:02:11Z"
}
```

## What's breaking

A change is **breaking** if a correct, well-behaved client could stop working because of it.
Breaking changes are **never** made in place within `v1`. They are only introduced in a new
major version. These include:

* **Removing or renaming** an endpoint, resource, field, or `expand[]` target.
* **Removing or repurposing** an existing field's meaning, type, or format.
* **Adding a new required request parameter**, or tightening validation on existing input.
* **Changing default values** or the default behavior of an endpoint.
* **Changing pagination, filtering, or default ordering** semantics (e.g. the `limit`
  bounds of `1..100`, the default of `10`, or the default sort by `created_at`).
* **Changing the structure of the list envelope** (`object`, `data`, `has_more`, `url`).
* **Changing an error `type` → HTTP status mapping** (e.g. moving a case from `409` to `400`).
* **Removing or repurposing a documented response header.**
* **Changing the authentication or authorization model** of a surface — for example, which key
  prefix (`ch_org_` vs. `ch_admin_`) is accepted on which surface.

<Warning>
  The surface security boundary is part of the contract and will not change within a major
  version: `/v1` rejects admin keys with `403`, `/admin/v1` rejects org keys with `403`, a
  missing key returns `401`, and dashboard sessions are never accepted on either surface.
</Warning>

## How breaking changes are rolled out

When we need to make a breaking change, we ship a new major version path and run both versions
in parallel. The rollout is deliberate and predictable:

<Card title="1. Announce" icon="megaphone">
  The new version, its breaking changes, and a migration guide are published in the
  [Changelog](/changelog) before it becomes the recommended version.
</Card>

<Card title="2. Run in parallel" icon="arrows-split-up-and-left">
  The previous version keeps working at its existing path. `v1` and `v2` are served side by
  side — no flag day, no forced cutover.
</Card>

<Card title="3. Migrate on your schedule" icon="route">
  You upgrade by changing the path segment in your base URL and adapting to the documented
  breaking changes. Test against the new version while production stays on the old one.
</Card>

<Card title="4. Deprecate with notice" icon="clock">
  When an old version is eventually retired, we communicate the timeline well in advance via
  the Changelog. Until then, the version you pinned keeps behaving exactly as it does today.
</Card>

Upgrading is a one-line change:

<CodeGroup>
  ```bash curl theme={null}
  # Before
  curl https://server.chataigne.ai/v1/organizations/org_4Tn1wD \
    -H "x-api-key: ch_org_live_3kQ9xV..."

  # After (hypothetical future major version)
  curl https://server.chataigne.ai/v2/organizations/org_4Tn1wD \
    -H "x-api-key: ch_org_live_3kQ9xV..."
  ```

  ```js Node.js theme={null}
  // Pin the version in one place so upgrades are a single edit.
  const API_VERSION = "v1"; // bump to "v2" when you're ready to migrate
  const BASE_URL = `https://server.chataigne.ai/${API_VERSION}`;

  const res = await fetch(`${BASE_URL}/organizations/org_4Tn1wD`, {
    headers: { "x-api-key": process.env.CHATAIGNE_API_KEY },
  });
  ```
</CodeGroup>

## Building a version-resilient integration

A few habits keep your integration stable across the entire life of a major version:

<ResponseField name="Pin the version explicitly" type="required">
  Hardcode `/v1` (ideally via a single constant). Never rely on a default or "latest" path.
</ResponseField>

<ResponseField name="Tolerate unknown fields" type="required">
  Parse the fields you use and ignore the rest. New optional fields will appear over time.
</ResponseField>

<ResponseField name="Don't hard-fail on new enum values" type="required">
  Treat fields like `currency`, `country`, and error `code` as extensible. Handle the values
  you know and degrade gracefully on the ones you don't.
</ResponseField>

<ResponseField name="Key off error `type`, not just status" type="recommended">
  Branch on the stable `error.type` (e.g. `rate_limit_error`) rather than parsing
  `error.message`, which is human-readable and may be reworded within a version.
</ResponseField>

<ResponseField name="Log the request ID" type="recommended">
  Capture `X-Request-Id` (mirrored as `error.request_id`) so version-related issues are fast to
  diagnose with support.
</ResponseField>

<Note>
  Subscribe to the [Changelog](/changelog) — it is the single source of truth for both additive
  changes shipped to `v1` and any future major-version announcements.
</Note>
