API Reference
All endpoints are relative to https://api.pixelengine.ai/functions/v1. Every request requires an API key.
/balanceReturns the authenticated user's current credit balance.
Response
{
"monthly_balance": 1200,
"purchased_balance": 500,
"total_balance": 1700,
"reserved": 20,
"available": 1680
}| Field | Type | Description |
|---|---|---|
monthly_balance | integer | Current monthly credit pool. |
purchased_balance | integer | Current purchased credit pool. |
total_balance | integer | monthly_balance + purchased_balance. |
reserved | integer | Credits held by in-flight jobs (not yet deducted). |
available | integer | Credits available for new jobs (total_balance − reserved, floor 0). |
Errors
| HTTP | Code | Cause |
|---|---|---|
| 401 | unauthorized | Invalid or inactive API key. |
/billingReturns 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
| Parameter | Required | Default | Description |
|---|---|---|---|
start_date | No | 30 days before end_date | Inclusive start date in YYYY-MM-DD format (UTC). |
end_date | No | Today | Inclusive end date in YYYY-MM-DD format (UTC). |
The maximum period is 365 days.
Response
{
"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
}
}| Field | Type | Description |
|---|---|---|
period.start_date | string | ISO timestamp of the period start. |
period.end_date | string | ISO timestamp of the period end. |
totals.credits_used | integer | Total credits charged (sum of debit entries). |
totals.credits_added | integer | Total credits added (purchases, monthly refresh, etc.). |
totals.refunds | integer | Total credits refunded. |
totals.net_change | integer | credits_added + refunds − credits_used. Positive means credits gained, negative means net spend. |
totals.jobs_charged | integer | Number of jobs that consumed credits in the period. |
balance | object | Current balance snapshot — same shape as GET /balance. |
Errors
| HTTP | Code | Cause |
|---|---|---|
| 400 | invalid_request | Invalid date format, start_date after end_date, or period exceeds 365 days. |
| 401 | unauthorized | Invalid or inactive API key. |
| 404 | invalid_request | No wallet found for the authenticated user. |
| 500 | internal_error | Server-side failure. |
/animateSubmits 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
{
"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"
}| Field | Type | Required | Description |
|---|---|---|---|
image | string | Yes | Base64-encoded image, or a data URL (data:image/png;base64,…). Accepted formats depend on model. See image constraints below. |
prompt | string | Yes | Non-empty text describing the desired animation. |
model | string | No | Which animation model to use. Defaults to "pixel-engine-v1.1". See Models below. |
negative_prompt | string | No | What to avoid in the generation. |
pixel_config | object | No | Pixel art color config. Defaults to { "colors": 24 }. Only allowed for "pixel-engine-v1.1". See PixelConfig below. |
output_frames | integer | No | Number of animation frames. Must be an even integer. Default: 8. Range depends on model. |
seed | integer | No | Seed for reproducibility. Integer between 1 and 9,999,999,999. If omitted, a random seed is used. |
output_format | string | No | "webp" (default), "gif", or "spritesheet". |
matte_color | string | No | 6-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".
| Model | Best for | Input formats | Image size | output_frames |
|---|---|---|---|---|
pixel-engine-v1.1 | Pixel art sprites and characters | PNG | Up to 256×256 px | 2–16 (even) |
frame-engine-v1.1 | Illustrations and non-pixel images | PNG or JPEG | 256×256 px to 2048×2048 px | 2–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.
{ "colors": 24 }{ "palette": ["#ffaa00", "#223344", "#ffffff"] }| Field | Type | Constraints |
|---|---|---|
colors | integer | 2–256. |
palette | string[] | Array of hex color strings (e.g. "#ff0000") |
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_colorbefore processing.
| Model | Format | Dimensions | Notes |
|---|---|---|---|
pixel-engine-v1.1 | PNG only | Each axis must be 256 px or smaller | Designed for pixel art input. |
frame-engine-v1.1 | PNG or JPEG | Each axis must be between 256 px and 2048 px | Both 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
{
"api_job_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"status": "queued",
"error": null
}Errors
| HTTP | Code | Cause |
|---|---|---|
| 400 | invalid_request | Missing or invalid field (prompt, image format, output_frames, etc.). |
| 400 | image_too_large | Image exceeds 5 MB decoded. |
| 401 | unauthorized | Invalid or inactive API key. |
| 402 | insufficient_credits | Not enough available credits. |
| 405 | method_not_allowed | Request method is not POST. |
| 500 | internal_error | Server-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.
/keyframesSubmits 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
{
"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"
}| Field | Type | Required | Description |
|---|---|---|---|
prompt | string | Yes | Non-empty text describing the desired animation. |
render_mode | string | Yes | "pixel" or "detailed". Determines image format constraints and post-processing. See Render modes below. |
total_frames | integer | Yes | Total number of output frames. Integer between 3 and 20. |
frames | array | Yes | 1–8 keyframe objects. Each provides a reference image at a specific position in the output sequence. |
frames[].index | integer | Yes | Frame position in the output sequence. Must be in range [0, total_frames − 1]. Each index may only appear once. |
frames[].image | string | One of | Base64-encoded image, or a data URL. Mutually exclusive with frames[].image_url. |
frames[].image_url | string | One of | HTTPS URL to download the keyframe image. Mutually exclusive with frames[].image. |
frames[].strength | number | No | Conditioning strength for this keyframe. Float between 0.0 and 1.0. Default: 1.0. |
negative_prompt | string | No | What to avoid in the generation. |
pixel_config | object | No | Pixel art color config. Defaults to { "colors": 24 }. Only allowed for render_mode: "pixel". See PixelConfig above. |
seed | integer | No | Seed for reproducibility. Integer between 1 and 9,999,999,999. |
output_format | string | No | "webp" (default), "gif", or "spritesheet". |
matte_color | string | No | 6-character hex color (e.g. "#ff0000") used to flatten any alpha channel before processing. Default: "#808080". |
Render modes
| Mode | Input formats | Image size |
|---|---|---|
pixel | PNG only | Up to 256×256 px per axis |
detailed | PNG or JPEG | 256–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_colorbefore processing.
Response
{
"api_job_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"status": "queued",
"error": null
}Errors
| HTTP | Code | Cause |
|---|---|---|
| 400 | invalid_request | Missing or invalid field (prompt, render_mode, frames, dimensions, etc.). |
| 400 | image_too_large | Single image exceeds 10 MB or total exceeds 20 MB. |
| 400 | image_fetch_failed | An image_url could not be downloaded or timed out. |
| 401 | unauthorized | Invalid or inactive API key. |
| 402 | insufficient_credits | Not enough available credits. |
| 405 | method_not_allowed | Request method is not POST. |
| 500 | internal_error | Server-side failure. |
/retakeRegenerates 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
{
"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"
}| Field | Type | Required | Description |
|---|---|---|---|
prompt | string | Yes | Non-empty text describing the desired animation. |
render_mode | string | Yes | "pixel" or "detailed". Must match the source animation's render mode. |
image | string | One of | Base64-encoded source animation (WebP or GIF), or a data URL. Mutually exclusive with image_url. |
image_url | string | One of | HTTPS URL to download the source animation. Mutually exclusive with image. |
retake_region | object | Yes | Specifies the frame range to regenerate. See Retake region below. |
negative_prompt | string | No | What to avoid in the generation. |
pixel_config | object | No | Pixel art color config. Defaults to { "colors": 24 }. Only allowed for render_mode: "pixel". See PixelConfig under POST /animate. |
seed | integer | No | Seed for reproducibility. Integer between 1 and 9,999,999,999. |
output_format | string | No | "webp" (default), "gif", or "spritesheet". |
matte_color | string | No | 6-character hex color (e.g. "#ff0000") used to flatten any alpha channel before processing. Default: "#808080". |
Retake region
{ "start_frame": 2, "end_frame": 5 }| Field | Type | Description |
|---|---|---|
start_frame | integer | First frame to regenerate (0-indexed, inclusive). Must be ≥ 0. |
end_frame | integer | Last 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
{
"api_job_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"status": "queued",
"error": null
}Errors
| HTTP | Code | Cause |
|---|---|---|
| 400 | invalid_request | Missing or invalid field (prompt, render_mode, retake_region, source format, etc.). |
| 400 | image_too_large | Source animation exceeds 20 MB. |
| 400 | image_fetch_failed | image_url could not be downloaded or timed out. |
| 401 | unauthorized | Invalid or inactive API key. |
| 402 | insufficient_credits | Not enough available credits. |
| 405 | method_not_allowed | Request method is not POST. |
| 500 | internal_error | Server-side failure. |
/pixelateConverts 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
{
"image": "<base64-encoded image or data URL>",
"colors": 24
}| Field | Type | Required | Description |
|---|---|---|---|
image | string | Yes | Base64-encoded image, or a data URL (data:image/png;base64,…). PNG or JPEG. See image constraints below. |
colors | integer | No | Target number of colors for automatic palette extraction. Integer between 2 and 256. Default: 24. Mutually exclusive with palette. |
palette | string[] | No | Array 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.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
{
"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
| HTTP | Code | Cause |
|---|---|---|
| 400 | invalid_request | Missing or invalid field (image format, colors out of range, etc.). |
| 400 | image_too_large | Image exceeds 10 MB decoded or 2048 px on either axis. |
| 400 | invalid_request | Both colors and palette were provided. |
| 401 | unauthorized | Invalid or inactive API key. |
| 405 | method_not_allowed | Request method is not POST. |
| 500 | internal_error | Server-side failure. |
/cancelCancel a queued or in-progress job. Credits held for the job are released immediately.
Cost: Free — does not deduct credits.
Request body
{
"api_job_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479"
}| Field | Type | Required | Description |
|---|---|---|---|
api_job_id | string | Yes | The api_job_id returned by POST /animate, POST /keyframes, or POST /retake. |
Response
{
"api_job_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"status": "cancelled"
}Errors
| HTTP | Code | Cause |
|---|---|---|
| 400 | invalid_request | Missing api_job_id or invalid JSON body. |
| 401 | unauthorized | Invalid or inactive API key. |
| 404 | job_not_found | No job with that ID, or the job belongs to a different API key. |
| 409 | invalid_request | Job is already in a terminal state (message includes the current status). |
| 500 | internal_error | Server-side failure. |
/enhance-promptRewrites 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
{
"prompt": "dash sword attack",
"image": "<base64-encoded image or data URL>",
"model": "pixel-engine-v1.1"
}| Field | Type | Required | Description |
|---|---|---|---|
prompt | string | Yes | The user's raw prompt text. May be an empty string when an image is provided. Maximum 2,000 characters. |
image | string | No | Base64-encoded image, or a data URL (data:image/png;base64,…). Accepted formats depend on model. See image constraints below. |
model | string | No | Which generation model the prompt is being written for. Defaults to "pixel-engine-v1.1". See Models below. |
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".
| Model | Best for | Input formats | Image size |
|---|---|---|---|
pixel-engine-v1.1 | Pixel art sprites and characters | PNG | Up to 256×256 px |
frame-engine-v1.1 | Illustrations and non-pixel game art | PNG or JPEG | 256×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.
| Model | Format | Dimensions |
|---|---|---|
pixel-engine-v1.1 | PNG only | Each axis must be 256 px or smaller. |
frame-engine-v1.1 | PNG or JPEG | Each axis must be between 256 px and 2048 px. |
Response
{
"enhanced_prompt": "The character dashes forward with a burst of speed, executing a wide, sweeping sword slash that leaves a large white crescent trail."
}| Field | Type | Description |
|---|---|---|
enhanced_prompt | string | The 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
| HTTP | Code | Cause |
|---|---|---|
| 400 | invalid_request | Bad JSON, missing required fields, or invalid field values. |
| 400 | image_too_large | Image exceeds 5 MB decoded. |
| 401 | unauthorized | Missing, invalid, or inactive API key. |
| 502 | upstream_error | The AI returned an empty response. Retry may help. |
| 500 | internal_error | Server-side failure. |
/jobsReturns the current state of a job. On completion, includes a download URL or error details.
Query parameters
| Parameter | Required | Description |
|---|---|---|
id | Yes | The api_job_id returned by POST /animate, POST /keyframes, POST /retake, or POST /pixelate. |
Response
{
"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
| Value | Meaning |
|---|---|
"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.
{
"credits_held": 20,
"credits_charged": 0,
"hold_status": "open"
}| Field | Type | Description |
|---|---|---|
credits_held | integer | Credits reserved (held) for this job. |
credits_charged | integer | Credits actually charged. 0 until the hold is captured on success. |
hold_status | string | "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)
{
"url": "https://...",
"content_type": "image/webp",
"metadata": { ... },
"expires_at": "2026-03-03T18:00:00.000Z"
}| Field | Description |
|---|---|
url | Temporary download URL for the generated file. |
content_type | "image/webp", "image/gif", or "image/png" (spritesheet). |
metadata | Output dimensions and format details. See shapes below. |
expires_at | ISO timestamp when the output file will be permanently deleted. |
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
{ "width": 64, "height": 64, "frame_count": 8, "fps": 8.0 }{
"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)
{
"code": "generation_failed",
"message": "Generation failed"
}Error object (on cancel)
{
"code": "job_cancelled",
"message": "Job was cancelled"
}Errors
| HTTP | Code | Cause |
|---|---|---|
| 400 | invalid_request | id query parameter missing. |
| 401 | unauthorized | Invalid or inactive API key. |
| 404 | job_not_found | No job with that ID, or the job belongs to a different API key. |
| 410 | job_expired | Job output has been deleted. Outputs are retained for 24 hours. |
| 500 | internal_error | Server-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.