AI tabletop RPG portraits via API: keep one art style on Sume

A party of RPG portraits in one art style: make an anchor portrait, then pass its URL as an input reference per character. $0.0375 each on Flux 2 Pro.

5 min readSume
All posts

A party of tabletop RPG portraits looks coherent when every portrait is made against the same style anchor. With the Sume image API that means one text-to-image call for the anchor, then one call per new character with the anchor passed in input_references and a prompt that says "same style as the reference, new subject". Sixteen rows of the catalog accept references; this post uses Flux 2 Pro at $0.0375 per image, so a six-character party costs 7 calls, $0.2625, before any rerolls.

This is the pattern; Sume does not promise identical faces or perfect style lock, and the results depend on your prompts. Check each portrait and re-roll the ones that drift.

Rows that take references

Cheapest reference-capable rows first (all accept at least ten references except Ideogram 4.5 at five).

Reference-capable rows in the Sume image catalog, read 2026-10-03.
ModelCatalog idPer imageReferences
Grok Imaginex-ai/grok-image$0.02510
Qwen Imageqwen/qwen-image$0.02510
Seedream 4.0bytedance-seed/seedream-4$0.032510
Flux 2 Problack-forest-labs/flux.2-pro$0.037510
Seedream 5.0 Litebytedance-seed/seedream-5-lite$0.0437510
Seedream 4.5bytedance-seed/seedream-4.5$0.0510
Flux 2 Flexblack-forest-labs/flux.2-flex$0.062510
ChatGPT Image 2.5openai/gpt-image-2.5$0.0658816

Anchor, then party

The script makes the anchor, then one portrait per character, each referencing the anchor. Reference URLs must be public HTTPS; the data[].url Sume returns is a hosted URL you can pass straight back. A call that is still running after the 30-second wait returns 202 with a job envelope instead of 200, so check the status code before reading data; see Jobs and results.

import os
import requests

HEADERS = {"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"}
URL = "https://api.sume.com/v1/images"
MODEL = "black-forest-labs/flux.2-pro"

def make(prompt, refs=None):
    body = {"model": MODEL, "prompt": prompt, "aspect_ratio": "1:1"}
    if refs:
        body["input_references"] = [
            {"type": "image_url", "image_url": {"url": u}} for u in refs
        ]
    r = requests.post(URL, headers=HEADERS, json=body, timeout=60)
    r.raise_for_status()
    if r.status_code == 202:
        raise RuntimeError("still running, poll " + r.json()["data"]["status_url"])
    return r.json()["data"][0]["url"]

anchor = make("painted fantasy portrait of a human ranger, bust, parchment-toned background, heavy brush strokes")
print(anchor)
for subject in ["a dwarf cleric", "an elven wizard", "a halfling rogue"]:
    print(subject, make("same style as the reference, new subject: " + subject, [anchor]))

Prompt habits that help

  • Put the style in the anchor prompt (medium, palette, framing) and repeat only the subject afterwards.
  • Ask for the same framing every time (bust, three-quarter view) so the set tiles in a character sheet.
  • Keep names out of the image; add labels in your own layout tool.
  • Use n: 4 on a character that matters, then pick one. Four images cost four times the price.

Budget

Ten characters with three rerolls each is 31 calls, about $1.16 on Flux 2 Pro. On Qwen Image at $0.025 it is $0.775. A failed call is not billed, so retrying after an error does not add to the total.

Sources

Related posts

More in Use cases

All Use cases posts

Written by Sume