*REST API › Guides*

# Versioning and deprecation

> Within v1 Filmo only adds things. Anything that could break your integration is announced first, either as a new major version or as a deprecation with at least six months before the sunset.

## The contract version

The contract version follows semver and appears in `info.version` in the OpenAPI file. [`GET /api/v1/account`](https://docs.filmo.io/rest-api/endpoint-reference/account/get-the-account) returns it too. Use that version to identify the contract your integration uses. See also the [OpenAPI reference](https://docs.filmo.io/rest-api/openapi).

## Compatibility policy

| Change | Within v1 | How it reaches you |
| --- | --- | --- |
| A new operation; a new optional request field, filter or parameter | Additive: allowed | Ships in any release without prior notice. Recorded in the changelog with the version it arrived in. |
| A new property in a response; a new value in a response union (a status, a kind) | Additive: allowed | Same as above. |
| A looser validation | Additive: allowed | Same as above. |
| Removing or renaming an operation, a field or a parameter; changing a type; making a response property nullable | Breaking | Only under a new major version, or through deprecation with notice. |
| Tightening a validation; changing the scope an operation requires | Breaking | Same as above. |
| Removing a field | Never within a major version | A field that stops making sense is marked deprecated in its schema and recorded in the changelog. It is removed only in the next major version. |

Fields with business-sensitive data (costs, margins, access codes, internal tax documents, staff payroll and personal data) are excluded by design from the public edge. They are not part of v1 today, so do not plan an integration around them.

## How a deprecation reaches you

A breaking change is made in exactly one of two ways.

- Under a new major version, `/api/v2`. Filmo keeps v1 running for at least twelve months after v2 is announced.
- Through deprecation with notice. The operation is marked `deprecated` in the OpenAPI file, with an `x-deprecation` object that carries `since` (the version that announced it), `on` (the day it takes effect), `sunset` (the day it disappears), `replacement` (optional) and a `note`. Days are `YYYY-MM-DD`.

A deprecated operation tells you in three places.

- Every response, error responses included, carries the `Deprecation` header (RFC 9745, a Unix timestamp prefixed with `@`) and the `Sunset` header (RFC 8594, an HTTP date).
- The same responses carry a `Link` header with two relations: `rel="deprecation"` and `rel="sunset"`, both pointing to the documentation.
- Every successful JSON body carries a `meta.warnings[]` entry with `code` set to `deprecated`, a `message`, the `sunset` day, the `replacement` (or `null` when there is none) and a `link` to the documentation.

The sunset day is at least 180 days (six months) after the day the deprecation takes effect. The operation keeps working until then and disappears on the sunset day: afterwards it answers 404 [`not_found`](https://docs.filmo.io/rest-api/errors/not_found), before the request is even authenticated, so a client that ignored the warnings sees a missing operation rather than an authorization error.

*Log deprecations in your HTTP client*

**Node**

```javascript
// Call this for every response you receive, with the parsed JSON body (or null).
export function noteDeprecation(method, path, res, body) {
  const deprecation = res.headers.get("Deprecation");
  const sunset = res.headers.get("Sunset");
  const warned = (body?.meta?.warnings ?? []).some((w) => w.code === "deprecated");
  if (deprecation || sunset || warned) {
    console.warn("Deprecated:", method, path, { deprecation, sunset });
  }
}
```

**Python**

```python
def note_deprecation(method, path, res, body):
    """Call for every response, with the parsed JSON body (or None)."""
    deprecation = res.headers.get("Deprecation")
    sunset = res.headers.get("Sunset")
    warnings = ((body or {}).get("meta") or {}).get("warnings") or []
    warned = any(w.get("code") == "deprecated" for w in warnings)
    if deprecation or sunset or warned:
        print("Deprecated:", method, path, {"deprecation": deprecation, "sunset": sunset})
```

## The changelog

Every release is recorded in the Changelog tab of these docs, in the Keep a Changelog format: a heading with the version and date (`[x.y.z] - YYYY-MM-DD`) and, under it, only the sections that have content among Added, Changed, Deprecated, Removed and Fixed. A deprecation line names the operation, the day it was deprecated, its sunset day and the replacement. Nothing is removed before its sunset. Subscribe to the feed and read it before each upgrade of a generated client.

## Write a tolerant client

Additive changes ship without notice, so your integration must tolerate them.

- Ignore response properties you do not use. Do not validate responses with a closed schema that rejects unknown properties.
- Handle values you do not know in a union: a status, a kind. Statuses are closed lists today, and a new value is a documented additive change. Give every switch a default branch.
- Be careful with clients generated with closed enums. A new value can make them throw while parsing a response.
- Do not control logic with `detail` or `errors[].message`. They are for people and change with the language. Branch on `code`.
- Alert on the `Deprecation` and `Sunset` headers and on `meta.warnings[]`, so a deprecation reaches a person at least 180 days before the sunset.

The same checks are on the [go-live checklist](https://docs.filmo.io/rest-api/guides/going-live).

---

Canonical URL: https://docs.filmo.io/rest-api/guides/versioning  
Last updated: 2026-10-09