Skip to content

Editing

Slicer API editing endpoints — video text with word ids, operations, the edit document, captions from speech, AI assistant, translation, style, own director.

On this page

Edits change the video the same way the app's editor does and are saved immediately. All of them are free except captions from speech, the AI assistant and caption translation — those are priced at AI cost (Captions from speech, AI assistant). Every edit passes the revision rev: if the video has changed meanwhile, the response is 409 stale_document. How to use them — in the guide Editing the video.

The video as text with word ids

GET/v1/projects/{id}/transcript
Scopes
projects:read
Rate limit
default

Path parameters

Field Type Description
idrequiredinteger≥ 1

Request

curl
JavaScript
Python
curl "https://api.slicer.media/v1/projects/42/transcript" \
  -H "Authorization: Bearer $SLICER_TOKEN"

Response

Response fields: Transcript (90)
Field Type Description
revrequiredintegerDocument revision: pass it to edits
durationSecrequirednumber
textrequiredstringThe video as text for an LLM: fragments with word ids w<id>, cut words in [brackets], graphics
blocksrequiredobject[]
blocks[].idrequiredstring
blocks[].positionrequiredinteger
blocks[].sourceIndexrequiredinteger
blocks[].kindrequiredstringwords · range
blocks[].wordsrequiredobject[]
blocks[].words[].idrequiredinteger
blocks[].words[].textrequiredstring
blocks[].words[].cutrequiredboolean
blocks[].words[].accentrequiredboolean
elementsrequiredobject
elements.hookrequiredstring | null
elements.plaquesrequiredobject[]
elements.plaques[].idrequiredstring
elements.plaques[].kindrequiredstring
elements.plaques[].titlerequiredstring
elements.plaques[].fromWordIdrequiredinteger | nullWord id; null — the element is placed by time (anchor)
elements.plaques[].toWordIdrequiredinteger | nullWord id; null — the element is placed by time (anchor)
elements.plaques[].startnumberWhere the element starts in the video, s; absent — hidden (its words were cut)
elements.plaques[].endnumberWhere the element ends in the video, s
elements.plaques[].anchorobjectPlaced by time: fragment, second of its source and duration in the video, s
elements.plaques[].anchor.blockIdrequiredstring
elements.plaques[].anchor.atrequirednumber
elements.plaques[].anchor.durationrequirednumber
elements.cardsrequiredobject[]
elements.cards[].idrequiredstring
elements.cards[].captionrequiredstring | null
elements.cards[].fromWordIdrequiredinteger | nullWord id; null — the element is placed by time (anchor)
elements.cards[].toWordIdrequiredinteger | nullWord id; null — the element is placed by time (anchor)
elements.cards[].startnumberWhere the element starts in the video, s; absent — hidden (its words were cut)
elements.cards[].endnumberWhere the element ends in the video, s
elements.cards[].anchorobjectPlaced by time: fragment, second of its source and duration in the video, s
elements.cards[].anchor.blockIdrequiredstring
elements.cards[].anchor.atrequirednumber
elements.cards[].anchor.durationrequirednumber
elements.emojirequiredobject[]
elements.emoji[].idrequiredstring
elements.emoji[].emojirequiredstring
elements.emoji[].wordIdrequiredinteger | nullWord id; null — the element is placed by time (anchor)
elements.emoji[].startnumberWhere the element starts in the video, s; absent — hidden (its words were cut)
elements.emoji[].endnumberWhere the element ends in the video, s
elements.emoji[].anchorobjectPlaced by time: fragment, second of its source and duration in the video, s
elements.emoji[].anchor.blockIdrequiredstring
elements.emoji[].anchor.atrequirednumber
elements.emoji[].anchor.durationrequirednumber
elements.zoomsrequiredobject[]
elements.zooms[].idrequiredstring
elements.zooms[].fromWordIdrequiredinteger | nullWord id; null — the element is placed by time (anchor)
elements.zooms[].toWordIdrequiredinteger | nullWord id; null — the element is placed by time (anchor)
elements.zooms[].startnumberWhere the element starts in the video, s; absent — hidden (its words were cut)
elements.zooms[].endnumberWhere the element ends in the video, s
elements.zooms[].anchorobjectPlaced by time: fragment, second of its source and duration in the video, s
elements.zooms[].anchor.blockIdrequiredstring
elements.zooms[].anchor.atrequirednumber
elements.zooms[].anchor.durationrequirednumber
elements.titlesrequiredobject[]Free text layers (titles)
elements.titles[].idrequiredstring
elements.titles[].textrequiredstring
elements.titles[].fontrequiredstring
elements.titles[].sizerequirednumber
elements.titles[].colorrequiredstring
elements.titles[].backgroundrequiredstringnone · box · pill
elements.titles[].backgroundColorstring
elements.titles[].outlineboolean
elements.titles[].shadowboolean
elements.titles[].alignrequiredstringleft · center · right
elements.titles[].xrequirednumber
elements.titles[].yrequirednumber
elements.titles[].animInstringfade · slide · pop · typewriter
elements.titles[].animOutstringfade · slide · pop
elements.titles[].fromWordIdrequiredinteger | nullWord id; null — the element is placed by time (anchor)
elements.titles[].toWordIdrequiredinteger | nullWord id; null — the element is placed by time (anchor)
elements.titles[].startnumberWhere the element starts in the video, s; absent — hidden (its words were cut)
elements.titles[].endnumberWhere the element ends in the video, s
elements.titles[].anchorobjectPlaced by time: fragment, second of its source and duration in the video, s
elements.titles[].anchor.blockIdrequiredstring
elements.titles[].anchor.atrequirednumber
elements.titles[].anchor.durationrequirednumber
elements.markersrequiredobject[]Author markers on the timeline (not shown in the video); hidden markers are omitted
elements.markers[].idrequiredstring
elements.markers[].timerequirednumber
elements.markers[].labelrequiredstring | null
elements.markers[].colorrequiredstringcyan · yellow · red · green · violet
elements.soundsrequiredobject[]Sound effects placed by the author; cut-off ones are omitted
elements.sounds[].idrequiredstring
elements.sounds[].kindrequiredstringwhoosh · pop · ding · click · swipe · rise · boom · chime
elements.sounds[].timerequirednumber
Response example
{
  "ok": true,
  "data": {
    "rev": 7,
    "durationSec": 42.5,
    "text": "string",
    "blocks": [
      {
        "id": "string",
        "position": 1,
        "sourceIndex": 1,
        "kind": "words",
        "words": [
          {
            "id": null,
            "text": null,
            "cut": null,
            "accent": null
          }
        ]
      }
    ],
    "elements": {
      "hook": "string",
      "plaques": [
        {
          "id": "string",
          "kind": "string",
          "title": "Монтаж за 3 минуты",
          "fromWordId": null,
          "toWordId": null,
          "start": 1.5,
          "end": 1.5,
          "anchor": {
            "blockId": null,
            "at": null,
            "duration": null
          }
        }
      ],
      "cards": [
        {
          "id": "string",
          "caption": "string",
          "fromWordId": null,
          "toWordId": null,
          "start": 1.5,
          "end": 1.5,
          "anchor": {
            "blockId": null,
            "at": null,
            "duration": null
          }
        }
      ],
      "emoji": [
        {
          "id": "string",
          "emoji": "string",
          "wordId": null,
          "start": 1.5,
          "end": 1.5,
          "anchor": {
            "blockId": null,
            "at": null,
            "duration": null
          }
        }
      ],
      "zooms": [
        {
          "id": "string",
          "fromWordId": null,
          "toWordId": null,
          "start": 1.5,
          "end": 1.5,
          "anchor": {
            "blockId": null,
            "at": null,
            "duration": null
          }
        }
      ],
      "titles": [
        {
          "id": "string",
          "text": "string",
          "font": "string",
          "size": 104857600,
          "color": "string",
          "background": "none",
          "backgroundColor": "string",
          "outline": true,
          "shadow": true,
          "align": "left",
          "x": 1.5,
          "y": 1.5,
          "animIn": "fade",
          "animOut": "fade",
          "fromWordId": null,
          "toWordId": null,
          "start": 1.5,
          "end": 1.5,
          "anchor": {
            "blockId": null,
            "at": null,
            "duration": null
          }
        }
      ],
      "markers": [
        {
          "id": "string",
          "time": 1.5,
          "label": "string",
          "color": "cyan"
        }
      ],
      "sounds": [
        {
          "id": "string",
          "kind": "whoosh",
          "time": 1.5
        }
      ]
    }
  }
}

