Sprite Agent
Plan, price and run a whole sprite pack from one prompt: the base sprite, its directions, an animation for each, restyles and lighting maps. REST and MCP.
What it does
One prompt becomes a plan, a graph of the single-asset tools (generate, rotate, animate, restyle, combine, 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 runs no generation, but it does run a model, so it's metered like the agent chat. Model cost adds up on your account, and each time it fills a 2-cent bucket the next call spends 2 tokens before it runs. The first bucket on an account is free. A balance that can't cover that charge answers 402 and plans nothing. Past that, a plan you never approve costs nothing, and a plan you approve costs exactly the quoted total, one token debit per step as it completes.
How a pack is priced
Every step costs what its tool costs on its own. The anchor sprite is a generate, the 8 facings a rotate, each direction's motion an animation, and the lighting a normal map per source frame. A Custom motion costs the same as a named preset.
| Step | Input | Tokens |
|---|---|---|
sprite_generate | 1 | |
sprite_generate_animation | frame_count 4 | 14 |
sprite_generate_animation | frame_count 6 | 14 |
sprite_generate_animation | frame_count 8 | 14 |
sprite_generate_animation | frame_count 10 | 16 |
sprite_generate_animation | frame_count 12 | 16 |
sprite_generate_animation | frame_count 14 | 18 |
sprite_generate_animation | frame_count 16 | 20 |
sprite_restyle | tier normal | 2 |
sprite_restyle | tier pro | 9 |
sprite_combine | tier normal | 3 |
sprite_combine | tier pro | 9 |
sprite_rotate | 12 | |
sprite_normal_map | each frame (columns x rows) | 1 |
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. Planning is metered as above and generates 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 run's jobs. 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 October 22, 2026