Sprite Agent
Plan, price and run a whole asset pack from one prompt: the base sprite, its facing directions, an animation per direction, restyles and lighting maps, priced before anything runs. REST endpoints and the MCP tool.
What it does
One prompt becomes a plan: a graph of the single-asset tools (generate, rotate, animate, restyle, normal map) that together make a coherent pack, every asset style-matched to the same anchor sprite. The plan is priced step by step before anything runs, and nothing is charged until you approve it. Every asset comes back with an id and a download URL, exactly like the single-asset endpoints.
Planning is free and runs no generation. A plan you never approve costs nothing; a plan you approve costs exactly the quoted total, one token debit per step as it completes.
How a pack is priced
| Step | Cost |
|---|---|
Anchor sprite (sprite_generate) | 1 token |
8-direction rotation (sprite_rotate) | 12 tokens |
Animation per direction (sprite_generate_animation) | 14-20 tokens (frame count, plus 2 for a Custom motion) |
Restyle, repose or item swap (sprite_restyle) | 2 tokens, or 9 on the pro tier |
Lighting map (sprite_normal_map) | 1 token per source frame |
A knight walking in four directions is one anchor, one rotation and four walk cycles, about 69 tokens. Ask for the goal, not the steps: name the motions and the directions the game needs, and the planner picks the tools, sizes and order.
POST/api/agent
Plan a pack and price it. Spends nothing. Returns the plan as an awaiting_approval run with a per-step breakdown; approval is a separate call.
| Field | Type | Required | Description |
|---|---|---|---|
prompt | string | Yes | The pack, in plain language, 3 to 1500 characters. Say what the game needs and how it is viewed. |
cap | integer | No | Per-run token ceiling. A plan priced above it is refused with 422 and nothing is persisted. |
user_supplied_ids | string[] | No | Ids of your existing sprites the plan may use, up to 50. A literal id in a plan is legal only when listed here. |
curl https://www.sprite-ai.art/api/agent \
-H "Authorization: Bearer sai_sk_your_key_here" \
-H "Content-Type: application/json" \
-d '{ "prompt": "an isometric knight for a 4-direction top-down game, walking", "cap": 100 }'const res = await fetch("https://www.sprite-ai.art/api/agent", {
method: "POST",
headers: {
Authorization: "Bearer sai_sk_your_key_here",
"Content-Type": "application/json",
},
body: JSON.stringify({
prompt: "an isometric knight for a 4-direction top-down game, walking",
cap: 100,
}),
});
const plan = await res.json(); // plan.estimated_tokens, plan.stepsimport requests
plan = requests.post(
"https://www.sprite-ai.art/api/agent",
headers={"Authorization": "Bearer sai_sk_your_key_here"},
json={"prompt": "an isometric knight for a 4-direction top-down game, walking", "cap": 100},
).json()
print(plan["estimated_tokens"], [s["tool"] for s in plan["steps"]]){
"id": "5f0e2c1a-...",
"status": "awaiting_approval",
"created_at": "2026-09-06T12:00:00.000Z",
"prompt": "an isometric knight for a 4-direction top-down game, walking",
"plan": { "version": 1, "goal": "...", "anchor_step": "s1", "steps": [ ... ] },
"steps": [
{ "key": "s1", "tool": "sprite_generate", "produces": "still", "depends_on": [], "params": { ... }, "estimated_tokens": 1 },
{ "key": "s2", "tool": "sprite_rotate", "produces": "sheet", "depends_on": ["s1"], "params": { ... }, "estimated_tokens": 12 },
{ "key": "s3", "tool": "sprite_generate_animation", "produces": "animation", "depends_on": ["s2"], "params": { ... }, "estimated_tokens": 14 }
],
"estimated_tokens": 69,
"balance": 250,
"plan_attempts": 1
}An unaffordable plan is still a 201: the plan is right and the balance is short, so the body carries shortfall: { cost, balance, missing } and the run waits. A prompt the planner could not turn into a legal plan is a 422 with code: "plan_failed" and the issues it hit; nothing is persisted. A plan priced above cap is a 422 with the cost, so you can raise the cap and call again.
POST/api/agent/{id}/run
Approve the plan and start it. This is the one call that spends: from here each step is charged as it completes. Returns 202 at once; the run continues on the server for minutes and you poll for it.
curl -X POST https://www.sprite-ai.art/api/agent/5f0e2c1a-.../run \
-H "Authorization: Bearer sai_sk_your_key_here"const res = await fetch(
"https://www.sprite-ai.art/api/agent/5f0e2c1a-.../run",
{ method: "POST", headers: { Authorization: "Bearer sai_sk_your_key_here" } },
);
const { poll_url } = await res.json();import requests
accepted = requests.post(
"https://www.sprite-ai.art/api/agent/5f0e2c1a-.../run",
headers={"Authorization": "Bearer sai_sk_your_key_here"},
).json()
poll_url = accepted["poll_url"]{
"id": "5f0e2c1a-...",
"status": "accepted",
"estimated_tokens": 69,
"poll_url": "https://www.sprite-ai.art/api/agent/5f0e2c1a-..."
}A run that is not awaiting_approval answers 400 with code: "run_not_approvable". A balance that dropped below the quote since planning answers 402.
GET/api/agent/{id}
The run and every step's state, derived from the generation rows the run produced. Poll it every couple of seconds while status is running; it touches no provider and spends nothing.
{
"id": "5f0e2c1a-...",
"status": "running",
"prompt": "...",
"goal": "...",
"estimated_tokens": 69,
"tokens_spent": 13,
"counts": { "total": 6, "pending": 2, "running": 2, "completed": 2, "failed": 0, "skipped": 0 },
"steps": [
{ "key": "s1", "tool": "sprite_generate", "status": "completed", "progress": 100,
"generation_id": "a1b2c3d4-...", "download_url": "https://www.sprite-ai.art/api/sprites/a1b2c3d4-.../download",
"tokens_spent": 1, "error": null, "is_output": false },
{ "key": "s3", "tool": "sprite_generate_animation", "status": "running", "progress": 40,
"generation_id": "b2c3d4e5-...", "download_url": null, "tokens_spent": 0, "error": null, "is_output": true }
],
"outputs": [
{ "step_key": "s2", "generation_id": "c3d4e5f6-...", "download_url": "https://www.sprite-ai.art/api/sprites/c3d4e5f6-.../download" }
]
}status ends as completed, failed or cancelled. outputs lists the deliverables in plan order; every completed step, deliverable or not, carries its own download_url. A step whose input failed reads skipped and is never charged.
POST/api/agent/{id}/cancel
Stop a run. Steps already completed are kept and stay charged; steps in flight or not yet started are not charged. Cancelling a plan that was never approved discards it.
{ "id": "5f0e2c1a-...", "status": "cancelled" }Last updated September 10, 2026