Image API wait_timeout_seconds: submit now, poll later
Set wait_timeout_seconds to 0 on POST /v1/images to stop blocking and treat every call as a job. How the 200 and 202 answers differ and a polling script.

wait_timeout_seconds on POST /v1/images takes 0 to 30 and defaults to 30. It is the blocking wait budget, so a low value makes the call return sooner with a 202 job envelope you poll yourself. Always branch on the status code, because a quick model can still answer 200 inside any budget above zero.
The Image API docs list the field in the request table: wait_timeout_seconds, integer, 0 to 30, default 30 on this route, "blocking wait budget for sync / subscribe." The same table says the default mode is sync.
When is a short wait the right choice?
A web request handler that must answer in a few seconds should not hold a connection for 30. A queue worker that fans out fifty images does not want fifty open connections either. In both cases, ask for little or no waiting and collect results later.
Choosing a value is simple. Use 0 when you will never wait. Use a small number such as 5 if you want fast models to answer inline while slow ones fall back to a job. Leave the default of 30 when a person is waiting and a delay under half a minute is acceptable.
- Serverless handlers with short execution limits.
- Fan-out scripts that submit many images then read them together.
- Anything that already stores job ids for crash recovery.
What do the three answers look like?
The shapes come from the docs. Do not parse the body to work out which one you got.
| Status | Meaning | What to do |
|---|---|---|
| 200 | Image finished inside the wait budget | Read data[].url and usage.cost |
| 202 | Job accepted, still running | Poll status_url, then read result_url |
429 with queue_full or rate_limited | Capacity or request rate | Back off using retry-after, reuse the idempotency key |
A submit-then-collect script
This sends five prompts with a zero wait, keeps the job ids, then polls them. It tolerates the occasional 200. Set SUME_IMAGE_MODEL to an id from the catalog.
import os, time, requests
B = "https://api.sume.com"
H = {"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"}
def done(o):
if isinstance(o, dict):
if o.get("status") in ("completed", "failed", "canceled"): return True
return any(done(v) for v in o.values())
return False
pending, urls = [], []
for i in range(5):
r = requests.post(B + "/v1/images", headers=H, timeout=30, json={
"model": os.environ["SUME_IMAGE_MODEL"], "wait_timeout_seconds": 0,
"prompt": f"Flat-lay product photo, variant {i + 1}"})
if r.status_code == 200: urls += [d["url"] for d in r.json()["data"]]
elif r.status_code == 202: pending.append(r.json()["data"])
else: print(r.status_code, r.text[:200])
for d in pending:
while not done(requests.get(d["status_url"], headers=H).json()): time.sleep(3)
print(requests.get(d["result_url"], headers=H).json())
print(urls)What stays the same?
Billing does not change with the wait budget. A completed image is billed in full and a failed or cancelled one is not. Closing your connection early is not a way to cancel: the Sume docs say client disconnects are treated as failed generations for billing, and a related post covers what happens to the job.
For many images, a webhook is cleaner than polling. Send mode: "webhook" with a public HTTPS webhook_url and verify the x-sume-webhook-signature header as the webhooks guide describes.
Keep the job ids you collect. The Jobs docs say to store the id from submit responses so you can recover work after a process restart, and to avoid resubmitting a paid request just because a local process timed out. A zero wait makes that discipline the norm instead of the exception.
Sources
Related posts
More in Developers
- Instagram Login or Facebook Login for a Reels publishing app?
Both logins can publish Reels. They differ in host, token and scopes, and resumable upload plus some metrics are Facebook Login only. Pick before you build.
- Instagram API Reels total_interactions: how it is calculated
Instagram's insights reference defines total_interactions as likes, saves, comments and shares minus unlikes and deletions, and marks it in development.
- Instagram content_publishing_limit: read quota_usage before a bulk run
Read GET /<IG_USER_ID>/content_publishing_limit before queuing Reels. Meta's pages cite 100 posts per 24 hours and show quota_total 50, so do not hard-code it.
- Instagram media_audio_type: MUSIC vs ORIGINAL_SOUND on Reels
Instagram added a media_audio_type field on June 1, 2026 that tells licensed MUSIC from ORIGINAL_SOUND. What it means for a Reel you build with Sume.
Written by Sume