API DOCS OPEN APP
← API OVERVIEW

Animate

A sprite plus a motion prompt in, an animated spritesheet and GIF out. Runs asynchronously: submit, get a job id, poll until it lands (typically 60 to 120 seconds).

POST /animate

POST /api/v1/animate 20 CR
FieldTypeNotes
image_b64string, requiredThe sprite to animate. Max 256x256, min 8x8, aspect ratio between 1:2 and 2:1. Transparent PNG works best
promptstring, requiredThe motion, e.g. "walking cycle, side view" or "gentle idle bounce". Max 2000 chars
framesint2 to 16, default 8. Rounded up to an even number

Returns 202:

{"job_id": "e17b…", "status": "queued", "cost": 20, "credits_remaining": 346}

GET /jobs/{job_id}

GET /api/v1/jobs/{job_id} FREE

Poll every few seconds. Statuses: queuedprocessing (with progress) → succeeded or failed. A failed job refunds the 20 credits automatically and the response says "refunded": true.

On success:

{
  "job_id": "e17b…",
  "status": "succeeded",
  "sheet_b64": "…",           # horizontal spritesheet PNG, transparent
  "gif_b64": "…",             # animated GIF with transparency
  "frame_count": 8,
  "frame_w": 96, "frame_h": 96,
  "fps": 8,
  "id": "f28a…"               # history row id (also viewable in the app)
}

Full example

import base64, time, requests

KEY = {"Authorization": "Bearer sl_live_YOUR_KEY"}
BASE = "https://spritelab.dev/api/v1"

sprite = base64.b64encode(open("slime_64.png", "rb").read()).decode()
r = requests.post(f"{BASE}/animate", headers=KEY, json={
    "image_b64": sprite,
    "prompt": "gentle idle bounce with squash and stretch",
    "frames": 8,
})
r.raise_for_status()
job_id = r.json()["job_id"]

while True:
    time.sleep(4)
    j = requests.get(f"{BASE}/jobs/{job_id}", headers=KEY).json()
    print(j["status"], j.get("progress", ""))
    if j["status"] in ("succeeded", "failed"):
        break

if j["status"] == "succeeded":
    open("slime_sheet.png", "wb").write(base64.b64decode(j["sheet_b64"]))
    open("slime.gif", "wb").write(base64.b64decode(j["gif_b64"]))
else:
    print("failed:", j.get("error"), "| refunded:", j.get("refunded"))

Notes