Apply edit operations

POST/v1/projects/{id}/edits
Scopes
projects:write
Rate limit
default

Free. Word ids — from GET …/transcript. Inapplicable operations are skipped and listed in skipped.

Path parameters

Field Type Description
idrequiredinteger≥ 1

Request body EditsRequest

Field Type Description
revrequiredintegerRevision from GET …/transcript or …/document
operationsrequiredEditOperation[]1–80

Request

curl
JavaScript
Python
curl -X POST "https://api.slicer.media/v1/projects/42/edits" \
  -H "Authorization: Bearer $SLICER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"rev":7,"operations":[{"op":"cut_words","fromWordId":42,"toWordId":42}]}'

Response

Response fields: EditsResult (7)
Field Type Description
revrequiredinteger
appliedrequiredinteger
skippedrequiredobject[]
skipped[].indexrequiredinteger
skipped[].oprequiredstring
skipped[].reasonrequiredstring
durationSecrequirednumber
Response example
{
  "ok": true,
  "data": {
    "rev": 7,
    "applied": 1,
    "skipped": [
      {
        "index": 1,
        "op": "string",
        "reason": "string"
      }
    ],
    "durationSec": 42.5
  }
}

Captions from speech

POST/v1/projects/{id}/transcribe
Scopes
montage:run
Rate limit
paid operations
Price
spends tokens

