Timeline plan for a 40-second Omni stitch: four segments, one minute

Run Sume's unbilled timeline plan on four 10-second Omni clips to see segment_count, billable_minutes and the cost before you render. Request body included.

4 min readSume
All posts

Before you render four 10-second Gemini Omni 1.1 Flash clips into a 40-second video, call POST /v1/timeline-1.0/plan. It is unbilled, creates no job and reserves nothing. It returns duration_seconds, segment_count (4 here), billable_minutes (1 here), estimated_cost_usd_micros and a filtergraph_summary. The render itself costs $0.10 per output minute rounded up per the Timeline docs, so 40 seconds is one billable minute.

Why plan a stitch

Google's Omni 1.1 Flash extends a video in 10-second steps up to 40 seconds (Google, read 2026-10-05). On Sume the catalog model takes 3 to 10 seconds per job (Sume docs: Video Router, read 2026-10-05), so a 40-second piece is four clips joined by a timeline. The plan call checks the join half of the job for free, and it checks your slot timing before any render.

The request

The plan takes the same body as the render. Every clip URL must be a media.sume.com artifact of your workspace; a finished generation job already returns one. video[0].start must be 0, later starts must increase, and a transition goes only on slots after the first.

If the plan comes back with a refusal, fix the body and plan again. You can plan as many times as you like, since nothing is reserved. A typical loop is: draft the slot list from your four job results, plan, read segment_count and billable_minutes, adjust starts, plan again, and only then render.

Slot starts are the part people get wrong. With four 10-second clips and no overlap the starts are 0, 10, 20 and 30. With a 0.25 second fade the compiler compensates for the cross-fade and never pre-shifts your declared starts, so you do not subtract the fade yourself. Declared starts are authoritative.

Last, the spine length: audio.duration_seconds is 40 here, and coverage may stop at most half a second before it. If your last clip is shorter than planned, the plan call will tell you before the render does.

curl -X POST https://api.sume.com/v1/timeline-1.0/plan \
  -H "Authorization: Bearer $SUME_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "audio": { "mode": "silence", "duration_seconds": 40 },
    "video": [
      { "source_url": "https://media.sume.com/artifacts/artf_demo/s1.mp4", "start": 0,  "duration": 10 },
      { "source_url": "https://media.sume.com/artifacts/artf_demo/s2.mp4", "start": 10, "duration": 10,
        "transition": { "type": "fade", "duration": 0.25 } },
      { "source_url": "https://media.sume.com/artifacts/artf_demo/s3.mp4", "start": 20, "duration": 10,
        "transition": { "type": "fade", "duration": 0.25 } },
      { "source_url": "https://media.sume.com/artifacts/artf_demo/s4.mp4", "start": 30, "duration": 10,
        "transition": { "type": "fade", "duration": 0.25 } }
    ]
  }'

What to read in the answer

A refusal tells you a rule before it costs you a render. The docs list codes such as timeline_must_start_at_zero, segment_overlap, transition_too_long and unsupported_media_source.

  • segment_count equals 4. If it does not, a slot is missing or merged.
  • billable_minutes equals 1. At 61 seconds it would be 2, so a 60-second ceiling is a price edge.
  • estimated_cost_usd_micros is the render estimate in millionths of a dollar. Compare it with the $0.10 rate on the pricing page and in GET /v1/catalog.

The plan is not the whole bill

The timeline line is small. The four generation jobs are the cost: at 720p that is 40 seconds at the Omni rate, worked out in the 35-second cost post for a similar cut. Run the plan to check slot timing and the render fee, and use the catalog for the clip prices. If you add a music bed, set it as audio.url or soundtrack; silence mode fits drafts and reviews.

Once the plan reads right, send the same body to POST /v1/timeline-1.0/render with an Idempotency-Key. It returns a job; poll GET /v1/jobs/:id/status and read video_url from the result.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume