API Reference

All endpoints are relative to https://api.pixelengine.ai/functions/v1. Every request requires an API key.

GET/balance

Returns the authenticated user's current credit balance.

Response

Response 200
{
  "monthly_balance": 1200,
  "purchased_balance": 500,
  "total_balance": 1700,
  "reserved": 20,
  "available": 1680
}
FieldTypeDescription
monthly_balanceintegerCurrent monthly credit pool.
purchased_balanceintegerCurrent purchased credit pool.
total_balanceintegermonthly_balance + purchased_balance.
reservedintegerCredits held by in-flight jobs (not yet deducted).
availableintegerCredits available for new jobs (total_balance − reserved, floor 0).

Errors

HTTPCodeCause
401unauthorizedInvalid or inactive API key.
GET/billing

Returns a billing summary for the authenticated user over a given date range, plus a current balance snapshot. Useful for tracking credit spend and understanding usage over time.

Query parameters

ParameterRequiredDefaultDescription
start_dateNo30 days before end_dateInclusive start date in YYYY-MM-DD format (UTC).
end_dateNoTodayInclusive end date in YYYY-MM-DD format (UTC).

The maximum period is 365 days.

Response

Response 200
{
  "period": {
    "start_date": "2026-03-01T00:00:00.000Z",
    "end_date": "2026-03-31T23:59:59.999Z"
  },
  "totals": {
    "credits_used": 1240,
    "credits_added": 1200,
    "refunds": 40,
    "net_change": 0,
    "jobs_charged": 62
  },
  "balance": {
    "monthly_balance": 920,
    "purchased_balance": 500,
    "total_balance": 1420,
    "reserved": 20,
    "available": 1400
  }
}
FieldTypeDescription
period.start_datestringISO timestamp of the period start.
period.end_datestringISO timestamp of the period end.
totals.credits_usedintegerTotal credits charged (sum of debit entries).
totals.credits_addedintegerTotal credits added (purchases, monthly refresh, etc.).
totals.refundsintegerTotal credits refunded.
totals.net_changeintegercredits_added + refunds − credits_used. Positive means credits gained, negative means net spend.
totals.jobs_chargedintegerNumber of jobs that consumed credits in the period.
balanceobjectCurrent balance snapshot — same shape as GET /balance.

Errors

HTTPCodeCause
400invalid_requestInvalid date format, start_date after end_date, or period exceeds 365 days.
401unauthorizedInvalid or inactive API key.
404invalid_requestNo wallet found for the authenticated user.
500internal_errorServer-side failure.
POST/animate

Submits an image-to-video generation job. The endpoint supports both pixel art animation and general-purpose frame animation. Returns immediately with a job ID; generation runs asynchronously. Poll GET /jobs to track progress.

Cost: 20 credits.

Request body

JSON
{
  "image": "<base64-encoded image or data URL>",
  "prompt": "a character walking through a forest",
  "model": "pixel-engine-v1.1",
  "negative_prompt": "blurry, distorted",
  "pixel_config": { "colors": 16 },
  "output_frames": 8,
  "seed": 12345,
  "output_format": "webp",
  "matte_color": "#808080"
}
FieldTypeRequiredDescription
imagestringYesBase64-encoded image, or a data URL (data:image/png;base64,…). Accepted formats depend on model. See image constraints below.
promptstringYesNon-empty text describing the desired animation.
modelstringNoWhich animation model to use. Defaults to "pixel-engine-v1.1". See Models below.
negative_promptstringNoWhat to avoid in the generation.
pixel_configobjectNoPixel art color config. Defaults to { "colors": 24 }. Only allowed for "pixel-engine-v1.1". See PixelConfig below.
output_framesintegerNoNumber of animation frames. Must be an even integer. Default: 8. Range depends on model.
seedintegerNoSeed for reproducibility. Integer between 1 and 9,999,999,999. If omitted, a random seed is used.
output_formatstringNo"webp" (default), "gif", or "spritesheet".
matte_colorstringNo6-character hex color (e.g. "#ff0000") used to flatten any alpha channel before processing. Default: "#808080".
To remove the background from the output animation, run it through POST /remove-background after generation completes.

Models

If model is omitted, the API defaults to "pixel-engine-v1.1".

