All docs

JSON format

JSON examples

Complete openCanviz JSON files you can copy, import and edit: a flow diagram, a two-scene explainer and a vertical Short.

Last updated

Each example below is a complete file that imports as is. Copy one, paste it into Import on the Create page, and click Import project. Each one passes the schema and plays from start to end. Change the text, colors and positions to make it your own, and keep the structure. For what each field means, see the schema reference.

The examples include narration lines as text. After you import, open the Narration panel and click Generate All Scenes to give them a voice.

A four-step flow diagram

A 16:9 scene that walks a web request from the browser to a database. It shows:

  • A title and three boxes, with the server and database starting at opacity 0.
  • Edges that attach to the side of a box with fromPort and toPort, and draw in with an edgeTween on trim.
  • Delta steps that set opacity to 1 for each box they reveal, alongside a fadeIn action.
  • A last step that changes fill colors with no action at all, so the change tweens on its own, and turns on a moving ball along each edge with animationStyle.
{
  "$schema": "https://opencanviz.com/schema/v1.json",
  "title": "How a web request travels",
  "artboard": {
    "x": -960,
    "y": -540,
    "width": 1920,
    "height": 1080,
    "background": "#0f172a"
  },
  "showCaptions": true,
  "diagrams": [
    {
      "nodes": [
        {
          "id": "title",
          "kind": "text",
          "x": -700,
          "y": -420,
          "w": 1400,
          "h": 100,
          "text": "How a web request travels",
          "fontSize": 64,
          "fontWeight": 700,
          "color": "#f8fafc",
          "textAlign": "center",
          "verticalAlign": "middle",
          "fill": "transparent",
          "stroke": "none",
          "opacity": 1
        },
        {
          "id": "client",
          "kind": "rect",
          "x": -820,
          "y": -100,
          "w": 360,
          "h": 200,
          "cornerRadius": 20,
          "fill": "#1e293b",
          "stroke": "#38bdf8",
          "strokeWidth": 4,
          "label": "Browser",
          "labelColor": "#f8fafc",
          "labelFontSize": 44,
          "opacity": 1
        },
        {
          "id": "server",
          "kind": "rect",
          "x": -180,
          "y": -100,
          "w": 360,
          "h": 200,
          "cornerRadius": 20,
          "fill": "#1e293b",
          "stroke": "#a78bfa",
          "strokeWidth": 4,
          "label": "API server",
          "labelColor": "#f8fafc",
          "labelFontSize": 44,
          "opacity": 0
        },
        {
          "id": "db",
          "kind": "rect",
          "x": 460,
          "y": -100,
          "w": 360,
          "h": 200,
          "cornerRadius": 20,
          "fill": "#1e293b",
          "stroke": "#34d399",
          "strokeWidth": 4,
          "label": "Database",
          "labelColor": "#f8fafc",
          "labelFontSize": 44,
          "opacity": 0
        }
      ],
      "edges": [
        {
          "id": "client_to_server",
          "from": "client",
          "to": "server",
          "fromPort": "E",
          "toPort": "W",
          "stroke": "#cbd5e1",
          "width": 5,
          "arrow": "end",
          "lineType": "straight",
          "trim": 0
        },
        {
          "id": "server_to_db",
          "from": "server",
          "to": "db",
          "fromPort": "E",
          "toPort": "W",
          "stroke": "#cbd5e1",
          "width": 5,
          "arrow": "end",
          "lineType": "straight",
          "trim": 0
        }
      ],
      "steps": [
        {
          "id": "browser",
          "durationMs": 2500,
          "caption": "A request starts in the browser.",
          "nodes": [
            {
              "id": "title",
              "kind": "text",
              "x": -700,
              "y": -420,
              "w": 1400,
              "h": 100,
              "text": "How a web request travels",
              "fontSize": 64,
              "fontWeight": 700,
              "color": "#f8fafc",
              "textAlign": "center",
              "verticalAlign": "middle",
              "fill": "transparent",
              "stroke": "none",
              "opacity": 1
            },
            {
              "id": "client",
              "kind": "rect",
              "x": -820,
              "y": -100,
              "w": 360,
              "h": 200,
              "cornerRadius": 20,
              "fill": "#1e293b",
              "stroke": "#38bdf8",
              "strokeWidth": 4,
              "label": "Browser",
              "labelColor": "#f8fafc",
              "labelFontSize": 44,
              "opacity": 1
            },
            {
              "id": "server",
              "kind": "rect",
              "x": -180,
              "y": -100,
              "w": 360,
              "h": 200,
              "cornerRadius": 20,
              "fill": "#1e293b",
              "stroke": "#a78bfa",
              "strokeWidth": 4,
              "label": "API server",
              "labelColor": "#f8fafc",
              "labelFontSize": 44,
              "opacity": 0
            },
            {
              "id": "db",
              "kind": "rect",
              "x": 460,
              "y": -100,
              "w": 360,
              "h": 200,
              "cornerRadius": 20,
              "fill": "#1e293b",
              "stroke": "#34d399",
              "strokeWidth": 4,
              "label": "Database",
              "labelColor": "#f8fafc",
              "labelFontSize": 44,
              "opacity": 0
            }
          ],
          "edges": [
            {
              "id": "client_to_server",
              "from": "client",
              "to": "server",
              "fromPort": "E",
              "toPort": "W",
              "stroke": "#cbd5e1",
              "width": 5,
              "arrow": "end",
              "lineType": "straight",
              "trim": 0
            },
            {
              "id": "server_to_db",
              "from": "server",
              "to": "db",
              "fromPort": "E",
              "toPort": "W",
              "stroke": "#cbd5e1",
              "width": 5,
              "arrow": "end",
              "lineType": "straight",
              "trim": 0
            }
          ],
          "actions": [
            {
              "type": "visibility",
              "target": {
                "kind": "node",
                "id": "title"
              },
              "mode": "fadeIn",
              "durationMs": 500
            },
            {
              "type": "visibility",
              "target": {
                "kind": "node",
                "id": "client"
              },
              "mode": "fadeIn",
              "durationMs": 500,
              "offsetMs": 400
            }
          ]
        },
        {
          "id": "to_server",
          "delta": true,
          "durationMs": 2500,
          "caption": "It travels to the API server.",
          "nodes": [
            {
              "id": "server",
              "opacity": 1
            }
          ],
          "edges": [
            {
              "id": "client_to_server",
              "trim": 1
            }
          ],
          "actions": [
            {
              "type": "edgeTween",
              "target": {
                "kind": "edge",
                "id": "client_to_server"
              },
              "from": {
                "trim": 0
              },
              "to": {
                "trim": 1
              },
              "durationMs": 600,
              "ease": "ease-out"
            },
            {
              "type": "visibility",
              "target": {
                "kind": "node",
                "id": "server"
              },
              "mode": "fadeIn",
              "durationMs": 400,
              "offsetMs": 600
            }
          ]
        },
        {
          "id": "to_db",
          "delta": true,
          "durationMs": 2500,
          "caption": "The server asks the database for the data.",
          "nodes": [
            {
              "id": "db",
              "opacity": 1
            }
          ],
          "edges": [
            {
              "id": "server_to_db",
              "trim": 1
            }
          ],
          "actions": [
            {
              "type": "edgeTween",
              "target": {
                "kind": "edge",
                "id": "server_to_db"
              },
              "from": {
                "trim": 0
              },
              "to": {
                "trim": 1
              },
              "durationMs": 600,
              "ease": "ease-out"
            },
            {
              "type": "visibility",
              "target": {
                "kind": "node",
                "id": "db"
              },
              "mode": "fadeIn",
              "durationMs": 400,
              "offsetMs": 600
            }
          ]
        },
        {
          "id": "answer",
          "delta": true,
          "durationMs": 3000,
          "caption": "The database answers, and the page loads.",
          "easing": "ease-out",
          "nodes": [
            {
              "id": "db",
              "fill": "#065f46"
            },
            {
              "id": "client",
              "fill": "#0c4a6e"
            }
          ],
          "edges": [
            {
              "id": "client_to_server",
              "animationStyle": "ball"
            },
            {
              "id": "server_to_db",
              "animationStyle": "ball"
            }
          ]
        }
      ],
      "narration": [
        {
          "id": "line_0",
          "text": "A request starts in the browser.",
          "stepIndex": 0,
          "voice": {
            "provider": "openai",
            "voiceId": "alloy",
            "voiceName": "Alloy"
          }
        },
        {
          "id": "line_1",
          "text": "It travels to the API server.",
          "stepIndex": 1,
          "voice": {
            "provider": "openai",
            "voiceId": "alloy",
            "voiceName": "Alloy"
          }
        },
        {
          "id": "line_2",
          "text": "The server asks the database for the data.",
          "stepIndex": 2,
          "voice": {
            "provider": "openai",
            "voiceId": "alloy",
            "voiceName": "Alloy"
          }
        },
        {
          "id": "line_3",
          "text": "The database answers, and the page loads.",
          "stepIndex": 3,
          "voice": {
            "provider": "openai",
            "voiceId": "alloy",
            "voiceName": "Alloy"
          }
        }
      ]
    }
  ]
}

