API Versioning Policy
The authoritative copy of this document lives at docs/api/versioning.md.
# API Versioning Policy
**Owner:** InsuredAudit Platform Team
**Status:** Effective 2026-05-23
**Applies to:** `api.insuredaudit.com/v1` and all future major versions.
This document is the contract between the platform and its consumers. It
explains how versions are numbered, how long old versions live, how breaking
changes are introduced, and how to read a deprecation header.
---
## 1. What "version" means
The platform exposes a single REST surface. The version is a **major number**
embedded in the URL path: `/v1/...`. Today, `v1` is the only version. When
the platform needs to ship a breaking change, a parallel `/v2/...` surface
will be introduced; `v1` will continue to serve traffic with a
`Deprecation: ...` header until the removal date.
There is **no minor or patch version in the URL**. Non-breaking additions
land on the current major. We use a separate `X-API-Version` response header
to communicate the server's running build, useful for debugging and for
client-side feature detection.
## 2. What counts as a breaking change
The following changes require a new major version:
| Change | Breaking? |
| ------------------------------------------------------------------- | --------- |
| Removing or renaming a route | **Yes** |
| Removing or renaming a request/response field | **Yes** |
| Changing a field's type (e.g. string → integer) | **Yes** |
| Tightening validation (a previously-accepted payload becomes invalid) | **Yes** |
| Changing the semantic meaning of an existing field | **Yes** |
| Changing an HTTP status code for a given outcome | **Yes** |
| Removing a value from an enum that the API returns | **Yes** |
| Adding a required field to a request body | **Yes** |
| Changing the order or shape of `Authorization` / scope semantics | **Yes** |
The following are **non-breaking** and may land on the current major:
| Change | Breaking? |
| ------------------------------------------------------------------- | --------- |
| Adding a new route | No |
| Adding a new optional request field | No |
| Adding a new field to a response object | No |
| Adding a new value to an enum that clients send (but not receive) | No |
| Adding new error codes (kept under the same HTTP status) | No |
| Loosening validation | No |
| Performance / latency improvements | No |
Clients **must** tolerate unknown response fields and **must not** depend on
field ordering. Treat the response shape as an open record.
## 3. Lifecycle of a major version
```
┌──────────────────────────────────────────────┐
v1 launch v2 launch v1 deprecation v1 removal
────●─────────────●─────────────────────●─────────────────────────────●─────►
│ │
│←─────── ≥ 18 months ───────→ │
│ │
Deprecation: 410 Gone
Sunset: <date>
response header
```
When a new major launches, the old major enters **deprecation**:
1. Every response on the old major includes a `Deprecation: true` header
(RFC 9745), and a `Sunset: <RFC 1123 date>` header with the planned
removal date.
2. The deprecation window is **at least 18 months** from the day `v2`
becomes generally available.
3. During the window, the platform commits to security patches and bug
fixes on the old major, but does **not** ship new functionality there.
4. After the sunset date passes, the old major is removed: requests return
`410 Gone` with body
`{"error":{"code":"VERSION_REMOVED","message":"v1 was removed on YYYY-MM-DD; see https://docs.insuredaudit.com/api/versioning"}}`.
## 4. How to opt into a new major
A new major version has its own base path. Clients update their `baseUrl`:
```
https://api.insuredaudit.com/v1/... → https://api.insuredaudit.com/v2/...
```
The official SDKs ship a parallel namespace per major. With `@creb/sdk`:
```ts
import { CrebClientV1, CrebClientV2 } from "@creb/sdk";
```
Both clients can coexist in the same process. Cut-over is per-route; you do
not have to migrate every call site simultaneously.
## 5. Pre-release versions
Major versions may be previewed on a `vNext` path (e.g. `/vNext/...`)
before they get their stable number. `vNext` has **no stability guarantee**;
fields may change weekly. Use it only for prototyping. Pre-release paths
respond with header `X-API-Stability: preview` so accidental production
traffic can be detected.
## 6. Backporting
A breaking change discovered to be necessary for security or correctness
will be backported to the live major as a corrective release. We notify
customers in writing (status page + email) at least seven days in advance,
or immediately for critical security issues. Corrective releases are the
only path by which the rules in section 2 are violated; they are rare and
always documented in the changelog.
## 7. Changelog format
Every API change is recorded in `docs/api/CHANGELOG.md` and surfaced on
`https://docs.insuredaudit.com/changelog`. Entry format:
```markdown
## v1.4.0 — 2026-08-12
### Added (non-breaking)
- POST `/v1/rules/import` — bulk rule ingest from a manifest URL.
- New optional `metadata.tags` field on POST `/v1/documents`.
### Deprecated
- GET `/v1/search/documents` — superseded by POST `/v1/search/q` with
`domain: "documents"`. Sunset: 2028-02-12. Returns header
`Deprecation: true; Sunset: Fri, 12 Feb 2028 00:00:00 GMT` from this
release forward.
### Fixed
- `/v1/bundles/:id/download` now sets `Content-Disposition` to `attachment`
even when the request includes `?download=false` (the query parameter was
never documented; this change closes a confusing behavior).
```
## 8. Deprecation headers — examples
Single deprecated route:
```
HTTP/1.1 200 OK
Deprecation: true
Sunset: Fri, 12 Feb 2028 00:00:00 GMT
Link: <https://docs.insuredaudit.com/api/changelog#deprecate-search-documents>; rel="deprecation"
```
Deprecated query parameter on an otherwise-live route:
```
HTTP/1.1 200 OK
Deprecation: parameter; name="include_inactive"; sunset="Fri, 12 Feb 2028 00:00:00 GMT"
Link: <https://docs.insuredaudit.com/api/changelog#deprecate-include-inactive>; rel="deprecation"
```
Removed major version:
```
HTTP/1.1 410 Gone
Content-Type: application/json
{"error":{"code":"VERSION_REMOVED","message":"v1 was removed on 2028-02-12; migrate to /v2. See https://docs.insuredaudit.com/api/versioning"}}
```
## 9. SDK versioning
SDKs follow **semver**. Major versions of an SDK can move independently of
the API major they target — for example `@creb/sdk` 2.0.0 might still talk
to `/v1` while introducing breaking *client-side* changes (renamed methods,
restructured types). The SDK README always documents which API major(s) a
given SDK release supports.
## 10. Out-of-band changes
| Subsystem | Versioning approach |
| -------------------- | ------------------------------------------------ |
| Webhook event payloads | Same policy as the REST API. Breaking changes ship as a new event type (e.g. `bundle.sealed.v2`) running in parallel for 18 months. |
| Bundle ZIP layout | Versioned in `manifest.json` under `bundle_schema_version`. Old layouts remain readable forever — bundles are signed, immutable artifacts. |
| Database migrations | Internal; do not affect the public API contract. |
| WORM blob hashes | Never change. SHA-256 is locked in for the lifetime of the platform. |
## 11. How to get notified
- **Email:** every tenant admin gets a deprecation email on `v2` GA and on
each sunset date.
- **Webhook:** subscribe to event type `platform.deprecation` to be notified
when a deprecation announcement is published.
- **Changelog:** https://docs.insuredaudit.com/changelog (RSS / Atom feed
forthcoming).
- **Status page:** https://status.insuredaudit.com — incidents and planned
maintenance, including the day-of cut-over of a removed version.
## 12. Questions
Email `[email protected]` or file an issue on the public docs repo.
For contract-level questions about a specific tenant's deprecation window,
your account manager has the authority to negotiate an extension up to an
additional 6 months at customer request.
