Titan base64 image fields vs Sume input_references URLs in Python
Titan sends images as base64 strings inside the request. Sume wants public HTTPS URLs. A Python adapter from a local file to a URL for edits.

A Bedrock Titan edit puts the image in the request body. Per Amazon's docs (read 2026-10-06), the maskImage field must be a base64-encoded string, and the input image is PNG or JPG. Sume's edit call works differently: the source is a URL, so a local file has to be hosted somewhere first.
| Step | Titan on Bedrock | Sume /v1/images |
|---|---|---|
| Source image | Base64 in the JSON body | Public HTTPS URL in input_references[].image_url.url |
| Mask | Base64 maskImage | mask_url, ChatGPT Image 2.5 only |
| Result | Image in the response | data[].url, a Sume-hosted signed URL |
| Next edit | Re-encode the bytes | Pass the previous data[].url back in as the new reference |
Hosting the source
Any public HTTPS host works: object storage with a presigned GET URL, your CDN, or a signed link. Give the link enough lifetime for a 202 job to fetch it later; the post on presigned URL expiry covers the timing. The result goes the other way, as a Sume-hosted URL, so there is no base64 to decode.
The adapter
This adapter takes a public URL (your upload step produces it) and returns the URL of the edited image, which you can feed back in for the next turn.
import os, requests
def edit(source_url: str, prompt: str, model: str = "ideogram/ideogram-v4.5") -> str:
r = requests.post(
"https://api.sume.com/v1/images",
headers={"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"},
json={"model": model, "prompt": prompt,
"input_references": [{"type": "image_url", "image_url": {"url": source_url}}]},
timeout=90,
)
r.raise_for_status()
return r.json()["data"][0]["url"]
turn1 = edit("https://example.com/room.jpg", "Paint the wall sage green.")
turn2 = edit(turn1, "Add a floor lamp in the corner. Keep everything else.")
print(turn2)Sources
Related posts
More in Developers
- Transcribe 10,000 short clips: queue capacity and wave size by plan
10,000 five-second clips cost $8.33 on Sume STT. How fast they finish depends on plan concurrency and queue capacity: 6, 24, 48 or 120 accepted jobs.
- Text-to-speech API in Node: submit, poll and save the MP3
A Node 18+ fetch example for the Sume TTS Router: submit with an Idempotency-Key, poll status_url, read the audio artifact and save an MP3 to disk.
- tts_sentence_selection_invalid 422 on Sume TTS: what triggers it
Sume TTS returns 422 tts_sentence_selection_invalid for gaps, repeated jobs, unfinished jobs and partial coverage. Each cause and its fix.
- tts_source_integrity_mismatch 422: job differs from accepted script
verify-spine returns 422 tts_source_integrity_mismatch when a finished TTS job's text no longer matches the accepted script. What it checks and how to recover.
Written by Sume