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.

GET/v1/collections/:id/canvases/:canvasId/export
curl https://api.masko.ai/v1/collections/COLLECTION_ID/canvases/CANVAS_ID/export \
  -H "Authorization: Bearer masko_YOUR_API_KEY"

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 asset URLs point to the CDN and can be used directly in a browser or desktop app.

Response Structure

{
  "version": "2.0",
  "name": "My Mascot",
  "initialNode": "idle",
  "autoPlay": true,
  "clickEffect": "next_state",
  "nodes": [
    {
      "id": "idle",
      "label": "Idle",
      "imageUrl": "https://assets.masko.ai/col_abc/idle.png",
      "loop": true
    },
    {
      "id": "waving",
      "label": "Waving",
      "imageUrl": "https://assets.masko.ai/col_abc/waving.png",
      "loop": false
    },
    {
      "id": "thinking",
      "label": "Thinking",
      "imageUrl": "https://assets.masko.ai/col_abc/thinking.png",
      "loop": true
    }
  ],
  "edges": [
    {
      "id": "idle-loop",
      "source": "idle",
      "target": "idle",
      "videos": {
        "webm": "https://assets.masko.ai/col_abc/idle-loop.webm",
        "hevc": "https://assets.masko.ai/col_abc/idle-loop.mp4"
      },
      "condition": "default"
    },
    {
      "id": "idle-to-waving",
      "source": "idle",
      "target": "waving",
      "videos": {
        "webm": "https://assets.masko.ai/col_abc/idle-to-waving.webm",
        "hevc": "https://assets.masko.ai/col_abc/idle-to-waving.mp4"
      },
      "condition": "on_click"
    },
    {
      "id": "waving-to-idle",
      "source": "waving",
      "target": "idle",
      "videos": {
        "webm": "https://assets.masko.ai/col_abc/waving-to-idle.webm",
        "hevc": "https://assets.masko.ai/col_abc/waving-to-idle.mp4"
      },
      "condition": "on_complete"
    }
  ],
  "inputs": [
    {
      "id": "show_thinking",
      "label": "Show Thinking",
      "targetNode": "thinking",
      "returnNode": "idle"
    }
  ]
}

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.
clickEffectstringWhat happens when the user clicks the mascot. e.g. "next_state".
nodes[]arrayMascot poses. Each has id, label, imageUrl, and loop flag.
edges[]arrayTransitions between nodes. Each has source, target, videos (webm/hevc), and condition.
inputs[]arrayProgrammatic triggers. Each has id, label, targetNode, and returnNode.

Using in Web

The config includes both webm and hevc video URLs for each edge. Use WebM for Chrome and Firefox, and HEVC (MP4) for Safari. Here is a minimal example for format selection:

<div id="mascot" style="width: 200px; height: 200px;"></div>

<script>
  // 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];
    videoEl.play();
  }
</script>

Using in Desktop

The Masko Code desktop app loads the MaskoAnimationConfig directly. Export the config, save it as a JSON file, and point the app to it. The desktop player handles format selection, caching, and state machine logic automatically.

Tip

The export endpoint only succeeds when all edges have completed videos. Check the /status endpoint first and wait for ready: true before exporting.