ModelBest forInput formatsImage sizeoutput_frames
pixel-engine-v1.1Pixel art sprites and charactersPNGUp to 256×256 px2–16 (even)
frame-engine-v1.1Illustrations and non-pixel imagesPNG or JPEG256×256 px to 2048×2048 px2–24 (even)
pixel_config is rejected for "frame-engine-v1.1" with 400 invalid_request.

PixelConfig

pixel_config is only valid for "pixel-engine-v1.1" (or when model is omitted, since that defaults to the pixel model). Provide one of two modes — never both. If pixel_config is omitted entirely, it defaults to count mode with 24 colors.

Count mode — cluster output to N colors
{ "colors": 24 }
Palette mode — force specific colors
{ "palette": ["#ffaa00", "#223344", "#ffffff"] }
FieldTypeConstraints
colorsinteger2–256.
palettestring[]Array of hex color strings (e.g. "#ff0000")
Palette mode is an experimental feature. Forcing a specific palette can produce worse results than letting the model choose its own colors. If quality matters more than exact color matching, prefer count mode (colors).

Image constraints

Data URL prefixes are stripped automatically.

  • Max decoded size: 5 MB for both models.
  • Aspect ratio: Between 1:2 and 2:1 for both models.
  • Alpha: flattened onto matte_color before processing.
ModelFormatDimensionsNotes
pixel-engine-v1.1PNG onlyEach axis must be 256 px or smallerDesigned for pixel art input.
frame-engine-v1.1PNG or JPEGEach axis must be between 256 px and 2048 pxBoth width and height must be at least 256 px.

output_frames must be an even integer starting at 2. The maximum is 16 for "pixel-engine-v1.1" and 24 for "frame-engine-v1.1".

Response

Response 200
{
  "api_job_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "status": "queued",
  "error": null
}

Errors

HTTPCodeCause
400invalid_requestMissing or invalid field (prompt, image format, output_frames, etc.).
400image_too_largeImage exceeds 5 MB decoded.
401unauthorizedInvalid or inactive API key.
402insufficient_creditsNot enough available credits.
405method_not_allowedRequest method is not POST.
500internal_errorServer-side failure.

Common validation failures include unsupported image formats for the chosen model, pixel_config being sent with "frame-engine-v1.1", images smaller than 256×256 px for "frame-engine-v1.1", and odd or out-of-range output_frames values.

POST/animate-batch

Submits multiple image-to-video jobs in a single request (2–10 sub-jobs). The whole batch runs sequentially inside one warm GPU container, which amortizes the cold-start cost across every sub-job — so a batch is cheaper per animation than submitting the same jobs one at a time through POST /animate. Returns immediately with a batch ID and one job ID per sub-job; generation runs asynchronously. Poll GET /batch-jobs to track the whole batch at once.

Cost: The first sub-job (the anchor) costs 20 credits; each additional sub-job costs 12 credits. A batch of N sub-jobs costs 20 + 12 × (N − 1) credits — e.g. 5 jobs = 68 credits vs. 100 if submitted individually.

Request body

JSON
{
  "jobs": [
    {
      "image": "<base64-encoded image or data URL>",
      "prompt": "a character walking through a forest",
      "model": "pixel-engine-v1.1",
      "pixel_config": { "colors": 16 },
      "output_frames": 8
    },
    {
      "image": "<base64-encoded image or data URL>",
      "prompt": "a character drawing its sword",
      "model": "pixel-engine-v1.1"
    }
  ]
}
FieldTypeRequiredDescription
jobsarrayYesBetween 2 and 10 sub-job objects. Each object accepts the exact same fields as the POST /animate request body (image, prompt, model, pixel_config, output_frames, seed, output_format, matte_color).
All sub-jobs must use the same pipeline. Every sub-job's model must map to the same engine — either all "pixel-engine-v1.1" or all "frame-engine-v1.1". Mixing pixel and frame models in one batch returns 400 invalid_request.

Image constraints

Each sub-job image follows the same per-model rules as POST /animate (format, dimensions, aspect ratio, alpha handling). In addition:

  • Max per image: 5 MB decoded.
  • Max total: 30 MB decoded across all sub-jobs combined.

Billing

A separate hold is placed for each sub-job at submission. The anchor (the first sub-job) pays a non-refundable cold-start fee: it is charged on both success and failure, and is only released if the batch is cancelled before the anchor runs. Every other sub-job follows the normal hold rules — released on failure or cancellation, charged only on success.

Response

Response 200
{
  "batch_id": "b1f2c3d4-5678-90ab-cdef-1234567890ab",
  "api_job_ids": [
    "f47ac10b-58cc-4372-a567-0e02b2c3d479",
    "9c858901-8a57-4791-81fe-4c455b099bc9"
  ],
  "status": "queued"
}
FieldTypeDescription
batch_idstringIdentifier for the whole batch. Pass to GET /batch-jobs or POST /cancel.
api_job_idsstring[]One job ID per sub-job, in submission order (index 0 is the anchor). Each is an ordinary job ID — poll a single sub-job with GET /jobs?id=<api_job_id> or cancel one with POST /cancel.
statusstringAlways "queued" on a successful submission.
If submission fails partway (e.g. a credit hold or upload error after some rows were created), the entire batch is marked failed and any holds are released — you are never charged for a batch that never started.

Errors

HTTPCodeCause
400invalid_requestjobs missing or not an array, fewer than 2 or more than 10 sub-jobs, mixed pixel/frame pipelines, or a single sub-job is invalid (the message is prefixed with jobs[i]:).
400image_too_largeA sub-job image exceeds 5 MB decoded.
400payload_too_largeTotal decoded image bytes across all sub-jobs exceed 30 MB.
401unauthorizedInvalid or inactive API key.
402insufficient_creditsNot enough available credits to cover the full batch.
405method_not_allowedRequest method is not POST.
500internal_errorServer-side failure.
POST/keyframes

Submits a keyframe-conditioned generation job. Provide one or more reference images at specific frame positions, and the model interpolates between them to produce a full animation. Supports both pixel art and general-purpose output. Returns immediately with a job ID; generation runs asynchronously. Poll GET /jobs to track progress.

Cost: 24 credits.

Request body

JSON
{
  "prompt": "a character walking cycle",
  "render_mode": "pixel",
  "total_frames": 8,
  "frames": [
    { "index": 0, "image": "<base64>", "strength": 1.0 },
    { "index": 4, "image": "<base64>", "strength": 0.8 },
    { "index": 7, "image": "<base64>", "strength": 1.0 }
  ],
  "negative_prompt": "blurry, distorted",
  "pixel_config": { "colors": 24 },
  "seed": 12345,
  "output_format": "webp",
  "matte_color": "#808080"
}
FieldTypeRequiredDescription
promptstringYesNon-empty text describing the desired animation.
render_modestringYes"pixel" or "detailed". Determines image format constraints and post-processing. See Render modes below.
total_framesintegerYesTotal number of output frames. Integer between 3 and 20.
framesarrayYesBetween 1 and total_frames keyframe objects. Each provides a reference image at a specific position in the output sequence.
frames[].indexintegerYesFrame position in the output sequence. Must be in range [0, total_frames − 1]. Each index may only appear once.
frames[].imagestringOne ofBase64-encoded image, or a data URL. Mutually exclusive with frames[].image_url.
frames[].image_urlstringOne ofHTTPS URL to download the keyframe image. Mutually exclusive with frames[].image.
frames[].strengthnumberNoConditioning strength for this keyframe. Float between 0.0 and 1.0. Default: 1.0.
negative_promptstringNoWhat to avoid in the generation.
pixel_configobjectNoPixel art color config. Defaults to { "colors": 24 }. Only allowed for render_mode: "pixel". See PixelConfig above.
seedintegerNoSeed for reproducibility. Integer between 1 and 9,999,999,999.
output_formatstringNo"webp" (default), "gif", or "spritesheet".
matte_colorstringNo6-character hex color (e.g. "#ff0000") used to flatten any alpha channel before processing. Default: "#808080".
To remove the background from the output animation, run it through POST /remove-background after generation completes.

Render modes

ModeInput formatsImage size
pixelPNG onlyUp to 256×256 px per axis
detailedPNG or JPEG256–2048 px per axis
pixel_config is rejected for render_mode: "detailed" with 400 invalid_request.

Image constraints

Data URL prefixes are stripped automatically.

  • Max per image: 10 MB decoded.
  • Max total: 20 MB across all keyframes combined.
  • Aspect ratio: Between 1:2 and 2:1.
  • Consistency: All keyframe images must have the same dimensions.
  • Alpha: flattened onto matte_color before processing.

Response

Response 200
{
  "api_job_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "status": "queued",
  "error": null
}

Errors

HTTPCodeCause
400invalid_requestMissing or invalid field (prompt, render_mode, frames, dimensions, etc.).
400image_too_largeSingle image exceeds 10 MB or total exceeds 20 MB.
400image_fetch_failedAn image_url could not be downloaded or timed out.
401unauthorizedInvalid or inactive API key.
402insufficient_creditsNot enough available credits.
405method_not_allowedRequest method is not POST.
500internal_errorServer-side failure.
POST/generate-image

Generates a still pixel-art image from a text prompt. Optionally accepts a reference image (base64 or URL) — when provided, the model edits/transforms the reference instead of generating from scratch (image-to-image). Returns immediately with a job ID; generation runs asynchronously. Poll GET /jobs to track progress and retrieve the output PNG.

Cost: Varies by model (6–36 credits). See Models below.

Request body

JSON — text-to-image
{
  "prompt": "a knight standing in a torchlit dungeon",
  "model": "nb_flash",
  "pixel_config": { "colors": 24 },
  "seed": 12345
}
JSON — image-to-image (with reference)
{
  "prompt": "the same character, now wearing a red cape",
  "model": "oai_gpt2_medium",
  "image": "<base64-encoded image or data URL>",
  "pixel_config": { "palette": ["#1a1a1a", "#c83232", "#f0c878", "#ffffff"] }
}
FieldTypeRequiredDescription
promptstringYesNon-empty text describing the desired image (or, in image-to-image mode, the desired edit).
modelstringNoWhich generation model to use. Defaults to "nb_flash". See Models below.
pixel_configobjectYesPixel art color config — required on this endpoint (all outputs are pixel art). Provide either colors or palette, never both. See PixelConfig below.
imagestringNoOptional reference image. Base64-encoded image or a data URL (data:image/png;base64,…). PNG or JPEG. Mutually exclusive with image_url. When omitted, the request runs as text-to-image.
image_urlstringNoHTTPS URL to download the reference image. Mutually exclusive with image.
seedintegerNoSeed for reproducibility. Integer between 1 and 9,999,999,999. Only honored by OpenAI models (oai_*) where supported; Google models (nb_*) accept the field but ignore it.
Providing both image and image_url returns 400 invalid_request. Omitting both is valid — the request runs as text-to-image.

Models

If model is omitted, the API defaults to "nb_flash". Cost is a flat per-model charge (no surcharge for the optional reference image).

ModelProviderDescriptionCost
nb_flashGoogle (Nano Banana 2)Default. Solid all-around; great quality for the price.12 credits
nb_proGoogle (Nano Banana Pro)Highest overall quality.36 credits
oai_gpt2_lowOpenAI (GPT Image 2 — Low)Cheap iteration for edits.6 credits
oai_gpt2_mediumOpenAI (GPT Image 2 — Medium)Solid all-around; best for edits.12 credits
oai_gpt2_highOpenAI (GPT Image 2 — High)Top edit quality on complex prompts.36 credits

PixelConfig

Required on this endpoint — every output is post-processed into pixel art. Provide one of two modes, never both.

Count mode — cluster output to N colors
{ "colors": 24 }
Palette mode — force specific colors
{ "palette": ["#ffaa00", "#223344", "#ffffff"] }
FieldTypeConstraints
colorsinteger2–256.
palettestring[]Array of 6-character hex color strings (e.g. "#ff0000").
Palette mode is an experimental feature. Forcing a specific palette can produce worse results than letting the model choose its own colors. If quality matters more than exact color matching, prefer count mode (colors).

Image constraints (reference image)

Only applies when image or image_url is provided. Data URL prefixes are stripped automatically.

  • Format: PNG or JPEG.
  • Max decoded size: 5 MB.
  • image_url: Must be an HTTPS URL.

Response

Response 200
{
  "api_job_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "status": "queued",
  "error": null
}

Poll GET /jobs?id=<api_job_id> for status. On success, output.content_type will be "image/png" and output.metadata will contain width and height of the generated image.