Recognises speech in the project sources (a manual project or new sources) — at AI cost, per minute of sound. Without confirmCost returns the price. Runs in the background: follow it with GET …/transcribe; when ready, the words are in the transcript and captions follow the speech.

Path parameters

Field Type Description
idrequiredinteger≥ 1

Request body TranscribeRequest

Field Type Description
sourcesinteger[]Source indexes (default — every source with sound whose speech is not recognised yet)1–40
languagestringSpeech language: auto or a two-letter code
confirmCostintegerPrice you agree to pay. Without it the response is a Quote and nothing starts

Request

curl
JavaScript
Python
curl -X POST "https://api.slicer.media/v1/projects/42/transcribe" \
  -H "Authorization: Bearer $SLICER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"sources":[1],"language":"ru"}'

Response

One of: Quote, TranscribeJob

Response fields: Quote (8)
Field Type Description
statusrequired"quote"
costrequiredintegerPrice in tokens; repeat the request with confirmCost equal to it. For an operation at cost (atCost) — the maximum: the actual cost is charged, never more
freerequiredbooleanThe operation is free (first video, free retry)
estimatenumberOperation at cost: expected price in tokens (fractional)
atCostbooleanPriced at the AI providers’ cost, no markup: the wallet is charged the actual cost, at most cost
availablerequiredintegerTokens available now
enoughrequiredbooleanEnough tokens to run
spendLimitLeftrequiredinteger | nullWhat is left of the token's monthly spend limit; null — no limit
Response fields: TranscribeJob (5)
Field Type Description
idrequiredstring
statusrequiredstringprocessing · ready · failed
sourcesrequiredinteger[]
createdAtrequiredstring
errorstring
Response example
{
  "ok": true,
  "data": {
    "status": "quote",
    "cost": 24,
    "free": true,
    "estimate": 1.5,
    "atCost": true,
    "available": 240,
    "enough": true,
    "spendLimitLeft": 200
  }
}

Speech recognition jobs

GET/v1/projects/{id}/transcribe
Scopes
projects:read
Rate limit
default

Path parameters

Field Type Description
idrequiredinteger≥ 1

Request

curl
JavaScript
Python
curl "https://api.slicer.media/v1/projects/42/transcribe" \
  -H "Authorization: Bearer $SLICER_TOKEN"

Response

Response example
{
  "ok": true,
  "data": [
    {
      "id": "string",
      "status": "processing",
      "sources": [
        1
      ],
      "createdAt": "2026-10-16T09:30:00Z",
      "error": "string"
    }
  ]
}

Command for the AI assistant

POST/v1/projects/{id}/assistant
Scopes
montage:run
Rate limit
paid operations
Price
spends tokens

Charged only if something changed. The result is saved.

Path parameters

Field Type Description
idrequiredinteger≥ 1

Request body AssistantRequest

Field Type Description
commandrequiredstringWhat to change, in any language≤ 500
revrequiredinteger
confirmCostintegerPrice you agree to pay. Without it the response is a Quote and nothing starts

Request

curl
JavaScript
Python
curl -X POST "https://api.slicer.media/v1/projects/42/assistant" \
  -H "Authorization: Bearer $SLICER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"command":"Сделай субтитры крупнее","rev":7}'

Response

One of: Quote, AssistantResult

Response fields: Quote (8)
Field Type Description
statusrequired"quote"
costrequiredintegerPrice in tokens; repeat the request with confirmCost equal to it. For an operation at cost (atCost) — the maximum: the actual cost is charged, never more
freerequiredbooleanThe operation is free (first video, free retry)
estimatenumberOperation at cost: expected price in tokens (fractional)
atCostbooleanPriced at the AI providers’ cost, no markup: the wallet is charged the actual cost, at most cost
availablerequiredintegerTokens available now
enoughrequiredbooleanEnough tokens to run
spendLimitLeftrequiredinteger | nullWhat is left of the token's monthly spend limit; null — no limit
Response fields: AssistantResult (6)
Field Type Description
revrequiredinteger
summaryrequiredstring
appliedrequiredinteger
chargedrequiredintegerTokens charged from the wallet (whole)
costTokensnumberActual cost of the command in tokens (fractional); the remainder accumulates with the project
durationSecrequirednumber
Response example
{
  "ok": true,
  "data": {
    "status": "quote",
    "cost": 24,
    "free": true,
    "estimate": 1.5,
    "atCost": true,
    "available": 240,
    "enough": true,
    "spendLimitLeft": 200
  }
}