A two-scene explainer

Two scenes joined by a crossfade, with captions in a band. It shows:

  • sceneNames, transitions and captionStyle at the project level.
  • Scene 1: a typewriter title, made with a transformTween on typeProgress from 0 to 1, and a subtitle that enters from below with slideInDown after a delay set by offsetMs.
  • Scene 2: an app box and a database cylinder that slide in from opposite sides, joined by a dashed edge.
  • A delta step that moves the database to a new x (set in the step and timed with a transformTween), adds a cache box with addNodes and a new edge with addEdges.
  • A last step that removes the slow edge with removeEdgeIds and zooms the camera in.
  • Ids prefixed per scene, s1_ and s2_, so they never clash.
{
  "$schema": "https://opencanviz.com/schema/v1.json",
  "title": "Caching in two minutes",
  "artboard": {
    "x": -960,
    "y": -540,
    "width": 1920,
    "height": 1080,
    "background": "#0f172a"
  },
  "sceneNames": [
    "Title",
    "Why caches help"
  ],
  "transitions": [
    {
      "kind": "crossfade",
      "durationMs": 600
    }
  ],
  "captionStyle": {
    "variant": "band",
    "fontScale": 1.1,
    "textColor": "#f8fafc",
    "bandColor": "#020617",
    "bandOpacity": 0.8
  },
  "diagrams": [
    {
      "nodes": [
        {
          "id": "s1_title",
          "kind": "text",
          "x": -800,
          "y": -160,
          "w": 1600,
          "h": 160,
          "text": "Caching in two minutes",
          "fontSize": 96,
          "fontWeight": 800,
          "color": "#f8fafc",
          "textAlign": "center",
          "verticalAlign": "middle",
          "fill": "transparent",
          "stroke": "none",
          "typeProgress": 1
        },
        {
          "id": "s1_subtitle",
          "kind": "text",
          "x": -600,
          "y": 40,
          "w": 1200,
          "h": 80,
          "text": "Why the second request is faster",
          "fontSize": 44,
          "fontWeight": 400,
          "color": "#94a3b8",
          "textAlign": "center",
          "verticalAlign": "middle",
          "fill": "transparent",
          "stroke": "none"
        }
      ],
      "edges": [],
      "steps": [
        {
          "id": "s1_type",
          "durationMs": 2600,
          "caption": "Caching, in two minutes.",
          "nodes": [
            {
              "id": "s1_title",
              "kind": "text",
              "x": -800,
              "y": -160,
              "w": 1600,
              "h": 160,
              "text": "Caching in two minutes",
              "fontSize": 96,
              "fontWeight": 800,
              "color": "#f8fafc",
              "textAlign": "center",
              "verticalAlign": "middle",
              "fill": "transparent",
              "stroke": "none",
              "typeProgress": 1
            },
            {
              "id": "s1_subtitle",
              "kind": "text",
              "x": -600,
              "y": 40,
              "w": 1200,
              "h": 80,
              "text": "Why the second request is faster",
              "fontSize": 44,
              "fontWeight": 400,
              "color": "#94a3b8",
              "textAlign": "center",
              "verticalAlign": "middle",
              "fill": "transparent",
              "stroke": "none"
            }
          ],
          "edges": [],
          "actions": [
            {
              "type": "transformTween",
              "target": {
                "kind": "node",
                "id": "s1_title"
              },
              "from": {
                "typeProgress": 0
              },
              "to": {
                "typeProgress": 1
              },
              "durationMs": 1400,
              "ease": "linear"
            },
            {
              "type": "visibility",
              "target": {
                "kind": "node",
                "id": "s1_subtitle"
              },
              "mode": "slideInDown",
              "durationMs": 500,
              "offsetMs": 1500,
              "slideDistance": 60
            }
          ]
        }
      ],
      "narration": [
        {
          "id": "s1_line_0",
          "text": "Caching, in two minutes.",
          "stepIndex": 0,
          "voice": {
            "provider": "openai",
            "voiceId": "alloy",
            "voiceName": "Alloy"
          }
        }
      ]
    },
    {
      "nodes": [
        {
          "id": "s2_app",
          "kind": "rect",
          "x": -760,
          "y": -110,
          "w": 340,
          "h": 220,
          "cornerRadius": 20,
          "fill": "#1e293b",
          "stroke": "#38bdf8",
          "strokeWidth": 4,
          "label": "App",
          "labelColor": "#f8fafc",
          "labelFontSize": 44
        },
        {
          "id": "s2_db",
          "kind": "cylinder",
          "x": 420,
          "y": -140,
          "w": 300,
          "h": 280,
          "fill": "#1e293b",
          "stroke": "#f59e0b",
          "strokeWidth": 4,
          "label": "Database",
          "labelColor": "#f8fafc",
          "labelFontSize": 40
        }
      ],
      "edges": [
        {
          "id": "s2_slow",
          "from": "s2_app",
          "to": "s2_db",
          "stroke": "#f59e0b",
          "width": 5,
          "arrow": "both",
          "strokeStyle": "dashed",
          "label": "200 ms",
          "labelColor": "#fbbf24",
          "labelFontSize": 32,
          "labelPosition": "above"
        }
      ],
      "steps": [
        {
          "id": "s2_slow_path",
          "durationMs": 3000,
          "caption": "Without a cache, every request goes all the way to the database.",
          "nodes": [
            {
              "id": "s2_app",
              "kind": "rect",
              "x": -760,
              "y": -110,
              "w": 340,
              "h": 220,
              "cornerRadius": 20,
              "fill": "#1e293b",
              "stroke": "#38bdf8",
              "strokeWidth": 4,
              "label": "App",
              "labelColor": "#f8fafc",
              "labelFontSize": 44
            },
            {
              "id": "s2_db",
              "kind": "cylinder",
              "x": 420,
              "y": -140,
              "w": 300,
              "h": 280,
              "fill": "#1e293b",
              "stroke": "#f59e0b",
              "strokeWidth": 4,
              "label": "Database",
              "labelColor": "#f8fafc",
              "labelFontSize": 40
            }
          ],
          "edges": [
            {
              "id": "s2_slow",
              "from": "s2_app",
              "to": "s2_db",
              "stroke": "#f59e0b",
              "width": 5,
              "arrow": "both",
              "strokeStyle": "dashed",
              "label": "200 ms",
              "labelColor": "#fbbf24",
              "labelFontSize": 32,
              "labelPosition": "above"
            }
          ],
          "actions": [
            {
              "type": "visibility",
              "target": {
                "kind": "node",
                "id": "s2_app"
              },
              "mode": "slideInLeft",
              "durationMs": 500
            },
            {
              "type": "visibility",
              "target": {
                "kind": "node",
                "id": "s2_db"
              },
              "mode": "slideInRight",
              "durationMs": 500,
              "offsetMs": 200
            },
            {
              "type": "edgeTween",
              "target": {
                "kind": "edge",
                "id": "s2_slow"
              },
              "from": {
                "trim": 0
              },
              "to": {
                "trim": 1
              },
              "durationMs": 700,
              "offsetMs": 800
            }
          ]
        },
        {
          "id": "s2_add_cache",
          "delta": true,
          "durationMs": 3200,
          "caption": "A cache keeps recent answers close to the app.",
          "nodes": [
            {
              "id": "s2_db",
              "x": 520
            }
          ],
          "edges": [],
          "addNodes": [
            {
              "id": "s2_cache",
              "kind": "rect",
              "x": -170,
              "y": -100,
              "w": 300,
              "h": 200,
              "cornerRadius": 20,
              "fill": "#3b0764",
              "stroke": "#c084fc",
              "strokeWidth": 4,
              "label": "Cache",
              "labelColor": "#f8fafc",
              "labelFontSize": 44,
              "opacity": 1
            }
          ],
          "addEdges": [
            {
              "id": "s2_fast",
              "from": "s2_app",
              "to": "s2_cache",
              "stroke": "#c084fc",
              "width": 5,
              "arrow": "both",
              "label": "2 ms",
              "labelColor": "#e9d5ff",
              "labelFontSize": 32,
              "labelPosition": "above",
              "trim": 0
            }
          ],
          "actions": [
            {
              "type": "transformTween",
              "target": {
                "kind": "node",
                "id": "s2_db"
              },
              "to": {
                "x": 520
              },
              "durationMs": 600,
              "ease": "ease-out"
            },
            {
              "type": "visibility",
              "target": {
                "kind": "node",
                "id": "s2_cache"
              },
              "mode": "fadeIn",
              "durationMs": 500,
              "offsetMs": 600
            },
            {
              "type": "edgeTween",
              "target": {
                "kind": "edge",
                "id": "s2_fast"
              },
              "from": {
                "trim": 0
              },
              "to": {
                "trim": 1
              },
              "durationMs": 600,
              "offsetMs": 1100
            }
          ]
        },
        {
          "id": "s2_zoom",
          "delta": true,
          "durationMs": 3000,
          "caption": "The next request is answered in two milliseconds.",
          "nodes": [],
          "edges": [
            {
              "id": "s2_fast",
              "trim": 1
            }
          ],
          "removeEdgeIds": [
            "s2_slow"
          ],
          "camera": {
            "x": -300,
            "y": 0,
            "zoom": 1.4
          },
          "cameraDurationMs": 1200,
          "cameraEasing": "ease-out"
        }
      ],
      "narration": [
        {
          "id": "s2_line_0",
          "text": "Without a cache, every request goes all the way to the database.",
          "stepIndex": 0,
          "voice": {
            "provider": "openai",
            "voiceId": "alloy",
            "voiceName": "Alloy"
          }
        },
        {
          "id": "s2_line_1",
          "text": "A cache keeps recent answers close to the app.",
          "stepIndex": 1,
          "voice": {
            "provider": "openai",
            "voiceId": "alloy",
            "voiceName": "Alloy"
          }
        },
        {
          "id": "s2_line_2",
          "text": "The next request is answered in two milliseconds.",
          "stepIndex": 2,
          "voice": {
            "provider": "openai",
            "voiceId": "alloy",
            "voiceName": "Alloy"
          }
        }
      ]
    }
  ]
}

