AI tarot deck via API: 78 cards at 2:3, cost and consistency on Sume

A 78-card deck at 2:3 costs $2.93 on Flux 2 Pro and $3.90 on Seedream 4.5 at Sume list prices. How to keep the style consistent with one anchor reference.

5 min readSume
All posts

A full tarot deck is 78 cards, and at the Sume image catalog's list prices (read 2026-10-03) one pass at 2:3 costs $2.92 on Flux 2 Pro, $3.90 on Seedream 4.5 and $1.95 on Qwen Image. Those three rows all list aspect_ratio: "2:3", take up to ten reference images, and return one to four images per call.

The hard part is not the price but the consistency. The same pattern as a character set works: make one card as the style anchor, then generate each card with the anchor in input_references.

Cost of one pass and of a re-roll budget

Deck cost at Sume list prices (78 cards, one image each), read 2026-10-03.
ModelPer image78 cards78 cards plus 50% re-rolls
Flux 2 Pro$0.0375$2.92$4.39
Seedream 4.5$0.05$3.90$5.85
Qwen Image$0.025$1.95$2.93
Flux 2 Flex$0.0625$4.88$7.31

Structure the prompts

Keep a fixed template and fill only the card name and its imagery. The template carries the frame, the palette and the linework style; the part you vary is the scene. Leave the card's title out of the image: ask for a blank banner at the bottom, and set the name and number in your layout tool, so spelling is never at risk.

Write the 78 prompts from data, then loop. Starting with the 22 major cards and the style anchor gives you a quick check before you spend on the 56 minor cards.

import os
import requests

headers = {"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"}
cards = ["The Fool", "The Magician", "The High Priestess"]
for name in cards:
    r = requests.post(
        "https://api.sume.com/v1/images",
        headers=headers,
        json={
            "model": "black-forest-labs/flux.2-pro",
            "prompt": f"ink and watercolor tarot illustration of {name}, ornate border, blank banner at the bottom, no text",
            "aspect_ratio": "2:3",
        },
        timeout=60,
    )
    r.raise_for_status()
    print(name, r.status_code, r.json()["data"])

Run it in waves

Seventy-eight sequential 30-second waits is slow. Submit with mode: "async" or a webhook and collect the results from the job endpoints, as described in Jobs and results. A call that outlives the 30-second wait returns 202 and a job envelope anyway, so write the loop to handle both.

Sources

Related posts

More in Use cases

All Use cases posts

Written by Sume