Skip to content

MV Scene Editing and Final Video

Product overview · Task model

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.

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:

  1. Read the current MVView and keep MVView.version.
  2. Quote the scene edit.
  3. Create the scene edit task with prompt, referenceImages, or both, plus expectedVersion.
  4. Poll the returned task until it reaches a terminal state.
  5. Read MVView again and inspect the edited scene’s sourceJob.
  6. Optionally select any isSelectable=true version from renderingHistory.
  7. 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.

Terminal window
export REQUEST_KEY="$(uuidgen)"
Terminal window
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:

Terminal window
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:

Terminal window
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:

Terminal window
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:

Terminal window
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:

Terminal window
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:

Terminal window
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:

Terminal window
curl https://api.omnapi.com/api/v1/tasks/{finalizeTaskId} \
-H "x-api-key: sk_live_..."
Terminal window
curl https://api.omnapi.com/api/v1/mv/{mvId}/final \
-H "x-api-key: sk_live_..."

Persist prompt or editorial changes before regenerating or rendering:

Terminal window
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
}'
FieldLimit and meaning
expectedVersionRequired non-negative MVView.version concurrency guard.
imagePromptPersistent still-image instruction, 1-1500 chars.
videoPromptPersistent scene-motion instruction, 1-1500 chars.
framing, lighting, moodOptional persistent direction, max 300 chars each.
lyricsWindowOptional lyric context for this scene, max 1000 chars.
startSec, endSecOptional 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.

Terminal window
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" }'
Terminal window
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:

Terminal window
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.

Terminal window
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..." }'

Quote the operation with mode:"studio", step:"lock-character", and the current mvId, then confirm the returned ceiling on the write:

Terminal window
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.

The paid Studio mutation endpoints reject unknown fields. Quote before each paid operation and use the current MVView.version as expectedVersion.

OperationRequired body fieldsOptional body fields
Regenerate imageexpectedVersionquoteId, maxCredits, imagePromptOverride, imagePrompt, config
Render one sceneexpectedVersionquoteId, maxCredits, prompt, videoPromptOverride, videoPrompt, durationSec, resolution, aspectRatio, fps, draft, videoProvider, videoModel, config
Render batchexpectedVersion, sceneIndexesquoteId, maxCredits, resolution, aspectRatio, fps, draft, videoProvider, videoModel, config
Select renderingexpectedVersion, renderingIdnone
Lock characterexpectedVersion, characterImagedescription, 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.


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.

Terminal window
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:

Terminal window
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 fieldTypeNotes
titlestringOptional title override.
retryboolRetry a failed finalize when supported.
expectedVersionnumberStudio required. Fast optional for backward compatibility, recommended for new clients; use the latest MVView.version.
selectLatestboolStudio: finalize latest ready rendering per scene.
scenesarrayStudio: explicit scene/rendering selection.
configobjectOptional 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:

Terminal window
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:

staleReasonAction
source_renderingWait for the scene edit task to finish, then read MVView again.
source_failedRetry the failed scene edit before finalizing.
source_changedCall POST /api/v1/mv/{mvId}/finalize to recompose.
final_processingPoll the finalize task or call GET /final again later.