duck_requires_audio_spine: no music ducking under silence mode
Timeline refuses soundtrack.duck_db when audio.mode is silence, since there is no voice to duck under. The fix, the other silence rules, and a check.

duck_requires_audio_spine is the Timeline 1.0 refusal for soundtrack.duck_db combined with audio.mode: "silence". Ducking lowers the music while a voice plays, and silence mode has no voice file. Remove duck_db and set the bed level with soundtrack.gain_db, or give the timeline a real spine (audio.url or audio.parts[]) and keep the duck.
Which silence-mode fields are refused?
The Timeline 1.0 page defines audio.mode: "silence" as a declared length with no spine file. In that mode url, parts, gain_db and source_in on the audio are illegal, and each one has its own code. duck_db on the soundtrack is the one people hit after switching an existing request to silence.
audio.duration_seconds is still required, from 1 to 1800 seconds, because it sets the output length.
| Code | Silence mode plus | Fix |
|---|---|---|
| silent_audio_takes_no_url | audio.url | Remove the url |
| silent_audio_takes_no_parts | audio.parts[] | Remove the parts |
| silent_audio_takes_no_gain | audio.gain_db | Remove it; use soundtrack.gain_db |
| silent_audio_takes_no_source_in | audio.source_in | Remove it |
| duck_requires_audio_spine | soundtrack.duck_db | Remove duck_db or add a real spine |
How is this different from sidechain ducking in FFmpeg?
In an FFmpeg graph you wire the voice into a compressor yourself, and nothing stops you from wiring silence into it. Sume's duck_db (0 to 20 dB) is a field on the soundtrack that always refers to the audio spine, so the API checks that a spine exists.
With a silent video and a music bed, what you want is a level, not a duck. Use soundtrack.gain_db (-60 to 12), loop: true for a bed shorter than the video, and fade_out_seconds up to 10.
A request that passes
The sketch below builds both bodies and asserts the rule that separates them. It runs as written, using placeholder artifact URLs in the documented shape.
Send the corrected body to POST /v1/timeline-1.0/plan first. It is unbilled and returns the same refusal, with no job created. Then render with an Idempotency-Key and poll as in Jobs and results.
base = {"video": [{"source_url": "https://media.sume.com/artifacts/artf_demo/b.mp4",
"start": 0, "duration": 12}]}
bad = {**base, "audio": {"mode": "silence", "duration_seconds": 12},
"soundtrack": {"url": "https://media.sume.com/artifacts/artf_demo/bed.mp3",
"duck_db": 12}}
good = {**base, "audio": {"mode": "silence", "duration_seconds": 12},
"soundtrack": {"url": "https://media.sume.com/artifacts/artf_demo/bed.mp3",
"gain_db": -6, "loop": True, "fade_out_seconds": 2}}
def refusal(body):
if body["audio"].get("mode") == "silence" and body.get("soundtrack", {}).get("duck_db", 0) > 0:
return "duck_requires_audio_spine"
print(refusal(bad)) # duck_requires_audio_spine
print(refusal(good)) # NoneWhich mode should a silent product loop use?
Silence mode with a soundtrack bed. Declare the length with audio.duration_seconds, give the video slots starts that add up to it, and let the soundtrack loop under the picture with a gain that sits well below full scale. The bed's fade_out_seconds gives a clean ending without any voice track.
If a voiceover is added later, switch the audio to a real spine, keep the same video slots, and then duck_db becomes legal. Because only the audio block changes, the move from silent to narrated is a small edit to the same document.
What are the soundtrack ranges?
On the Timeline 1.0 page the soundtrack fields are gain_db from -60 to 12, duck_db from 0 to 20, fade_out_seconds up to 10, and loop. Out-of-range values are refused at submit, so a quick range check in your builder saves a round trip.
A sensible starting point for a silent product loop is a negative gain, a loop and a short fade-out, then adjust by ear after the first render. Because the plan call is unbilled, you can iterate on the structure for free and only pay for the renders you listen to.
Sources
Related posts
More in Developers
- timeline_must_start_at_zero and transition_on_first_segment fixes
Timeline 1.0 needs video[0].start to be 0 and no transition on slot 0. How to open on a fade or a later in-point, with a Python builder that runs.
- Timeline segment_overlap: set start times when clips cross-fade
Sume Timeline returns segment_overlap when a slot starts before the previous one ends minus the fade. The rule, the fix, and a Python check.
- Timeline transition_too_long: 1 s cap and half the shorter clip
transition_too_long means a Timeline fade is over 1 s or over half the shorter neighbour. Sub-frame fades fail too. Limits, snapping, and a check.
- Transactional outbox for paid API calls in Python (Sume)
Write the Sume request and its Idempotency-Key in the order's transaction, drain later: a tested Python outbox that survives crashes, 429s and 409s.
Written by Sume