UGC-style ad: a music bed that ducks under the voice
Add a looped music bed to a UGC-style ad and lower it under the voice with soundtrack.duck_db in a Timeline 1.0 render. Needs a real voice spine.

To put a music bed under a UGC-style ad and have it dip when the creator speaks, add a soundtrack to the Timeline 1.0 render document with duck_db between 0 and 20. The bed lowers by that many decibels under the audio spine, which carries the voice. Ducking needs a real spine: with audio.mode: "silence" the request fails with duck_requires_audio_spine.
Source: Timeline 1.0: assemble clips into one MP4. A render is $0.10 per output minute, rounded up, at the public rate, so a 30-second ad is $0.10; confirm the live price in GET /v1/catalog.
What goes in the soundtrack object
soundtrack.url is a Sume-hosted audio file; gain_db sets its base level; loop repeats a short bed to fill the length; fade_out_seconds is at most 10; and duck_db is 0 to 20. A bed that is shorter than the ad and set to loop covers any length without you editing the track. A soundtrack fade longer than the spine is refused with soundtrack_fade_exceeds_output.
Choosing numbers that work
A UGC voice is usually a phone microphone, so it is not loud. A bed that sits only a few decibels under it will fight it. Start with duck_db around 12 and gain_db at a modest negative number, listen on phone speakers, and adjust in 2 dB steps. These starting numbers are a suggestion for a first listen, not a published standard. The point of ducking is that you can leave the bed fairly present between sentences and let it drop when someone talks.
The document below is a 30-second ad: one voice spine, one video slot and a looped bed with a 2-second fade out. The render needs an Idempotency-Key.
import json, os, urllib.request
doc = {
"audio": {
"url": "https://media.sume.com/artifacts/artf_demo/creator-voice-30s.wav",
"duration_seconds": 30,
},
"video": [
{"source_url": "https://media.sume.com/artifacts/artf_demo/ugc-30s.mp4",
"start": 0, "duration": 30},
],
"soundtrack": {
"url": "https://media.sume.com/artifacts/artf_demo/bed-loop.mp3",
"gain_db": -6,
"loop": True,
"fade_out_seconds": 2,
"duck_db": 12,
},
}
req = urllib.request.Request(
"https://api.sume.com/v1/timeline-1.0/render",
data=json.dumps(doc).encode(),
headers={"Authorization": "Bearer " + os.environ["SUME_API_KEY"],
"Content-Type": "application/json",
"Idempotency-Key": "ugc-bed-001"},
)
with urllib.request.urlopen(req) as r:
print(r.status, json.load(r))
Where the bed comes from
Sume also generates music through its Music surfaces, and the output is a hosted file you can pass as soundtrack.url. Pick a track by listening, because AI music varies from take to take. If you use a licensed track from elsewhere, import it to media.sume.com first, and check that its licence covers paid ads.
| Field | Range or value | Refusal code if wrong |
|---|---|---|
| duck_db | 0 to 20 | duck_requires_audio_spine with silence |
| loop | true or false | None |
| fade_out_seconds | At most 10 | soundtrack_fade_exceeds_output if longer than the spine |
| gain_db | Set a base level | Not allowed with silence |
| url | Sume-hosted audio | unsupported_media_source if off host |
Test it properly
Listen on a phone speaker and on headphones, because the two hide different problems. Then listen once with the sound at a low volume, the way most people will meet the ad. If you can no longer follow the voice, raise duck_db. The render is cheap, so run two or three values and keep the best.
Two more controls sit outside the soundtrack object. output.fade_in_seconds and output.fade_out_seconds run from 0 to 5 seconds and fade the whole render, picture and sound, and their sum must not exceed the output length. The soundtrack fade is separate and goes up to 10 seconds, but it cannot be longer than the spine. If you want the bed to end cleanly under a closing line, use the soundtrack fade; if you want the picture to fade to black as well, use the output fade.
If you generate the bed with Sume, the Music Router is priced at $0.125 per audio generation at the standard margin, per the catalog read on 2026-10-06. A bed is reusable, so one generation can sit under every variant of an ad. Looping makes a short bed cover the ad, but a loop point can be audible; listen to the seam at the loop, not only at the start.
Sources
Related posts
More in Use cases
- Video ad end card: add a fade-in and fade-out with Timeline
Close an ad with a 1-second fade-out and open it with a 0.5-second fade-in using output.fade_in_seconds and fade_out_seconds in a Timeline 1.0 render.
- Which Sume video model makes a 15-second 9:16 ad? A catalog filter
List the models in GET /v1/videos/models that accept 15 seconds at 9:16 with a short Python filter, instead of trusting a stale table.
- Yard sign artwork via API: 3:2 art, a quoted headline, a print check
Generate yard sign artwork at 3:2 on Sume with GPT Image 2.5 or Ideogram 4.5, keep the headline to a few words, quote it, and check the pixel size for print.
- YouTube Shorts series covers: one template, one edit per episode
YouTube is rolling out Shorts series with covers. Make one template with Ideogram 4.5, then change only the episode number with one edit call per episode.
Written by Sume