Skip to content

    Music Video

    Music Video — drafts, edits and upgrades

    Availability varies by operationOpen App ↗

    Everything on this page happens around a video created as described in the Music Video API. Each paid action — a preview, a scene edit, a recompose, an upgrade — is a separate purchase with its own quote, taskId, Idempotency-Key and settlement. Saving, reading and checking are free.

    Use the endpoint family that created the video: /api/v2/mv for Omn, /api/v1/mv for OneClick, OneClick Turbo, Studio and Omn on API v1.

    A draft stores a request so you can revise it, buy a short preview, and only then buy the full video. Drafts expire after 30 days.

    Omn (/api/v2/mv/drafts)

    1. POST /api/v2/mv/drafts with a normal Omn request (source, creative, output, optional references, captions). Save the returned id and version.
    2. Revise with PATCH /api/v2/mv/drafts/{id} sending expectedVersion and the replacement request. A 409 means someone else changed it — read it again.
    3. Optional preview: POST /{id}/preview/preflight with expectedVersion, then buy it with POST /{id}/preview using that preflightId, expectedVersion, maxCredits and an Idempotency-Key. A preview covers at most ten seconds of the selected range and does not buy the full video. previewSelection reports the exact range chosen (cached_energy picks a high-energy part; opening_fallback starts at the beginning of your range).
    4. Full video: POST /{id}/preflight, then POST /{id}/generate with expectedVersion, maxCredits and a new Idempotency-Key.

    OneClick, Turbo and Omn on API v1 (/api/v1/mv/drafts) follow the same steps, but the body is a brief and revisions use PUT with expectedVersion and the complete brief. The draft defaults to vidu-v2; set engineVersion to choose another model. Style and performance are optional (auto); GET /api/v1/mv/styles lists style cards. Audio sources accept title (≤ 200 chars), musicStyle (≤ 500) and lyrics (≤ 5,000).

    {
    "source": { "type": "audio", "audioUrl": "https://media.example.com/song.mp3" },
    "engineVersion": "omn-v1",
    "performanceMode": "story",
    "description": "A traveler follows a paper bird through a rainy hometown",
    "renderTier": "draft",
    "subtitles": false
    }

    API v1 and API v2 drafts are not interchangeable. If preparation cannot find enough song information or a visual concept, the Task stops and asks for more context — add lyrics or describe the visuals.

    Reusable creative versions (development preview). Omn requests may carry creative.continuity to reuse a project and revision from GET /api/v2/mv/creative-projects with the same audio and mode. Omit it for an independent video. DELETE /api/v2/mv/creative-projects/{id} archives a project. Confirm this is available in your deployment before relying on it.

    Scene edits re-render one shot. They do not refresh the full video: afterwards you recompose to produce a new final MP4. Every write takes the MV’s current version as expectedVersion; a stale value returns 409 MV_VERSION_CONFLICT — read the MV again and retry with the new version.

    Omn (/api/v2/mv)

    1. Quote: POST /api/v2/mv/{mvId}/quote with operation: "scene-edit" and sceneIndex (zero-based).
    2. Edit: POST /api/v2/mv/{mvId}/scenes/{sceneIndex}/edit with prompt, referenceImages, an optional performance (story, sing, perform, dance), expectedVersion, the quote or maxCredits, and an Idempotency-Key.
    3. Wait for the edit Task, then read the MV. To use an older take, pick a renderingHistory item with isSelectable: true and call PATCH /api/v2/mv/{mvId}/scenes/{sceneIndex}/select-rendering with renderingId and expectedVersion. Selecting is free.
    4. Recompose: quote with operation: "compose", then POST /api/v2/mv/{mvId}/recompose with the authorization and an Idempotency-Key. Review the cuts around edited scenes.

    OneClick and Turbo (/api/v1/mv) — the edit reuses the render endpoint:

    Terminal window
    # Quote the edit (free)
    curl -X POST https://api.omnapi.com/api/v1/mv/quote \
    -H "x-api-key: $OMNAPI_KEY" -H "Content-Type: application/json" \
    -d '{ "mode": "fast", "step": "scene-edit", "mvId": "MV_ID", "sceneIndex": 2 }'
    # Edit scene 2 (paid). Save the key once and reuse it on retries.
    export EDIT_KEY="$(uuidgen)"
    curl -X POST https://api.omnapi.com/api/v1/mv/MV_ID/scenes/2/render \
    -H "x-api-key: $OMNAPI_KEY" -H "Idempotency-Key: $EDIT_KEY" \
    -H "Content-Type: application/json" \
    -d '{
    "expectedVersion": 4,
    "quoteId": "QUOTE_ID",
    "maxCredits": 240,
    "prompt": "close-up singer shot, warm backlight, smoother camera motion",
    "referenceImages": ["https://cdn.example.com/references/singer-close-up.jpg"]
    }'
    # After the edit Task completes: quote and recompose (paid)
    curl -X POST https://api.omnapi.com/api/v1/mv/quote \
    -H "x-api-key: $OMNAPI_KEY" -H "Content-Type: application/json" \
    -d '{ "mode": "fast", "step": "compose", "mvId": "MV_ID" }'
    export COMPOSE_KEY="$(uuidgen)"
    curl -X POST https://api.omnapi.com/api/v1/mv/MV_ID/finalize \
    -H "x-api-key: $OMNAPI_KEY" -H "Idempotency-Key: $COMPOSE_KEY" \
    -H "Content-Type: application/json" \
    -d '{ "expectedVersion": 5, "quoteId": "QUOTE_ID", "maxCredits": 50 }'
    • An edit needs prompt, referenceImages (1–7 URLs, replacing the scene’s images) or both. Omitting referenceImages preserves the scene’s images; an empty list is invalid.
    • Read capabilities.canRerenderSceneWithPrompt / canRerenderSceneWithImages before showing edit controls. Turbo deployments that have not enabled editing return 503 without charging.
    • If an edit fails, the previous take stays playable. Retry the edit or select another take before recomposing.
    • A compose quote of 0 means the final already matches the selected scenes.
    • Use GET /api/v1/mv/{mvId}?historyLimit=5 in editors to fetch only recent takes.

    Edits and recompose verify the source media first. If the audio or references have expired, they return 409 MV_PRECONDITION_FAILED with details.reason: "source_assets_unavailable" before charging; repeating the request will not help.

    Omn videos can be re-rendered at a higher resolution. An upgrade is a new full-video purchase at the target price (not the difference), keeps the aspect ratio and includes recomposition.

    1. Read the MV: capabilities.upgrade.available, reason and resolutions. Burned-in captions and motion-transfer videos cannot be upgraded.
    2. POST /api/v2/mv/{mvId}/upgrade/preflight with output: { "resolution": "1080p" }. It returns an upgrade quoteId, price and expiry.
    3. POST /api/v2/mv/{mvId}/upgrade with the same output, the quoteId, maxCredits and an Idempotency-Key. A failed upgrade keeps the previous video.
    ResponseMeaning
    400Invalid target, or not higher than the current resolution
    422The video is not eligible (for example captions burned in)
    409The MV is not finished or another operation is running

    Upgrades for Omn videos created on /api/v1/mv use render tiers; see Omn on API v1.

    After editing scenes you can return every scene to the last delivered video without paying for a new composition. This is a development preview: it requires lastFinalRestore: true in GET /api/v2/mv/capabilities.

    1. GET /api/v2/mv/{mvId}/final-restore (task:read) previews videoUrl, changedScenes, sceneCount and retainedUntil.
    2. POST /api/v2/mv/{mvId}/final-restore (task:create) with the returned expectedVersion and snapshotSha256, unchanged.
    3. Read the MV: creditsCharged: 0, finalizationRequired: false. Newer takes stay in scene history; retention is unchanged.

    A 409 means the preview is stale, an operation is running, or assets are missing or expired — read a new preview. No Task is created.

    Studio is a manual workflow on /api/v1/mv with mode: "studio": OmnAPI creates a storyboard with scene stills, you review and edit scenes, render the ones you want, and finalize. Audio is 10–300 seconds.

    Terminal window
    export STUDIO_KEY="$(uuidgen)"
    curl -X POST https://api.omnapi.com/api/v1/mv \
    -H "x-api-key: $OMNAPI_KEY" -H "Idempotency-Key: $STUDIO_KEY" \
    -H "Content-Type: application/json" \
    -d '{
    "mode": "studio",
    "source": { "type": "audio", "audioUrl": "https://example.com/song.mp3", "durationSec": 30 },
    "title": "Pocket Change",
    "prompt": "cinematic music video, warm close-ups, rhythm-aware editing",
    "aspectRatio": "9:16",
    "resolution": "540p",
    "maxCredits": 2000,
    "generation": { "imageProvider": "gpt-image-2", "videoProvider": "p-video", "videoModel": "p-video" }
    }'

    The receipt has autoFinalize: false and deliveryStatus: "drafting". When the storyboard is ready (status: READY), work scene by scene:

    StepEndpointPrice
    Storyboard and scene stillsPOST /api/v1/mv250, plus optional Visual Board images
    Edit a scene’s text, timing or directionPATCH /api/v1/mv/{mvId}/scenes/{i}Free
    Regenerate one stillPOST /api/v1/mv/{mvId}/scenes/{i}/regenerate-image15
    Render one scene videoPOST /api/v1/mv/{mvId}/scenes/{i}/renderQuoted by model, resolution, fps and duration
    Render several scenesPOST /api/v1/mv/{mvId}/scenes/render-batch (1–30 scenes)Quoted; failed scenes are refunded
    Pick a renderingPATCH /api/v1/mv/{mvId}/scenes/{i}/select-renderingFree
    FinalizePOST /api/v1/mv/{mvId}/finalize50

    Quote each paid step first with POST /api/v1/mv/quote (mode: "studio" and step: storyboard, regenerate-image, render-scene, render-batch, finalize or total).

    Save the change first, then regenerate. PATCH …/scenes/{i} accepts expectedVersion (required) and any of imagePrompt, videoPrompt (1–1,500 chars), framing, lighting, mood (≤ 300), lyricsWindow (≤ 1,000), startSec, endSec. Scenes must stay 1–16 seconds, not overlap and stay within the audio. An image change invalidates the still and its renderings; a video-only change marks the scene stale.

    Terminal window
    curl -X POST https://api.omnapi.com/api/v1/mv/MV_ID/scenes/2/regenerate-image \
    -H "x-api-key: $OMNAPI_KEY" -H "Idempotency-Key: $(cat regen-key.txt)" \
    -H "Content-Type: application/json" \
    -d '{ "expectedVersion": 5, "quoteId": "QUOTE_ID", "maxCredits": 15, "imagePromptOverride": "warmer sunset palette, keep the same character" }'
    Terminal window
    curl -X POST https://api.omnapi.com/api/v1/mv/MV_ID/scenes/2/render \
    -H "x-api-key: $OMNAPI_KEY" -H "Idempotency-Key: $(cat render-key.txt)" \
    -H "Content-Type: application/json" \
    -d '{ "expectedVersion": 6, "quoteId": "QUOTE_ID", "maxCredits": 240, "videoProvider": "p-video", "videoModel": "p-video", "resolution": "540p" }'

    For Studio, prompt is a one-off video prompt override. render-batch takes sceneIndexes and the same render options under one quote, key and Task.

    POST /api/v1/mv/{mvId}/lock-character accepts characterImage, expectedVersion, optional description and maxCredits. There is currently no public quote for it: POST /api/v1/mv/quote rejects step: "lock-character". If your integration requires a quote before every purchase, keep this action disabled.

    All Studio writes reject unknown fields and require expectedVersion.

    OperationRequiredOptional
    Regenerate imageexpectedVersionquoteId, maxCredits, imagePromptOverride, imagePrompt, config
    Render one sceneexpectedVersionquoteId, maxCredits, prompt, videoPromptOverride, videoPrompt, durationSec (1–16), resolution (540p/720p/1080p), aspectRatio, fps (24/48), draft, videoProvider (p-video, hailuo, vidu), videoModel, config
    Render batchexpectedVersion, sceneIndexes (1–30)as render one scene, without prompts
    Select renderingexpectedVersion, renderingId—
    Lock characterexpectedVersion, characterImagedescription (≤ 500), quoteId, maxCredits, config

    Studio finalize stitches the selected renderings with the audio. Pass explicit scenes: [{ sceneIndex, renderingId }] or selectLatest: true:

    Terminal window
    curl -X POST https://api.omnapi.com/api/v1/mv/MV_ID/finalize \
    -H "x-api-key: $OMNAPI_KEY" -H "Idempotency-Key: $(cat finalize-key.txt)" \
    -H "Content-Type: application/json" \
    -d '{ "expectedVersion": 8, "scenes": [ { "sceneIndex": 0, "renderingId": "rend_01H..." }, { "sceneIndex": 1, "renderingId": "rend_01J..." } ] }'

    The same endpoint recomposes OneClick and Turbo videos after edits, and recovers a failed finalize with retry: true. It returns taskId, creditsRequired and status; read GET /api/v1/mv/{mvId}/final when the Task completes.

    COMPLETED confirms the operation finished; it does not certify story, character consistency, lip sync or musical timing. Watch the full video before publishing.

    • qualityStatus on the Task and MV: pending, not_evaluated, human_review_required (watch some shots) or needs_revision (findings to review). Neither changes success, billing or refunds. qualityReviewUrl links to the evidence.
    • The workflow quality object lists suggestedRepairSceneIndexes, playbackReviewSceneIndexes, internalCutSceneIndexes, frameBorderSceneIndexes, coverage counts and per-check shotChecks. Scene indexes are zero-based. Unreviewed scenes are not passes.
    • quality.filmReview, when present, is a separate review of sampled frames from the delivered video; no_findings_in_samples is not approval.
    • Omn asks for review only on concrete evidence: continuity, picture or identity defects, a duplicated or extra person, a finding against your stated requirements, unconfirmed mouth timing on a singing shot, or a failed shot check.
    • highlight on the MV view (url, startSec, durationSec) is a short excerpt without captions, useful as a preview. It expires; read the MV again for a new URL.

    Review findings never buy anything. Use them to choose which scenes to edit.

    For progress detail beyond Task status, read the workflow of any operation’s taskId (task:read):

    Endpoint (Omn / API v1)Use
    GET /api/v2/mv/tasks/{id}/workflow · GET /api/v1/tasks/{taskId}/workflowStages, settlement, quality findings
    …/workflow/eventsDurable events; pass nextCursor as after
    …/workflow/streamServer-sent events; reconnect with Last-Event-ID
    …/workflow/artifactsCustomer-visible intermediate media, paginated with after
    …/workflow/artifacts/{assetId}A fresh access URL for one artifact
    • A run waiting for a delivery slot or for vocal separation reports activity.wait (reason: delivery_queue or lyric_timing, queuePosition). It is not failing and needs no action.
    • billing.debited, billing.refunded and billing.net are decimal strings in credits; wait for billing.final: true. debited "61", refunded "1", net "60" with settlement: "CHARGED" is a partial refund.
    • A completed phase with MV_AUTO_SUBTITLE_FALLBACK_SKIPPED means the video continued without automatic captions.

    MV webhooks use the standard config.webhookUrl and task.* events; finalize operations can also send mv.ready / mv.failed with mvId and finalUrl. See Completion webhooks.