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.

5 min readSume
All posts

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.

curl retry flags, from the curl manual, and the Sume reading, read 2026-10-02.
FlagWhat the curl manual saysFor a Sume submit
--retry <num>Retries transient errors; default 0.Safe once the Idempotency-Key header is set.
--retry-max-timeLimits the total time allowed for retries.Set it, so a full queue does not keep curl waiting.
--retry-delayDisables the exponential backoff.Leave it off; the doubling is what you want.
--retry-all-errorsThe 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_url rather than resubmitting.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume