MV Scene Editing and Final Video
Scene Controls
Section titled “Scene Controls”Fast and Studio write operations are versioned. New clients should send
expectedVersion from the latest MVView.version; stale versions return
409 MV_VERSION_CONFLICT. On conflict, read GET /api/v1/mv/{mvId} again and
retry with the current version. Studio requires this version for storyboard
writes. Fast uses the same field for managed scene edits and later
recomposition. If expectedVersion is omitted on a Fast request, OmnAPI uses
the latest MV version available when the request is accepted. This is kept for
backward compatibility; sending expectedVersion is recommended so concurrent
edits can be detected.
Edit one Fast scene
Section titled “Edit one Fast scene”Fast scene edit reuses the public render endpoint. OmnAPI maps this to the
managed scene edit operation and increments MVView.version when the edit is
accepted. It does not refresh the final MP4 by itself.
Recommended flow:
- Read the current
MVViewand keepMVView.version. - Quote the scene edit.
- Create the scene edit task with
prompt,referenceImages, or both, plusexpectedVersion. - Poll the returned task until it reaches a terminal state.
- Read
MVViewagain and inspect the edited scene’ssourceJob. - Optionally select any
isSelectable=trueversion fromrenderingHistory. - When the selected composition is ready, quote and finalize to recompose the final MP4.
Read the current version:
For each new logical operation, set and save a fresh REQUEST_KEY once.
Reuse it with the exact same route and body only when recovering that operation.
Use a different saved key when trying a different example or export format.
export REQUEST_KEY="$(uuidgen)"curl https://api.omnapi.com/api/v1/mv/{mvId} \ -H "x-api-key: sk_live_..."Preview the scene edit charge before creating the paid edit task:
curl -X POST https://api.omnapi.com/api/v1/mv/quote \ -H "x-api-key: sk_live_..." \ -H "Content-Type: application/json" \ -d '{ "mode": "fast", "step": "scene-edit", "mvId": "{mvId}", "sceneIndex": 2 }'Edit one generated Fast scene:
curl -X POST https://api.omnapi.com/api/v1/mv/{mvId}/scenes/2/render \ -H "x-api-key: sk_live_..." \ -H "Content-Type: application/json" \ -d '{ "expectedVersion": 4, "quoteId": "{quoteId}", "maxCredits": 240, "prompt": "close-up singer shot, warm backlight, smoother camera motion", "referenceImages": [ "https://cdn.example.com/references/singer-close-up.jpg" ] }'Fast scene edit requests require at least one of prompt or
referenceImages. referenceImages accepts one to seven public image URLs.
A non-empty list replaces the selected scene’s source images for the new
rendering; omitting referenceImages preserves them. An empty list is invalid,
so a prompt-only edit must omit the field rather than send [].
expectedVersion and task config are optional. videoPromptOverride and
videoPrompt are accepted only as compatibility aliases for the Fast prompt;
new Fast integrations should send prompt. Studio render fields such as
resolution, videoProvider, and videoModel are Studio-only; passing them
on a Fast MV is rejected.
Use MVView.capabilities.canRerenderSceneWithPrompt and
canRerenderSceneWithImages to enable the matching editor controls. The
accepted prompt and replacement images are returned on the new
renderingHistory[] entry so an editor can explain how each version was
created.
The response includes taskId, sceneIndex, version, charged, and
creditsRequired. Poll the task:
curl https://api.omnapi.com/api/v1/tasks/{taskId} \ -H "x-api-key: sk_live_..."After the edit task completes, read MVView again. If
scene.sourceJob.status is RENDERING, keep polling or read again later. If it
is FAILED, the previous playable scene.videoUrl may still remain available;
retry the scene edit or select a different successful history item before
recomposing.
Select any Fast scene version with isSelectable=true by passing the
corresponding MVView.scenes[].renderingHistory[].id:
curl -X PATCH https://api.omnapi.com/api/v1/mv/{mvId}/scenes/2/select-rendering \ -H "x-api-key: sk_live_..." \ -H "Content-Type: application/json" \ -d '{ "expectedVersion": 5, "renderingId": "019f..." }'The response includes the refreshed version. Selecting the already effective
rendering is a no-op. Selecting a different rendering makes the final MP4 stale
until you recompose it.
Quote the final recomposition:
curl -X POST https://api.omnapi.com/api/v1/mv/quote \ -H "x-api-key: sk_live_..." \ -H "Content-Type: application/json" \ -d '{ "mode": "fast", "step": "compose", "mvId": "{mvId}" }'Then create the finalize task with the refreshed MVView.version:
curl -X POST https://api.omnapi.com/api/v1/mv/{mvId}/finalize \ -H "x-api-key: sk_live_..." \ -H "Content-Type: application/json" \ -d '{ "expectedVersion": 5, "quoteId": "{quoteId}", "maxCredits": 50 }'Poll the finalize task using the returned taskId, then read the final URL:
curl https://api.omnapi.com/api/v1/tasks/{finalizeTaskId} \ -H "x-api-key: sk_live_..."curl https://api.omnapi.com/api/v1/mv/{mvId}/final \ -H "x-api-key: sk_live_..."Studio: regenerate one scene image
Section titled “Studio: regenerate one scene image”Persist prompt or editorial changes before regenerating or rendering:
curl -X PATCH https://api.omnapi.com/api/v1/mv/{mvId}/scenes/2 \ -H "x-api-key: sk_live_..." \ -H "Content-Type: application/json" \ -d '{ "expectedVersion": 4, "imagePrompt": "same singer, warmer sunset palette", "videoPrompt": "slow push-in with restrained motion", "framing": "close-up", "lighting": "golden hour", "mood": "hopeful", "lyricsWindow": "We meet again beneath the amber sky", "startSec": 8, "endSec": 14 }'| Field | Limit and meaning |
|---|---|
expectedVersion | Required non-negative MVView.version concurrency guard. |
imagePrompt | Persistent still-image instruction, 1-1500 chars. |
videoPrompt | Persistent scene-motion instruction, 1-1500 chars. |
framing, lighting, mood | Optional persistent direction, max 300 chars each. |
lyricsWindow | Optional lyric context for this scene, max 1000 chars. |
startSec, endSec | Optional non-negative timing boundaries; when changed they must satisfy the timing rules below. |
At least one editable field must change. Unknown fields are rejected.
Image-affecting edits invalidate the previous still and selected rendering; video-only edits retain the still but make the scene stale. The response returns the incremented scene and MV versions.
Timing edits must keep each scene within 1–16 seconds, avoid overlap with adjacent scenes, and stay within the known source duration. Submitting only unchanged values is rejected instead of invalidating an otherwise current scene.
curl -X POST https://api.omnapi.com/api/v1/mv/{mvId}/scenes/2/regenerate-image \ -H "x-api-key: sk_live_..." \ -H "Content-Type: application/json" \ -d '{ "expectedVersion": 5, "quoteId": "{quoteId}", "maxCredits": 15, "imagePromptOverride": "warmer sunset palette, keep the same character" }'Studio: render one scene video
Section titled “Studio: render one scene video”curl -X POST https://api.omnapi.com/api/v1/mv/{mvId}/scenes/2/render \ -H "x-api-key: sk_live_..." \ -H "Content-Type: application/json" \ -d '{ "expectedVersion": 6, "quoteId": "{quoteId}", "maxCredits": 240, "videoProvider": "p-video", "videoModel": "p-video", "resolution": "540p" }'For Studio, prompt is treated as a one-shot videoPromptOverride.
To render several current scene versions with one quote, idempotency key, task,
and charge, use step:"render-batch" on quote and then:
curl -X POST https://api.omnapi.com/api/v1/mv/{mvId}/scenes/render-batch \ -H "x-api-key: sk_live_..." \ -H "Idempotency-Key: $REQUEST_KEY" \ -H "Content-Type: application/json" \ -d '{ "expectedVersion": 6, "quoteId": "{quoteId}", "maxCredits": 720, "sceneIndexes": [0, 1], "videoProvider": "p-video", "videoModel": "p-video", "resolution": "540p" }'The batch accepts 1-30 scenes. Each scene result remains visible; a partial failure does not hide successful renders. OmnAPI charges the successful scene components and atomically refunds the failed scene components; if every scene fails, the task follows the normal full-refund path.
Select a Studio rendering
Section titled “Select a Studio rendering”curl -X PATCH https://api.omnapi.com/api/v1/mv/{mvId}/scenes/2/select-rendering \ -H "x-api-key: sk_live_..." \ -H "Content-Type: application/json" \ -d '{ "expectedVersion": 6, "renderingId": "rend_01H..." }'Studio: lock a character anchor
Section titled “Studio: lock a character anchor”Quote the operation with mode:"studio", step:"lock-character", and the
current mvId, then confirm the returned ceiling on the write:
curl -X POST https://api.omnapi.com/api/v1/mv/{mvId}/lock-character \ -H "x-api-key: sk_live_..." \ -H "Content-Type: application/json" \ -d '{ "expectedVersion": 7, "quoteId": "{quoteId}", "maxCredits": 5, "characterImage": "https://example.com/portrait.jpg", "description": "same singer throughout the video" }'characterImage must be a public http(s) URL.
Studio mutation request fields
Section titled “Studio mutation request fields”The paid Studio mutation endpoints reject unknown fields. Quote before each
paid operation and use the current MVView.version as expectedVersion.
| Operation | Required body fields | Optional body fields |
|---|---|---|
| Regenerate image | expectedVersion | quoteId, maxCredits, imagePromptOverride, imagePrompt, config |
| Render one scene | expectedVersion | quoteId, maxCredits, prompt, videoPromptOverride, videoPrompt, durationSec, resolution, aspectRatio, fps, draft, videoProvider, videoModel, config |
| Render batch | expectedVersion, sceneIndexes | quoteId, maxCredits, resolution, aspectRatio, fps, draft, videoProvider, videoModel, config |
| Select rendering | expectedVersion, renderingId | none |
| Lock character | expectedVersion, characterImage | description, quoteId, maxCredits, config |
quoteId is 1-100 chars, maxCredits is non-negative, and config is the
standard Task config. Prompt limits are 3000 chars for prompt, 1500 for
imagePromptOverride, imagePrompt, videoPromptOverride, and videoPrompt,
and 500 for the character description. Studio durationSec is 1-16;
resolution is 540p, 720p, or 1080p; aspectRatio is 16:9, 9:16,
1:1, 4:3, or 3:4; fps is numeric 24 or 48; videoProvider is
p-video, hailuo, or vidu; and videoModel is at most 100 chars.
sceneIndexes contains 1-30 unique non-negative indexes. renderingId and
characterImage must be non-empty strings.
Finalize
Section titled “Finalize”Fast create normally generates and stores the final MP4 automatically. After the
create task completes, call GET /api/v1/mv/{mvId}/final to get a fresh
temporary URL. This endpoint is read/refresh only: it returns ready=true only
when the stored final matches the current source composition. If Fast scene
edits later make the final stale, the response returns ready=false,
staleReason="source_changed", and actionHint="recompose_after_edit".
Fast explicit finalize is used for recovery or to recompose after successful Fast scene edits or selection changes. The finalize task creates a new final MP4 from the selected successful scene outputs. For legacy Fast projects with no explicit selections, OmnAPI uses the newest successful output per scene.
curl -X POST https://api.omnapi.com/api/v1/mv/{mvId}/finalize \ -H "x-api-key: sk_live_..." \ -H "Content-Type: application/json" \ -d '{ "expectedVersion": 5 }'Studio finalize stitches selected scene renderings with the resolved audio:
curl -X POST https://api.omnapi.com/api/v1/mv/{mvId}/finalize \ -H "x-api-key: sk_live_..." \ -H "Content-Type: application/json" \ -d '{ "expectedVersion": 8, "scenes": [ { "sceneIndex": 0, "renderingId": "rend_01H..." }, { "sceneIndex": 1, "renderingId": "rend_01J..." } ] }'| Body field | Type | Notes |
|---|---|---|
title | string | Optional title override. |
retry | bool | Retry a failed finalize when supported. |
expectedVersion | number | Studio required. Fast optional for backward compatibility, recommended for new clients; use the latest MVView.version. |
selectLatest | bool | Studio: finalize latest ready rendering per scene. |
scenes | array | Studio: explicit scene/rendering selection. |
config | object | Optional task config for the finalize task. |
Response fields: taskId, creditsRequired, status, idempotent,
optional finalMvId, optional compositionHash, optional retryable.
Fast finalize uses the selected successful output per scene and records composition metadata so repeated finalization remains idempotent. Studio finalize remains selected-scene stitching; when the selected composition changes, OmnAPI prepares a final asset for the new composition.
When the task completes:
curl https://api.omnapi.com/api/v1/mv/{mvId}/final \ -H "x-api-key: $OMNAPI_KEY"Returns a short-lived final MP4 URL when ready (60 minutes by default):
{ "id": "<final-mv-asset-id>", "ready": true, "status": "READY", "videoUrl": "https://cdn.omnapi.com/...", "expiresInSec": 3600, "urlExpiresAt": "2026-07-11T15:00:00.000Z", "retainedUntil": "2026-08-10T14:00:00.000Z"}If GET /final returns ready=false, use staleReason to choose the next
action:
staleReason | Action |
|---|---|
source_rendering | Wait for the scene edit task to finish, then read MVView again. |
source_failed | Retry the failed scene edit before finalizing. |
source_changed | Call POST /api/v1/mv/{mvId}/finalize to recompose. |
final_processing | Poll the finalize task or call GET /final again later. |