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.0audio.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_audio → jobs_wait → jobs_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)
| Code | When |
|---|---|
audio_concat_requires_parts | Concat without parts. |
audio_concat_takes_no_url / audio_concat_takes_no_ranges | Concat plus a split field. |
audio_split_requires_url / audio_split_requires_ranges | Split missing url or ranges. |
audio_split_takes_no_parts | Split plus parts. |
audio_range_end_before_start | A range end ≤ start. |
audio_parts_channel_mismatch | Concat parts do not share a channel layout (worker). |
unsupported_media_source / source_not_found | Off-host or dead URL. |
| Provider / ffmpeg keys | 400 — filtergraph, ffmpeg_args, codec, crf, friends. |
Off-host URLs (https://example.com/…) are rejected at admit. Import first.
Not this surface
| Need | Use |
|---|---|
| Audio track of one video as wav / mp3 | Audio detach |
| Join only for one render | Timeline 1.0 audio.parts[] |
| Sequence several clips | Timeline 1.0 |
| Still + video in one frame | Timeline compose |
| Speech-to-text | POST /v1/stt-1.0/generate |