Timeline audio

Current SoT. Timeline 1.0 audio (sume/timeline-1.0/audio, #3516). Dest and prod. This mints a reusable audio file. A join that is only needed inside one render belongs on Timeline 1.0 audio.parts[] — skip this job.

Timeline audio joins Sume-hosted audio into one gapless file (operation: concat) or slices one file into ranges (operation: split) and returns durable media.sume.com URLs plus timings. The join is sample-domain — no re-TTS and no silence at the seams. The server compiles ffmpeg on the same worker media runtime as the render (apps/api/src/routes.ts createTimelineV1Audio / submitSumeTimelineAudioJob).

There is no GET /v1/timeline-1.0/audio/:id. Poll the job envelope:

Hosted MCP: timeline_audio (packages/mcp-server/src/mcp.ts). Writes need idempotency_key (and mcp:write under OAuth). Flow: timeline_audiojobs_waitjobs_result.

Concat

Required: operation: "concat" and parts[] (1–20, ordered). Each part is { url, source_in?, duration? }. Do not send url or ranges at the top level (audio_concat_takes_no_url / audio_concat_takes_no_ranges). All URLs must already be this workspace’s media.sume.com audio. Import first (POST /v1/media-imports). Idempotency-Key is required.

Default mode is async. Pass mode: "sync" to wait up to 30 seconds for a 200 finished job, or get 202 and poll.

Result kind: timeline_audio with one audio_url, duration_seconds, and segments[] (index, start, duration_seconds) — the concat offsets to re-base Timeline 1.0 video[].start against. Use that file as audio.url on the render, or as Avatar 1.0 image-to-video audio.

Parts must share one channel layout (audio_parts_channel_mismatch).

Split

Required: operation: "split", top-level url, and ranges[] (1–20). Each range is { start, end? } (end omitted = rest of file). Do not send parts (audio_split_takes_no_parts). Ranges may overlap.

Result kind: timeline_audio with segments[], each with its own audio_url. For many ranges off a talking-head MP4: audio detach once, then split here.

Output format

Optional output.format: wav (default, pcm_s16le, sample-exact) or mp3 (smaller; re-adds priming padding at every edge). Keep wav when the file will be joined again or drives lip-sync.

Produced audio ≤ 1800 s.

Public rate: $0.01 flat per job (TIMELINE_AUDIO_PUBLIC_PRICING; confirm live in GET /v1/catalog). No provider inference — worker ffmpeg only.

Refusals (stable codes)

CodeWhen
audio_concat_requires_partsConcat without parts.
audio_concat_takes_no_url / audio_concat_takes_no_rangesConcat plus a split field.
audio_split_requires_url / audio_split_requires_rangesSplit missing url or ranges.
audio_split_takes_no_partsSplit plus parts.
audio_range_end_before_startA range endstart.
audio_parts_channel_mismatchConcat parts do not share a channel layout (worker).
unsupported_media_source / source_not_foundOff-host or dead URL.
Provider / ffmpeg keys400 — filtergraph, ffmpeg_args, codec, crf, friends.

Off-host URLs (https://example.com/…) are rejected at admit. Import first.

Not this surface

NeedUse
Audio track of one video as wav / mp3Audio detach
Join only for one renderTimeline 1.0 audio.parts[]
Sequence several clipsTimeline 1.0
Still + video in one frameTimeline compose
Speech-to-textPOST /v1/stt-1.0/generate