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".

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/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.
framesarrayYes1–8 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".

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/retake

Regenerates a range of frames within an existing animation. Provide the source animation (WebP or GIF) and a frame range to retake — the model keeps all other frames frozen and regenerates only the selected region. 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",
  "image": "<base64-encoded webp or gif>",
  "retake_region": { "start_frame": 2, "end_frame": 5 },
  "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". Must match the source animation's render mode.
imagestringOne ofBase64-encoded source animation (WebP or GIF), or a data URL. Mutually exclusive with image_url.
image_urlstringOne ofHTTPS URL to download the source animation. Mutually exclusive with image.
retake_regionobjectYesSpecifies the frame range to regenerate. See Retake region below.
negative_promptstringNoWhat to avoid in the generation.
pixel_configobjectNoPixel art color config. Defaults to { "colors": 24 }. Only allowed for render_mode: "pixel". See PixelConfig under POST /animate.
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".

Retake region

retake_region
{ "start_frame": 2, "end_frame": 5 }
FieldTypeDescription
start_frameintegerFirst frame to regenerate (0-indexed, inclusive). Must be ≥ 0.
end_frameintegerLast frame to regenerate (0-indexed, inclusive). Must be ≥ start_frame and within the source animation's frame count.

Frame bounds are validated against the actual frame count of the source animation on the server. If end_frame exceeds the last frame index, the job will fail with an error.

Source animation constraints

  • Format: WebP or GIF.
  • Max size: 20 MB.
  • Data URLs: Prefixes are stripped automatically.

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, retake_region, source format, etc.).
400image_too_largeSource animation exceeds 20 MB.
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/cancel

Cancel a queued or in-progress job. Credits held for the job are released immediately.

Cost: Free — does not deduct credits.

Request body

JSON
{
  "api_job_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479"
}
FieldTypeRequiredDescription
api_job_idstringYesThe api_job_id returned by POST /animate, POST /keyframes, or POST /retake.

Response

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

Errors

HTTPCodeCause
400invalid_requestMissing api_job_id or invalid JSON body.
401unauthorizedInvalid or inactive API key.
404job_not_foundNo job with that ID, or the job 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 /retake, or POST /pixelate.

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 /retake, or POST /pixelate. 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 always match the original input image, regardless of internal upscaling.

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.

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.