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.

curl --retry 5 will retry a failed POST, so a Sume submit sent that way needs an Idempotency-Key first. The key is a fixed -H in the command, so every attempt sends the same one and a retry returns the original job instead of billing a second. Add --retry-max-time to cap the total time, and send Content-Type: application/json yourself, because -d defaults to form encoding.
curl's side comes from the curl manual (read 2026-10-02). Sume's side comes from Jobs and results and Errors and rate limits, and from MDN's Retry-After page.
What does curl --retry actually retry?
Per the manual, a transient error is a timeout, an FTP 4xx, or an HTTP 408, 429, 500, 502, 503, 504, 522, or 524. The first wait is one second and each later wait doubles, up to 10 minutes, and curl honors a Retry-After header when one is present. --retry-delay turns the doubling off.
| Flag | What the curl manual says | For a Sume submit |
|---|---|---|
--retry <num> | Retries transient errors; default 0. | Safe once the Idempotency-Key header is set. |
--retry-max-time | Limits the total time allowed for retries. | Set it, so a full queue does not keep curl waiting. |
--retry-delay | Disables the exponential backoff. | Leave it off; the doubling is what you want. |
--retry-all-errors | The sledgehammer; may send or receive duplicate data. | Do not use it on a paid POST. |
Which Sume errors will curl retry for me?
Sume's 429 rate_limited and 429 queue_full and its 503 provider_capacity_exceeded all fall inside curl's transient list, and the docs say to retry each with the same idempotency key. Errors that need a fix do not: 400, 401, 402, 404, and 409 are not on curl's list, so they fail fast.
Note queue_full. It means the workspace has no accepted generation capacity left until a job finishes or is canceled, so more retries inside a short window will not help. That is why --retry-max-time matters.
What does the full command look like?
--fail-with-body makes curl exit non-zero on an HTTP error while still printing Sume's JSON error body, which carries the request_id to quote to support.
curl -sS --fail-with-body --retry 5 --retry-max-time 90 \
-X POST https://api.sume.com/v1/images \
-H "Authorization: Bearer $SUME_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-8823-hero-v1" \
-d '{"model":"sume/auto","prompt":"matte black bottle on marble","mode":"async"}'What can still go wrong?
Four mistakes account for most double charges and stuck scripts.
- A new key per run defeats the point. Derive the key from your business intent, such as order id plus revision, not from a timestamp.
- Reusing a key with a changed payload returns
409 idempotency_conflict. - Do not reuse a key for a different request; a new intent needs a new key.
- curl retries the submit only. After a 202, poll
status_urlrather than resubmitting.
Sources
Related posts
More in Developers
- 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.
- Dub a 20-minute video: audio detach 900 s cap, STT 600 s, TTS 1,200 s
A 20-minute video needs chunking before a dub: audio detach outputs at most 900 s, STT reservation tops out at 600 s, and TTS fails past 1,200 s.
- Facebook Reels API: start, upload, finish and the video_state values
Publishing a Facebook Reel takes three calls: upload_phase start, a file upload to rupload, then finish with video_state PUBLISHED, SCHEDULED or DRAFT.
Written by Sume