AI postcard via API: 3:2 front art, address side drawn in code
Make a postcard front at 3:2 with GPT Image 2.5 custom pixels, then draw the back with message, address lines and a stamp box in Pillow. Code runs as written.

A postcard has two sides with different jobs: the front is a picture, the back is a layout of text. Let the image model make the front and build the back in code. For a 3:2 front on Sume, openai/gpt-image-2.5 accepts a custom pixel size such as 1536x1024 through image_size (both edges multiples of 16), and Nano Banana 2 lists 3:2 as a ratio, so either route works.
This split also solves the usual postcard complaint: a model that draws a lovely scene and mangles the greeting. The front carries no text; the back is drawn from strings you control, so the message, the names and the address block are correct every time.
The front: 3:2 with no lettering
Ask for a scene that reads at a glance, with a clear subject and room around the edges, since printers trim. Say no text. If you want a caption on the front, add it in code, as in the vintage travel poster recipe.
Custom pixels on GPT Image 2.5 must satisfy the model's rules: both edges multiples of 16, maximum edge 3840, ratio at most 3:1, between 655,360 and 8,294,400 pixels (Sume Image API docs). 1536x1024 meets all four and is exactly 3:2.
import os, requests
r = requests.post("https://api.sume.com/v1/images", timeout=120, json={
"model": "openai/gpt-image-2.5",
"prompt": ("Postcard front: a sunny seaside promenade with striped beach huts and a "
"small sailboat, warm vintage color, clear subject, no text"),
"image_size": "1536x1024", "quality": "medium",
}, headers={"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"})
r.raise_for_status()
if r.status_code == 202:
raise SystemExit("queued: poll the job status_url")
print(r.json()["data"][0]["url"], r.json()["usage"]["cost"])The back: message, address lines, stamp box
The back is a plain layout: a vertical divider, the message on the left, ruled address lines on the right and a stamp square at the top right. Draw it at the same pixel size as the front so both sides print at the same scale.
The function takes the message as a list of lines so you control the wrapping. Swap the default font for a licensed file when you print, and keep a safe margin inside the trim edge.
from PIL import Image, ImageDraw, ImageFont
def postcard_back(out, message_lines, size=(1536, 1024)):
w, h = size
img = Image.new("RGB", size, "#fbf7ee")
d = ImageDraw.Draw(img)
font = ImageFont.load_default(size=44)
d.line([(w // 2, h * 0.08), (w // 2, h * 0.92)], fill="#8a7f6a", width=3)
for i, line in enumerate(message_lines):
d.text((w * 0.07, h * 0.12 + i * 64), line, font=font, fill="#2b2b2b")
d.rectangle([w * 0.82, h * 0.08, w * 0.94, h * 0.26], outline="#8a7f6a", width=3)
for i in range(4):
y = h * 0.45 + i * 90
d.line([(w * 0.56, y), (w * 0.93, y)], fill="#8a7f6a", width=2)
img.save(out)
return img.size
print(postcard_back("back.png", ["Dear Sam,", "Sunshine, sea air and", "far too much ice cream.", "Wish you were here!"]))Before you print
Postcard sizes and postal rules differ by country and service, so check your printer's template and the postal service's size limits before choosing pixel dimensions; this recipe only fixes the ratio. If you change the front's ratio, change the back's size to match.
For related card layouts see the AI greeting card generator, and for how size and image_size differ see size vs image_size on the images API.
Sources
Related posts
More in Use cases
- AI shopping referrals up 693%: a Sume output schema for listing copy
Adobe data in KTVZ has AI referrals to US retail up 693.4% in Nov-Dec 2025. Bind a headline, hero image and alt-text schema so each video returns typed JSON.
- Four shoppable videos per ASIN: demo, how-to, lifestyle, unboxing
Amazon allows up to 4 shoppable videos per ASIN for sellers with a professional account and three months of history. A four-clip plan batched on Sume.
- Amazon allows four shoppable videos per ASIN: eligibility and plan
Amazon allows up to four shoppable videos per ASIN for professional sellers with three months of history. A demo, how-to, lifestyle and unboxing plan.
- Amazon Posts 9:16 video: render a vertical product clip
Set aspect_ratio 9:16 on a Sume video request and animate a product still as the first frame.
Written by Sume