Translate captions

POST/v1/projects/{id}/translate
Scopes
montage:run
Rate limit
paid operations
Price
spends tokens

Path parameters

Field Type Description
idrequiredinteger≥ 1

Request body TranslateRequest

Field Type Description
languagerequiredstringen · es · pt · de · fr · it · pl · tr · id · uk · ru
revrequiredinteger
confirmCostintegerPrice you agree to pay. Without it the response is a Quote and nothing starts

Request

curl
JavaScript
Python
curl -X POST "https://api.slicer.media/v1/projects/42/translate" \
  -H "Authorization: Bearer $SLICER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"language":"en","rev":7}'

Response

One of: Quote, TranslateResult

Response fields: Quote (8)
Field Type Description
statusrequired"quote"
costrequiredintegerPrice in tokens; repeat the request with confirmCost equal to it. For an operation at cost (atCost) — the maximum: the actual cost is charged, never more
freerequiredbooleanThe operation is free (first video, free retry)
estimatenumberOperation at cost: expected price in tokens (fractional)
atCostbooleanPriced at the AI providers’ cost, no markup: the wallet is charged the actual cost, at most cost
availablerequiredintegerTokens available now
enoughrequiredbooleanEnough tokens to run
spendLimitLeftrequiredinteger | nullWhat is left of the token's monthly spend limit; null — no limit
Response fields: TranslateResult (4)
Field Type Description
revrequiredinteger
phrasesrequiredinteger
chargedrequiredintegerTokens charged from the wallet (whole)
costTokensnumberActual cost of the translation in tokens (fractional)
Response example
{
  "ok": true,
  "data": {
    "status": "quote",
    "cost": 24,
    "free": true,
    "estimate": 1.5,
    "atCost": true,
    "available": 240,
    "enough": true,
    "spendLimitLeft": 200
  }
}

Auto colour and colour matching (free)

POST/v1/projects/{id}/auto-color
Scopes
projects:write
Rate limit
default

No AI: statistics of 10 frames of the fragment → «Adjust» values (exposure, contrast, saturation, white balance). The result is applied and saved.

Path parameters

Field Type Description
idrequiredinteger≥ 1

Request body AutoColorRequest

Field Type Description
revrequiredintegerRevision from GET …/transcript or …/document
blockIdrequiredstringFragment id: the one to correct (auto) or the sample (match)≤ 64
moderequiredstringauto — balance this fragment; match — make all other fragments look like it (with its filter and LUT)auto · match

Request

curl
JavaScript
Python
curl -X POST "https://api.slicer.media/v1/projects/42/auto-color" \
  -H "Authorization: Bearer $SLICER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"rev":7,"blockId":"string","mode":"auto"}'

Response

Response fields: AutoColorResult (5)
Field Type Description
revrequiredinteger
moderequiredstringauto · match
adjustrequiredRecord<string, object>New «Adjust» values by fragment id
appliedrequiredinteger
durationSecrequirednumber
Response example
{
  "ok": true,
  "data": {
    "rev": 7,
    "mode": "auto",
    "adjust": {},
    "applied": 1,
    "durationSec": 42.5
  }
}

Change the style

PATCH/v1/projects/{id}/style
Scopes
projects:write
Rate limit
default

Path parameters

Field Type Description
idrequiredinteger≥ 1

Request body StyleRequest

Field Type Description
templateIdstring
fontIdstring
colorIdstring
subtitlesobjectCaption look; a partial change keeps the other fields. A new design without highlight/animation/words resets them to auto
subtitles.enabledboolean
subtitles.designstringdynamic · karaoke · classic · minimal · pop · box · word
subtitles.sizestringsmall · medium · large
subtitles.positionstringauto — each phrase where the frame has the most free space (off the face, hook, plaques, titles)auto · top · center · bottom
subtitles.speakerColorsbooleanEach speaker in its own colour
subtitles.highlightstringThe spoken word: colour, pop (grows), box, underline; auto — as the design intendsauto · none · color · pop · box · underline
subtitles.animationstringPhrase entrance; words — word by word as spokenauto · none · fade · pop · slide · words
subtitles.wordsstringWords on screen at onceauto · one · few · line · phrase
subtitles.letterCasestringLetter case; auto — as the font intendsauto · upper · normal
paramsobject
params.soundEffectsboolean
params.introZoomboolean

Request

curl
JavaScript
Python
curl -X PATCH "https://api.slicer.media/v1/projects/42/style" \
  -H "Authorization: Bearer $SLICER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"templateId":"string","fontId":"string"}'

Response

