API DOCS OPEN APP
← API OVERVIEW

Text to Sprite

One prompt in, one cleaned sprite out: transparent background, quantised palette, crisp 1px outline. Then iterate for free with /resize.

POST /generate

POST /api/v1/generate 1 CR EPIC · 6 CR MYTHIC

Returns raw image/png bytes. The result is also saved to your SpriteLab history.

FieldTypeNotes
promptstring, requiredWhat to draw. Max 500 chars. Subject description only; the pixel art style scaffolding is added server-side
qualitystringepic (default, 1 credit) or mythic (6 credits, finer detail and cleaner shapes)
heightint16 to 512, default 128. Send height ONLY: the sprite is exactly this tall and width follows its natural proportions, no squishing
widthintLegacy: width plus a matching height forces an exact square canvas (stretches non-square subjects). Kept for existing clients; skip it for characters
size_modestringexact (default), native or crisp. See Pixel size and cleanup
cleanupstringadvanced (default) or classic. See Pixel size and cleanup
directionstringauto, front, left, right, back, top, angled. Default right. auto picks front for tiny sprites, side for larger. Ignored when style_reference_id is set
detailint1 to 3 shading richness: 1 flat, 2 some shading, 3 rich detail. Default 1
isometricboolIsometric prop: exact 2:1 angle, real-world height on the iso tileset grid. Pivot in X-SpriteLab-Pivot-X/Y
iso_tileintIsometric only: 64 (default) or 32
iso_footprintstringIsometric only: auto, 1x1, 2x1, 1x2, 2x2, 3x3
iso_heightstringIsometric only: auto, short, medium, tall, very_tall or metres
style_notesstringFree-text style direction appended to the prompt, e.g. "muted earthy palette, thick outline". Max 500 chars
style_reference_idstringSprite id of an earlier generation to anchor style on (see Style reference)
…plus any of the tuning parameters below

curl:

curl -X POST https://spritelab.dev/api/v1/generate \
  -H "Authorization: Bearer sl_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"prompt": "red health potion in a round glass bottle", "height": 64}' \
  --output potion.png

Python:

import requests

r = requests.post(
    "https://spritelab.dev/api/v1/generate",
    headers={"Authorization": "Bearer sl_live_YOUR_KEY"},
    json={
        "prompt": "armoured knight with tower shield",
        "quality": "mythic",
        "height": 128,
        "max_colours": 16,
        "palette_lock": "pico8",
    },
)
r.raise_for_status()
open("knight.png", "wb").write(r.content)
print("sprite id:", r.headers["X-SpriteLab-Sprite-Id"])
print("credits left:", r.headers["X-SpriteLab-Credits-Remaining"])

Response headers: X-SpriteLab-Sprite-Id (use it with /resize), X-SpriteLab-Credits-Remaining, and the pixel size headers below.

Pixel size and cleanup

Every sprite is drawn on its own pixel grid. A sprite delivered at that size, or at a whole multiple of it, keeps every pixel the same size and a 1px outline. Any other height is resampled to fit, which is fine for most uses but softer up close.

size_modeResult
exactDefault. The sprite is exactly height tall
nativeThe model's own pixel size, the crispest result. height is ignored
crispThe model's pixel size times the whole number closest to height, e.g. a 40 px drawing asked at 128 comes back at 120

native and crisp need height only (no width), otherwise 400 size_mode_needs_height. If a sprite has no clean pixel grid it comes back at height instead, with a scale of 0.

cleanup: advanced (default) keeps the model's own pixels, so thin lines and 1px details like eyes survive. classic is the previous cleanup, if you prefer its look or need results to match older sprites. Requests with colour tuning (contrast, saturation, brightness), palette_lock, dithering or the legacy width+height always use classic.

Response headers on /generate and /resize (the same fields are in the JSON of /convert):

HeaderNotes
X-SpriteLab-Cleanupadvanced or classic: the cleanup that ran
X-SpriteLab-Native-Height / -WidthThe model's pixel size as a sprite size, i.e. the native result. 0 when unknown
X-SpriteLab-ScaleThe whole-number multiple of the native size the sprite was delivered at. 0 = an exact height, not a multiple

