Connection check
verified live · 28h ago
spriteship
Build a game's 2D art layer with your agent: characters, animations, tilesets, levels, 5 engines.
Tools
44
GitHub stars
—
Installs / wk
—
Licence
—
Transport
streamable-http
Last checked
28h ago
Tools & capabilities
44 toolsRead from the running server on 28h ago.
animate_asset
pairsdryRunassetId*closeLoopmotionHintvideoModel
+3
PAID (image-to-video, cost scales with duration × pair count). Animate ANY asset type — the animation lands on the source asset and its still image is preserved. For grid assets (t… PAID (image-to-video, cost scales with duration × pair count). Animate ANY asset type — the animation lands on the source asset and its still image is preserved. For grid assets (tileset/staged) pass pairs of tile indices; a self-loop { from: n, to: n } makes one tile loop seamlessly. ASK THE USER WHICH STAGES FIRST. Call get_asset, describe the tiles you can see, and get an explicit answer on which is the START and which is the END before you spend. "Animate the treasure box" does not tell you whether they mean closed→open, open→closed, or the lid alone, and guessing wrong bills them for a clip they cannot use. The server rejects a grid animate with no pairs (400) precisely so that this choice is always made deliberately — do not satisfy it by defaulting to 0→last. DEFAULTS TO A COST PREVIEW — see the dryRun argument. Returns { jobId } — poll get_job.
approve_directional_poses
jobId*poseScalesframeIndices*
FREE approval checkpoint. Use only when get_job returns status:"waiting_approval", wizardPhase:"waiting-directional-pose-approval", and directionalPoseReview. Present the eight pre… FREE approval checkpoint. Use only when get_job returns status:"waiting_approval", wizardPhase:"waiting-directional-pose-approval", and directionalPoseReview. Present the eight previewUrls to the user, let them adjust the proposed frameIndices and poseScales, then submit all eight indices and scales. Closing or declining means do not call this tool: the job remains paused and no dependent animation credits are spent. The server rechecks the live credit balance immediately before resuming paid dependent animations.
cancel_job
jobId*
FREE. Abort a running job. Failed/incomplete provider work is refunded automatically. If the job is waiting for directional-pose approval, its successful reusable 360 and pose char… FREE. Abort a running job. Failed/incomplete provider work is refunded automatically. If the job is waiting for directional-pose approval, its successful reusable 360 and pose charges are retained; no dependent animation has started. Use this when a generation is clearly going wrong rather than letting it run to completion.
create_animation_from_pose
fpsnewIdposeId*characterId*displayName
FREE, no AI. Promote a pose into a real 1-frame animation (a still/idle) that is scaled to match the character's other animations and exports to every engine. Pass poseId "__idle__… FREE, no AI. Promote a pose into a real 1-frame animation (a still/idle) that is scaled to match the character's other animations and exports to every engine. Pass poseId "__idle__" to use the character's default image when it has no poses. Returns a jobId — poll get_job.
create_asset
nameslugstylebgTypedryRunprompt*
+16
PAID (one image call). Creates a NEW asset from a prompt in any of the six types. The default dry run now returns both the exact semantic plan (`plan.preview`, item count/list, cam… PAID (one image call). Creates a NEW asset from a prompt in any of the six types. The default dry run now returns both the exact semantic plan (`plan.preview`, item count/list, camera, project-derived look) and `planToken`. SHOW that preview to the user. A real call requires the same request plus that planToken; changing the prompt, project settings, type, model, or output settings invalidates it and requires a new dry run. Object (`assetType: "static"`, formerly Static Asset) defaults to four sprites, tileset to 16 items, staged to four stages, terrain to 25 pieces, texture to four samples, and background to one image when the user did not specify a count. Explicit counts/semantic sets override defaults, and non-square counts are filled to the smallest supported 2×2–5×5 square with disclosed supplemental items. projectId is REQUIRED — the project supplies gameType, which decides how the art is drawn, and keeps the asset findable in the web app. A fan-out create returns one jobId — the asset ids appear in get_job as gridAssetIds once the job finishes. Terrain has NO per-tile edit path: revising a terrain asset regenerates the whole sheet. DEFAULTS TO A PLAN + COST PREVIEW — see dryRun. Returns { jobId, assetId } — poll get_job, then call get_asset. Generated atlases are cut by logical foreground objects, not trusted row geometry; get_asset exposes extraction status/warnings.
create_character
styledryRunprompt*gameTypegridColsgridRows
+6
PAID (~150 credits). Generate a NEW character from a text prompt. This is the entry point for building art from nothing — call create_project first if the user has no project. IMAG… PAID (~150 credits). Generate a NEW character from a text prompt. This is the entry point for building art from nothing — call create_project first if the user has no project. IMAGE ONLY: it produces the character still, not animations. Animation is a separate explicit step (generate_character_animation for a walk cycle, generate_character_turn for the 360 rotation), because animating costs several times more and the user should choose it. SET gridRows:2 AND gridCols:2 TO REQUEST FOUR DESIGN VARIATIONS FOR THE SAME PRICE — these fields are a legacy trigger; one image call is split by complete character silhouettes, never fixed cells. Four is the expected count; if the provider renders additional clearly separated full characters, they are preserved as additional results. Show the user every result and let them pick. Returns { jobId, expectedCharacterCount } — poll get_job; on status:"done" its characterIds and characterPreviews tell you which characters exist and what they look like. gameType defaults from the project but can be overridden for this character. Use topdown for the Top-Down Angled character pipeline, including characters intended for isometric projects. Passing isometric is accepted as an alias and creates a topdown character because that is the measured working directional pipeline. The STORED CHARACTER gameType — not the project gameType — controls every later animation and whether a user-facing 360 turn is available. A topdown character inside a platformer project therefore keeps the top-down directional pipeline and supports generate_character_turn. DEFAULTS TO A COST PREVIEW — see the dryRun argument.
create_project
name*stylegameType*description
FREE and SYNCHRONOUS (no jobId — do not poll). Creates the container everything else needs: characters and assets are created INSIDE a project, and the project's gameType is what d… FREE and SYNCHRONOUS (no jobId — do not poll). Creates the container everything else needs: characters and assets are created INSIDE a project, and the project's gameType is what decides how they are drawn and animated. Also seeds a starter level map, so the game preview has something real to render immediately. Call list_projects first — reuse an existing project rather than making a near-duplicate.
duplicate_animation
newIdanimation*characterId*
FREE, synchronous, no AI. Make an exact copy of the CURRENT saved animation under a new slug, preserving its selected frame order, loop/hold settings, compositing, mounts, and rend… FREE, synchronous, no AI. Make an exact copy of the CURRENT saved animation under a new slug, preserving its selected frame order, loop/hold settings, compositing, mounts, and rendered pixels. The original is untouched. Returns { jobId: null, animation }; do not poll a job.
export_map
read-only
mapId*engine
Engine-ready map JSON built from the SAVED level data, with custom-field values baked in. For the zip bundle (per-tile PNGs, loader scripts, tileset files) use get_export_command i… Engine-ready map JSON built from the SAVED level data, with custom-field values baked in. For the zip bundle (per-tile PNGs, loader scripts, tileset files) use get_export_command instead.
fix_asset_seams
dryRunassetId*iterationId*idempotencyKey
PAID (~100 credits, one image-to-image call). Make a texture tile seamlessly. Textures are created as raw grid cells, so CHECK get_asset first: metadata.seamless.seamMetric.pass is… PAID (~100 credits, one image-to-image call). Make a texture tile seamlessly. Textures are created as raw grid cells, so CHECK get_asset first: metadata.seamless.seamMetric.pass is a FREE verdict on whether this cell already tiles cleanly, and metadata.seamless.fixed tells you if it was already fixed. Do not spend on a cell that passes. The fix lands as a new current revision. DEFAULTS TO A COST PREVIEW — see the dryRun argument. Returns { jobId } — poll get_job.
frame_animation
fpsnameassetId*iterationId*frameIndices*
FREE, and NO AI AT ALL — no video model, no credits, nothing to approve. The tiles of a tileset/staged asset ARE the frames: give the tile indices in playback order (repeats allowe… FREE, and NO AI AT ALL — no video model, no credits, nothing to approve. The tiles of a tileset/staged asset ARE the frames: give the tile indices in playback order (repeats allowed) and they are composited into a real spritesheet animation on that asset, exportable to every engine. This is how you animate a coin flip, a flickering torch or a chest opening WITHOUT paying for image-to-video. Try this before animate_asset whenever the motion already exists across the tiles. Returns a jobId — poll get_job.
generate_character_animation
dryRunanimations*videoModelanimPromptscharacterId*customAnims
+7
PAID, and the cost MULTIPLIES BY THE NUMBER OF ANIMATIONS (each is its own image-to-video call, ~400 credits at defaults). This is real motion — a walk cycle, an attack, an idle bo… PAID, and the cost MULTIPLIES BY THE NUMBER OF ANIMATIONS (each is its own image-to-video call, ~400 credits at defaults). This is real motion — a walk cycle, an attack, an idle bob — not the 1-frame still that create_animation_from_pose produces. Read the character's gameType and use the standard animation names for it (get_character shows what already exists); the project gameType is irrelevant after character creation. A topdown character inside a platformer project still uses top-down prompts and directional behavior. A name that already exists is NEVER replaced: the server allocates the next numeric slug (walk → walk_2 → walk_3), and the returned animations list contains the resolved names. Ask the user which animations they want before spending: 4 animations cost 4x. Every animation defaults to 2 seconds, including walks, runs, attacks, and loops. Omit animDurations and customAnims[*].duration unless the user explicitly asks for a different clip length; never infer a longer duration from the motion or from the fact that it loops. If the character came from a 2x2 create, there are at least four siblings and animating is per-character: show the user the characterPreviews from get_job and have them pick one before you spend. For multi-direction sets, mirrorAnims gives you FREE flipped copies of a direction generated in the same call (walk_left from walk_right) — prefer a real generation when the character is asymmetric, because a held item switches sides under a mirror. The server chooses the release-new-animation-pipeline rollout for this API-key owner; there is no flag argument to set. When the user wants stored poses as the actual video endpoints, call list_character_poses and pass their ids through poseFirstFrameIds / poseLastFrameIds. Omit those maps to let the server plan anchors automatically; never pass a pose URL. Before each new clip the server classifies the effective anchor as empty-handed, held, or unclear and adds the matching inventory-preservation lock automatically; there is no inventory argument to send. For topdown/isometric clips with targetFacings, automatic planning uses one cached standing internal 360 rotation for every action, including custom actions; its one-time surcharge is included in the dry-run quote. Do NOT call generate_character_turn merely to prepare an animation — that explicit visible turn is a separate action. When that internal 360 is needed, the job pauses at waiting_approval before any animation video starts. Present directionalPoseReview from get_job and call approve_directional_poses only after the user accepts all eight candidates. The dry-run response includes animationPipelineAssignmentToken; copy it verbatim into the confirmed call so the quoted rollout decision cannot change while the user is deciding. If it expires, run the same dry-run again. The same response includes preflight with per-animation resolved names, durations and credits; setup and total credits; model resolution; runtime frame size; and explicit unknown-until-generated frame count/FPS/ETA. Show that structured preview instead of inventing precision. For free treatment accounts only, the server may allow ONE activation request beyond the 600-credit rolling limit when this call requests exactly one fresh playable animation (no reuse, edit, or mirror), the full preflight total is at most 1000 credits, fewer than two distinct net-paid generation jobs occurred in the rolling window, and no playable animation has succeeded before. Required internal pose/360 setup is included in that same claimed job and remains authorized across its approval pause. This is server-decided and shown in dryRun.freeCreditLimit.firstAnimationAllowance. Explicit turn/turn_* rotations, reuse, edit, mirror, and multi-animation requests do not qualify; a failed fully-refunded claim is reusable only if it produced no playable animation. Never split calls, omit requested work, or retry to game it. Returns { jobId, animations, operations, rejectedOperations? }; jobId is the first operation only for backward compatibility. Poll, retry, or cancel every operations[].jobId independently. When an operation reaches done, it returns an animationQualityGate requiring get_character; finish that review/repair loop before exporting or saying the animation is ready. A prompt that composes too long for the model is rejected with PROMPT_TOO_LONG before anything is charged, and the response names the animation. Check isTemplate on that entry: false means YOUR text is what is long, so shorten it; true means the shipped template is over the ceiling and no prompt you send can fix it — report it rather than retrying. DEFAULTS TO A COST PREVIEW — see the dryRun argument.
generate_character_turn
dryRunseedPoseIdcharacterId*idempotencyKeydiscardPendingResult
PAID (~400 credits — ONE 2-second rotation video), except retrying the exact failed job is FREE while its provider task/result or validated stored source survives. The default dry… PAID (~400 credits — ONE 2-second rotation video), except retrying the exact failed job is FREE while its provider task/result or validated stored source survives. The default dry run reports 0 credits and recovery:"stored_artifact" in that case; confirmation revives the same job and never starts another paid provider task. Spins the character through a full 360 so the sprite exists from every side; its frames are also what the directional-pose extractor reads, which is what makes top-down characters usable in more than one facing (isometric projects use top-down characters). ONLY topdown and isometric characters are supported — any other game type errors 400 TURN_NOT_SUPPORTED (topdown_overhead: the engine rotates the sprite image; platformer/point_and_click: side/front views, mirror instead). Eligibility reads the STORED CHARACTER gameType, not its project: a topdown character inside a platformer project is supported. This explicit visible turn is separate from the internal mid-walk rotation that generate_character_animation may plan for eligible directional walk/run clips; do not call it as mandatory setup for every animation. Lands as the animation "turn", or "turn_<seedPoseId>" when seeded from a pose. An existing turn is NEVER replaced: an occupied name becomes turn_2, turn_3, and so on. It 409s (ENTITY_BUSY) while ANY other job is running on the character, because it rebuilds the spritesheet: poll that job first. Returns { jobId, animation, resumed } — poll get_job. A successful standalone 360 finishes at done after its animation is rebuilt; it does not open the directional-pose approval checkpoint. Only an internal 360 planned by generate_character_animation pauses for directionalPoseReview before dependent animation videos start. If a retained provider URL is repeatedly proven expired, support may set discardPendingResult:true and preview again; that explicit escape abandons the stale result and is a new paid generation. DEFAULTS TO A COST PREVIEW — see the dryRun argument.
generate_pose
name*dryRunimageModelcharacterId*idempotencyKeyposeDescription*
+1
PAID (~150 credits). Generate a new pose for a character from a text description. DEFAULTS TO A COST PREVIEW — see the dryRun argument. Returns { poseId } once executed; poses have… PAID (~150 credits). Generate a new pose for a character from a text description. DEFAULTS TO A COST PREVIEW — see the dryRun argument. Returns { poseId } once executed; poses have no jobId, so poll list_character_poses until status is done or error.
generate_project_vision
name*styledryRungameType*referencesdescription
+1
PAID but very cheap (one Gemini call) and SYNCHRONOUS — the result comes back in this response, there is no jobId to poll. Turns a rough game idea into { aiVision, aiPromptGuidance… PAID but very cheap (one Gemini call) and SYNCHRONOUS — the result comes back in this response, there is no jobId to poll. Turns a rough game idea into { aiVision, aiPromptGuidance, aiNegativeGuidance }: a written creative direction plus the positive/negative guidance to reuse in later prompts, which is what keeps a whole project visually consistent instead of every asset drifting. Stores NOTHING — feed the wording into create_project (description/style) and into your own prompts. DEFAULTS TO A COST PREVIEW — see the dryRun argument.
get_asset
read-only
assetId*
One asset with its revision iterations and typed animation projection. Accepts the asset id OR its slug. Texture assets carry metadata.seamless.seamMetric (a FREE wrap-edge verdict… One asset with its revision iterations and typed animation projection. Accepts the asset id OR its slug. Texture assets carry metadata.seamless.seamMetric (a FREE wrap-edge verdict) and metadata.seamless.fixed — read seamMetric.pass to decide whether a cell needs the paid fix_asset_seams call at all. Generation Contract assets expose `generationPlan` plus `extraction`. `extraction.status:"exact"` means the planned number of logical foreground objects was recovered; `"recovered"` means small detached decorations were safely grouped; `"needs_review"` preserves every detected object and carries a warning instead of silently deleting or inventing one. `grid.tiles[].url` returns each extracted object as its own transparent PNG; the grid is a rebuilt presentation layout, not the geometry used to cut the model output. Legacy assets without `extraction` retain their historical fixed-grid metadata and should still be reviewed with the old grid fields. Backgrounds carry a `background` block echoing the sub-type, view and the aspect ratio actually generated — read it back to confirm the shape when you left aspectRatio unset.
get_character
read-only
characterId*
The full PhaserCharacter JSON: animations, frameSize, gameType, per-group atlas + spritesheet URLs, poses and mount points. The top-level animationQualityGate is the delivery verdi… The full PhaserCharacter JSON: animations, frameSize, gameType, per-group atlas + spritesheet URLs, poses and mount points. The top-level animationQualityGate is the delivery verdict per animation: ready:true means its deliveredIssues list is empty; needs_review means follow its actions before claiming the animation is ready; unscored means inspect the frames because no machine score can certify it. Check collision automatically: while an animation plays use animations[activeName].collisionBody before the character-level collisionBody; while displaying a pose use pose.collisionBody first. Fall back to a bbox only when the resolved body is absent. Bodies are normalized to the FULL untrimmed frameSize — never subtract atlas spriteSourceSize/alpha-trim offsets. Every binary URL is presigned and expires in ~1h — download immediately, never store or commit one. This is the same payload the in-app game preview consumes, so it is always a correct export.
get_character_manifest
read-only
characterId*
The self-describing export contract (tizo-export.json manifest + its JSON Schema) without downloading the zip. Use this to learn the Phaser integration shape and field meanings bef… The self-describing export contract (tizo-export.json manifest + its JSON Schema) without downloading the zip. Use this to learn the Phaser integration shape and field meanings before wiring an export into a game project. Its files[] is a logical canonical inventory, not an exact archive listing; use get_export_command and read the downloaded zip's tizo-export.json when exact shipped contents matter.
get_credits
read-only
limitapiKeyIdincludeLedger
Current credit balance, and optionally the recent ledger. Every ledger entry carries apiKeyId/apiKeyName so you can see exactly what THIS key spent. Check the balance before propos… Current credit balance, and optionally the recent ledger. Every ledger entry carries apiKeyId/apiKeyName so you can see exactly what THIS key spent. Check the balance before proposing any paid generation. When the balance will not cover what the user wants, say what IS affordable rather than only that they are short — "1200 for all three animations, you have 900, so two now or top up for all three" is the useful answer. Two different walls exist and they need OPPOSITE advice: running out of BALANCE is fixed by buying credits (the 402 carries a topUpUrl — send that link, never quote prices, they change), while a free account may instead have wallet balance but no rolling allowance — get_credits reports its freeCreditLimit. If needed <= limit, wait for the non-null resetsAt; if needed > limit, resetsAt is null because waiting can never make that unchanged request fit. Report that and never reduce or split work without fresh user approval. freeCreditLimit.firstAnimationAllowance reports whether the one activation exception is still available: exactly one fresh playable character animation plus required setup, at most 1000 credits, before two recent net-paid generation jobs and before any successful playable animation. Explicit turn/turn_* rotations, reuse, edit, mirror, and multi-animation requests do not qualify; a failed fully-refunded claim is reusable only if no playable animation was produced. Never split or reshape work to manufacture eligibility. An eligible reset, or completing any plan/pack purchase, clears that wall. hitting the key's DAILY SPEND CAP is not a money problem at all — the credits are already in the account, and the fixes are raising the cap or waiting for resetsAt. Never suggest a purchase for a cap trip. If the user asks HOW to raise the cap: the 403 carries capSettingsUrl — give them that link and tell them to edit the key there. YOU cannot change it, by design: the cap edit needs a logged-in session and is unreachable with an API key, because a key that could raise its own cap would not be a cap. Do not retry hoping it passes, and do not ask them to paste credentials.
get_custom_fields
read-only
kind*entityId*
Typed custom-field definitions for a character or asset, plus the derived builtins ($animation for characters, $autoplay/$loop for animated assets). Per-placement VALUES ride on ge… Typed custom-field definitions for a character or asset, plus the derived builtins ($animation for characters, $autoplay/$loop for animated assets). Per-placement VALUES ride on get_map; map exports bake resolved values and ship fields-schema.json. Read-only here — definitions are edited in the dashboard.
get_export_command
read-only
sizeengine*target*entityId*
Build the authenticated download URL + a ready-to-run curl line for a zip export (character engine bundle, asset bundle, or map bundle). Run the curl in your own shell — zips are m… Build the authenticated download URL + a ready-to-run curl line for a zip export (character engine bundle, asset bundle, or map bundle). Run the curl in your own shell — zips are multi-MB binaries and must not be passed through the model. Phaser character exports may select size 512, 256, 128, or 64; the selected sheet/atlas pairs keep canonical size-agnostic filenames. Requires SPRITESHIP_API_KEY to be set in that shell.
get_frames
read-only
sizeformatpairIdtarget*indicesentityId*
+1
Presigned per-frame thumbnails for a character animation or an asset motion pair — never inline base64. Use format:"sheet" to get ONE index-labeled contact sheet, which lets you ju… Presigned per-frame thumbnails for a character animation or an asset motion pair — never inline base64. Use format:"sheet" to get ONE index-labeled contact sheet, which lets you judge a whole capture in a single look; that is the intended way to pick which frames to keep before calling select_frames.
get_job
read-only
jobId*
Poll a background job. Every write tool that returns a jobId is polled here. On status:"error" the response is enriched with creditsRefunded, retryCost, retryMode, and retryRecover… Poll a background job. Every write tool that returns a jobId is polled here. On status:"error" the response is enriched with creditsRefunded, retryCost, retryMode, and retryRecovery, so you can distinguish a free recovery from paid regeneration. Poll every few seconds — generations routinely take minutes. THIS IS HOW YOU LEARN WHAT A CREATE CALL MADE: characterIds / assetIds list the entities this job produced — ONE normally, FOUR when create_character ran with the 2x2 variation grid — and on status:"done" characterPreviews carries a presigned image per character so you can show the user the options and let them pick. IMPORTANT FOR CHARACTER ANIMATION JOBS: status:"done" means processing finished, not that the animation is ready. The response carries animationQualityGate.status:"check_required" with the affected animationNames; you MUST call get_character and resolve each affected animation until its gate is ready (or report that it needs review). Do not export, sync, or claim completion before this check. queued:true means it has not started yet (waiting for a slot) and has spent nothing. On any TERMINAL status (done or error) the response carries a `credits` block — { charged, refunded, net, balance, spendCapDaily, spentLast24h, capRemaining }. TELL THE USER `credits.net` AND `credits.balance` when the work finishes, in one short line. Report `net`, never your own pre-flight estimate: the two differ routinely — a 2x2 grid is ONE charge for four entities and failed steps are refunded — so quoting the estimate can report a cost that never happened. Do NOT attach a purchase suggestion to a successful generation; only raise buying credits when a call is actually blocked or the balance will not cover what the user asked for next.
get_map
read-only
mapId*
A map row plus its saved level data (layers, placements, per-placement custom-field values). Returns mapData:null when the map has never been saved. A map row plus its saved level data (layers, placements, per-placement custom-field values). Returns mapData:null when the map has never been saved.
get_project
read-only
projectId*
One project with its description, registered mount slots, and assetSuggestions — premade AI prompt ideas per entity type (character + the 6 asset types), tailored to the project's… One project with its description, registered mount slots, and assetSuggestions — premade AI prompt ideas per entity type (character + the 6 asset types), tailored to the project's vision. Use them as ready-made prompts when creating characters/assets. May be null right after create (generated asynchronously — re-fetch to read).
list_assets
read-only
nameslugtypelimitprojectId
Assets (Object / tileset / staged / background / terrain / texture) with slug, hasAnimation, updatedAt, tags and favourite. Object was formerly called Static Asset; its API type re… Assets (Object / tileset / staged / background / terrain / texture) with slug, hasAnimation, updatedAt, tags and favourite. Object was formerly called Static Asset; its API type remains `static`. hasAnimation is data-derived: ANY asset type can carry an animation, so never infer it from the type.
list_character_poses
read-only
characterId*
All poses on a character: { id, name, prompt, status pending|done|error, url, direction, pendingSince, errorCode, creditsRefunded }. This is the poll target after generate_pose — p… All poses on a character: { id, name, prompt, status pending|done|error, url, direction, pendingSince, errorCode, creditsRefunded }. This is the poll target after generate_pose — pose generation has no job id. It is also the source of ready pose ids for generate_character_animation poseFirstFrameIds / poseLastFrameIds. A pose still pending long after pendingSince is stalled, not working.
list_characters
read-only
namelimitprojectId
Characters with the re-sync signals: contentVersion (opaque change token — compare for equality, never parse or order), hasActiveJob, apiReady, pose/animation counts, tags, favouri… Characters with the re-sync signals: contentVersion (opaque change token — compare for equality, never parse or order), hasActiveJob, apiReady, pose/animation counts, tags, favourite. Persist contentVersion per character and re-fetch only when it changes.
list_maps
read-only
limitprojectId
Level-editor maps with updatedAt and hasMapData. hasMapData:false means the map was never saved and cannot be exported. Level-editor maps with updatedAt and hasMapData. hasMapData:false means the map was never saved and cannot be exported.
list_projects
read-only
limit
All of the user's projects: { id, name, gameType, style, itemCount, createdAt, updatedAt }. gameType (platformer / topdown / topdown_overhead / isometric / point_and_click) is the… All of the user's projects: { id, name, gameType, style, itemCount, createdAt, updatedAt }. gameType (platformer / topdown / topdown_overhead / isometric / point_and_click) is the default perspective for new content — read it before generating anything. A character may override that default at creation; afterward its stored character gameType controls its own animation and turn behavior.
mirror_animation
animation*characterId*
FREE, no AI. Flip every cached frame of ONE animation horizontally and rebuild it — the cheap way to get walk_left from walk_right. NOT idempotent: calling it twice flips the anima… FREE, no AI. Flip every cached frame of ONE animation horizontally and rebuild it — the cheap way to get walk_left from walk_right. NOT idempotent: calling it twice flips the animation back to its original orientation, so call it once and check the result before calling again. Frame count and order are preserved, so any frame selection stays valid. To keep BOTH directions, call duplicate_animation first and mirror the copy. Returns { jobId, mirrored } (frames flipped) — poll get_job.
phase_split
phases*animation*characterId*
FREE, no AI. Carve ONE multi-state clip into separate game-phase animations by frame windows — the classic case is a jump becoming crouch/rise/fall/land, with fall looping while ai… FREE, no AI. Carve ONE multi-state clip into separate game-phase animations by frame windows — the classic case is a jump becoming crouch/rise/fall/land, with fall looping while airborne and the rest playing once. Each phase becomes a real exportable animation; the source animation is untouched. Jump-family animations often carry a ready-made suggestion: get_character → animations[<anim>].phaseProposal — pass its phases through verbatim. Frame windows index the FULL capture. Returns { jobId, created } — poll get_job.
plan_sync
read-only
entities*
Compare the versions in assets/spriteship/spriteship.lock.json with current SpriteShip state in one call. Returns unchanged/changed/unavailable per character, asset, or map; exact… Compare the versions in assets/spriteship/spriteship.lock.json with current SpriteShip state in one call. Returns unchanged/changed/unavailable per character, asset, or map; exact animation frame-count/FPS/collision, revision, runtime-intent, and map-shape summaries when the previous lock entry includes the snapshot returned by an earlier call; and explicit fetch/download/review-removal actions. Existing v1 lock files without snapshots still detect version changes, then upgrade by saving each returned snapshot. Requests may contain 100 entries; honor Retry-After if the weighted sync budget is reached. Never delete local files for an unavailable entity without user confirmation.
rebuild_character
animationcharacterId*
FREE, no AI. Re-render one animation from its durable cached frames by passing animation. This is the repair/refresh tool: use it when a sheet looks stale or wrong after a series o… FREE, no AI. Re-render one animation from its durable cached frames by passing animation. This is the repair/refresh tool: use it when a sheet looks stale or wrong after a series of edits, or when a previous rebuild failed. It never re-generates art, so it cannot change what the character looks like — only how the frames are packed and normalized. Omit animation only for an explicit full-character maintenance rebuild. Exact pose-owned scale references make the targeted path sibling-independent; legacy captures retain their compatibility sizing fallback. Image-only characters return NO_ANIMATIONS_TO_REBUILD without creating a job. A targeted rebuild returns an operationId/jobId — poll get_job.
regen_asset_pair
dryRunpairId*assetId*videoModelmotionPromptidempotencyKey
+1
PAID (~400 credits at defaults). Re-run video generation for a SINGLE motion pair of an animated asset, leaving its other pairs alone. The new take lands as an additional iteration… PAID (~400 credits at defaults). Re-run video generation for a SINGLE motion pair of an animated asset, leaving its other pairs alone. The new take lands as an additional iteration on that pair — earlier takes are preserved. DEFAULTS TO A COST PREVIEW — see the dryRun argument. Returns { jobId } — poll get_job.
rematte_animation
animation*characterId*
FREE, no AI. Try a cleaner background removal on ONE animation's source video — the repair for a quality read showing deliveredIssues containing "matte" (green fringe, flickering h… FREE, no AI. Try a cleaner background removal on ONE animation's source video — the repair for a quality read showing deliveredIssues containing "matte" (green fringe, flickering holes, ragged edges). The cleaner version is kept ONLY if it measures better, so this can never make the animation worse; the motion itself is unchanged. One attempt per capture: if the same frames were already tried (matteRepair stamp), a repeat call is a cheap re-check + free re-render — regenerate the animation for a fresh take instead. Fails with SOURCE_VIDEO_EXPIRED when the source video aged past its 30-day retention. Returns { jobId } — poll get_job, then re-read the character's quality block: "matte" gone = the cleaner version shipped.
reprocess_asset
anchorassetId*cellInsetcellOffsetsiterationId*fitItemIndices
FREE and SYNCHRONOUS (no jobId — do not poll), no AI. Rebuild a staged, tileset, or terrain collection's presentation layout: anchor chooses the shared fixed point and cellOffsets… FREE and SYNCHRONOUS (no jobId — do not poll), no AI. Rebuild a staged, tileset, or terrain collection's presentation layout: anchor chooses the shared fixed point and cellOffsets apply per-item nudges. Modern manifest revisions are recomposed from their independent item PNGs and are never re-sliced; legacy staged and tileset revisions retain the source-sheet re-cut path, where cellInset can remove separator bleed. For a manifest revision, fitItemIndices makes those items fill their shared cell as much as possible while preserving aspect ratio. Legacy terrain must be upgraded to independent items first. Omitted fields keep the revision's current values; send cellOffsets:[] or cellInset:0 to clear. Returns a grid summary; call get_asset afterwards for fresh presigned tile URLs.
retry_job
jobId*dryRunidempotencyKey
FREE when the original KIE task or a validated stored artifact can be recovered; otherwise PAID only for the sub-steps that still need to run. Re-runs the FAILED step of a job whos… FREE when the original KIE task or a validated stored artifact can be recovered; otherwise PAID only for the sub-steps that still need to run. Re-runs the FAILED step of a job whose status is "error" — the prompt, model and every setting are already on the job, so this is the cheap way out of a failure instead of creating the whole thing again. Work that already succeeded is NOT redone or re-charged: a generation that failed after its image landed reuses the paid result. get_job reports retryMode, retryRecovery and retryCost, and the dryRun quote here is that same number. A non-retryable phase answers 400 JOB_NOT_RETRYABLE — some late phases hold partially-committed state and deliberately have no blanket retry. DEFAULTS TO A COST PREVIEW — see the dryRun argument. Returns { jobId } — poll get_job.
revise_asset
dryRunpromptassetId*planTokenimageModeltemplateId
+4
PAID. Generate a new revision of an asset from feedback text. The previous revision is kept — revisions are additive, never destructive. Terrain assets also accept templateId to pu… PAID. Generate a new revision of an asset from feedback text. The previous revision is kept — revisions are additive, never destructive. Terrain assets also accept templateId to pull a whole category pack (edges / grounds / props / slopes / textures / structures). Passing sourceItemIndex uses that extracted item as the visual source for a complete new related collection: the source stays untouched and every output is a separate new asset listed in get_job.assetIds. The default dry run returns the exact semantic revision plan and planToken; show the preview to the user, then resend the unchanged request with that token. DEFAULTS TO A PLAN + COST PREVIEW — see dryRun. Returns { jobId } — poll get_job.
select_frames
frames*pairIdtarget*entityId*animationcompositing
FREE, no AI. Curate which frames an animation keeps, by index into the full capture, in order. Pass an empty array to reset to all frames. Non-destructive: the full capture is reta… FREE, no AI. Curate which frames an animation keeps, by index into the full capture, in order. Pass an empty array to reset to all frames. Non-destructive: the full capture is retained, so you can re-select at any time. Use get_frames with format:"sheet" first to choose indices. Returns a jobId — poll get_job.
set_asset_collision_body
assetId*tileIndexiterationId*collisionBody*
FREE and SYNCHRONOUS (no jobId — do not poll). Author the PHYSICS shape a game should build its collider from for an asset revision: a rect, a circle, or a closed polygon, in NORMA… FREE and SYNCHRONOUS (no jobId — do not poll). Author the PHYSICS shape a game should build its collider from for an asset revision: a rect, a circle, or a closed polygon, in NORMALIZED coordinates (0..1 fractions of the sprite/tile cell, origin top-left; a circle radius is a fraction of WIDTH). Set tileIndex to give one tile of a tileset/staged asset its own shape — it overrides the asset-level default for that tile. Pass collisionBody: null to clear. This is what stops a game from falling back to the sprite bounding box. The shape flows into every map and asset export made AFTER this edit — Tiled per-tile objectgroups, the Tiled map Collision layer, and the Phaser/Godot/Unity/GameMaker colliders — and it is resolved from the asset at export time, so it applies to tiles that were already placed on a map before you set it. Distinct from the FOOTPRINT, which is only the level editor's snap/tessellation shape and has no physics meaning.
set_asset_runtime_intent
configassetId*tileIndexruntimeUse*iterationId*
FREE and SYNCHRONOUS (no jobId — do not poll). Declare how an asset revision should be rendered at runtime: plain_image, particle_emitter, deformable_strip, repeat_fill, nine_slice… FREE and SYNCHRONOUS (no jobId — do not poll). Declare how an asset revision should be rendered at runtime: plain_image, particle_emitter, deformable_strip, repeat_fill, nine_slice or shader_effect. path_follow is accepted only for backward compatibility; do not set it on new assets. Draw and configure motion per placement in the level editor instead. The intent and its config flow into every engine export made AFTER this edit. Set tileIndex to target one tile of a tileset/staged asset.
suggest_motion_hint
pairsdryRunassetId*idempotencyKey
PAID but very cheap (one Gemini call) and SYNCHRONOUS — returns { hint, cost } inline, no jobId. Reads a STAGED asset's prompt plus the stage pairs you intend to animate and writes… PAID but very cheap (one Gemini call) and SYNCHRONOUS — returns { hint, cost } inline, no jobId. Reads a STAGED asset's prompt plus the stage pairs you intend to animate and writes the one-sentence motion description to pass as animate_asset's motionHint. Use it when you are about to spend ~400 credits on video and are unsure what to write: a few credits here protects that spend. Staged assets only — any other type answers 400.
whoami
read-only