# API & GraphQL 1.x compatibility

Source: https://docs.externa.qiick.io/docs/api-compatibility

This page is the **contract for API consumers** of Externa **1.x**: Public CMS REST (`/api/v1`) and GraphQL (`/api/graphql`). Package semver follows the same spirit (Release process / issue #22).

> **Related**
> [Public CMS API](/docs/public-cms-api) · [GraphQL](/docs/graphql) · [Public CMS API types](/docs/public-cms-api-types) · [`CHANGELOG.md`](https://github.com/qiick-io/externa-core/blob/develop/CHANGELOG.md) (once present)

## Versioning surface

| Surface            | Stability in 1.x                                                                                              |
| ------------------ | ------------------------------------------------------------------------------------------------------------- |
| **`/api/v1/*`**    | Stable base path for the entire 1.x line. No `/api/v2` required for compatible evolution.                     |
| **`/api/graphql`** | Same auth, collection guards, and field ACL as REST. Schema evolves under the rules below.                    |
| Auth               | Anonymous via `public` role matrix, or `Authorization: Bearer ek_…` API keys bound to a non–super-admin role. |

Admin session routes, Inertia props, and internal jobs are **not** covered by this public-API policy.

## What may change in a minor (1.y → 1.y+1)

**Additive** changes are allowed without a major bump:

- New REST endpoints under `/api/v1`
- New optional request/query fields (defaults preserve prior behaviour)
- New response fields (clients must ignore unknown keys)
- New GraphQL types, fields, arguments that are optional or additive
- New enum values where clients treat unknowns safely
- Performance / docs / non-contract bug fixes

## What requires deprecation or a major (2.0)

Treat as **breaking** (major release, or announced deprecation then removal):

- Removing or renaming REST paths, required fields, or response fields consumers rely on
- Changing auth semantics (how keys / `public` resolve) in an incompatible way
- Removing GraphQL fields/types/arguments without a deprecation window
- Tightening validation so previously valid requests fail (unless fixing a security hole — then document as security fix)

Security fixes that change behaviour may ship in a patch/minor with a clear CHANGELOG **Security** note.

## Deprecation window

1. Mark the behaviour deprecated in **CHANGELOG** (`Deprecated` section) and in this docs site.
2. Prefer keeping the old path/field working through at least **one minor** after announcement (longer when practical).
3. Optional later: response headers or GraphQL `@deprecated` directives — not required for 1.x start.
4. Removal happens in a **major** (or at end of the announced window called out in release notes).

## Auth & roles (unchanged intent)

- API keys never grant `super-admin`.
- Collection/file access still comes from the key’s role (or `public`) matrices — not Spatie admin permissions.
- See [Public CMS API](/docs/public-cms-api) for setup.

## Client guidance

- Pin to a documented Externa version for production.
- Tolerate additive JSON/GraphQL fields.
- Watch CHANGELOG + GitHub Releases when upgrading minors.
- Prefer Bruno collection / published types for contract smoke tests.

## Alignment with package semver

| Package bump | Typical API impact                                           |
| ------------ | ------------------------------------------------------------ |
| **Patch**    | Fixes; no intentional public contract break                  |
| **Minor**    | Additive API/GraphQL; deprecations may be announced          |
| **Major**    | Breaking removals/renames after (or with) deprecation notice |

App version lives in `composer.json` (mirrored in `package.json`). Release checklist: issue #22 / Releasing docs.