To get a crisp sprite at double size, generate with native, then /resize with size_mode: "crisp" and twice the native height. Free, no new generation.

curl -X POST https://spritelab.dev/api/v1/generate \
  -H "Authorization: Bearer sl_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"prompt": "hooded rogue with twin daggers", "size_mode": "native"}' \
  -D headers.txt --output rogue.png

POST /resize

POST /api/v1/resize FREE

Re-run the cleanup pipeline on a sprite you already generated, at new dimensions and/or with new tuning. No model call, so it's free and fast (typically under a second). This is the iteration endpoint: generate once, then resize and retune as many times as you like. Works on /generate and /convert results.

FieldTypeNotes
sprite_idstring, requiredFrom the X-SpriteLab-Sprite-Id header or the JSON id field of a previous generation. Owner-only
heightint16 to 512. Required unless size_mode is native. Height only = natural proportions; adding a matching width = legacy exact square
size_modestringexact (default), native or crisp, as on /generate
cleanupstringadvanced or classic. Defaults to the cleanup the sprite was made with (API sprites from before this option existed: classic, so they keep their look)
…plus any of the tuning parameters below
curl -X POST https://spritelab.dev/api/v1/resize \
  -H "Authorization: Bearer sl_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"sprite_id": "SPRITE_ID", "height": 32, "max_colours": 8}' \
  --output potion_32.png

Sprites from other modes (micro, backgrounds, animation) can't go through this pipeline and return 409 not_resizable.

POST /enhance-prompt

POST /api/v1/enhance-prompt FREE

Rewrites a rough prompt into a richer sprite description (the same enhancement the app's prompt-improve button uses). Useful as a pre-processing step before /generate.

curl -X POST https://spritelab.dev/api/v1/enhance-prompt \
  -H "Authorization: Bearer sl_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"prompt": "cool sword"}'

# → {"enhanced": "ornate longsword with a jewelled crossguard, ..."}

GET /credits

GET /api/v1/credits FREE

Your API-spendable balance (the top-up bucket) and account tier.

curl https://spritelab.dev/api/v1/credits \
  -H "Authorization: Bearer sl_live_YOUR_KEY"

# → {"credits": 380, "tier": "knight"}

Style reference

Generate one hero asset first. Pass its id as style_reference_id to everything after: palette, proportions and rendering match automatically, so a whole cast reads as one game. Same price as a plain generate.

hero = requests.post(f"{BASE}/generate", headers=KEY,
    json={"prompt": "knight hero, blue cloak"})
hero_id = hero.headers["X-SpriteLab-Sprite-Id"]

goblin = requests.post(f"{BASE}/generate", headers=KEY,
    json={"prompt": "goblin enemy, crooked dagger",
          "style_reference_id": hero_id})

Tuning parameters

Accepted on /generate, /resize and /convert. All optional; anything you omit uses the pipeline default. Anything not listed here is ignored.

ParamType / rangeWhat it does
max_coloursint, 2 to 64Palette size after quantisation
outline_thicknessint, 0 to 4Outline width in pixels. 0 disables the outline entirely
outline_colourhex, #RGB or #RRGGBBOutline colour (default black)
palette_lockstringSnap to a preset palette: gameboy, demichrome, cga, slso8, pico8, sweetie16, nes, endesga16, endesga32, apollo. Or pass your own space-separated hex list ("#1a1c2c #5d275d #b13e53"). "none" or omit to disable
ditheringboolDither against the palette. Only meaningful with palette_lock
dither_stylestringedges (default) dithers only where two palette colours meet over a real gradient, so flat areas stay flat. fs is classic Floyd-Steinberg across the whole sprite
contrastfloat, 0.0 to 3.01.0 = unchanged
saturationfloat, 0.0 to 3.01.0 = unchanged
brightnessfloat, 0.0 to 3.01.0 = unchanged