Response fields: Project (26)
Field Type Description
idrequiredinteger
titlerequiredstring
statusrequiredstringdraft — an “edit it myself” project before its first export: edit it with operations, then exportqueued · processing · succeeded · failed · cancelled · draft
moderequiredstringai — edited by the AI director; manual — materials on the timeline as is, free (only AI operations cost)ai · manual
stagerequiredstring | null
progressrequiredintegerProgress of the current run, %
clientrequiredstring | nullWhere it was created: web, mobile, api, mcp
settingsrequiredobjectMontage settings (see MontageSettingsInput)
briefrequiredstring | null
isFreerequiredboolean
watermarkrequiredboolean
tokensCostrequiredinteger
errorrequiredobject | null
error.coderequiredstring
error.messagerequiredstring
durationSecrequirednumber | null
versionChoicerequiredinteger[] | nullVersion ids awaiting your choice; a montage returns one version, so usually null
resultrequiredobject | null
result.urlrequiredstring (uri)Download with the token (Range supported)
result.posterUrlrequiredstring (uri) | null
result.containerrequiredstring
result.inforequiredobject | null
appUrlrequiredstring (uri)The project in the Slicer web app
sourcesAvailablerequiredbooleanSources are kept 7 days after the montage
createdAtrequiredstringISO 8601 date-time, UTC
finishedAtrequiredstring | null
Response example
{
  "ok": true,
  "data": {
    "id": 42,
    "title": "Монтаж за 3 минуты",
    "status": "queued",
    "mode": "ai",
    "stage": "string",
    "progress": 0.5,
    "client": "string",
    "settings": {},
    "brief": "Динамично, с акцентом на главные мысли",
    "isFree": true,
    "watermark": true,
    "tokensCost": 24,
    "error": {
      "code": "string",
      "message": "string"
    },
    "durationSec": 42.5,
    "versionChoice": [
      1
    ],
    "result": {
      "url": "https://example.com/hook",
      "posterUrl": "https://api.slicer.media/v1/…",
      "container": "string",
      "info": {}
    },
    "appUrl": "https://api.slicer.media/v1/…",
    "sourcesAvailable": true,
    "createdAt": "2026-10-16T09:30:00Z",
    "finishedAt": "2026-10-16T09:30:00Z"
  }
}

Your own director

Your AI agent edits the video itself — for free: a brief with the material and the plan and observation schemas, frames of the sources and accepting the plan with observations from the frames. The rules of the Slicer AI director are applied to the plan on the server; the answer has fixes and issues. How to use them — Your own director.

Director brief for your AI assistant (free)

POST/v1/projects/{id}/director/brief
Scopes
projects:write
Rate limit
default

The material (speech by word ids, pauses, retakes, wishes), general tips and the schemas of the plan and of scenes. Your assistant looks at the footage with sourceFrames and sends the plan with what it saw to submitDirectorPlan; the rules of the Slicer director run on the server there. Optional settings are saved to the project.

Path parameters

Field Type Description
idrequiredinteger≥ 1

Request body DirectorBriefRequest

Field Type Description
modestringVideo typeauto · talking · story · product · aesthetic
pacestringcalm · balanced · dynamic
effectsstringoff · light · bold
targetDurationSecinteger | nullTarget length, s; null — the director decides (up to 90 s)10–180
hookbooleanOpen with a hook and an on-screen title
plaquesboolean
emojiboolean
cameraMotionbooleanZooms and camera moves

Request

curl
JavaScript
Python
curl -X POST "https://api.slicer.media/v1/projects/42/director/brief" \
  -H "Authorization: Bearer $SLICER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"mode":"auto","pace":"calm"}'

Response

Response fields: DirectorBrief (15)
Field Type Description
projectIdrequiredinteger
revrequiredinteger
settingsrequiredRecord<string, object>
sourcesrequiredobject[]
sources[].indexrequiredinteger
sources[].kindrequiredstring
sources[].durationSecrequirednumber
sources[].fileNamerequiredstring | null
sources[].wordsrequiredinteger
speechRecognizedrequiredboolean
materialrequiredstringThe material: sources, speech by word ids, pauses, retakes, wishes
guiderequiredstring[]General tips (the Slicer director rules run on the server when you submit the plan)
planSchemarequiredRecord<string, object>JSON schema of the plan for submitDirectorPlan
scenesSchemarequiredRecord<string, object>JSON schema of what you saw in the frames
nextrequiredstring[]
Response example
{
  "ok": true,
  "data": {
    "projectId": 42,
    "rev": 7,
    "settings": {},
    "sources": [
      {
        "index": 1,
        "kind": "string",
        "durationSec": 42.5,
        "fileName": "interview.mp4",
        "words": 1
      }
    ],
    "speechRecognized": true,
    "material": "string",
    "guide": [
      "string"
    ],
    "planSchema": {},
    "scenesSchema": {},
    "next": [
      "string"
    ]
  }
}

