Does the Sume SDK retry POST? Only with an Idempotency-Key
createSumeClient retries 408, 429 and 5xx twice with backoff, but a POST is only retried when it carries an Idempotency-Key. Why and how to set it.

createSumeClient retries 408, 429, 5xx and transport failures up to 2 times by default, with exponential backoff and jitter, honoring retry-after. But a POST is retried only when it carries an Idempotency-Key. Without one, a replay would start and bill a second run, so the client sends the request once and surfaces the failure.
Details are from Waiting for runs and jobs and Jobs and results, read 2026-10-02.
What are the defaults?
Two layers handle transient trouble, both on by default.
| Layer | Default | Option |
|---|---|---|
| createSumeClient retries 408, 429, 5xx and transport failures | 2 retries, exponential backoff and jitter, honors retry-after | maxRetries, timeout |
| waitForRun tolerates consecutive transient read failures | 6 | maxTransientFailures, onTransientError |
Who generates the key?
subscribeFormatRun generates a UUID key for you unless you pass your own idempotencyKey, or null to send none. A replay of a finished run returns immediately. For the generated job operations, such as generateVideoV1, you pass the key yourself in the idempotency-key header, as the job example in the docs does.
For a stable key, derive it from your own business event, such as an order id plus a version, not from a clock. A random key per attempt defeats the point, because every retry then looks like a new request.
import { createSumeClient, generateVideoV1 } from "@sume-com/sdk";
const client = createSumeClient({
apiKey: process.env.SUME_API_KEY!,
maxRetries: 2,
});
const { data, error } = await generateVideoV1({
client,
headers: { "idempotency-key": "order-8823-hero-v1" },
body: { prompt: "Slow push-in on a ceramic mug", mode: "async" },
});
if (error) throw new Error(JSON.stringify(error));
console.log(data!.data.request_id);What does a replay return?
Retrying a submit with the same Idempotency-Key returns the original job instead of billing a second one. The docs say to reuse the key only for the same operation and payload. A different body under a used key is a 409 idempotency_conflict, and a request still in flight under the same key is 409 idempotency_key_in_use, which is retryable after about a second.
A failed create releases its key, but a run that failed after it started keeps the key bound to its receipt, so retry a failed run with a new key.
What should I check when a POST seems to fail once?
If a call timed out client-side, do not resubmit with a new key. The job may exist and be billing. Resend the same request with the same key, or look the job up by id if you stored it.
- Always send a key on paid creates, so the client can retry safely.
- Store the job id from the first response, since every mode returns one.
- On
429, waitretry-after; onqueue_full, wait for a job to finish. - Do not turn
maxRetriesup to hide an outage; the loop does not cancel anything.
Sources
Related posts
More in Developers
- curl --retry on a POST: retry a Sume submit with one key
curl --retry also retries a POST, and it resends the same headers each time. Put an Idempotency-Key on a Sume submit first, then pick --retry-max-time.
- Decart lucy-latest vs a pinned Lucy model; Sume catalog ids
Decart's lucy-latest alias can move while legacy Lucy Clip costs $0.15 per second against $0.04 for Lucy 2.5. Why pin a model id, and how to do it on Sume.
- Detect new AI image models: diff Sume GET /v1/images/models
Image models arrive weekly. A short Python diff against GET /v1/images/models tells you when Sume adds or retires an image model id, with no news feed to watch.
- Download a finished Seedance or Kling MP4 from the Sume API
Two ways to get the file: GET /v1/videos/{id}/content with your key, or the hosted artifact URL from /v1/jobs/{id}/result. A Python download script.
Written by Sume