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.

5 min readSume
All posts

For homebrew beer label art, generate a square illustration on Sume with no text, then draw the beer name, style and ABV in code. The batch number and the alcohol percentage change each brew and must be right, so they belong in your script, and the same artwork can serve every batch of that beer.

GPT Image 2.5 can produce the illustration; fal lists it as OpenAI's default image model with natural lighting and rich textures (read 2026-10-06, fal). The Image API docs show how to choose aspect_ratio and quality. A 1:1 image is easy to crop to a wrap or a round coaster later.

Which parts change per batch

The illustration is the brand of the beer and rarely changes. The numbers and dates change on every brew. Keep them apart and the artwork cost is a one-off.

Label elements by how often they change, read 2026-10-06
ElementSourceChanges per batch
IllustrationGenerated, 1:1No
Beer nameCodeNo
StyleCodeRarely
ABVCodeYes
Batch number and dateCodeYes

Generate once, label every batch

The script generates the illustration and writes a labelled copy for each batch in a small list. Use a bold TrueType font in 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": "Retro illustration of a lighthouse on a rocky coast at "
        "dusk, warm orange and deep teal. Empty band across the bottom "
        "third. No text.",
        "aspect_ratio": "1:1",
        "quality": "medium",
    },
    timeout=60,
)
r.raise_for_status()
raw = requests.get(r.json()["data"][0]["url"], timeout=60).content
batches = [("12", "5.2%"), ("13", "5.4%")]
for batch, abv in batches:
    img = Image.open(io.BytesIO(raw)).convert("RGB")
    w, h = img.size
    d = ImageDraw.Draw(img)
    d.text((w // 8, int(h * 0.72)), "LIGHTHOUSE PALE ALE", fill="white")
    d.text((w // 8, int(h * 0.80)), f"Batch {batch}  ABV {abv}", fill="white")
    img.save(f"label-batch-{batch}.png")

Rules to check before you print

Labels for beer you give away or sell are covered by local rules, and the rules differ by country and by state. Check what your area requires before you print, because the art cannot satisfy a legal rule by itself.

  • Whether a label must show alcohol content, volume or a warning.
  • Whether a brewing license is needed to give or sell the beer.
  • Whether claims such as a style name or a health claim are limited.
  • Whether the label must use a minimum type size for required text.

Printing the labels

Print a test sheet on plain paper and wrap it round a bottle before you order a run. Check the label against the actual bottle diameter, and keep the art away from the seam where the label overlaps. Use a waterproof or varnished stock if the bottles go in ice, since ordinary paper lifts when wet.

A series of beers

If you brew several styles, keep one prompt template and swap the scene and palette. A lighthouse for the pale ale, a forest for the porter and a harbor for the lager gives a family of labels that clearly belong together. The template stays the same and the code that draws the name, style and ABV is shared, so each new beer costs only its illustration.

Name the series in your prompt notes, so a new batch of the same beer next year uses the same wording and the same look.

Cropping for a wrap label

A wrap label is wider than a square. If you need one, generate the art at a wider ratio such as 3:2 instead of cropping a square, so the scene is composed for the shape. Keep the key elements away from the overlap edge, and check the label on a real bottle before you print a full sheet.

Keep a folder per beer with the prompt, the final illustration and the script that stamps the numbers. When you brew it again, you can run the same script with a new batch row and get a label that matches the earlier ones, without trying to recreate the look from memory. Download the image and host it yourself; do not rely on a generation URL staying available forever.

Take the ABV from your own measurements, not from the recipe. Store the batch table in a file under version control so each printed label can be traced to a row. For the ratio choice and other sizes, see Image API aspect ratios and custom sizes.

Sources

Related posts

More in Use cases

All Use cases posts

Written by Sume