Frames of a source (free)

GET/v1/projects/{id}/sources/{index}/frames
Scopes
projects:read
Rate limit
default

Path parameters

Field Type Description
idrequiredinteger≥ 1
indexrequiredinteger

Query parameters

Field Type Description
timesstring
fromnumber
tonumber
countinteger1–16

Request

curl
JavaScript
Python
curl "https://api.slicer.media/v1/projects/42/sources/1/frames" \
  -H "Authorization: Bearer $SLICER_TOKEN"

Response

Response fields: SourceFrames (6)
Field Type Description
sourceIndexrequiredinteger
durationSecrequirednumber
framesrequiredobject[]
frames[].timerequirednumber
frames[].mimeTyperequired"image/jpeg"
frames[].datarequiredstringJPEG, base64, 512 px on the longer side
Response example
{
  "ok": true,
  "data": {
    "sourceIndex": 1,
    "durationSec": 42.5,
    "frames": [
      {
        "time": 1.5,
        "mimeType": "image/jpeg",
        "data": "string"
      }
    ]
  }
}

Apply a director plan (free)

POST/v1/projects/{id}/director/plan
Scopes
projects:write
Rate limit
default

The rules of the Slicer director are applied to the plan on the server (word boundaries, retakes, footage by your scenes, restraint, length): the plan becomes the video document — a new revision, visible in the editor — and the answer lists fixes and issues to address. Media cards from a description are not accepted (their picture is a paid generation).

Path parameters

Field Type Description
idrequiredinteger≥ 1

Request body DirectorPlanRequest

Field Type Description
revrequiredintegerrev from directorBrief / transcript
planrequiredRecord<string, object>The plan in DirectorBrief.planSchema
scenesRecord<string, object>[]What you saw in the frames, in DirectorBrief.scenesSchema0–400

Request

curl
JavaScript
Python
curl -X POST "https://api.slicer.media/v1/projects/42/director/plan" \
  -H "Authorization: Bearer $SLICER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"rev":7,"plan":{}}'

Response

Response fields: DirectorPlanResult (10)
Field Type Description
revrequiredinteger
durationSecrequirednumber
planSegmentsrequiredinteger
fragmentsrequiredinteger
fixesrequiredstring[]What Slicer corrected by its director rules
issuesrequiredobject[]What you should fix and submit again
issues[].coderequiredstring
issues[].segmentinteger
issues[].messagerequiredstring
videorequiredstringThe resulting video as text (fragments, words, elements) — check it against the plan
Response example
{
  "ok": true,
  "data": {
    "rev": 7,
    "durationSec": 42.5,
    "planSegments": 1,
    "fragments": 1,
    "fixes": [
      "string"
    ],
    "issues": [
      {
        "code": "string",
        "segment": 1,
        "message": "string"
      }
    ],
    "video": "string"
  }
}

Edit document

Edit document

GET/v1/projects/{id}/document
Scopes
projects:read
Rate limit
default

Path parameters

Field Type Description
idrequiredinteger≥ 1

Request

curl
JavaScript
Python
curl "https://api.slicer.media/v1/projects/42/document" \
  -H "Authorization: Bearer $SLICER_TOKEN"

Response

Response fields: DocumentState (3)
Field Type Description
revrequiredinteger
durationSecrequirednumber
documentrequiredobjectEdit document (EditDocument v1). Fields are only added within v1
Response example
{
  "ok": true,
  "data": {
    "rev": 7,
    "durationSec": 42.5,
    "document": {}
  }
}

Replace the edit document (advanced)

PUT/v1/projects/{id}/document
Scopes
projects:write
Rate limit
default

Path parameters

Field Type Description
idrequiredinteger≥ 1

Request body PutDocumentRequest

Field Type Description
revrequiredinteger
documentrequiredobject

Request

curl
JavaScript
Python
curl -X PUT "https://api.slicer.media/v1/projects/42/document" \
  -H "Authorization: Bearer $SLICER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"rev":7,"document":{}}'

Response

Response fields: DocumentState (3)
Field Type Description
revrequiredinteger
durationSecrequirednumber
documentrequiredobjectEdit document (EditDocument v1). Fields are only added within v1
Response example
{
  "ok": true,
  "data": {
    "rev": 7,
    "durationSec": 42.5,
    "document": {}
  }
}

Schemas

Transcript

