Retry an avatar video submit without paying twice on Sume
Use one Idempotency-Key per paid avatar video submit and poll the job instead of resubmitting after a timeout. A Python example and the rules from Sume docs.
Send an Idempotency-Key header on every paid avatar video submit, keep the key stable across retries of the same clip, and poll the job instead of submitting again when your client times out. Sume's docs say: do not submit a paid request again only because your local worker timed out.
Rules from the docs
The Generation admission page (read 2026-10-08) lists the recommended client behavior for production integrations:
- Prefer async submit with an idempotency key.
- Treat queued and processing as normal non-terminal states.
- Use exponential backoff when polling; avoid tight loops across many jobs.
- Poll until terminal is true, or until your own deadline.
- Store status_url, result_url, events_url and cancel_url when present.
- Check generation_limits; when queue capacity is low, do not add more work.
Key design
The key must identify the clip, not the attempt. Build it from stable inputs such as a campaign id and clip number, and change it only when the request body genuinely changes, for example after you edit the script. If you generate a random key on every retry, you defeat the purpose.
The docs' own batch example uses keys shaped like avatar-batch-001-item-001, one per item.
| Situation | Key | Action |
|---|---|---|
| Network timeout on submit | Same key | Resubmit the identical body, or poll if you stored the job |
| Script edited | New key | Submit as a new paid job |
| Job reached failed state | Decide per error | Fix the cause, then use a new key |
| Queue full | Same key | Back off, wait for capacity, then retry |
Example submit
This standard-library Python script submits one clip and prints the poll URLs. It reads the key from SUME_API_KEY.
import json
import os
import urllib.request
key = os.environ["SUME_API_KEY"]
body = {
"avatar_handle": "product_host",
"aspect_ratio": "9:16",
"script": "Meet the host who never needs a reshoot.",
}
req = urllib.request.Request(
"https://api.sume.com/v1/avatar-1.0/talking-video",
data=json.dumps(body).encode(),
method="POST",
headers={
"Authorization": f"Bearer {key}",
"Content-Type": "application/json",
"Idempotency-Key": "campaign-12-clip-03",
},
)
with urllib.request.urlopen(req, timeout=30) as resp:
job = json.load(resp)
print(job.get("status_url"), job.get("result_url"))
After submit
Poll the status URL with backoff until the job is terminal, then read the result URL. Avatar videos are not something to wait on in one HTTP request: sync and subscribe modes are the same bounded wait of at most 30 seconds, per Jobs and results. Use async plus polling, or a webhook with a poll fallback.
Handling a rejected submit
A 4xx from the API means the request itself is wrong, such as a script outside the 4-60 second window or a bad URL. Fix the body and use a new key. A 5xx or a timeout means you do not know whether Sume accepted the job, which is exactly the case the key protects.
If you stored a job id from an earlier attempt, poll it first. Only resubmit with the same key if you have nothing to poll. Keep logs that tie each key to a clip, so billing questions later are easy to answer.
Sources
Related posts
More in Developers
- Review a 30-second Wan 3.0 clip: video inspect caps at 24 stills
Video inspect returns at most 24 stills per call, so a 30-second clip needs a sample rate of 0.8 fps or an explicit list of 24 times. Python builds the request.
- Rotate the Sume webhook secret twice in one 24-hour window: what dies
Sume signs with both secrets for 24 hours after a rotation. Rotate a second time inside that window and the secret from two rotations back stops at once.
- Rotate the Sume webhook secret without dropping events
After POST /v1/webhooks/signing-secret/rotate, Sume signs with both secrets for 24 hours. How verifyWebhook handles the two-entry header, and the deploy order.
- Same prompt on five Sume image models in one script: about 18 cents
One loop sends a text-in-image prompt to Flux 2 Pro, Seedream 5.0 Lite, Qwen Image, Imagen 4 Fast and Recraft V4. Expected total $0.18125. Code you can run.
Written by Sume