Errors

HTTPCodeCause
400invalid_requestMissing or invalid field (prompt, model, pixel_config, image format, both image and image_url provided, etc.).
400image_too_largeReference image exceeds 5 MB decoded.
400image_fetch_failedimage_url could not be downloaded or timed out.
401unauthorizedInvalid or inactive API key.
402insufficient_creditsNot enough available credits.
405method_not_allowedRequest method is not POST.
500internal_errorServer-side failure.
POST/pixelate

Converts an image to clean pixel art. Automatically detects the pixel grid, quantizes colors, and resamples the image to the detected grid resolution. Returns immediately with a job ID; processing runs asynchronously. Poll GET /jobs to track progress and retrieve the output PNG.

Cost: Free — does not deduct credits.

Request body

JSON
{
  "image": "<base64-encoded image or data URL>",
  "colors": 24
}
FieldTypeRequiredDescription
imagestringYesBase64-encoded image, or a data URL (data:image/png;base64,…). PNG or JPEG. See image constraints below.
colorsintegerNoTarget number of colors for automatic palette extraction. Integer between 2 and 256. Default: 24. Mutually exclusive with palette.
palettestring[]NoArray of hex color strings (e.g. "#ffaa00") to force an exact palette. Mutually exclusive with colors.
colors and palette are mutually exclusive. Providing both returns 400 invalid_request. If neither is provided, the API defaults to colors: 24.
Palette mode is an experimental feature. Forcing a specific palette can produce worse results than letting the algorithm choose its own colors. If quality matters more than exact color matching, prefer count mode (colors).

Image constraints

Data URL prefixes are stripped automatically.

  • Format: PNG or JPEG.
  • Max decoded size: 10 MB.
  • Max dimension: 2048 px on either axis.
  • Aspect ratio: Between 1:2 and 2:1.

Response

Response 200
{
  "api_job_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "status": "queued",
  "error": null
}

Poll GET /jobs?id=<api_job_id> for status. On success, output.content_type will be "image/png" and output.metadata will contain width and height of the output image.

Errors

HTTPCodeCause
400invalid_requestMissing or invalid field (image format, colors out of range, etc.).
400image_too_largeImage exceeds 10 MB decoded or 2048 px on either axis.
400invalid_requestBoth colors and palette were provided.
401unauthorizedInvalid or inactive API key.
405method_not_allowedRequest method is not POST.
500internal_errorServer-side failure.
POST/remove-background

Removes the background from a still PNG or animated WebP, returning the same format with a transparent background. No prompt or model selection — this is a pure image-processing operation. Returns immediately with a job ID; processing runs asynchronously. Poll GET /jobs to track progress and retrieve the output.

Cost: 2 credits.

Run this endpoint after POST /animate or POST /keyframes completes to strip the background from the generated animation.

Request body

JSON
{
  "image": "<base64-encoded image or data URL>",
  "rmbg_alpha_threshold": 128
}
FieldTypeRequiredDescription
imagestringOne ofBase64-encoded image, or a data URL (data:image/png;base64,…). PNG or animated WebP. Mutually exclusive with image_url.
image_urlstringOne ofHTTPS URL to download the source image. Mutually exclusive with image.
rmbg_alpha_thresholdintegerNoHard alpha cutoff (0255). Lower values keep more partial transparency around edges; higher values snap harder to fully opaque or fully transparent. When omitted, a source-dependent default is applied automatically.
Exactly one of image or image_url must be provided. Providing both — or neither — returns 400 invalid_request.

Image constraints

Data URL prefixes are stripped automatically.

  • Format: PNG or WebP (still or animated WebP both supported).
  • Max decoded size: 10 MB.
  • Dimensions: No fixed cap. Larger inputs take longer to process.

Response

Response 200
{
  "api_job_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "status": "queued",
  "error": null
}

Poll GET /jobs?id=<api_job_id> for status. On success, output.content_type matches the input format — "image/png" for PNG inputs, "image/webp" for WebP inputs (animated WebP stays animated). output.metadata.rmbg_threshold reflects the threshold value that was applied.

Errors

HTTPCodeCause
400invalid_requestMissing or invalid field, both image and image_url provided, or neither provided.
400image_too_largeImage exceeds 10 MB decoded.
400image_fetch_failedimage_url could not be downloaded or timed out.
401unauthorizedInvalid or inactive API key.
402insufficient_creditsNot enough available credits.
405method_not_allowedRequest method is not POST.
500internal_errorServer-side failure.
POST/cancel

Cancel a queued or in-progress job, or an entire batch. Credits held for the cancelled job(s) are released immediately. Provide exactly one of api_job_id or batch_id.

Cost: Free — does not deduct credits.

Request body

JSON — cancel a single job
{
  "api_job_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479"
}
JSON — cancel a whole batch
{
  "batch_id": "b1f2c3d4-5678-90ab-cdef-1234567890ab"
}
FieldTypeRequiredDescription
api_job_idstringOne ofThe api_job_id returned by POST /animate, POST /animate-batch, POST /keyframes, POST /generate-image, POST /pixelate, or POST /remove-background. Passing a batch sub-job's ID cancels its entire batch.
batch_idstringOne ofThe batch_id returned by POST /animate-batch. Cancels every non-terminal sub-job in the batch.
Provide exactly one of api_job_id or batch_id. Supplying both — or neither — returns 400 invalid_request. Already-completed sub-jobs in a batch are left untouched; only non-terminal ones are cancelled.

Response

Response 200 — single job
{
  "api_job_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "status": "cancelled"
}
Response 200 — batch
{
  "batch_id": "b1f2c3d4-5678-90ab-cdef-1234567890ab",
  "status": "cancelled",
  "cancelled_count": 3
}

For a batch, cancelled_count is the number of sub-jobs that were non-terminal at cancel time and have now been cancelled.

Errors

HTTPCodeCause
400invalid_requestInvalid JSON body, or not exactly one of api_job_id / batch_id provided.
401unauthorizedInvalid or inactive API key.
404job_not_foundNo job with that ID, or the job belongs to a different API key.
404batch_not_foundNo batch with that ID, or the batch belongs to a different API key.
409invalid_requestJob is already in a terminal state (message includes the current status).
500internal_errorServer-side failure.
POST/enhance-prompt

Rewrites a short user prompt into a precise animation caption optimized for the generation model. Optionally accepts a reference image — when provided, the AI identifies the character from the image rather than inventing appearance details. This is a synchronous endpoint; the result is returned directly (typically 1–3 seconds).

Cost: Free — does not deduct credits.

Request body

JSON
{
  "prompt": "dash sword attack",
  "image": "<base64-encoded image or data URL>",
  "model": "pixel-engine-v1.1"
}
FieldTypeRequiredDescription
promptstringYesThe user's raw prompt text. May be an empty string when an image is provided. Maximum 2,000 characters.
imagestringNoBase64-encoded image, or a data URL (data:image/png;base64,…). Accepted formats depend on model. See image constraints below.
modelstringNoWhich generation model the prompt is being written for. Defaults to "pixel-engine-v1.1". See Models below.
At least one of prompt (non-empty string) or image must be provided.

Models

The model field should match the model you intend to use with POST /animate. Image constraints are enforced per model. If omitted, defaults to "pixel-engine-v1.1".

ModelBest forInput formatsImage size
pixel-engine-v1.1Pixel art sprites and charactersPNGUp to 256×256 px
frame-engine-v1.1Illustrations and non-pixel game artPNG or JPEG256×256 px to 2048×2048 px

Image constraints

Same per-model constraints as POST /animate. Data URL prefixes are stripped automatically.

  • Max decoded size: 5 MB for both models.
  • Aspect ratio: Between 1:2 and 2:1 for both models.
ModelFormatDimensions
pixel-engine-v1.1PNG onlyEach axis must be 256 px or smaller.
frame-engine-v1.1PNG or JPEGEach axis must be between 256 px and 2048 px.

Response

Response 200
{
  "enhanced_prompt": "The character dashes forward with a burst of speed, executing a wide, sweeping sword slash that leaves a large white crescent trail."
}
FieldTypeDescription
enhanced_promptstringThe rewritten prompt, ready to pass directly to POST /animate. Plain text, no Markdown or formatting. Typically 25–50 words.

Behavior

When an image is provided, the model uses it as a reference for the rewritten caption. Without an image, it rewrites based on the text prompt alone. If only an image is provided, it generates a generic caption from the image.

Errors

HTTPCodeCause
400invalid_requestBad JSON, missing required fields, or invalid field values.
400image_too_largeImage exceeds 5 MB decoded.
401unauthorizedMissing, invalid, or inactive API key.
502upstream_errorThe AI returned an empty response. Retry may help.
500internal_errorServer-side failure.
GET/jobs

Returns the current state of a job. On completion, includes a download URL or error details.

Query parameters

ParameterRequiredDescription
idYesThe api_job_id returned by POST /animate, POST /keyframes, POST /generate-image, POST /pixelate, or POST /remove-background — or any single sub-job ID from POST /animate-batch. To poll a whole batch at once, use GET /batch-jobs instead.

Response

Response 200 — queued
{
  "api_job_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "status": "queued",
  "progress": 0.0,
  "created_at": "2026-03-02T18:00:00.000Z",
  "finished_at": null,
  "cancelled_at": null,
  "billing": {
    "credits_held": 20,
    "credits_charged": 0,
    "hold_status": "open"
  },
  "inputs": {
    "prompt": "a character walking through a forest",
    "negative_prompt": "",
    "model": "pixel-engine-v1.1",
    "pixel_config": { "colors": 16 },
    "output_frames": 8,
    "seed": 12345,
    "output_format": "webp",
    "matte_color": "#808080"
  },
  "output": null,
  "error": null
}

Status values

ValueMeaning
"queued"Job accepted, waiting to be picked up.
"pending"Job is actively running.
"success"Generation complete. output is populated. billing.credits_charged > 0.
"failure"Generation failed. error is populated, hold is released.
"cancelled"Cancelled via POST /cancel. error is populated, hold is released.

progress is a float 0.0–1.0. May remain 0 until the job is actively running.

cancelled_at is an ISO-8601 timestamp set when a job is cancelled via POST /cancel, otherwise null.

Billing object

Present whenever a wallet hold was created for the job. null if no hold exists.

billing
{
  "credits_held": 20,
  "credits_charged": 0,
  "hold_status": "open"
}
FieldTypeDescription
credits_heldintegerCredits reserved (held) for this job.
credits_chargedintegerCredits actually charged. 0 until the hold is captured on success.
hold_statusstring"open" (job in progress), "released" (cancelled/failed, credits returned), "captured" (charged on success), "expired" (hold timed out).

Inputs object

Reflects the generation parameters submitted with POST /animate, POST /keyframes, POST /generate-image, POST /pixelate, or POST /remove-background. Always present. Fields match the original request body (excluding image / image_url). If seed was not provided in the original request, it will be absent here.

Output object (on success)

output — status: "success"
{
  "url": "https://...",
  "content_type": "image/webp",
  "metadata": { ... },
  "expires_at": "2026-03-03T18:00:00.000Z"
}
FieldDescription
urlTemporary download URL for the generated file.
content_type"image/webp", "image/gif", or "image/png" (spritesheet).
metadataOutput dimensions and format details. See shapes below.
expires_atISO timestamp when the output file will be permanently deleted.
Output files are permanently deleted 24 hours after job creation — after that, polling returns 410 job_expired. The signed url is valid for 1 hour; re-poll GET /jobs to get a fresh one before it expires.

Metadata shapes

webp and gif
{ "width": 64, "height": 64, "frame_count": 8, "fps": 8.0 }
spritesheet
{
  "width": 512,
  "height": 64,
  "output_format": "spritesheet",
  "frame_count": 8,
  "frame_w": 64,
  "frame_h": 64
}

Spritesheets are a single horizontal strip: width == frame_count × frame_w, height == frame_h.

Output dimensions

Output dimensions depend on whether the job runs in a pixel-art pipeline or a general-purpose pipeline, not on the output format. All formats (webp, gif, spritesheet) for a given job render at the same per-frame resolution.

PipelineUsed byOutput dimensions
Pixel artPOST /animate with "pixel-engine-v1.1"; POST /keyframes with render_mode: "pixel"Output frames exactly match the original input image dimensions. A 64×64 input produces 64×64 frames in every format.
GeneralPOST /animate with "frame-engine-v1.1"; POST /keyframes with render_mode: "detailed"Output frames are rendered at the model's internal resolution: 640 px on the long side, with the short side scaled to preserve the input's aspect ratio (rounded to a multiple of 8 for frame-engine-v1.1, or 64 for render_mode: "detailed"). For example, a 1024×768 input produces 640×480 frames; a 1080×1920 input produces 360×640 frames.
A maximum-size general-pipeline spritesheet — 24 frames at 640×640 px from frame-engine-v1.1, or 20 frames at 640×640 px from render_mode: "detailed", packed horizontally as one PNG strip — can reach ~15–20 MB. Output files expire 24 hours after job creation; if you need to keep them longer, download and store them on your own infrastructure before the expires_at timestamp.

Error object (on failure)

error — status: "failure"
{
  "code": "generation_failed",
  "message": "Generation failed"
}

Error object (on cancel)

error — status: "cancelled"
{
  "code": "job_cancelled",
  "message": "Job was cancelled"
}

Errors

HTTPCodeCause
400invalid_requestid query parameter missing.
401unauthorizedInvalid or inactive API key.
404job_not_foundNo job with that ID, or the job belongs to a different API key.
410job_expiredJob output has been deleted. Outputs are retained for 24 hours.
500internal_errorServer-side failure.
GET/batch-jobs

Returns the current state of every sub-job in a batch, plus a roll-up summary. Poll this once per interval to track an entire POST /animate-batch submission instead of polling each sub-job individually.

Cost: Free — does not deduct credits.

Query parameters

ParameterRequiredDescription
batch_idYesThe batch_id returned by POST /animate-batch.

Response

Response 200
{
  "batch_id": "b1f2c3d4-5678-90ab-cdef-1234567890ab",
  "batch_size": 2,
  "summary": {
    "queued": 0,
    "pending": 1,
    "success": 1,
    "failure": 0,
    "cancelled": 0
  },
  "sub_jobs": [
    {
      "api_job_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
      "batch_position": 0,
      "status": "success",
      "progress": 1.0,
      "created_at": "2026-03-02T18:00:00.000Z",
      "finished_at": "2026-03-02T18:01:30.000Z",
      "cancelled_at": null,
      "billing": { "credits_held": 20, "credits_charged": 20, "hold_status": "captured" },
      "inputs": { "prompt": "a character walking", "model": "pixel-engine-v1.1" },
      "output": {
        "url": "https://...",
        "content_type": "image/webp",
        "metadata": { "width": 64, "height": 64, "frame_count": 8, "fps": 8.0 },
        "expires_at": "2026-03-03T18:00:00.000Z"
      },
      "error": null
    },
    {
      "api_job_id": "9c858901-8a57-4791-81fe-4c455b099bc9",
      "batch_position": 1,
      "status": "pending",
      "progress": 0.4,
      "created_at": "2026-03-02T18:00:00.000Z",
      "finished_at": null,
      "cancelled_at": null,
      "billing": { "credits_held": 12, "credits_charged": 0, "hold_status": "open" },
      "inputs": { "prompt": "a character jumping", "model": "pixel-engine-v1.1" },
      "output": null,
      "error": null
    }
  ]
}
FieldTypeDescription
batch_idstringThe batch identifier.
batch_sizeintegerNumber of sub-jobs in the batch.
summaryobjectCount of sub-jobs in each status (queued, pending, success, failure, cancelled). The batch is done once queued + pending == 0.
sub_jobsarrayOne entry per sub-job, ordered by batch_position (the anchor is position 0). Each entry mirrors the GET /jobs response shape, with an added batch_position field.
Per-sub-job billing, inputs, output, and error objects have the same shapes documented under GET /jobs. Outputs expire 24 hours after batch creation; a sub-job whose output has been cleaned up reports a job_expired error in its error field while the rest of the batch stays intact.

Errors

HTTPCodeCause
400invalid_requestbatch_id query parameter missing.
401unauthorizedInvalid or inactive API key.
404batch_not_foundNo batch with that ID, or the batch belongs to a different API key.
405method_not_allowedRequest method is not GET.
500internal_errorServer-side failure.

See also

The Introduction covers everything needed before making your first request: base URL, authentication and API key management, the credit system, the shared error response format, and the recommended polling pattern for async jobs.