Field Type Description
revrequiredintegerDocument revision: pass it to edits
durationSecrequirednumber
textrequiredstringThe video as text for an LLM: fragments with word ids w<id>, cut words in [brackets], graphics
blocksrequiredobject[]
blocks[].idrequiredstring
blocks[].positionrequiredinteger
blocks[].sourceIndexrequiredinteger
blocks[].kindrequiredstringwords · range
blocks[].wordsrequiredobject[]
blocks[].words[].idrequiredinteger
blocks[].words[].textrequiredstring
blocks[].words[].cutrequiredboolean
blocks[].words[].accentrequiredboolean
elementsrequiredobject
elements.hookrequiredstring | null
elements.plaquesrequiredobject[]
elements.plaques[].idrequiredstring
elements.plaques[].kindrequiredstring
elements.plaques[].titlerequiredstring
elements.plaques[].fromWordIdrequiredinteger | nullWord id; null — the element is placed by time (anchor)
elements.plaques[].toWordIdrequiredinteger | nullWord id; null — the element is placed by time (anchor)
elements.plaques[].startnumberWhere the element starts in the video, s; absent — hidden (its words were cut)
elements.plaques[].endnumberWhere the element ends in the video, s
elements.plaques[].anchorobjectPlaced by time: fragment, second of its source and duration in the video, s
elements.plaques[].anchor.blockIdrequiredstring
elements.plaques[].anchor.atrequirednumber
elements.plaques[].anchor.durationrequirednumber
elements.cardsrequiredobject[]
elements.cards[].idrequiredstring
elements.cards[].captionrequiredstring | null
elements.cards[].fromWordIdrequiredinteger | nullWord id; null — the element is placed by time (anchor)
elements.cards[].toWordIdrequiredinteger | nullWord id; null — the element is placed by time (anchor)
elements.cards[].startnumberWhere the element starts in the video, s; absent — hidden (its words were cut)
elements.cards[].endnumberWhere the element ends in the video, s
elements.cards[].anchorobjectPlaced by time: fragment, second of its source and duration in the video, s
elements.cards[].anchor.blockIdrequiredstring
elements.cards[].anchor.atrequirednumber
elements.cards[].anchor.durationrequirednumber
elements.emojirequiredobject[]
elements.emoji[].idrequiredstring
elements.emoji[].emojirequiredstring
elements.emoji[].wordIdrequiredinteger | nullWord id; null — the element is placed by time (anchor)
elements.emoji[].startnumberWhere the element starts in the video, s; absent — hidden (its words were cut)
elements.emoji[].endnumberWhere the element ends in the video, s
elements.emoji[].anchorobjectPlaced by time: fragment, second of its source and duration in the video, s
elements.emoji[].anchor.blockIdrequiredstring
elements.emoji[].anchor.atrequirednumber
elements.emoji[].anchor.durationrequirednumber
elements.zoomsrequiredobject[]
elements.zooms[].idrequiredstring
elements.zooms[].fromWordIdrequiredinteger | nullWord id; null — the element is placed by time (anchor)
elements.zooms[].toWordIdrequiredinteger | nullWord id; null — the element is placed by time (anchor)
elements.zooms[].startnumberWhere the element starts in the video, s; absent — hidden (its words were cut)
elements.zooms[].endnumberWhere the element ends in the video, s
elements.zooms[].anchorobjectPlaced by time: fragment, second of its source and duration in the video, s
elements.zooms[].anchor.blockIdrequiredstring
elements.zooms[].anchor.atrequirednumber
elements.zooms[].anchor.durationrequirednumber
elements.titlesrequiredobject[]Free text layers (titles)
elements.titles[].idrequiredstring
elements.titles[].textrequiredstring
elements.titles[].fontrequiredstring
elements.titles[].sizerequirednumber
elements.titles[].colorrequiredstring
elements.titles[].backgroundrequiredstringnone · box · pill
elements.titles[].backgroundColorstring
elements.titles[].outlineboolean
elements.titles[].shadowboolean
elements.titles[].alignrequiredstringleft · center · right
elements.titles[].xrequirednumber
elements.titles[].yrequirednumber
elements.titles[].animInstringfade · slide · pop · typewriter
elements.titles[].animOutstringfade · slide · pop
elements.titles[].fromWordIdrequiredinteger | nullWord id; null — the element is placed by time (anchor)
elements.titles[].toWordIdrequiredinteger | nullWord id; null — the element is placed by time (anchor)
elements.titles[].startnumberWhere the element starts in the video, s; absent — hidden (its words were cut)
elements.titles[].endnumberWhere the element ends in the video, s
elements.titles[].anchorobjectPlaced by time: fragment, second of its source and duration in the video, s
elements.titles[].anchor.blockIdrequiredstring
elements.titles[].anchor.atrequirednumber
elements.titles[].anchor.durationrequirednumber
elements.markersrequiredobject[]Author markers on the timeline (not shown in the video); hidden markers are omitted
elements.markers[].idrequiredstring
elements.markers[].timerequirednumber
elements.markers[].labelrequiredstring | null
elements.markers[].colorrequiredstringcyan · yellow · red · green · violet
elements.soundsrequiredobject[]Sound effects placed by the author; cut-off ones are omitted
elements.sounds[].idrequiredstring
elements.sounds[].kindrequiredstringwhoosh · pop · ding · click · swipe · rise · boom · chime
elements.sounds[].timerequirednumber

