# nLight.fit API versioning and deprecation

A client — especially an automated one — needs to know two things before it commits to an integration: which version it is talking to, and how it would find out that version is going away. Both are answered by response headers, so neither requires reading this page at runtime.

## Which version answered

Every response carries the version that served it.

```http
Api-Version: 2026-08-22
```

The version is a date rather than a number. The API is additive: new actions, tools and fields appear without a version change, because adding something breaks nothing. The date advances only when a change would break a client that was written against the previous behaviour, and it names the day that change took effect.

A `/api/v1/*` alias exists for tooling that insists on a path segment — `POST /api/v1/mcp` reaches the same handler as `POST /api/mcp`. It is a convenience, not a second version; there is no second version to reach.

## What counts as breaking

Treated as breaking, and therefore version-advancing:

- Removing an endpoint, an `action` value, or an MCP tool.
- Removing a field from a response, or changing its type.
- Making a previously optional request field required.
- Narrowing what an existing field will accept.
- Changing an authentication or scope requirement.

Not treated as breaking, and shipped without notice:

- Adding an endpoint, an action, a tool or a response field.
- Adding an optional request parameter.
- Widening what a field accepts.
- Changing the *content* of a computed value — a correlation strengthening, a summary being rewritten. The shape is the contract; the numbers are the product.

MCP protocol revisions are negotiated separately and are not covered by this policy. The server states which revisions it speaks, and refuses anything else with the supported list attached. See [errors and limits](/docs/errors).

## How deprecation is signalled

Deprecation happens in two stages, and each has its own header.

**Stage one: deprecated but working.** The endpoint still responds exactly as before. It gains an [RFC 9745](https://www.rfc-editor.org/rfc/rfc9745.html) `Deprecation` header carrying the moment deprecation began, and a `Link` pointing here.

```http
Deprecation: @1788134399
Link: <https://nlight.fit/docs/versioning>; rel="deprecation"; type="text/html"
```

The value is a structured-field date: `@` followed by whole seconds since the Unix epoch. `@1788134399` is 2026-08-22.

**Stage two: a retirement date is fixed.** A [RFC 8594](https://www.rfc-editor.org/rfc/rfc8594.html) `Sunset` header is added, giving the moment the endpoint stops responding. It uses the older HTTP-date format — the two headers deliberately differ, and RFC 9745 says so explicitly.

```http
Deprecation: @1788134399
Sunset: Sun, 20 Feb 2027 23:59:59 GMT
Link: <https://nlight.fit/docs/versioning>; rel="deprecation"; type="text/html"
```

Where a replacement exists, it is named too:

```http
Link: <https://nlight.fit/api/successor>; rel="successor-version"
```

The sunset date is never earlier than the deprecation date.

## The notice you get

- **At least 90 days** between the `Deprecation` header first appearing and the `Sunset` header naming a date.
- **At least 180 days** between a `Sunset` date being published and the endpoint ceasing to respond.

Nothing is removed without both headers having been served first. If you have not seen a `Deprecation` header on an endpoint, it is not going away in the next 180 days.

Every deprecation is also recorded in the [changelog](/docs/changelog), and the machine-readable version of this policy is in the `x-deprecation-policy` block of the [OpenAPI document](https://nlight.fit/openapi.json).

## Reading the headers

Both `Deprecation` and `Sunset` are listed in `Access-Control-Expose-Headers`, so a browser-based client can read them cross-origin. A client that wants to notice deprecation without polling this page should check for the presence of `Deprecation` on any response and surface it.

## Nothing is deprecated today

As of `2026-08-22`, no endpoint, action or tool carries a `Deprecation` header. The mechanism above is in place so that when something is deprecated, the signal is already something clients are reading — a policy announced at the same moment as the first deprecation is a policy nobody had time to act on.
