Port a Bedrock image call to Sume /v1/images in Python
Moving from boto3 invoke_model for Nova Canvas or Titan to Sume's REST call: the request mapping, the response shape, the status codes, and the swap code.

A Bedrock image call posts a task-specific JSON body and reads images from the response. Sume's call is one flat JSON body with the same fields for every model. The mapping is mostly renaming, plus three behaviour changes.
| Bedrock concept | Sume field |
|---|---|
| Prompt text | prompt |
| numberOfImages | n, capped per model |
| Source image, base64 | input_references[].image_url.url, a public HTTPS URL |
| maskImage, base64 | mask_url, GPT Image 2.5 only |
| Width and height | aspect_ratio, resolution or image_size |
| cfgScale, seed | No field; unsupported parameters return 400 |
Three behaviour changes
- Results are URLs, in
data[].url, not base64 strings. - The call waits 30 seconds by default, then returns
202with a job envelope. Handle it. - Errors come back as an envelope with
category,retryableandnext_action, and failed jobs are not billed.
A wrapper with the same return type
Most Bedrock callers want bytes back. This wrapper returns bytes and raises on anything that is not a finished image, so your downstream code does not change.
import os, requests
def generate_bytes(prompt: str, source_url: str | None = None,
model: str = "google/nano-banana-2") -> bytes:
body = {"model": model, "prompt": prompt}
if source_url:
body["input_references"] = [
{"type": "image_url", "image_url": {"url": source_url}}]
r = requests.post("https://api.sume.com/v1/images", json=body, timeout=90,
headers={"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"})
if r.status_code != 200:
raise RuntimeError(f"{r.status_code}: {r.text[:200]}")
return requests.get(r.json()["data"][0]["url"], timeout=60).content
open("out.png", "wb").write(generate_bytes("A ceramic mug on a wooden table"))A 202 raises in this wrapper. Add the polling loop from the timeout post when you move to higher qualities or sizes.
Sources
Related posts
More in Developers
- Build a Sume Idempotency-Key from an order id: changed body result
The same key and body replays the original Sume job. A different body with the same key is a 409. Pick keys that make both outcomes safe, in runnable Python.
- Bulk create returns 429: wait retry-after, resend with the same key
A 429 on a Sume bulk create means the write budget is spent. Wait retry-after, then resend with the same Idempotency-Key; the same payload cannot double-queue.
- BullMQ delayed job that polls an AI video job and reschedules itself
A BullMQ worker reads Sume's job status once, then adds the next poll with a delay from next_poll_after_seconds, so no worker slot is held while a clip renders.
- A calendar file for AI model shutdown dates: .ics from Python
Generate an .ics file with all-day events and 14-day reminders for the gpt-image-1 and gpt-image-1.5 shutdown dates, then import it into any calendar app.
Written by Sume