POST /v1/images status codes on Sume: 200, 202, 400, 404, 502
What each HTTP status from Sume's image route means and what to do: 200 images, 202 job envelope, 400 unsupported_parameter, 404 model_not_found, 502 failed.

A client for POST /v1/images needs five branches, not two. The route waits up to 30 seconds by default (mode: "sync", wait_timeout_seconds: 30) and answers according to what happened inside that window. Facts below are from the Sume Image API docs, read 2026-10-07.
The five outcomes
| Status | Meaning | What to do |
|---|---|---|
| 200 | Job finished inside the wait; body has data[].url, media_type, usage.cost | Download the URLs; log usage.cost |
| 202 | Wait expired, or mode was async or webhook; body is the job envelope with status_url and result_url | Poll GET /v1/jobs/{id}/status, then fetch /result; or use a webhook |
| 400 | Bad request, for example unsupported_parameter or streaming_not_supported | Fix the request; read the model's supported_parameters |
| 404 | model_not_found: unknown model id | Check GET /v1/images/models |
| 502 | A wait-mode job ended failed; error envelope with code, retryable, next_action | Read next_action; the failed job is not billed |
Two traps
First, 202 is not an error. Slow configurations (4K, high or higher quality, large n) are the likeliest to fall out of the 30-second window. Check the status code, not whether data exists in the body.
Second, 502 carries the same remapped error fields as the job status route, including retryable and next_action. A reference URL that cannot be fetched gives a non-retryable input_media_unreachable with next_action: "fix_input"; do not blindly retry it. In async or webhook mode a failed job does not become a 502, because the job is the answer.
A client that branches
import os, requests
H = {"Authorization": "Bearer " + os.environ["SUME_API_KEY"]}
r = requests.post("https://api.sume.com/v1/images", headers=H, timeout=60,
json={"model": "bytedance-seed/seedream-5-lite", "prompt": "a paper boat"})
if r.status_code == 200:
print([d["url"] for d in r.json()["data"]])
elif r.status_code == 202:
print("poll", r.json()["data"]["result_url"])
elif r.status_code == 502:
e = r.json()["error"]
print(e["code"], e["retryable"], e["next_action"])
else:
print(r.status_code, r.text[:200])Sources: Sume Image API docs and Jobs and results (read 2026-10-07).
Sources
Related posts
More in Developers
- Probe a finished video before upload: duration, size and aspect
Run video inspect with frames false to read a render's duration, size and frame rate before posting. Check it against the 3-minute Shorts limit.
- URL or QR code in an AI avatar video: say it, caption it, or link it
An avatar clip cannot reliably carry a QR code or a long URL. Three Sume-supported options: spoken words, authored caption cues, or the text beside the video.
- Python asyncio.Semaphore sized to a Sume plan's job capacity
Free holds 6 paid jobs at once, Pro 24, Startup 48, Scale 120. A Semaphore of that size keeps a 60-job batch from hitting 429 queue_full.
- Python: check Omni Flash 1.1 limits against /v1/videos/models first
Google's Omni runs a sync call and extends in 10-second steps up to 40 seconds. Sume's gemini-omni-flash-1.1 takes 3 to 10 seconds per job. A preflight check.
Written by Sume