Skip to content
Masko logomasko
Docs
Documentation

API Changelog

Changes to the Masko API are recorded here, newest first. Breaking changes are flagged clearly with a migration note.

Read the notes for any version that is newer than when you last integrated, then update your REST client against the current OpenAPI specification.


Talking animations up to 5 minutes (additive)

Under API version 2026-09-26.

  • A talking animation now holds a talk of up to 5 minutes of video, instead of 2 minutes. A talk longer than 5 minutes returns 400.
  • speech.script accepts up to 15,000 characters and speech.text up to 7,500.

Talking animations up to 2 minutes (additive)

Under API version 2026-09-26.

  • A talking animation now holds a talk of up to 2 minutes of video, instead of about 14 seconds of speech. A talk longer than 15 seconds is recorded in one go and cut in its real pauses into takes that start and end on the start image, then joined into one video. The voice stays as recorded; the video model can lengthen the pause at a cut by a fraction of a second, and the transcript's times include it.
  • speech.script accepts up to 6,000 characters and speech.text up to 3,000. A talk longer than 2 minutes returns 400.
  • Movements are performed in place: a move toward the viewer, such as leaning in close, no longer changes the framing, and spoken words are never drawn on screen.

Talking animations (additive)

Under API version 2026-09-26. Adding a voice unlocks once the account has spent $50 on Masko; until then the voice design calls return 403 with details.reason: "voice_locked".

  • POST /v1/mascots/{id}/generate accepts speech with type: "animation": the mascot says a line in its voice, with movements written in square brackets. Costs 3 credits per second; the request charges the longest the line could need and refunds unused seconds once the voice is recorded. dry_run: true returns the estimate for free. The receipt adds estimate, script, and audio and transcript asset IDs.
  • New voice endpoints under /v1/mascots/{id}/voice and /v1/mascots/{id}/variants/{variantId}/voice: get, keep (PUT), remove, suggestions, adjust, and samples (1 credit for three).
  • New asset types audio (MP3) and transcript (JSON). Video metadata of talking animations reports has_audio: true.

See talking animations.

Generation response privacy

Public job and asset responses now omit internal generation execution details for all API versions and credentials. Customer-authored mascot descriptions, styles, references, requested edits and public generation tiers remain available. Stored generation records are unchanged.

Migration: remove the former include=prompts query option; it no longer changes the response. Do not depend on raw execution fields in job input_data, output_data or asset metadata. Mask-refinement quality is now returned as original or pro; older input values are still accepted. Use job IDs and request IDs when contacting support about failures.

Direct image animation

Available in the production OpenAPI specification as of September 28, 2026, under API version 2026-09-26.

  • New POST /v1/animations animates an uploaded image under an existing mascot_id, or explicitly creates a mascot via create_mascot: {project_id, name?} in the same request. An omitted mascot name is supplied by AI; no character description is generated. Returns the mascot ID for reuse alongside the job receipt. Defaults to Standard, 5 seconds, 10 credits. Supports Idempotency-Key across mascot creation and generation.

  • Input-framing behavior change: existing horizontal and vertical image sources are now center-cropped to square before animation, including item-only sources and transition end frames. Previously the full image reached the video model and only the resulting animation was cropped. Square inputs are unchanged. Originals remain intact and cropping adds no credits. To retain a specific framing, upload a prepared square image or set the new source_image_crop / end_image_crop pixel rectangles. See image framing.

  • Animate an unattached image from /v1/upload directly under an existing mascot, without generating another pose or changing mascot references. The source import preserves the original file and selected variant context. Only animation credits are charged.

How versions work

The API path stays /v1. Each set of changes is named by a date, and the current version is 2026-09-26. Send it as the Masko-API-Version header (or api_version query parameter); every response returns the version it used in the same header. Additive changes, such as new fields, endpoints or optional headers, ship inside the current version. A change that could break a working client gets a new date and a migration note here. The OpenAPI specification's info.version always equals the current version.

Media exports (additive)

Available in the production OpenAPI specification as of September 28, 2026, under API version 2026-09-26.

  • New POST/GET /v1/assets/{id}/exports create and list image/video exports, with reusable jobs, signed downloads, resizing and optional regeneration.
  • Mascot settings add publish_params.image_exports for PNG/WebP versions and sizes. New POST /v1/mascots/{id}/exports explicitly backfills saved settings.
  • POST /v1/projects/{id}/export-settings applies settings to current project/folder mascots, with optional backfill. Existing video routes and settings remain compatible.
  • Image exports preserve source files, transparency and aspect ratio, without upscaling or generation credits. See media exports.

