GPT Image 2.5 curl command: generate and download in a shell
A copy-paste curl call to Sume's POST /v1/images for GPT Image 2.5, with jq to pull the URL, download the file, and a check for the 202 job response.

The shortest GPT Image 2.5 call from a shell is one curl to https://api.sume.com/v1/images with model set to openai/gpt-image-2.5 and a prompt, and jq to read the image URL from data[0].url. Download that URL with a second curl. If the response has no data array it is probably a 202 job envelope, which needs a status poll instead.
The script below does the whole round trip, checks for the 202 case, and writes out.png. It uses only curl and jq. Facts are from the Image API docs and Jobs and results, read 2026-10-03.
What is the one-liner?
Export your key as SUME_API_KEY. Sume accepts either Authorization: Bearer or x-api-key. The call below asks for medium quality at 1024x1024; if you leave quality out, Sume uses high.
set -euo pipefail
resp=$(curl -sS -w '\n%{http_code}' https://api.sume.com/v1/images \
-H "Authorization: Bearer $SUME_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"openai/gpt-image-2.5","quality":"medium","image_size":"1024x1024","prompt":"A red kite over a green hill, flat illustration"}')
code=${resp##*$'\n'}
body=${resp%$'\n'*}
if [ "$code" = 200 ]; then
url=$(printf '%s' "$body" | jq -r '.data[0].url')
curl -sS -o out.png "$url"
echo "saved out.png"
elif [ "$code" = 202 ]; then
echo "still running; poll: $(printf '%s' "$body" | jq -r '.data.status_url')"
else
echo "HTTP $code: $body" >&2; exit 1
fiWhy does the script check the status code?
Sume's docs say to check the status code, not the body shape: 200 is the image response and 202 is the job envelope. The blocking wait is capped at 30 seconds; slower configurations such as 4K, high quality or a larger n are the likeliest to return 202.
On a 202, the job is already running and billed on completion. Poll status_url with the same header until terminal is true, then read result_url. Do not run the original command again.
Which flags and fields do I change most?
These are the knobs you will edit, all taken from Sume's schema.
| Field | Values on GPT Image 2.5 | Note |
|---|---|---|
quality | auto, low, medium, high, xhigh, max | Omitted means high on Sume |
image_size | WIDTHxHEIGHT, both multiples of 16, max edge 3840 | Aspect at most 3:1, 655,360 to 8,294,400 pixels |
output_format | png, jpeg, webp | Check the model row; svg is listed in the schema |
background | auto, transparent, opaque | GPT Image 2.5 only |
mode | sync, async, subscribe, webhook | Async always returns the job envelope |
How do I edit a photo with curl?
Add input_references with a public HTTPS URL and set aspect_ratio to auto so the output matches the source. Do not set image_size and aspect_ratio together; image_size wins. A local file path will not work, because references must be public HTTPS URLs.
curl -sS https://api.sume.com/v1/images \
-H "Authorization: Bearer $SUME_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"openai/gpt-image-2.5","aspect_ratio":"auto","quality":"medium",
"prompt":"Keep the subject; change the sky to sunset. Change nothing else.",
"input_references":[{"type":"image_url","image_url":{"url":"https://example.com/photo.jpg"}}]}'What goes wrong most often?
Most failed first attempts come from a short list.
- A
400 unsupported_parameterfrom a field the model does not list, such asseedoroutput_compression. - A custom size with an edge that is not a multiple of 16, for example 1080.
- A
402because the workspace balance is too low; no job starts. - Pasting the same command again after a 202 and paying for a second image.
How do I poll a 202 from the shell?
Take status_url and result_url from the 202 body, then loop: read status_url with the same header, stop when terminal is true, and only then request result_url. Honour next_poll_after_seconds if the status response includes it, and fall back to a few seconds between reads. Stop on failed or canceled and read the job's error instead of retrying the paid request.
If you plan to run many of these, move to mode: "async" so every call returns the job envelope and your script has one code path. Add an Idempotency-Key header for any call you might repeat after a network failure, and reuse the key only for the identical payload.
A quick way to see what a model accepts before you script it is GET /v1/images/models, which lists the capability descriptors per model. Anything missing from a model's list is rejected with 400 unsupported_parameter, so a thirty-second look saves a failed run.
Sources
Related posts
More in Developers
- Use a local photo as a GPT Image 2.5 reference: it needs a URL
Sume's input_references take public HTTPS image URLs only; localhost and private URLs are rejected. Three ways to turn a file on disk into a usable reference.
- GPT Image 2.5 negative prompt: no field, so write exclusions
Sume's /v1/images has no negative_prompt for GPT Image 2.5. Put exclusions in the prompt as positive rules and a preserve list; examples and a curl call.
- Batch GPT Image 2.5 from a CSV in Python: async jobs, safe retries
Render one GPT Image 2.5 packshot per CSV row on Sume: mode async, an Idempotency-Key per SKU, a small worker pool, and the 429 queue_full rule.
- GPT Image 2.5 seed: can you get the same image twice?
Sume lists seed in the schema but does not serve it: seed returns 400 unsupported_parameter. How to keep a look repeatable with references and masked edits.
Written by Sume