Animations
Generate animated mascot videos from scratch or from existing images. Image-to-video animation uses /generate with type: "animation". From Video uses the reference-video endpoint below.
Upload and animate in one request
Upload your image with POST /v1/upload, then use its data.asset_id below.
You can create the mascot and start animation in the same request:
curl -X POST https://api.masko.ai/v1/animations \
-H "Authorization: Bearer $MASKO_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: first-wave-001" \
-d '{
"source_image_asset_id": "UPLOADED_IMAGE_ID",
"create_mascot": { "project_id": "PROJECT_ID" },
"name": "Wave",
"animation_prompt": "Wave gently, keeping the feet planted.",
"animation_model": "standard",
"duration": 5
}'create_mascot.name is optional. If omitted, AI chooses a short character name,
such as Pip. It generates no character description. If naming is unavailable,
a temporary Mascot <suffix> name is used. You can rename it later with
PATCH /v1/mascots/{id}. The original upload becomes the new mascot's first
reference without image regeneration.
The 202 response includes data.mascot_id, data.mascot_name,
data.mascot_created, data.job_id, data.item_id, data.asset_ids,
data.estimated_cost and data.poll_url.
For subsequent animations of that character, replace create_mascot with the
returned mascot_id:
{
"mascot_id": "RETURNED_MASCOT_ID",
"source_image_asset_id": "UPLOADED_IMAGE_ID",
"name": "Bounce",
"animation_prompt": "Bounce gently in place."
}Send exactly one of mascot_id or create_mascot. Each create_mascot request
creates a separate mascot in the specified project, so reuse mascot_id to
keep related animations together. Existing mascot references remain unchanged.
An optional variant_id is supported for an existing mascot.
This endpoint defaults to Standard, 5 seconds, and looping: 10 credits.
Naming, mascot creation and cropping add no credits. Non-square images use a
centered square crop; pass source_image_crop for explicit framing as described
under image framing.
Retry an uncertain response with the same Idempotency-Key and unchanged body.
If generation fails after creating the mascot, error.details.mascot_id gives
its ID. Reuse that ID with a new key when submitting a corrected request.
The API never guesses whether two different uploads are the same character.
Image + Animation (New)
Generate a new image and animate it in one request. Provide both an image_prompt (for the pose) and an animation_prompt (for the motion). With Standard, this costs 1 credit for the image plus 2 credits per second of video: a 5-second animation costs 11 credits total. Premium costs 31 credits for the same duration.
curl -X POST https://api.masko.ai/v1/mascots/MASCOT_ID/generate \
-H "Authorization: Bearer masko_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "animation",
"animation_model": "standard",
"name": "Idle breathing",
"image_prompt": "standing relaxed with arms at sides",
"animation_prompt": "gentle breathing motion, subtle body sway",
"duration": 5,
"loop": true
}'Animate Existing Image
Animate an image you already have by passing source_image_asset_id. This skips image generation, so you only pay for the video - 10 credits for 5 seconds with Standard.
curl -X POST https://api.masko.ai/v1/mascots/MASCOT_ID/generate \
-H "Authorization: Bearer masko_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "animation",
"animation_model": "standard",
"name": "Waving animated",
"source_image_asset_id": "3c8ce568-35ce-59c2-b3f8-9fb7e4a16e52",
"animation_prompt": "waving hello with smooth arm motion",
"duration": 5,
"loop": true
}'From Video
Transfer motion from a video to your mascot with Premium. This operation costs 6 credits per output second plus 1 image credit. Output duration is 4–30 whole seconds and defaults to 5 seconds, for 31 credits. Standard is not available for From Video.
Upload the motion video and an image of its first frame using POST /v1/upload
with multipart form data. Each upload returns an asset_id. Video uploads accept
MP4 or WebM, up to 50 MB; image uploads accept PNG, JPEG, and WebP up to 10 MB.
Use a short, clear motion clip within the 4–30 second range.
curl -X POST https://api.masko.ai/v1/upload \
-H "Authorization: Bearer $MASKO_API_KEY" \
-F "file=@motion.mp4"
curl -X POST https://api.masko.ai/v1/upload \
-H "Authorization: Bearer $MASKO_API_KEY" \
-F "file=@first-frame.png"
curl -X POST https://api.masko.ai/v1/mascots/$MASCOT_ID/animations/reference-video \
-H "Authorization: Bearer $MASKO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"video_asset_id": "VIDEO_ASSET_ID",
"first_frame_asset_id": "FRAME_ASSET_ID",
"name": "Friendly wave from video",
"animation_model": "premium",
"duration": 5
}'Both source assets must be completed, active, and accessible to your API key.
Optional variant_id selects an approved mascot variant; context_asset_id
reuses the saved mascot context of an asset in this mascot when no variant
is specified. Optional prompt adds pose or appearance instructions.
The response is 202 Accepted with data.job_id, data.poll_url,
data.estimated_cost, and data.asset_ids. It creates one animation item and
two pose items, identified by item_id, start_item_id, and end_item_id.
Poll GET /v1/jobs/{job_id} until completed or failed; do not submit the
request again while it is processing. Use the returned asset IDs to fetch the
MP4, transparent WebM/HEVC, and start/end images with GET /v1/assets/{id}.
Transitions
Create a transition between two poses by providing both source_image_asset_id and end_image_asset_id. Transitions automatically set loop: false since they play once between two states. Costs 10 credits for 5 seconds with Standard.
curl -X POST https://api.masko.ai/v1/mascots/MASCOT_ID/generate \
-H "Authorization: Bearer masko_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "animation",
"animation_model": "standard",
"name": "Idle to Wave",
"source_image_asset_id": "6aec5b1a-cb7f-5f10-8d6e-235ec16b4d97",
"end_image_asset_id": "18d4fd5e-7193-57f1-8af9-f3bdff007783",
"animation_prompt": "smoothly transitioning from idle stance to waving",
"duration": 5
}'Loops use the source pose's saved generation context, including its named variant. An explicit conflicting variant_id returns 409, unless that variant intentionally includes the image among its references; then the selected variant guides the new animation without changing the source image's provenance. On a mixed canvas, a Sporty pose keeps Sporty's context even when the canvas defaults to Original. Transitions preserve the before and after contexts separately.
For uploaded images without a generation receipt, variant_id selects the context when that variant includes the image in its references. Without a selection, an upload in Original's references uses Original; an upload belonging to exactly one variant uses that variant. If several variants share an upload and Original does not reference it, generation returns 409 before charging. Select a matching variant or first generate distinct poses for the intended contexts. One shared upload cannot represent two different endpoint contexts in the same request; use separate generated poses for that transition.
Auto-Reverse
When creating a transition, set auto_reverse: true to automatically generate the return transition (B to A) at 0 extra credits. The response includes a reverse_job with its own job ID and asset IDs.
curl -X POST https://api.masko.ai/v1/mascots/MASCOT_ID/generate \
-H "Authorization: Bearer masko_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "animation",
"animation_model": "standard",
"name": "Idle to Wave",
"source_image_asset_id": "6aec5b1a-cb7f-5f10-8d6e-235ec16b4d97",
"end_image_asset_id": "18d4fd5e-7193-57f1-8af9-f3bdff007783",
"animation_prompt": "transitioning from idle to waving",
"auto_reverse": true,
"reverse_name": "Wave to Idle",
"duration": 5
}'Duration & Looping
Pass animation_model to choose the same quality options as Studio. The field is supported by single generation, each request in generate-batch, and canvas edge / generate-all requests.
animation_model | Duration | Default | Credits per second |
|---|---|---|---|
standard | 5–15 whole seconds | 5s | 2 |
premium | 4–30 whole seconds | 5s | 6 |
| omitted (legacy clients) | 4–10 whole seconds | 4s | 5 |
Use "animation_model": "premium" for Premium. Durations outside the selected range return 400 before charging. Images remain 1 credit; an existing source image has no image charge. Reverse animations remain free. Video editing has its separate existing pricing.
Omitting animation_model preserves existing provider selection and pricing for older integrations. Explicitly send the field to use the new rates.
The loop field defaults to true for standard animations and is automatically set to false for transitions (when end_image_asset_id is provided). loop asks generation for a seamless clip. Your player or runtime decides whether to repeat it, hold a frame, or move to another state.
Output Formats
Every animation produces multiple format variants optimized for different platforms:
| Type | Format | Use Case |
|---|---|---|
video | MP4 (H.264) | Universal fallback, opaque background |
webm | WebM (VP9) | Transparent video for Chrome, Firefox, Edge |
hevc | MOV (HEVC + Alpha) | Transparent video for Safari, iOS, macOS |
stacked_video | MP4 (stacked) | Transparent video for Android (color + alpha stacked vertically) |
Size Variants
By default, animations are generated at full resolution. You can configure a mascot to automatically produce smaller size variants for each new animation - useful for responsive layouts, thumbnails, or mobile-optimized assets.
curl -X PATCH https://api.masko.ai/v1/mascots/COL_ID/settings \
-H "Authorization: Bearer masko_..." \
-H "Content-Type: application/json" \
-d '{
"publish_params": {
"animation_sizes": {
"enabled": true,
"sizes": [480, 360, 240]
}
}
}'Available sizes are 720, 480, 360, and 240 pixels. When enabled, new animation outputs automatically generate resized variants alongside the original.
To backfill missing size variants for existing completed animations, use the dedicated endpoint. Normal usage sends an empty body; it uses the mascot's configured sizes, or [360] if no sizes are configured, and only creates missing variants.
curl -X POST https://api.masko.ai/v1/mascots/COL_ID/size-variants \
-H "Authorization: Bearer masko_..." \
-H "Content-Type: application/json" \
-d '{}'Do not re-toggle PATCH /v1/mascots/:id/settings to force a backfill. The size-variants endpoint is the idempotent repair path. force: true exists only for explicit recovery when you intentionally want to regenerate existing variants.
Instant CDN URLs for Size Variants
When generating an animation, pass the sizes array to get pre-allocated CDN URLs for specific size variants immediately in the response:
curl -X POST https://api.masko.ai/v1/mascots/COL_ID/generate \
-H "Authorization: Bearer masko_..." \
-H "Content-Type: application/json" \
-d '{
"type": "animation",
"animation_model": "standard",
"name": "wave",
"image_prompt": "standing with a smile",
"animation_prompt": "waving hello",
"duration": 5,
"sizes": [480]
}'The response includes both original and variant URLs:
{
"data": {
"urls": {
"webm": "https://assets.masko.ai/.../wave.webm",
"hevc": "https://assets.masko.ai/.../wave.mov",
"webm_480": "https://assets.masko.ai/.../wave-480.webm",
"hevc_480": "https://assets.masko.ai/.../wave-480.mov",
"stacked_video_480": "https://assets.masko.ai/.../wave-480.mp4"
}
}
}The sizes parameter is a filter - it only returns URLs for sizes that are enabled in the mascot settings. If you request sizes: [720] but the mascot only has [480, 360] configured, no 720 URLs are returned.
All variant URLs serve placeholders immediately and are replaced with the real resized files when the size variant workflow completes. Poll the job to check size_variants.status.
Cost Reference
At the 5-second default for explicitly selected Standard or Premium:
| Operation | Standard | Premium |
|---|---|---|
| New image + animation | 11 credits | 31 credits |
| Animate existing image | 10 credits | 30 credits |
| Transition (A to B) | 10 credits | 30 credits |
| Auto-reverse (B to A) | 0 credits | 0 credits |
From Video uses Premium at 31 credits for 5 seconds, including the pose image.
Without animation_model, legacy pricing remains 20 credits for a 4-second
animation, plus 1 credit if a new source image is needed.
Direct uploads
source_image_asset_id also accepts an unattached image returned by
POST /v1/upload. The upload must belong to the caller. Masko imports a source
record under the destination mascot, preserves the original uploaded file,
and skips image generation. Non-square sources are center-cropped before animation. It does not add or replace mascot references.
Select an approved variant_id for a new upload when needed. Existing source
assets keep their saved context. See animate an uploaded image.
Image framing
Animations use square input images. Before sending an existing image to the
video model, Masko center-crops horizontal or vertical images to a square and
saves a separate 1024 × 1024 source. Square images are used directly. The same
rule applies to images resolved through item_id and transition end frames.
The original file and mascot references stay unchanged, and cropping adds no
credits.
For a character that is not centered, set source_image_crop explicitly:
{
"type": "animation",
"name": "Wave",
"source_image_asset_id": "IMAGE_ASSET_ID",
"source_image_crop": { "x": 200, "y": 0, "width": 800, "height": 800 },
"animation_prompt": "Wave gently.",
"animation_model": "standard",
"duration": 5
}This example selects an 800 × 800 region from an image at least 1000 × 800.
Coordinates are integers in pixels after applying EXIF orientation. Width and
height must describe a square, within one pixel for crop-tool rounding. The
rectangle must fit inside the image. Invalid crops return 400 before a job
is queued or credits are deducted.
For transitions, end_image_crop sets the end frame's crop independently and
requires end_image_asset_id. Omit either crop to use its centered default.
Image crops do not apply when reversing an existing video.