# API Lifecycle

The MakeFX REST API uses an explicit major-version contract without putting the
version in the URL. Its production OpenAPI description is available at
[https://makefx.app/api/openapi.json](https://makefx.app/api/openapi.json).

## Current version and negotiation

The current REST major version is `1`. Existing `/api/...` paths remain stable;
there is no `/v1` path prefix.

Clients may send this request header on documented REST operations:

```http
MakeFX-API-Version: 1
```

The header is optional. Omitting it selects v1 for backward compatibility, and
sending exactly `1` has identical behavior. A present value is rejected when it
is unsupported or malformed, including an empty value, surrounding-only
whitespace, a repeated or comma-joined value, `v1`, or a dotted value such as
`1.0`.

Rejection happens before authentication, request validation, and operation side
effects. The response is a bounded JSON error with HTTP status `400`:

```json
{
  "error": "unsupported_api_version",
  "error_description": "MakeFX-API-Version must be exactly 1 when provided.",
  "resolution_url": "https://makefx.app/docs/api-lifecycle"
}
```

This version header applies only to the documented external REST operations.
OAuth protocol endpoints, the hosted MCP transport, webhooks, metadata
endpoints, and public documents keep their separate contracts.

## Compatibility

Additive changes that preserve existing request and response meaning remain in
v1. Examples include a new optional request field, a new operation, or a new
response field that clients are expected to ignore when unknown.

A change that breaks conforming v1 clients requires a newly supported major
version. Examples include removing or renaming a field or operation, making an
optional input required, changing a field's type or meaning, or changing
established status-code semantics. The lifecycle document and OpenAPI document
will identify supported majors before clients can select a new one.

## Deprecation and sunset

No REST operation is currently deprecated. When an operation is deprecated,
its responses will carry the standards-based lifecycle signals below rather
than relying on an undocumented announcement:

- `Deprecation` using RFC 9745;
- `Sunset` using RFC 8594 when a removal date is scheduled;
- `Link: <policy-url>; rel="deprecation"` pointing to migration guidance.

Deprecation does not itself remove v1 behavior. A scheduled sunset will be
published with migration guidance, and a breaking replacement will use a new
major version.

## Enforced rate limits

Rate-limit headers describe only a limiter that actually evaluated the request.
MakeFX does not attach them to authentication failures, static metadata,
cacheable documents, or endpoints without an enforced limiter.

Generation admission for Variant regeneration and forced audio alignment has a
fixed-window limiter. An admitted `202` response includes `RateLimit-Policy` and
`RateLimit`. A denied `429` response also includes `Retry-After`, in seconds.
The two `RateLimit` fields use IETF Structured Field syntax and report the
enforced policy, quota, remaining allowance, window, and effective reset delay.

OAuth dynamic client registration at `/api/oauth/register` has a separate
fixed-window policy. Evaluated registration responses include
`RateLimit-Policy` and `RateLimit`; a limit denial also includes `Retry-After`.
That OAuth boundary is independent from generation admission and is not part of
REST version negotiation.

Clients should treat the returned policy and timing values as authoritative,
wait at least `Retry-After` seconds after a `429`, and avoid assuming a global
or public unauthenticated API quota where no limiter is enforced.
