Retrying a Sume music job: Idempotency-Key and no double charge
Retry a timed-out Sume music request with the same Idempotency-Key and get the original job back. Lyria 3.5 varies per call, so never use a new key.

How do I retry a music request without paying for two tracks?
Send the same Idempotency-Key on every retry of the same request. Sume returns the original job rather than starting a second generation, and each generation is billed at the fixed Music price. Without a key, a client retry after a timeout is a second paid generation, and you will get a different song.
This matters more for music than for most jobs. Google's Lyria 3.5 page states that results may vary between calls, even with the same prompt, so a duplicate cannot be treated as a cache hit or "the same track again".
When does a music submit time out?
The Music Router accepts mode values of async, sync, subscribe and webhook, plus wait_timeout_seconds from 0 to 30 for sync and subscribe. That wait bounds the HTTP call, not the job. The jobs documentation says that if no terminal update arrives before the timeout, the response is still a 2xx with the current job state and polling URLs, and you must not submit a new paid job for the same intent.
Real retries come from network failures, load balancers, workflow engines and clients that re-send after a cut connection. In all of those, the first request may already have been accepted.
What exactly does the same key do?
The docs rule is short: reuse a key only for the same operation and payload. A matching retry returns the original job. A reused key with a different prompt or operation returns 409 idempotency_conflict, and the docs tell you to reuse keys only for exact retries.
| Situation | What to send | Result |
|---|---|---|
| Connection dropped after submit | Same key, same body | Original job returned |
| sync wait timed out (2xx with sync.timed_out) | Poll status_url, no new submit | Same job, keep waiting |
| You want a different take | New key, new submit | New paid generation |
| Same key, edited prompt | Do not | 409 idempotency_conflict |
| Queue full (429 queue_full) | Same key after capacity opens | Retry is safe |
What does a safe retry look like in practice?
Generate the key from your own record, not from a random value at call time, so a restarted process derives the same string. Below, the second call is a retry of the first and returns the same job.
KEY="campaign-482-intro-bed-v1"
BODY='{"prompt":"Warm lo-fi hip hop, 84 BPM, C minor. A 30-second track. Instrumental, no vocals."}'
for i in 1 2; do
curl -s -X POST https://api.sume.com/v1/music-router/generate \
-H "Authorization: Bearer $SUME_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $KEY" \
-d "$BODY"
echo
doneWhat else should the integration do?
Poll GET /v1/jobs/{id}/status until the job is terminal, then read the audio artifact from GET /v1/jobs/{id}/result. Keep status polling even if you use a webhook, because the docs describe delivery as an optimization, not your only recovery path.
Store the job id with your campaign record. The metadata field is stored on the job and not sent to the provider, so you can tag the job with your own id; see the metadata post.
Finally, do not retry a failed job by changing the key silently. Failed jobs and canceled jobs are different cases; decide deliberately whether you want a new paid attempt.
Sources
Related posts
More in Developers
- Mux direct upload chunks: multiples of 256 KB, UpChunk at ~5 MB
Mux direct uploads need chunks in multiples of 256 KB; UpChunk sends about 5 MB. A chunk-size helper and the upload states to wait on before using an asset.
- Mux Robots webhook events vs Sume job events: a verifier
Mux sends robots.job.{workflow}.{status} on every change. Sume sends only job.completed, job.failed and job.canceled, signed. Verify them in Python.
- Nano Banana edit slow? Thinking can't be turned off, expect 202
Google says Nano Banana thinking cannot be disabled. On Sume a call that outlasts 30 seconds returns 202 with a job id. How to handle both without paying twice.
- Netflix subtitle limit: 42 characters per line, and max_chars
Netflix's English timed text spec allows 42 characters per line and two lines. Sume's caption design.phrasing.max_chars accepts 4 to 60, so 42 fits.
Written by Sume