Measured endpoints
Characters, measured
- Standard bases draw on a canvas 28px larger than
image_size(64 → 92, 104 → 132). Adirectionsreference is placed on it as is, centred, pixel for pixel. - Pro Flash returns exactly the requested canvas, and refuses a
style_imagelarger than it ("Style image must fit the native canvas"). Its/pro-flash/costanswer foroperation=characterwasimage5 up to 96px, 6 from 100 to 208px, 9 at 224px and above, plusrotationsequal to v3'sceil(side² × 8 / 65536)on the padded square canvas; two live jobs (7 and 2) billed exactly the estimate.first_framebills the rotations only. - A 64px
create-character-statemoved the balance by about 22 against the 20 to 40 tier documented; other jobs were running on the account, so it is a rough number. animate-characterwithcustom_start_frameandend_framemay return frames taller than the rotation (92 × 104 for a crouch).enhance_promptwrites the expanded text into the animation'sanimation_type. A v3 text loop on a 96px pro-flash base came back at 108 × 108.- Template loops need a skeleton template. On a pro-flash base with
template_id: customawalking-8-framesjob failed upstream at once; on a round robot fitted tomannequinthe same template returned a different, humanoid character standing nearly still. A v3 text loop ("walking forward in place, short legs stepping") kept the robot and walked. For anything that is not a biped or one of the four quadrupeds, animate from text. - Request validation is strict: an unknown body field is a 422 listing every problem at once, which is a free way to check a body's shape.
portrait-character-pro(direction: character_to_portrait, a full-body sprite in, a bust out) is job-based:POSTreturnsbackground_job_id,GET /portrait-character-pro/{job_id}answers 423 while drawing and, oncestatus: "completed", adownload_url(its ownusageis alwaysnull; read the billed amount fromGET /background-jobs/{background_job_id}instead, same as every other job here). Not the couple-generations "conversion" the name suggests: the smallestresult_size(16px) billed 20 generations, the same order of magnitude as a state or1dir.POST /characters/{id}/portrait(attaching a portrait image to a character record) is a separate, synchronous, free call (usage.generations: 0); its response is the only place the stored portrait's URL appears; the character's ownGET /characters/{id}never gains a portrait field, so PixelKiln has to remember the URL itself.character_to_portraitandSetPortraitare two independent calls with no automatic link between them.transfer-outfit-v2(a reference outfit image plus 2–16 existing frames back wearing it) is job-based the same way, polled throughGET /background-jobs/{id}only (no dedicated status endpoint). A 2-frame, 92×92 job billed 20 generations — again a real generation cost, not a cheap frame edit. The completed job returns the result frames inline as base64 inlast_response.quantized_images, not as storage URLs like every other multi-frame result here.
