Retry an avatar video request without paying twice

A timed-out avatar video submit can be retried safely with the same Idempotency-Key. What Sume returns, what causes a 409, and how to build the key.

4 min readSume
All posts

If your request to POST /v1/avatar-1.0/talking-video times out, retry the exact same request with the exact same Idempotency-Key; Sume returns the original job instead of creating and billing a second one. Do not generate a new key for a retry, and do not reuse a key for a different script. A reused key with a different operation or payload is rejected as 409 idempotency_conflict.

The reason this matters for video is cost and time. An avatar render is billed per second, from $0.184 on standard to $0.55 on max, and it runs for longer than the 30 seconds a submit call may wait. A client that gives up and resubmits is the usual way to pay twice.

What each situation should do

The rules come from Sume's generation admission and jobs docs.

From Generation admission and Jobs and results.
What happenedDo thisNot this
Your HTTP client timed out after submitResubmit with the same key, or poll the status_url if you stored itSubmit with a fresh key
sync wait ended with sync.timed_outPoll status_url; the job existsTreat it as a failure and resubmit
429 queue_fullWait for jobs to finish, then retry with the same keyHammer the endpoint in a loop
503 provider_capacity_exceededRetry later with the same key unless the error says otherwiseChange the payload to dodge it
409 idempotency_conflictUse a new key for the new operationOverwrite the old key with a different script

Building a good key

A key should name the intent, not the attempt. Include the business object and the content version, for example order-8841-intro-v3. When the script changes, the version changes, and so does the key. When only the network failed, nothing changes.

Store the key in your own database before you send the request. After a crash you can retry with the same value without guessing.

KEY="onboarding-step2-v1"
for attempt in 1 2 3; do
  curl -sS --max-time 20 -X POST https://api.sume.com/v1/avatar-1.0/talking-video \
    -H "Authorization: Bearer $SUME_API_KEY" \
    -H "Content-Type: application/json" \
    -H "Idempotency-Key: $KEY" \
    -d '{"avatar_handle":"studio_presenter","script":"Open Settings, then choose Team.","mode":"async"}' \
    && break
  sleep $((attempt * 5))
done

After the job exists

  • Keep status_url, result_url, events_url and cancel_url from the first response.
  • Poll with backoff until terminal is true, or use a signed webhook and keep polling as the backup.
  • Cancel with POST /v1/jobs/{id}/cancel if the script was wrong; cancelling an already canceled job returns the same canceled job.
  • Failed jobs and failed queue admission release or refund their reserved usage.

Limits

An idempotency key protects the submit call. It does not stop you from sending two different scripts that you both meant to send, and it does not make a render cheaper. If you fan out many videos, also watch generation_limits on the response and stop adding work when queue capacity is low.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume