Skip to content
Masko logomasko
Docs
Documentation

Export Canvas

Once all edge videos are generated, export the canvas as a MaskoAnimationConfig JSON object. This config contains everything needed to run your interactive mascot - nodes, edges, video URLs, and input mappings.

curl https://api.masko.ai/v1/canvases/CANVAS_ID/export \
  -H "Authorization: Bearer masko_YOUR_API_KEY"

Before exporting

Enable asset hosting and publish the mascot in the Masko app, then wait for all media required by the export target. Unpublished mascots and missing required media return HTTP 400. Check the canvas’s media readiness before retrying.

The MaskoAnimationConfig

The MaskoAnimationConfig is a versioned JSON format (current version 2.0) that describes an interactive mascot state machine. It is the output of the export endpoint and the input to the Masko embed player. The config is self-contained - all media URLs use the public CDN. This endpoint requires a published mascot.

Response Structure

{
  "version": "2.0",
  "name": "My Mascot",
  "initialNode": "idle",
  "autoPlay": true,
  "clickEffect": "none",
  "nodes": [
    {
      "id": "idle",
      "name": "Idle",
      "transparentThumbnailUrl": "https://assets.masko.ai/57fa7e3f-4fdb-556a-8167-968b2b3d8f4b/idle.png"
    },
    {
      "id": "waving",
      "name": "Waving",
      "transparentThumbnailUrl": "https://assets.masko.ai/57fa7e3f-4fdb-556a-8167-968b2b3d8f4b/waving.png"
    },
    {
      "id": "thinking",
      "name": "Thinking",
      "transparentThumbnailUrl": "https://assets.masko.ai/57fa7e3f-4fdb-556a-8167-968b2b3d8f4b/thinking.png"
    }
  ],
  "edges": [
    {
      "id": "idle-loop",
      "source": "idle",
      "target": "idle",
      "isLoop": true,
      "duration": 4,
      "videos": {
        "webm": "https://assets.masko.ai/57fa7e3f-4fdb-556a-8167-968b2b3d8f4b/idle-loop.webm",
        "hevc": "https://assets.masko.ai/57fa7e3f-4fdb-556a-8167-968b2b3d8f4b/idle-loop.mp4"
      }
    },
    {
      "id": "idle-to-waving",
      "source": "idle",
      "target": "waving",
      "isLoop": false,
      "duration": 4,
      "videos": {
        "webm": "https://assets.masko.ai/57fa7e3f-4fdb-556a-8167-968b2b3d8f4b/idle-to-waving.webm",
        "hevc": "https://assets.masko.ai/57fa7e3f-4fdb-556a-8167-968b2b3d8f4b/idle-to-waving.mp4"
      },
      "conditions": [{ "input": "behavior::interact", "op": "==", "value": true }]
    },
    {
      "id": "waving-to-idle",
      "source": "waving",
      "target": "idle",
      "isLoop": false,
      "duration": 4,
      "videos": {
        "webm": "https://assets.masko.ai/57fa7e3f-4fdb-556a-8167-968b2b3d8f4b/waving-to-idle.webm",
        "hevc": "https://assets.masko.ai/57fa7e3f-4fdb-556a-8167-968b2b3d8f4b/waving-to-idle.mp4"
      }
    }
  ],
  "inputs": [
    {
      "name": "behavior::interact",
      "type": "boolean",
      "default": false
    }
  ]
}

Config Fields

FieldTypeDescription
versionstringConfig format version. Currently "2.0".
namestringDisplay name of the canvas.
initialNodestringID of the node to display on load.
autoPlaybooleanStart playing the initial loop automatically.
clickEffectstringOptional click effect, currently "ripple" or "none".
nodes[]arrayMascot poses. Each has id, name, and optional transparentThumbnailUrl.
edges[]arrayTransitions between nodes. Each has source, target, isLoop, duration, videos, and optional conditions.
inputs[]arrayProgrammatic inputs. Each has name, type, and default.

Using in Web

For a complete clip-handoff design, read smooth mascot playback. Changing clips requires two persistent players and verified frame readiness; the source-selection sample below is not a smooth interactive player.

The config includes both webm and hevc video URLs for each edge. Use WebM for Chrome and Firefox, and HEVC (MP4) for Safari. The example below selects a format for one edge; it is not a complete state-machine player. Your renderer must implement conditions, transitions and input handling:

<div id="mascot" style="width: 200px; height: 200px;">
  <video muted playsinline style="width:100%;height:100%"></video>
</div>

<script type="module">
  // Load the exported config
  const config = await fetch('/mascot-config.json').then(r => r.json());

  // Detect format support
  function getVideoFormat() {
    const video = document.createElement('video');
    if (video.canPlayType('video/webm; codecs="vp9"')) return 'webm';
    if (video.canPlayType('video/mp4; codecs="hvc1"')) return 'hevc';
    return 'webm'; // fallback
  }

  const format = getVideoFormat();

  // Play a transition
  function playEdge(edge) {
    const videoEl = document.querySelector('#mascot video');
    videoEl.src = edge.videos[format];
    return videoEl.play();
  }
</script>

Using in Desktop

For frozen playback, create a canvas release through /v1/canvases/CANVAS_ID/history, then fetch its signed /releases/RELEASE_ID/delivery?target=desktop payload through your backend. See Studio migration. Do not pass a raw draft export or a REST credential to a visitor. Installed CLI/SDK playback compatibility depends on the client version; older named-character methods target the retired backend.

Targeted delivery

Use ?delivery=1&target=macos to request the runtime delivery envelope instead of the compatibility animation config. target also accepts web, windows, or full; these select media formats, not a guarantee that a desktop SDK exists for that platform. The current developer runtime is macOS-only.

mode=selected is the default; mode=manifest requests manifest delivery. An optional positive integer size selects a variant. Read the returned envelope under data and use the endpoint reference for its fields.