Digital gift card art via API: generate the art, print the code
Make digital gift card artwork with GPT Image 2.5 on Sume, leave a clear text band, then print the amount and code in Pillow so no model ever types a real code.

For a digital gift card, generate the artwork with an image model on Sume, ask for a clear empty band where the details go, and draw the amount and the code on top in Pillow. A gift code must be exact and unique, so it never belongs in a generated image; the API makes the art and your own code makes the card.
A good choice for the art is openai/gpt-image-2.5. fal lists GPT Image 2.5 as OpenAI's default image model, with natural lighting, rich textures and support for complex layouts (read 2026-10-06, fal). On Sume it takes quality from low to max, defaults to high, and accepts a custom image_size as described in the Image API docs. A landscape card at 3:2 or 16:9 fits most email and wallet layouts.
Split the work between model and code
The split is simple. The model supplies the mood: a seasonal pattern, a border, a texture, a small decorative motif. Your code supplies everything a customer or a clerk will rely on: the amount, the code, the expiry line and the store name if it must be exact. This also makes one art file reusable across many cards, which keeps the cost close to a single generation.
| Element | Made by | Why |
|---|---|---|
| Background and border art | Image model on Sume | Style, not data |
| Amount | Your code | Must match the sale |
| Gift code | Your code | Must be unique and exact |
| Terms line | Your code | Legal text, checked once |
| Barcode or QR | Your code | Must scan |
Generate once, stamp many
The script generates one card background, downloads it, and stamps a code on a copy. Replace the text and the position with your layout; the default Pillow font is small, so load a real font file for production.
import io
import os
import requests
from PIL import Image, ImageDraw
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": "Autumn leaf pattern gift card background, soft gold and "
"cream, empty clear band across the lower third, no text at all",
"aspect_ratio": "3:2",
"quality": "medium",
},
timeout=60,
)
r.raise_for_status()
art = requests.get(r.json()["data"][0]["url"], timeout=60).content
card = Image.open(io.BytesIO(art)).convert("RGB")
draw = ImageDraw.Draw(card)
w, h = card.size
draw.text((w // 10, int(h * 0.75)), "$50 CODE: ABCD-1234", fill="black")
card.save("gift-card.png")
print("saved", card.size)Handling a slow response
A request blocks for up to 30 seconds and returns 200 with the image. High quality or a large size can run past that, and Sume then returns 202 with a job envelope; the call above uses raise_for_status, which accepts a 202, so in production check the status code and fetch GET /v1/jobs/{id}/result as the jobs and results page describes.
Medium quality is plenty for a flat pattern with no text. Spend on high only if you can see a difference in the file.
Checklist before the card goes live
A gift card is money, so treat the image as a document and check it like one.
- The gift code on the image comes from your system of record, not from any model.
- Nothing in the art implies a value, expiry or brand claim that your terms do not support.
- The text area is empty in the art, so the code is easy to read at phone size.
- The final file is a PNG or JPEG you generated, stored under your own control.
- Each card has its own file, because every code is different.
Cost of a card run
Because the art is reused, the cost does not grow with the number of cards. If you want five seasonal designs for a shop, that is five generations at the quality you choose, plus the cost of any rejected drafts. Read the endpoint pricing for GPT Image 2.5 before you start, since the docs say output cost depends on size and quality, and the billed line includes Sume's margin. Keep the best art file and a copy of the prompt so a new season can start from a known look. If a single design should differ per customer, such as a name, draw it in code rather than generating a new image for each person.
What a customer sees
Check the finished card on a phone screen at the size it is displayed, in dark mode if your wallet or email client has one. A pale band that works on a white page can vanish on a dark background. Keep the band a mid-tone or add a solid panel behind the text in Pillow so the code stays readable either way.
Sources
Related posts
More in Use cases
- Product hero video: pin the first frame to your own packshot
Use frame_images with first_frame on sume/auto so a 6-second product video opens on your exact packshot, not a regenerated lookalike.
- Graduation announcement card art at 4:5, name and year added in code
Generate graduation card art on Sume at 4:5 with a clear middle, then add the graduate's name and year in code so the details are exact and easy to change.
- Homebrew beer label art with an API: the name and ABV added in code
Generate square label art on Sume with no text, then draw the beer name, style and ABV in code so every batch gets exact numbers on the same artwork.
- Insert a sponsor read into a podcast: TTS plus one audio concat
Generate the ad read with Sume TTS, then join it into the episode at the second you choose with one Timeline audio concat: sample-exact, $0.01 per join.
Written by Sume