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.
- Migrate Veo 3.1 API calls to Gemini Omni Flash 1.1: parameter map
Veo 3.1 previews shut down October 22, 2026. A parameter-by-parameter map from the Veo guide to Gemini Omni Flash 1.1 requests on Sume, with a working curl.
- Music API has no duration field: steer length in the prompt
Sume's music router rejects duration and duration_seconds. Ask for a 30-second or 2-minute track in the prompt, with section timestamps, and verify.
- Music API metadata field: tag a track job with your own ids
Sume's music request has an optional metadata field, stored on the job and not sent to the provider. Use it to match tracks to your own records.
Written by Sume