MAI-Image-2.6 returns base64 PNG; Sume returns a hosted image URL
Foundry returns MAI-Image-2.6 as b64_json PNG only. Sume returns a signed media URL in data[].url, in png, jpeg or webp per model. How to handle each in code.

MAI image models on Foundry return a JSON object whose data[].b64_json holds a base64 PNG, and the output format is always PNG (Microsoft Learn, read 2026-10-01). Sume's Image API returns data[].url, a Sume-hosted signed URL, with media_type per image, and the format can be png, jpeg or webp depending on what the model lists. So the save step differs: decode bytes for MAI, download a URL for Sume.
Sume keeps responses small on purpose: the Image API reference says media is mirrored and URLs are returned instead of inline base64.
What does each response look like?
Same job, different handling.
| Item | MAI-Image-2.6 (Foundry) | Sume Image API |
|---|---|---|
| Image field | data[].b64_json | data[].url |
| Format | PNG only | png, jpeg or webp, as the model lists |
| Where the bytes live | In the JSON body | On Sume media storage |
| Cost in the response | Not in the body | usage.cost in USD billed |
| Long job | Not described on the page | 202 with a job envelope after 30 seconds |
How do I save a Sume image to disk?
Check the status code first. 200 is the image response and 202 is a job envelope, so branch before reading data[0].url:
import os
import requests
r = requests.post(
"https://api.sume.com/v1/images",
headers={"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"},
json={"model": "openai/gpt-image-2.5", "prompt": "a lighthouse at dusk"},
timeout=60,
)
if r.status_code != 200:
raise SystemExit(f"not an image response: {r.status_code} {r.text[:200]}")
item = r.json()["data"][0]
ext = item["media_type"].split("/")[-1]
with open(f"out.{ext}", "wb") as f:
f.write(requests.get(item["url"], timeout=60).content)
print("saved", ext)Why keep your own copy?
A signed URL is a delivery link, not an archive. Download the file into your own storage as soon as the job finishes, and store the job id so you can fetch the result again from the jobs API, whose artifacts also live on media.sume.com. Jobs and results shows the artifact shape for a completed job.
Limits
MAI is not in Sume's image list as of this post; the table compares two APIs' conventions. PNG is lossless and large, so a page full of MAI outputs weighs more than the same page in WebP, and you would convert after download. On Sume, ask for output_format only when the model lists it: an unsupported value is rejected rather than ignored.
Sources
Related posts
More in Developers
- Make an AI avatar video from the terminal with the Sume CLI
sume avatars create and sume avatar-videos create submit Avatar 1.0 jobs from a shell. Flags, the --confirm-paid guard, and how to recover the job.
- Make an AI voice sound the same across videos: read the job record
A completed Sume TTS job records the engine, voice, language, output format and settings it used. Reuse them so the next line matches. Why it matters after v4.
- Mastra 1.69 Inngest retries option: durable agents and Sume jobs
Mastra core 1.69.0 adds a retries option for Inngest workflows and durable agents. Pair it with a Sume Idempotency-Key so a retried step never pays twice.
- Check a Meta ad batch for duplicates before upload with Python
A short Python check that flags ads in a batch sharing the same hook and visual before you upload. Useful now that Meta rates creative diversity.
Written by Sume