A vertical Short

A 9:16 single-scene file in the flat form, with nodes, edges and steps at the top level. It shows:

  • A headline that enters from above with slideInUp.
  • Three cards that start at opacity 0 and are revealed one per step with slideInLeft and a back ease.
  • A progress bar whose value rises in each step and tweens on its own.
{
  "$schema": "https://opencanviz.com/schema/v1.json",
  "title": "3 habits of fast teams",
  "artboard": {
    "x": -540,
    "y": -960,
    "width": 1080,
    "height": 1920,
    "background": "#fffbeb"
  },
  "nodes": [
    {
      "id": "headline",
      "kind": "text",
      "x": -460,
      "y": -760,
      "w": 920,
      "h": 240,
      "text": "3 habits of\nfast teams",
      "fontSize": 96,
      "fontWeight": 800,
      "lineHeight": 1.1,
      "color": "#1c1917",
      "textAlign": "center",
      "verticalAlign": "middle",
      "fill": "transparent",
      "stroke": "none"
    },
    {
      "id": "habit_0",
      "kind": "rect",
      "x": -440,
      "y": -380,
      "w": 880,
      "h": 240,
      "cornerRadius": 28,
      "fill": "#fde68a",
      "stroke": "#1c1917",
      "strokeWidth": 4,
      "label": "Ship small",
      "labelColor": "#1c1917",
      "labelFontSize": 52,
      "labelFontWeight": "bold",
      "opacity": 0
    },
    {
      "id": "habit_1",
      "kind": "rect",
      "x": -440,
      "y": -80,
      "w": 880,
      "h": 240,
      "cornerRadius": 28,
      "fill": "#bbf7d0",
      "stroke": "#1c1917",
      "strokeWidth": 4,
      "label": "Review fast",
      "labelColor": "#1c1917",
      "labelFontSize": 52,
      "labelFontWeight": "bold",
      "opacity": 0
    },
    {
      "id": "habit_2",
      "kind": "rect",
      "x": -440,
      "y": 220,
      "w": 880,
      "h": 240,
      "cornerRadius": 28,
      "fill": "#bfdbfe",
      "stroke": "#1c1917",
      "strokeWidth": 4,
      "label": "Automate tests",
      "labelColor": "#1c1917",
      "labelFontSize": 52,
      "labelFontWeight": "bold",
      "opacity": 0
    },
    {
      "id": "progress",
      "kind": "progress",
      "x": -440,
      "y": 620,
      "w": 880,
      "h": 28,
      "value": 0,
      "fill": "#e7e5e4",
      "stroke": "none",
      "progressColor": "#f59e0b"
    }
  ],
  "edges": [],
  "steps": [
    {
      "id": "hook",
      "durationMs": 1800,
      "caption": "Three habits of fast teams.",
      "nodes": [
        {
          "id": "headline",
          "kind": "text",
          "x": -460,
          "y": -760,
          "w": 920,
          "h": 240,
          "text": "3 habits of\nfast teams",
          "fontSize": 96,
          "fontWeight": 800,
          "lineHeight": 1.1,
          "color": "#1c1917",
          "textAlign": "center",
          "verticalAlign": "middle",
          "fill": "transparent",
          "stroke": "none"
        },
        {
          "id": "habit_0",
          "kind": "rect",
          "x": -440,
          "y": -380,
          "w": 880,
          "h": 240,
          "cornerRadius": 28,
          "fill": "#fde68a",
          "stroke": "#1c1917",
          "strokeWidth": 4,
          "label": "Ship small",
          "labelColor": "#1c1917",
          "labelFontSize": 52,
          "labelFontWeight": "bold",
          "opacity": 0
        },
        {
          "id": "habit_1",
          "kind": "rect",
          "x": -440,
          "y": -80,
          "w": 880,
          "h": 240,
          "cornerRadius": 28,
          "fill": "#bbf7d0",
          "stroke": "#1c1917",
          "strokeWidth": 4,
          "label": "Review fast",
          "labelColor": "#1c1917",
          "labelFontSize": 52,
          "labelFontWeight": "bold",
          "opacity": 0
        },
        {
          "id": "habit_2",
          "kind": "rect",
          "x": -440,
          "y": 220,
          "w": 880,
          "h": 240,
          "cornerRadius": 28,
          "fill": "#bfdbfe",
          "stroke": "#1c1917",
          "strokeWidth": 4,
          "label": "Automate tests",
          "labelColor": "#1c1917",
          "labelFontSize": 52,
          "labelFontWeight": "bold",
          "opacity": 0
        },
        {
          "id": "progress",
          "kind": "progress",
          "x": -440,
          "y": 620,
          "w": 880,
          "h": 28,
          "value": 0,
          "fill": "#e7e5e4",
          "stroke": "none",
          "progressColor": "#f59e0b"
        }
      ],
      "edges": [],
      "actions": [
        {
          "type": "visibility",
          "target": {
            "kind": "node",
            "id": "headline"
          },
          "mode": "slideInUp",
          "durationMs": 600
        }
      ]
    },
    {
      "id": "habit_0_in",
      "delta": true,
      "durationMs": 1800,
      "caption": "One: ship small changes.",
      "nodes": [
        {
          "id": "habit_0",
          "opacity": 1
        },
        {
          "id": "progress",
          "value": 0.333
        }
      ],
      "edges": [],
      "actions": [
        {
          "type": "visibility",
          "target": {
            "kind": "node",
            "id": "habit_0"
          },
          "mode": "slideInLeft",
          "durationMs": 500,
          "ease": "back"
        }
      ]
    },
    {
      "id": "habit_1_in",
      "delta": true,
      "durationMs": 1800,
      "caption": "Two: review them the same day.",
      "nodes": [
        {
          "id": "habit_1",
          "opacity": 1
        },
        {
          "id": "progress",
          "value": 0.667
        }
      ],
      "edges": [],
      "actions": [
        {
          "type": "visibility",
          "target": {
            "kind": "node",
            "id": "habit_1"
          },
          "mode": "slideInLeft",
          "durationMs": 500,
          "ease": "back"
        }
      ]
    },
    {
      "id": "habit_2_in",
      "delta": true,
      "durationMs": 1800,
      "caption": "Three: let tests catch the mistakes.",
      "nodes": [
        {
          "id": "habit_2",
          "opacity": 1
        },
        {
          "id": "progress",
          "value": 1.0
        }
      ],
      "edges": [],
      "actions": [
        {
          "type": "visibility",
          "target": {
            "kind": "node",
            "id": "habit_2"
          },
          "mode": "slideInLeft",
          "durationMs": 500,
          "ease": "back"
        }
      ]
    }
  ]
}

Make your own from a backup

The fastest way to learn the format is to look at a real project. Open any project in the editor, choose More > Download data (backup), and open the file in a text editor. A backup carries extra fields the app fills in, such as recorded audio. The rules for AI agents list which ones to leave out when you write a file from scratch.


All Rights Reserved.