Measured endpoints

VFX artist (POST /vfx), measured once

PixelLab 0.4.130 added "Create VFX" to the REST API: an effects artist (the website's VFX creator) that builds an effect from a plain-language description, renders it, checks its own work, and saves it to My effects. The request and price table come from the OpenAPI document.

Measured once (October 2026, Tier 3 account): pixelkiln vfx --description "a small orange fireball flying right, flickering flames, short looping trail" --artist lite, no sprite. The submit quoted 1 generation and the finished job's usage billed exactly 1 (balance 5104 to 5103). The job finished in about 20 s. files held the GIF, the sheet, and the atlas. The result was a 163×26 canvas, 8 frames at 12 fps, looping, anchor origin at (80, 13), parts fireball and trail. The sheet is 489×78, a 3×3 grid holding 8 frames, and the atlas is an Aseprite-style frames list with per-frame frame rects and 83 ms durations. pixelkiln's slicer cut 8 correct frames from it. A sprite, the pro artist, a change, and the game pack remain unmeasured.

Request (VfxRequest): description (required, up to 8000 characters; with effect_id, what to change), sprite (optional base64 PNG or GIF, up to 512×512 per frame; an animation is a GIF or a horizontal strip of sprite_frames, 1–32), sprite_fps (1–60), artist (lite, the default, or pro), effect_id (change a saved effect in place; it keeps its own sprite), conversation (from a previous result, with its effect_id: priced as a change), name (up to 80 characters), and game_pack.

Response. A 202 with background_job_id, status, quoted_generations, and usage. Poll GET /background-jobs/{id} every 5–10 s (PixelLab says 30–90 s usually). A completed job's last_response has files (no-auth links: <name>.gif, <name>.png sheet, <name>.json with frames, durations, pivot, and meta.anchor, <name>-game.zip with game_pack, <name>-normals.png when a light made the sprite's normal map), effect_id, name, edit_url, message, canvas {w, h}, frames, fps, loop, anchor {kind, x, y}, parts, and conversation. The shape of files (a list or a map) is not documented; pixelkiln reads a URL list, a list of {name, url} records, or a name-to-URL map, and fails naming the keys it got otherwise.

Errors. 400 is a request to change (the detail says what), 402 means insufficient credits, 429 too many concurrent jobs, and 503 the renderer is busy. The shared HTTP policy retries 429 and 503 with backoff.

Cost (generations), quoted at submit and charged on delivery: the quote, or more when the effect took much longer (the overrun past 25% of the quote), never more than twice the quote.

litepro
new effect, no sprite or up to 128 px16 (8 with a sprite)
change (with conversation)14
sprite up to 256 px3 (change 2)14 (change 5)
sprite up to 512 px5 (change 2)28 (change 8)

An animated sprite adds "a little per frame", unpriced; pixelkiln sends still PNG sprites only. Plans and --budget count twice the quote, the most a job can bill, and the lock records quotedGenerations beside the bill read from the finished job's usage.

Wired up as pixelkiln vfx --description (CLI) and as a vfx block's description (GENERATORS.md).