2026-09-26

Deployed on 2026-09-27. The API contract date remains 2026-09-26.

Mascots and canvases

  • Canonical routes /v1/mascots and /v1/canvases return mascot_id. Existing /v1/collections routes keep working with their legacy fields and are marked deprecated. See the Studio migration guide.
  • New GET /v1/canvases/{canvasId}/status: generation progress with generation (ready plus node and edge counts), preview, variants, failed_nodes and failed_edges.
  • Canvas responses contain only public fields: object, id, project_id, mascot_id, name, graph, graph_content_hash, created_at, updated_at.
  • GET /v1/canvases pages like other lists when you send limit, offset or cursor, and returns 400 with param: "project_id" when project_id is missing.
  • generate-all returns poll_url on each job, and 409 appearance_unavailable when a mascot has no published appearance to generate with.
  • Breaking in this version: the hosted character registry and its plans, runs, versions and playback issuer are retired. Existing credentials and installed releases are preserved. See terminal setup.

Conventions (additive)

  • Every response has a Request-Id header and the Masko-API-Version it used.
  • Errors add doc_url, request_id and, when a field is at fault, param. Validation errors list every problem in details.issues. Existing code values are unchanged. See error codes.
  • Standard authenticated resource POST endpoints accept Idempotency-Key (/v1/auth/* and /v1/admin/* are excluded). Completed results, including 500 errors, replay for 24 hours with the same workspace, API version and exact request bytes. See conventions.
  • Lists return meta.pagination.next_cursor; pass it back as cursor. offset keeps working.
  • Resources carry an object field naming their type, for example "object": "mascot" or "object": "job".
  • Error messages on mascot routes say "Mascot not found" instead of "Collection not found". The not_found code is unchanged.

Retry fixes

  • Both canonical and legacy collection canvas DELETE return 409 conflict when checkpoints or releases retain history. Generated assets remain stored.
  • Canonical canvas operations accept idempotency keys through their nested handlers without rejecting their own reservation.
  • Replays recheck resource access and preserve the original API representation. A key cannot retrieve a response from another credential workspace or API version.
  • Multipart uploads preserve binary bytes. Reusing an expired completed key no longer fails on a consumed body, and concurrent retries cannot remove a replacement reservation.
  • Errors after execution retain their keys, preventing a retry from repeating committed writes. If the receipt cannot be saved, the API returns 503 idempotency_persistence_failed and keeps the reservation blocked. Retry with the same key and check the operation outcome before starting another request.

Jobs

  • GET /v1/jobs/{id} and GET /v1/jobs initially omitted internal execution details by default. The generation response privacy change above makes that omission unconditional. Customer-authored mascot prompts, styles, references, variants and transition endpoints remain available.

Webhooks (additive)

  • Deliveries add id (stable across retries) and object: "event", plus Masko-Event-Id and a timestamp-bound Masko-Signature: t=...,v1=... header next to the existing signature headers.
  • Failed deliveries retry for about 21 hours with increasing delays. A webhook is disabled after 100 consecutive failures. Deleting a webhook also deletes its delivery history. See webhooks.

Marketplace listings

  • Organization mascots publish under a team profile with a shared handle, name, logo and bio. Team owners/admins manage publishing, existing creator eligibility and review still apply, and earnings go to the team wallet. Publication state now includes the seller workspace and management permission.

  • Marketplace purchases can belong to Personal or the selected organization. Organization purchases spend team credits and are shared with current team members inside that workspace. Personal purchases stay personal. Library API reads and canvas creation require a license in the credential/project workspace.

  • Publication supports withdraw, returns listing_preview and sales to the owner, makes the description optional, and requires at least 5 finished animations and a creator handle before submitting.

  • Studio Marketplace prices and purchase amounts use credits from your existing balance. The catalog returns price_credits. Existing purchases and ownership remain unchanged; older Desktop versions retain their compatible price fields.

1.14.0 - 2026-08-20

Added

  • GET /v1/collections/:id/canvases/:canvasId now returns status.nodes.failed and status.failed_nodes. Failed node and edge entries include the related job ID and a customer-safe error message.

Compatibility

  • status.nodes.pending still counts all incomplete nodes, including failed nodes. Existing polling clients keep their previous behavior and can adopt status.nodes.failed when ready.

1.6.0 - 2026-05-23

Added

  • GET /v1/collections/:id/cdn-export returns the same published CDN JSON shape as the collection page Get Links export modal. Use this for copy-paste app manifests; use /items and /assets for raw IDs, prompts, metadata, and status checks.

Changed

  • CDN export requests now fail clearly with 409 cdn_export_not_ready when asset hosting is disabled, the collection is not published, or no CDN assets have been published yet.

1.5.0 - 2026-05-16

Added

  • GET /v1/assets and GET /v1/collections/:id/assets now accept optional include_file_urls=false for faster metadata-only lists. Defaults are unchanged, so existing callers still receive signed file_url values.

1.2.0 - 2026-04-19

API cleanup pass. Applies one consistent convention across every endpoint: plural resources, verb endpoints only for one-shot actions, {data, meta?} response envelope, generation responses with data.poll_url, and path-parameter IDs instead of bodies.

Added

  • POST /v1/analyze - unified analysis endpoint. Body: {type: "image" | "url", image_url?, url?}. Replaces the two legacy endpoints.
  • GET /v1/collections/:id/suggestions - AI-suggested action names for a mascot collection. Read-only, no credits.
  • GET /v1/assets and GET /v1/assets/:id - first-class access to assets. Filter by collection_id, type, is_archived.
  • DELETE /v1/assets/:id - archive an asset (soft delete).
  • PATCH /v1/collections/:id/items/:itemId - update an item's name or prompt.
  • DELETE /v1/collections/:id/items/:itemId - archive an item.
  • DELETE /v1/collections/:id/canvases/:canvasId - delete a canvas.
  • PATCH /v1/canvas-templates/:id and GET /v1/canvas-templates/:id.
  • DELETE /v1/collections/:id/references/:assetId - remove a reference by path param.

Changed (breaking)

  • POST /v1/collections/:id/generate-batch - returns 202 Accepted with data.jobs, data.total_cost, and data.poll_url.
  • DELETE /v1/collections/:id/references - the asset ID moves from the body to the URL path. Old: DELETE /references with {asset_id} in body. New: DELETE /references/:assetId.
  • POST /v1/collections/:id/canvases - now accepts an optional template_id (plus node_overrides, edge_overrides). The legacy /canvases/:canvasId/from-template endpoint is removed - apply templates at creation time instead.
  • PUT /v1/collections/:id/canvases/:canvasId - now PATCH /v1/collections/:id/canvases/:canvasId. Body unchanged.
  • GET /v1/collections/:id/canvases/:canvasId/status - removed. The status object is now on the canvas GET response.
  • PATCH /v1/collections/:id/cdn-slug - removed. Set slug via PATCH /v1/collections/:id with {slug} in the body.
  • GET /v1/collections/:id/cdn-status - removed. The cdn_status array is now on GET /v1/collections/:id.
  • GET /v1/collections/:id/urls - removed. Use GET /v1/collections/:id/assets - URLs are already attached to each asset.
  • Paginated responses - pagination now lives under meta.pagination instead of top-level pagination. Shape is unchanged: {total, limit, offset, has_more}.
  • Async responses - poll_url now lives inside data (previously top-level). Clients that construct the poll URL from job_id are unaffected.

Removed

  • POST /v1/analyze-image - use POST /v1/analyze with {type: "image", image_url}.
  • POST /v1/analyze-url - use POST /v1/analyze with {type: "url", url}.
  • POST /v1/collections/:id/suggest-actions - use GET /v1/collections/:id/suggestions.

Not changed

  • POST /v1/collections/:id/generate - URL, body, and response are unchanged.
  • POST /v1/upload - unchanged.
  • GET /v1/jobs/:id - unchanged. Still supports ?wait=true&timeout=120.
  • Authentication and credit costs - all unchanged.

Migration checklist

  • POST /analyze-image callers: swap to POST /analyze with {type: "image", image_url}.
  • POST /analyze-url callers: swap to POST /analyze with {type: "url", url}.
  • POST /suggest-actions callers: swap to GET /suggestions. No body needed.
  • DELETE /references body callers: move asset_id from body to URL path.
  • cdn-slug / cdn-status / urls callers: read and write via the main collection endpoints.
  • Canvas from-template callers: pass template_id on POST /canvases instead.
  • Canvas PUT callers: change the method to PATCH.

Most customers will not need code changes if they only use POST /generate and GET /jobs/:id with the documented request and response shapes.


1.1.0 - 2026-04-10

  • Envelope enforcement: every v1 response now wraps data in {data} or {error: {code, message}}. Lists include pagination metadata.
  • Introduced the api-key permission levels: read, write, admin. New keys default to write.

1.0.0 - 2025-12-01

Initial public release of the Masko v1 API covering projects, collections, items, canvases, generation, jobs, webhooks, and credits.


How to follow updates