# Versioning and compatibility

> How Slicer versions its API — the version in the path, additive-only changes within v1, the specification number and rules for robust clients.

Source: https://docs.slicer.media/en/api/versioning/

We want code written today to keep working a year from now. That's why the API has two levels of versions and strict rules about what may change within one version.

## Version in the path

The major version is in the URL: `https://api.slicer.media/v1`. Within `/v1`, changes are **additive only**:

-   new endpoints;
-   new optional request fields and new response fields;
-   new values at the end of enumerations (for example, a new publication status or a new font in the catalog);
-   new webhook events and new error codes.

Removing or renaming a field, changing its meaning or type, making an optional field required — these are breaking changes. They can only happen in `/v2`, and after it ships `/v1` keeps working for at least 12 months.

## Specification number

The API specification — [`GET /v1/openapi.json`](https://api.slicer.media/v1/openapi.json) (OpenAPI 3.1) — has its own semver number in `info.version`. It is currently `1.10.0`.

| Part | When it grows |
| --- | --- |
| minor (`1.1.0`) | an endpoint, field, event or enumeration value was added |
| patch (`1.0.1`) | a description or behavior was fixed without changing the contract |
| major (`2.0.0`) | together with the new `/v2` path |

The MCP server uses the same number — its tools are built on the same contracts. Every API and MCP change is published in the [changelog](https://docs.slicer.media/en/changelog/) with the "API change" label: what changed in the specification and whether clients need to do anything.

## Version history

All versions below are within `/v1` and only add capabilities: a client written for `1.0.0` keeps working unchanged.

| Version | Date | What was added |
| --- | --- | --- |
| `1.10.0` | 2026-10-28 | A montage produces one version, checked by the director: `versionChoice` is `null` after a montage and the `project.version_ready` event doesn't come. `POST /v1/projects/{id}/versions/{versionId}/choose` and MCP `choose_version` also make any version from the history with a file (`hasFile`) current — for example, the video from before a rebuild ([Video versions](https://docs.slicer.media/en/api/montage/#versions)) |
| `1.9.0` | 2026-10-27 | The Sound first transition: the `jcut` kind in the transitions of the `tune_block` and `set_all_transitions` operations, lasting from 0.15 to 1 s ([Transitions](https://docs.slicer.media/en/guide/editor/transitions/#audio-lead)) |
| `1.8.0` | 2026-10-19 | Captions: the `pop`, `box` and `word` designs and the `pop` template; in `subtitles` of the style (`PATCH /v1/projects/{id}/style`, MCP `set_style`) and of montage settings — the fields `highlight` (the spoken-word highlight), `animation` (the phrase entrance), `words` (words on screen), `letterCase` and `speakerColors`; `subtitleOptions` in the `GET /v1/styles` catalog. A partial `subtitles` change keeps the other fields; a new `design` without `highlight`, `animation` and `words` resets them to `auto`. `position: "auto"` places each phrase where the frame has the most free space ([Style](https://docs.slicer.media/en/api/editing/#style)) |
| `1.7.0` | 2026-10-19 | Edits cover everything the timeline does: the cutting operations `split_block`, `trim_block`, `duplicate_block`, `freeze_frame`, `set_hold`, `replace_source`; free processing `set_process` and camera moves `apply_keyframe_preset`; music `set_music`, `remove_music`, `fit_music`, `fit_to_beats`; the voice track `add_voice`, `move_voice`, `trim_voice`, `set_voice_volume`, `remove_voice`; your own photos and videos over the video `add_insert`, `update_insert`, `remove_insert`; `update_plaque`, `update_card`, `update_zoom`, `set_element_position`, `set_phrase_text`, `reset_phrase_text`; the `background` field in `tune_block`, sounds and markers in `move_element`. Skip reasons `block_or_source_not_found`, `audio_not_found`, `no_music_or_beats`, `recording_not_found`, `media_or_place_not_found`, `word_not_found`. Captions from speech: `POST /v1/projects/{id}/transcribe` (at cost; without `confirmCost` — a `Quote`) and `GET /v1/projects/{id}/transcribe` — recognition jobs, the `transcribe` kind in `POST /v1/estimate`, the MCP tools `transcribe_speech` and `get_transcribe_jobs`. In MCP, `create_project` creates a project without the AI director by default (`mode: "manual"`). [Your own director](https://docs.slicer.media/en/api/editing/#own-director): `POST /v1/projects/{id}/director/brief`, `GET /v1/projects/{id}/sources/{index}/frames`, `POST /v1/projects/{id}/director/plan` — free, the MCP tools `get_director_brief`, `get_frames`, `submit_director_plan` and the `direct_reel` prompt |
| `1.6.0` | 2026-10-18 | Picture in picture: the `set_pip` operation — an insert as a window over the video or back to full frame (position, size, rotation, opacity, shape, corners, border, sound), the `pip` field of inserts in the edit document |
| `1.5.0` | 2026-10-18 | Frame and motion: the `set_framing` operation (including `track` — the frame follows the face), `set_keyframe` and `remove_keyframe` (rotation, opacity, easing), `set_mask` (position, rotation, inversion, animation), `set_chromakey` — chroma key, `set_speed_curve` — a footage speed curve, `set_smooth` — smooth slow motion, `set_volume_keys` — volume by points. Skip reasons `block_not_footage`, `keyframe_not_found`, `block_not_found_or_no_face_data` |
| `1.4.0` | 2026-10-17 | Colour: `POST /v1/projects/{id}/auto-color` and the MCP tool `auto_color`, `adjust` and `lut` in `tune_block` and `set_all_color`. Author sounds: the `add_sound`, `update_sound`, `remove_sound` operations |
| `1.3.0` | 2026-10-17 | Markers: the `add_marker`, `update_marker`, `remove_marker` operations and `elements.markers` in the video text. Fragment sound fade-in and fade-out (`fadeIn`, `fadeOut` in `tune_block`). The `apply_look` operation — one fragment's look on others, `slip_block` — slip the frames of a b-roll fragment, `set_cover` — a cover with a title. 12 new transition kinds |
| `1.2.0` | 2026-10-17 | Titles — free text layers: the `add_title`, `update_title`, `remove_title` operations and `elements.titles`. The `add_source` operation — put a project source into the video as a new fragment |
| `1.1.0` | 2026-10-17 | Projects without the AI director: `mode: "manual"` and `format` in `POST /v1/projects`, the `mode` field and the `draft` status of a project, the `status=draft` filter. Elements placed by video time (`start`, `duration`) where there is no speech, and the `anchor` placement in the video text. A single operation catalog: `cut_silences`, `move_element`, `set_all_color`, animations in `tune_block`, zoom scale and motion in `add_zoom`. The AI assistant and translation are priced at cost: `estimate` and `atCost` in `Quote`, `costTokens` in the response |
| `1.0.0` | 2026-10-16 | The first version: uploads, montage with price confirmation, three versions of a video, edit operations, AI assistant, translation, style, export and publishing, webhooks |

Details of each version are in the [changelog](https://docs.slicer.media/en/changelog/).

## Writing a robust client

-   **Ignore unknown fields** in responses and webhooks — new fields appear without notice.
-   **Be ready for new enumeration values.** If you get an unknown `status` or event type, treat it as "other" instead of crashing. An example is the `draft` status added in `1.1.0`.
-   **Don't rely on field order** in JSON or on the exact `message` text — only on `code`.
-   **Send only the fields you need.** The server drops unknown fields in the request body; a typo in a field name won't cause an error but won't work either — check the [reference](https://docs.slicer.media/en/api/reference/).
-   **The edit document** (`GET /v1/projects/{id}/document`) is the internal model of the video; within v1 fields are only added to it as well. For edits, [operations](https://docs.slicer.media/en/api/editing/) are more reliable: they don't depend on how the document is structured.

## Generating a client

You can feed the specification to a client generator — for example, `openapi-typescript` for TypeScript or `openapi-python-client` for Python:

Terminal:

```bash
npx openapi-typescript https://api.slicer.media/v1/openapi.json -o slicer-api.d.ts
```

The specification is available without a token. The reference in these docs is built from it too, so the docs and the server don't drift apart.

## What's next

[ReferenceEvery v1 endpoint.](https://docs.slicer.media/en/api/reference/)[ChangelogWhat's new in the API, MCP and the app.](https://docs.slicer.media/en/changelog/)
