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).
| Field | Type | Notes |
|---|---|---|
| image_b64 | string, required | The sprite to animate. Standard max 256x256; Pro max 320x320. Min 8x8, aspect ratio between 1:2 and 2:1. Transparent PNG works best |
| prompt | string, required | The motion, e.g. "walking cycle, side view" or "gentle idle bounce". Max 2000 chars |
| engine | string | standard (default, 20 CR) or pro (30 CR). Inputs over 256 on either axis that fit within 320x320 automatically use Pro. Above 320 on either axis returns 400 |
| frames | int | Default 8. Standard: even integers 2 to 16. Pro, including auto-routed inputs: any integer 3 to 16. Invalid counts return 400 |
Returns 202:
{"job_id": "e17b…", "status": "queued", "engine": "standard", "cost": 20, "credits_remaining": 346}
Poll every few seconds. Statuses: queued → processing (with progress) → succeeded or failed. A failed job refunds the reserved amount (20 or 30 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
"engine": "standard",
"frame_count": 8,
"frame_w": 96, "frame_h": 96,
"fps": 8,
"id": "f28a…" # history row id (also viewable in the app)
}
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,
"engine": "standard",
})
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"))
frame_w intervals.