Mascots and canvases
Mascots contain identity, variants and assets. Canvases belong to projects and reference mascot content. A canvas has an autosaved draft, named checkpoints and immutable releases.
Use /v1/mascots and /v1/canvases for new integrations. Their resource payloads use mascot_id, source_mascot_id and parent_mascot_id, without the old collection aliases. Existing IDs are preserved.
Shared paths such as /v1/jobs, /v1/assets and /v1/canvas-templates support both contracts. Send Masko-API-Version: 2026-09-26 or api_version=2026-09-26 for canonical fields. A mascot_id query filter also selects the new contract. Unversioned shared requests retain legacy fields; this keeps existing production clients working. Responses state the effective version in Masko-API-Version.
Old /v1/collections URLs always use legacy payloads and call the same services. They are adapters, not redirects. Canonical requests reject collection_id; mixed old/new identifiers return 400, even if their values match. Follow the canonical poll_url exactly: it carries the version selector for shared job routes.
Graph documents, user metadata, frozen generation receipts and signed runtime delivery retain their stored format. The naming migration changes REST resource fields, not hashes or installed packages. Where a historical record contains both an authoring collection ID and an old runtime mascot ID, the canonical API names them mascot_id and runtime_binding_id respectively.
OpenAPI marks legacy operations deprecated. Removal requires an announced cutoff, migrated active consumers and 30 consecutive days with no non-test legacy calls. No cutoff has been announced. This API migration is local and not deployed yet.
Use GET /v1/canvases?project_id=PROJECT_ID and POST /v1/canvases with project_id, mascot_id and name. Read and update a canvas at /v1/canvases/CANVAS_ID. Updates require expected_graph_hash to reject concurrent edits. Generation, validation and export operations are nested under that canvas.
History
GET /v1/canvases/CANVAS_ID/history returns the draft, checkpoints and releases. POST to the same route with one action:
| Action | Additional fields |
|---|---|
checkpoint | name, expected_graph_hash |
restore | checkpoint_id, expected_graph_hash |
release | operation_id (UUID), notes, expected_graph_hash |
restore_release | release_id, expected_graph_hash |
copy_release | release_id, name, expected_graph_hash |
Restore preserves current work in a checkpoint first. It does not rerun generation, spend credits, activate Desktop, or publish content. A release requires complete media and freezes exact dependencies. Existing installed releases stay pinned until explicitly replaced.
Publication and purchases
First call POST /v1/mascots/MASCOT_ID/publication with {action:"start"} to create a listing or edit its approved version. Merely viewing a mascot never creates a listing. Then call the same endpoint with {action:"preview",selection:{asset_ids:[],identity_ids:["original"]}}. It returns plan_id and an exact preview. Submit with action:"submit", the same selection and plan_id within ten minutes. Changed content returns 409. Repeating the same plan returns its existing submission. Admins approve the frozen content in the library review screen. Use GET /v1/mascots/MASCOT_ID/published-library?project_id=PROJECT_ID for entitled content.
For a Marketplace listing, add offer: {price_credits: 0, description: "A sleepy cloud mascot", accept_creator_terms: true, cover_asset_id: "SELECTED_ASSET_UUID"} to the selection. description is optional. The thumbnail must be an included image, never an animation or delivery export. If cover_asset_id is omitted, an included generated image is chosen automatically, falling back to the first included image. Include at least one image and at least 5 animations. The mascot must have at least one completed generated image, and the listing must include at least one asset. The thumbnail is frozen with the reviewed selection; changing it requires a new preview. GET /v1/mascots/MASCOT_ID/publication returns gallery assets with their transparent image/WebM/HEVC URLs when available and has_generated_image. Formats are not additional selectable assets. To change a listing while it is in review, send {"action": "withdraw"}: the listing returns to draft with the submitted content, and any published version stays live. The owner response also includes listing_preview: the offer and content currently in review, or the approved listing, or null before the first submission.
Customer library publication is separate from public CDN hosting. A creator submits an exact selection of identities, assets and required dependencies. Approved content stays available while a later submission waits for review. Future generated assets are private until selected and approved.
The new marketplace sells mascot libraries only. It does not include canvas releases. Previous purchases retain their existing playable release rights. Shared context is read-only; approved changes apply to future generation. Duplicating an identity creates a personal variant with copied context and permitted references, independent of later source edits.
The unused developer character registry (/v1/characters), generation plans/runs and character playback sessions are retired in this migration. Use mascot generation and canvas operations directly. Application credential records are retained; no credentials are rotated or revoked by the migration.
Check your server's OpenAPI specification for rollout availability. Local endpoints use http://localhost:3000/api/v1.
CLI and SDK clients
With the matching local client source, use masko studio GET mascots --json or
masko studio POST canvases/CANVAS_ID/history --file request.json --json.
Swift exposes MaskoCloud.studio(_:path:body:); TypeScript exposes
Masko.client().studio(method, path, body). These use the existing authenticated
transport. For shared resources, pass the query selector in the relative path, for example jobs/JOB_ID?api_version=2026-09-26. Previously installed clients need an update; no installer was published
by this local implementation.
Your backend can fetch GET /v1/canvases/CANVAS_ID/releases/RELEASE_ID/delivery?target=web
and forward only data.delivery to its authorized customer. target=desktop
returns the full media format. The response is temporary signed playback access,
not a private library or authoring credential. Refresh it through your backend.
Listing visibility and reviewed changes
GET /v1/mascots/{id}/publication returns state: null before you start a listing. After starting, state.visibility is unpublished, published, or archived, while state.changes_status is independently draft, pending, approved, or rejected. A published listing can have pending changes.
- Save work with
{action:"save_draft",draft_id:"CURRENT_DRAFT_UUID",selection:{...}}. Descriptions may be empty while drafting. Saving never publishes. - Preview the completed selection, then submit its plan. Every submission waits for review, including submissions by admins. While pending, the draft is locked. Rejection returns it for editing with reviewer feedback.
- Approval replaces the live selection, name, description, thumbnail and price together. Existing buyers retain the content they acquired.
{action:"archive"}hides the approved listing and stops new acquisitions. Existing buyers keep access.{action:"restore"}immediately restores only the approved version. Draft or pending changes remain private.- Submitting edits while archived requests publication after approval. Archiving after submission overrides that request: approval keeps the listing archived.
{action:"remove",kind:"asset",resource_id:"ASSET_UUID"}now stages removal in a draft; it requires review before affecting new buyers.
The app uses Create listing → Listing details → Review → Submit for approval. Approval makes the listing public unless the owner archived it while review was pending. Canvas releases remain separate.
Renaming a mascot changes the name used by its next listing submission. The published name remains unchanged until approval. Listing display names may be duplicated; listing IDs and generated slugs identify them uniquely.
Marketplace creators must set a handle and make their profile public before submitting a listing. Approval and restore also check this requirement. Archive all published mascot libraries before changing the profile to private or unlisted. Existing private profiles are not made public automatically.
Personal and organization purchases
Choose Personal or your organization before buying in Marketplace. The confirmation names the owner and the credit balance charged. Any joined team member can buy for that organization; insufficient team credits never spend personal credits. Team ownership remains with the organization when the buyer leaves. The same mascot can be purchased separately for Personal and each organization.
Library access follows the target project. Use an organization API credential and a project in that organization for its purchased libraries. GET /v1/mascots/MASCOT_ID/published-library?project_id=PROJECT_ID includes retained purchased content only for that workspace. A personal license cannot be borrowed by an organization, or vice versa. Repeating a team purchase, including by another member, returns the existing ownership without charging again.
Publish as an organization
A mascot in an organization project publishes under that organization's profile. Select the team and open Profile to set its name, handle, logo and bio. Owners and admins can edit the profile, manage the listing and submit updates. Submission still requires the acting account's existing creator eligibility and the normal review process.
The listing shows the team as its creator, and sales earnings go to the team's credit wallet. The member who submits is recorded separately. Personal profiles and personal credit balances are unchanged. A remaining authorized admin can manage the same listing after its original publisher leaves.
GET /v1/mascots/{id}/publication includes seller.user_id or seller.organization_id (exactly one is non-null), plus seller.can_publish for the viewer's management permission. The project determines the seller; callers cannot select an unrelated profile. Submitted and published mascots cannot be moved to a different owning workspace; ownership transfer needs a separate explicit process.
Canvas deletion returns 409 conflict when checkpoints or releases retain its history. This applies to both /v1/canvases/{canvasId} and the legacy /v1/collections/{id}/canvases/{canvasId} route. A canvas without retained history can still be deleted; generated assets are kept.