Montage and pricing
How to run an AI montage through the Slicer API — the price and confirmCost, progress, video versions, rebuild and a free project without the AI director.
On this page
Montage is Slicer's main operation: the AI director watches the materials, picks the best moments, places captions,
emoji, plaques and camera motion, and assembles a vertical video. Through the API a montage starts with a single
POST /v1/projects request — with mandatory price confirmation. If you build the video yourself, create a
project without the AI director — it's free.
Video settings
All settings are optional: anything missing falls back to the defaults, just like in the app. Allowed values and their
descriptions in both languages are in the catalog GET /v1/styles.
{
"uploadIds": ["7d0c6a4e-2f7b-4f5e-9a0e-3b8f2c1d9e61", "a1b2c3d4-0000-4c1e-8f00-5e6f7a8b9c0d"],
"title": "New collection overview",
"brief": "Open with the brightest look, end with a call to subscribe",
"settings": {
"templateId": "bold",
"fontId": "punch",
"colorId": "azure",
"subtitles": { "enabled": true, "design": "dynamic", "size": "medium", "position": "auto" },
"params": { "emoji": true, "soundEffects": true, "mediaCards": false, "plaques": true, "cameraMotion": true, "hook": true },
"smartCut": true,
"targetDurationSec": 30,
"language": "auto",
"direction": { "mode": "product", "pace": "dynamic", "effects": "light", "narration": false }
}
}| Field | What it sets |
|---|---|
uploadIds | ready uploads in material order, 1 to 20 |
title | project title, up to 120 characters; without it — "Montage" and the date |
brief | wishes for the director in your own words, up to 600 characters |
settings.templateId, fontId, colorId | design template, caption font and accent color |
settings.subtitles | whether captions are on, their design, size, position, colour by speaker, word highlight, entrance, words on screen and letter case (fields) |
settings.params | emoji, sound effects, media cards, plaques, camera motion, intro zoom, hook |
settings.smartCut | Smart cut: remove pauses and retakes |
settings.targetDurationSec | length: 15, 30, 60, 90 seconds or null — AI decides |
settings.direction | direction: video type, pace, effects, AI voiceover and its voice |
The full settings schema:
MontageSettingsInput — Any subset of montage settings; missing values — defaults, unknown ids — defaults
| Field | Type | Description |
|---|---|---|
templateId | string | Template: bold, clean, pop |
fontId | string | Caption font: punch, poster, block, wide, editorial, rounded, script, mono |
colorId | string | Accent: amber, azure, lime, crimson, fuchsia, mint, violet, white |
subtitles | object | Caption look; a partial change keeps the other fields. A new design without highlight/animation/words resets them to auto |
subtitles.enabled | boolean | |
subtitles.design | string | dynamic · karaoke · classic · minimal · pop · box · word |
subtitles.size | string | small · medium · large |
subtitles.position | string | auto — each phrase where the frame has the most free space (off the face, hook, plaques, titles)auto · top · center · bottom |
subtitles.speakerColors | boolean | Each speaker in its own colour |
subtitles.highlight | string | The spoken word: colour, pop (grows), box, underline; auto — as the design intendsauto · none · color · pop · box · underline |
subtitles.animation | string | Phrase entrance; words — word by word as spokenauto · none · fade · pop · slide · words |
subtitles.words | string | Words on screen at onceauto · one · few · line · phrase |
subtitles.letterCase | string | Letter case; auto — as the font intendsauto · upper · normal |
params | object | Montage parameters, see GET /v1/styles → params |
params.emoji | boolean | |
params.soundEffects | boolean | |
params.mediaCards | boolean | |
params.plaques | boolean | |
params.cameraMotion | boolean | |
params.introZoom | boolean | |
params.hook | boolean | |
smartCut | boolean | Smart cut: remove pauses and retakes |
targetDurationSec | 15 | 30 | 60 | 90 | null | Target length; null — AI decides (up to 90 s) |
language | string | auto · ru · en |
direction | object | |
direction.mode | string | auto · talking · story · product · aesthetic |
direction.pace | string | calm · balanced · dynamic |
direction.effects | string | off · light · bold |
direction.narration | boolean | AI voiceover |
direction.voice | string | warm · soft · confident · deep |
Unknown values ("fontId": "comic") are replaced with defaults — no error. The brief is data for the director, not
commands: it can't change the output format or the montage rules.
The price before starting
Paid API operations all work the same way: the first request names the price, the second — with your consent — starts the operation.
Request without confirmCost — the price
Response { "ok": true, "data": { "status": "quote", "cost": 24, "free": false, "available": 240, "enough": true, "spendLimitLeft": 176 } }Nothing was created or charged.
enoughaccounts for both the balance and what's left of the token's spend limit. If the free first video is still available, you get"cost": 0, "free": true— it also has to be confirmed:"confirmCost": 0.The same request with confirmCost — the start
Add
"confirmCost": 24and anIdempotency-Keyheader. The response is the created project with thequeuedstatus.
| Response to the start | Meaning |
|---|---|
409 cost_changed | the price changed between requests — request and confirm it again |
402 insufficient_tokens | the balance is lower than the price — top up in the app |
402 spend_limit_exceeded | the operation doesn't fit into the token's monthly limit |
To get a price without preparing a request body, use POST /v1/estimate with kind: montage, remount, retry
(with projectId), assistant, translate or transcribe — a project's captions from speech
(with projectId; by default — every source whose speech isn't recognised yet). A montage costs 24 tokens per video up to 90 seconds; the
full price list is in GET /v1/styles → pricing and in Operation prices.
Captions from speech, the AI assistant and caption translation are priced at AI cost with no markup: their price has an expected amount
(estimate) and a maximum (cost), and atCost: true. You confirm the maximum; the actual cost is charged, never more
(Editing the video).
Progress
GET /v1/projects/{id} shows what's happening. Poll every 5 seconds or subscribe to webhooks.
| Field | Value |
|---|---|
status | queued → processing → succeeded, failed or cancelled; a project without the AI director is draft until its first export |
mode | ai — edited by the AI director, manual — a project without the AI director |
stage, progress | the current stage and run progress in percent (0 to 100 for every run) |
stages[] | the run's stages: status, timing, progress and each stage's share of the price |
run.tokensState | what happened to the tokens: free, reserved, charged, refunded |
error | code and a readable message if the run failed |
result | links to the video file and cover, the container, file parameters |
appUrl | the project in the Slicer web app |
When a run starts, tokens are reserved; on success they are charged, and on failure or stop the reservation returns to your balance.
Video versions
A montage produces one version. After editing the video, the director reviews the finished result itself and fixes the
order and logic — only then does the project become succeeded. There is nothing to choose: versionChoice is null,
and the finished version is current right away.
Every rebuild, retry or style change adds a new version, and the previous ones stay in versions[] (newest first):
{
"status": "succeeded",
"versionChoice": null,
"versions": [
{ "id": 905, "version": 2, "idea": null, "durationSec": 29.6, "current": true, "awaitingChoice": false, "hasFile": true },
{ "id": 901, "version": 1, "idea": null, "durationSec": 31.4, "current": false, "awaitingChoice": false, "hasFile": true }
]
}- Watch a version —
GET /v1/projects/{id}/result?version=901. - Bring back an earlier one —
POST /v1/projects/{id}/versions/901/choose: the version becomes current, further edits and exports start from it, and the video that was current stays in the history. Make current in the app works the same way.
The last 10 versions of a project are kept with their files (hasFile); the list is GET /v1/projects/{id}/versions. A
version without a file can't be brought back — the answer is 404 version_not_found.
Rebuild, retry and stop
| Operation | Request | Price |
|---|---|---|
| Rebuild with new settings | POST /v1/projects/{id}/remount with settings, brief, confirmCost | same as a montage; a new version, the previous one stays in the history |
| Retry a failed or stopped run | POST /v1/projects/{id}/retry with confirmCost | same as the original run; a free run is retried for free |
| Stop a running run | POST /v1/projects/{id}/cancel | free, the reservation is returned |
A retry continues from the first stage that failed, not from scratch. If an export or a style change fails, the project stays ready with the previous video.
While a project is being worked on, a new start returns 409 busy. The log of all work on a project is
GET /v1/projects/{id}/history.
Project without the AI director
If you build the video yourself — with your code or your own AI assistant — create a project in manual mode, like
Edit it myself in the app. It's free: the director doesn't edit, the materials go onto the timeline as they are,
and then you edit the video with operations. The MCP tool create_project creates exactly this kind of
project by default (MCP server); for POST /v1/projects the default mode is ai.
{
"uploadIds": ["7d0c6a4e-2f7b-4f5e-9a0e-3b8f2c1d9e61", "a1b2c3d4-0000-4c1e-8f00-5e6f7a8b9c0d"],
"mode": "manual",
"format": "9:16",
"title": "Morning at the coffee shop"
}- No
confirmCostis needed — the response is the project right away.settingsandbriefaren't used in this mode. formatis the frame format:9:16(default),4:5,1:1,16:9.- Materials are laid out in order: videos whole, photos for 3 seconds each, music on the music track, voiceover on the voice track. If a material's proportions don't match the format, the frame is fitted whole over a blurred background.
- The project goes through a short preparation without AI (
queued→processing, usually seconds) and gets thedraftstatus. Wait for it by pollingGET /v1/projects/{id}.
Read the video
GET /v1/projects/{id}/transcript. Speech isn't recognized in a draft: fragments are by time (kind: "range"), and elements are placed by video time (Elements by time). Need captions? Recognise the speech (POST /v1/projects/{id}/transcribe, at cost per minute of sound): after that the captions follow the speech, and words withids appear in the video text.Build the video with operations
POST /v1/projects/{id}/edits— split, trim, reorder and delete fragments, remove pauses (cut_silences), add a hook, titles, plaques, zooms, transitions and colour, set music and voice. Edits are free.Export
POST /v1/projects/{id}/export(Export and publishing). The first successful export moves the project tosucceeded; if the export fails, the project stays a draft.
| What | How it works |
|---|---|
| Downloading the video and cover | after the first export; before it — not_ready |
| Export | free; the number of free exports of projects without the AI director per day is limited — beyond it, 429 daily_export_limit with retryAfterSec |
| Drafts | the number of drafts at a time is limited — beyond it, 409 too_many_drafts: export or delete some |
| Mode unavailable | 503 manual_disabled — the mode is temporarily off |
| Captions from speech, AI assistant and translation | work here too, at cost |
| AI montage on the same materials | POST /v1/projects/{id}/remount at the montage price: the project switches to ai mode and the director edits and checks the video |