GPT Image 2.5 returns base64; Sume returns a URL: port the code
OpenAI's image API returns base64 data for GPT Image models, and Sume's returns hosted URLs. The three lines that change when you move a decoder over.

If you move a GPT Image 2.5 integration from OpenAI's API to Sume's Image API, the response parsing is the first thing that breaks. OpenAI's guide says the GPT image models return base64-encoded image data (OpenAI image generation guide, read 2026-10-04), so existing code decodes a string and writes bytes. Sume returns data[].url, a hosted link to the file, plus a media_type, so the new code downloads instead of decoding.
The change is small, but three other differences travel with it: the model id, the hosted file's lifetime assumption, and the status-code split at 30 seconds. This post puts the old and new side by side and lists what to change.
Old response, new response
A Sume image response is {created, model, data: [{url, media_type}], usage: {..., cost}}. The model field echoes the id you sent, usage.cost is the USD billed to your wallet, and token counts are always 0 because images are metered per image (Sume Image API docs). On OpenAI's side you read the image payload from the response data and decode it; the table summarises where each piece lives.
Output format is output_format on Sume with png, jpeg or webp on the rows checked for this post. OpenAI's guide also lists a 0-100 compression setting; on Sume, output_compression is part of the schema but returns 400 unsupported_parameter today.
| Item | OpenAI (GPT Image models) | Sume Image API |
|---|---|---|
| Image payload | base64-encoded data you decode | data[].url hosted link you download |
| Format control | output format and 0-100 compression | output_format; output_compression returns 400 |
| Model id | gpt-image-2.5-flare, gpt-image-2.5-sunburst | openai/gpt-image-2.5, openai/gpt-image-2.5-sunburst |
| Slow generations | OpenAI notes complex prompts can take up to 2 minutes | 202 with a job envelope after 30 seconds |
The port, in one function
The function below saves the images from a Sume response, and handles the 202 path by returning the job URLs instead of pretending it has files. It keeps the file extension in line with media_type. It needs requests and a Sume key.
If you stream OpenAI results straight into a decoder, switch to a download step; the hosted files are served from media.sume.com, as in the docs' example response.
import os, requests
EXT = {"image/png": "png", "image/jpeg": "jpg", "image/webp": "webp"}
def generate(prompt: str, prefix: str = "out") -> list[str]:
r = requests.post("https://api.sume.com/v1/images", timeout=120, json={
"model": "openai/gpt-image-2.5", "prompt": prompt, "quality": "medium"},
headers={"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"})
r.raise_for_status()
if r.status_code == 202:
job = r.json()["data"]
raise RuntimeError(f"still running: poll {job['status_url']}")
paths = []
for i, item in enumerate(r.json()["data"]):
path = f"{prefix}-{i}.{EXT.get(item['media_type'], 'bin')}"
with open(path, "wb") as f:
f.write(requests.get(item["url"], timeout=60).content)
paths.append(path)
return paths
print(generate("a paper boat on a pond, soft morning light"))Checklist when porting
Rename the model id, replace the decoder with a download, treat 200 and 202 as two response shapes, and drop compression settings. For the full request on Sume, see GPT Image 2.5 on Sume and the Python example.
Do not send stream: true to Sume: it returns 400 streaming_not_supported, and usage.cost replaces any token-based cost tracking you had.
Sources
Related posts
More in Developers
- GPT Image 2.5 can take two minutes: handle the 202 job on Sume
OpenAI says complex GPT Image 2.5 prompts can take up to two minutes. Sume blocks 30 seconds, then returns a 202 job. Submit async, poll, and fetch the result.
- GPT Image 2.5 custom size: 3840x2160 passes, 3840x1200 fails
Check a custom image_size for ChatGPT Image 2.5 on Sume before you send it: multiples of 16, 3840 max edge, 3:1 max ratio, 655,360 to 8,294,400 pixels.
- One config file for gpt-image ids before December 1
OpenAI retires gpt-image-1-mini, gpt-image-1.5 and chatgpt-image-latest on 2026-12-01. Keep image ids in one map, and test Flare and Sunburst on Sume now.
- Graceful shutdown for a Node webhook receiver: 503 while draining
On SIGTERM, refuse new Sume webhooks with 503, finish the in-flight write, then exit. Sume retries non-2xx responses 10 times, so deploys lose nothing.
Written by Sume