EditOperation

Field Type Description

EditsResult

Field Type Description
revrequiredinteger
appliedrequiredinteger
skippedrequiredobject[]
skipped[].indexrequiredinteger
skipped[].oprequiredstring
skipped[].reasonrequiredstring
durationSecrequirednumber

TranscribeRequest

Field Type Description
sourcesinteger[]Source indexes (default — every source with sound whose speech is not recognised yet)1–40
languagestringSpeech language: auto or a two-letter code
confirmCostintegerPrice you agree to pay. Without it the response is a Quote and nothing starts

TranscribeJob

Field Type Description
idrequiredstring
statusrequiredstringprocessing · ready · failed
sourcesrequiredinteger[]
createdAtrequiredstring
errorstring

AssistantResult

Field Type Description
revrequiredinteger
summaryrequiredstring
appliedrequiredinteger
chargedrequiredintegerTokens charged from the wallet (whole)
costTokensnumberActual cost of the command in tokens (fractional); the remainder accumulates with the project
durationSecrequirednumber

TranslateResult

Field Type Description
revrequiredinteger
phrasesrequiredinteger
chargedrequiredintegerTokens charged from the wallet (whole)
costTokensnumberActual cost of the translation in tokens (fractional)

StyleRequest

Field Type Description
templateIdstring
fontIdstring
colorIdstring
subtitlesobjectCaption look; a partial change keeps the other fields. A new design without highlight/animation/words resets them to auto
subtitles.enabledboolean
subtitles.designstringdynamic · karaoke · classic · minimal · pop · box · word
subtitles.sizestringsmall · medium · large
subtitles.positionstringauto — each phrase where the frame has the most free space (off the face, hook, plaques, titles)auto · top · center · bottom
subtitles.speakerColorsbooleanEach speaker in its own colour
subtitles.highlightstringThe spoken word: colour, pop (grows), box, underline; auto — as the design intendsauto · none · color · pop · box · underline
subtitles.animationstringPhrase entrance; words — word by word as spokenauto · none · fade · pop · slide · words
subtitles.wordsstringWords on screen at onceauto · one · few · line · phrase
subtitles.letterCasestringLetter case; auto — as the font intendsauto · upper · normal
paramsobject
params.soundEffectsboolean
params.introZoomboolean

DirectorBriefRequest

Field Type Description
modestringVideo typeauto · talking · story · product · aesthetic
pacestringcalm · balanced · dynamic
effectsstringoff · light · bold
targetDurationSecinteger | nullTarget length, s; null — the director decides (up to 90 s)10–180
hookbooleanOpen with a hook and an on-screen title
plaquesboolean
emojiboolean
cameraMotionbooleanZooms and camera moves

DirectorBrief

Field Type Description
projectIdrequiredinteger
revrequiredinteger
settingsrequiredRecord<string, object>
sourcesrequiredobject[]
sources[].indexrequiredinteger
sources[].kindrequiredstring
sources[].durationSecrequirednumber
sources[].fileNamerequiredstring | null
sources[].wordsrequiredinteger
speechRecognizedrequiredboolean
materialrequiredstringThe material: sources, speech by word ids, pauses, retakes, wishes
guiderequiredstring[]General tips (the Slicer director rules run on the server when you submit the plan)
planSchemarequiredRecord<string, object>JSON schema of the plan for submitDirectorPlan
scenesSchemarequiredRecord<string, object>JSON schema of what you saw in the frames
nextrequiredstring[]

SourceFrames

Field Type Description
sourceIndexrequiredinteger
durationSecrequirednumber
framesrequiredobject[]
frames[].timerequirednumber
frames[].mimeTyperequired"image/jpeg"
frames[].datarequiredstringJPEG, base64, 512 px on the longer side

DirectorPlanRequest

Field Type Description
revrequiredintegerrev from directorBrief / transcript
planrequiredRecord<string, object>The plan in DirectorBrief.planSchema
scenesRecord<string, object>[]What you saw in the frames, in DirectorBrief.scenesSchema0–400

DirectorPlanResult

Field Type Description
revrequiredinteger
durationSecrequirednumber
planSegmentsrequiredinteger
fragmentsrequiredinteger
fixesrequiredstring[]What Slicer corrected by its director rules
issuesrequiredobject[]What you should fix and submit again
issues[].coderequiredstring
issues[].segmentinteger
issues[].messagerequiredstring
videorequiredstringThe resulting video as text (fragments, words, elements) — check it against the plan

DocumentState

Field Type Description
revrequiredinteger
durationSecrequirednumber
documentrequiredobjectEdit document (EditDocument v1). Fields are only added within v1