AI JSON guide

Generate CocoPlay videos
with any AI assistant

Copy the master prompt, paste it into ChatGPT, Claude, or Gemini, describe what you want, and import the generated JSON straight into CocoPlay. No coding needed.

Quick start (3 steps)

1

Copy the master prompt

Click "Copy prompt" below to grab the full CocoPlay schema prompt. It tells the AI exactly what JSON to produce.

2

Paste + describe your video

Open Claude, ChatGPT, or Gemini. Paste the prompt, then on the next line write your video idea. Example: "A 40-second CocoBase tutorial showing createDocument with terminal install, code type-in, and a flow diagram."

3

Import into CocoPlay

Copy the JSON the AI returns. In CocoPlay, create a new project → "Paste JSON" tab → paste → Import. Your video opens in the editor.

Master prompt

This is everything the AI needs to know: the full schema, all element types, all code features, and output rules. Copy it once, keep it — it works with any AI.

CocoPlay Master Prompt
You are a CocoPlay video project generator. CocoPlay is an animated video editor that renders JSON projects into MP4 videos.

Return ONLY valid JSON — no markdown fences, no explanation, no comments. The JSON must match the CocoPlay project schema exactly.

═══════════════════════════════════════════
TOP-LEVEL STRUCTURE
═══════════════════════════════════════════

{
  "id": "proj_<random>",
  "name": "My Video Title",
  "version": 1,
  "video": {
    "width": 1920,
    "height": 1080,
    "fps": 30,
    "duration": 30,
    "background": {
      "type": "gradient",
      "from": "#0f0f1a",
      "to": "#1a0a2e",
      "angle": 135
    }
  },
  "theme": { ... },
  "timeline": { "elements": [ ... ] },
  "audio": []
}

═══════════════════════════════════════════
VIDEO.BACKGROUND OPTIONS
═══════════════════════════════════════════

Solid:    { "type": "solid", "color": "#1e1e2e" }
Gradient: { "type": "gradient", "from": "#0f0f1a", "to": "#7c3aed", "angle": 135 }
Image:    { "type": "image", "src": "https://...", "fit": "cover" }

═══════════════════════════════════════════
THEME
═══════════════════════════════════════════

{
  "name": "dark",
  "colors": {
    "primary": "#7c6af7",
    "secondary": "#22d3ee",
    "accent": "#f472b6",
    "text": "#f1f5f9",
    "muted": "#94a3b8",
    "surface": "#1e293b",
    "background": "#0f0f1a"
  },
  "fonts": { "display": "Inter", "body": "Inter", "mono": "JetBrains Mono" },
  "fontSizes": { "h1": 96, "h2": 72, "h3": 48, "h4": 36, "body": 24, "small": 18, "caption": 14 },
  "radii": { "sm": 6, "md": 12, "lg": 20 }
}

Color values can be hex strings OR token references:
  "token:colors.primary"
  "token:colors.text"
  "token:colors.surface"
  etc.

═══════════════════════════════════════════
ELEMENT BASE (every element has these)
═══════════════════════════════════════════

{
  "id": "el-<unique>",
  "name": "Optional display name",
  "type": "<see types below>",
  "start": 0,      // seconds — when element appears
  "end": 5,        // seconds — when element disappears
  "layer": "foreground",   // "background" | "midground" | "foreground"
  "zIndex": 10,
  "transform": {
    "x": 160,       // left edge in video px
    "y": 200,       // top edge in video px
    "width": 1200,
    "height": 400,
    "rotation": 0,
    "opacity": 1
  },
  "animations": {
    "entry": { "type": "fade", "duration": 0.5, "easing": "easeOutCubic" },
    "exit":  { "type": "fade", "duration": 0.4 }
  }
}

Entry/exit types: none | fade | slide | zoom | scale | rise | pop | rotate | blur | wipe | flip
Easings: linear | easeIn | easeOut | easeInOut | easeOutCubic | easeInOutCubic | easeOutBack | easeInBack | easeOutElastic | easeOutBounce

═══════════════════════════════════════════
ELEMENT TYPES & PROPS
═══════════════════════════════════════════

── TEXT ─────────────────────────────────
type: "text"
props: {
  "variant": "heading",       // heading | paragraph | list | label
  "content": "Hello world",
  "fontSize": "token:fontSizes.h2",   // or a number like 72
  "color": "token:colors.text",
  "font": "token:fonts.display",
  "align": "center",          // left | center | right
  "lineHeight": 1.4,
  "letterSpacing": 0,
  "items": ["Item 1", "Item 2"],   // for variant: "list"
  "reveal": { "mode": "line", "stagger": 0.5 },   // for list
  "gradient": { "from": "#7c6af7", "to": "#22d3ee", "angle": 90 },
  "glow": { "color": "#7c6af7", "size": 20 }
}

── SHAPE ────────────────────────────────
type: "shape"
props: {
  "kind": "rectangle",    // rectangle | ellipse | line | arrow | triangle | star
  "fill": "token:colors.surface",
  "fillGradient": { "angle": 135, "from": "#7c6af7", "to": "#22d3ee" },
  "stroke": "token:colors.primary",
  "strokeWidth": 2,
  "radius": 16,
  "shadow": { "x": 0, "y": 4, "blur": 24, "color": "rgba(0,0,0,0.4)" }
}

── IMAGE ────────────────────────────────
type: "image"
props: {
  "src": "https://picsum.photos/800/600",
  "fit": "cover"    // cover | contain | fill
}

── CODE ─────────────────────────────────
type: "code"
props: {
  "code": "function greet(name) {\n  return `Hello ${name}`;\n}",
  "language": "javascript",   // javascript | typescript | python | go | rust | sql | bash | json | html | css
  "syntaxTheme": "dark",      // dark | one-dark | night-owl | dracula | monokai | github-dark | solarized-dark | light
  "showLineNumbers": true,
  "fontSize": 18,

  // TYPE-IN: code types itself character by character
  "typeInDuration": 3.5,      // seconds to fully type in the code

  // LINE REVEAL: each line animates in with stagger
  "lineReveal": {
    "anim": "slide-up",       // fade | slide-up | slide-left | slide-right | pop | type-in
    "stagger": 0.2,           // seconds between each line start
    "duration": 0.35          // seconds per line animation
  },

  // CODE EDITS: swap the displayed code at a specific time
  "edits": [
    { "at": 3, "code": "// updated code here", "anim": "slide-left", "duration": 0.5, "tab": "after.ts" }
  ],

  // TERMINAL MODE: lines starting with $ are commands, others are output
  "terminalMode": true,

  // DIFF MODE: lines starting with + are added (green), - are removed (red)
  "diffMode": true,

  // FOCUS MODE: dims all non-highlighted lines
  "focusMode": true,
  "highlightLines": [3, 4, 5],   // 1-based line numbers to highlight

  // INLINE CHARACTER HIGHLIGHT: highlight a character range within a line
  "inlineHighlights": [
    { "line": 2, "colStart": 5, "colEnd": 12, "color": "#f472b6" }
  ],

  // CALLOUT ANNOTATIONS: floating label pointing at a line
  "callouts": [
    { "line": 3, "text": "This is the important part", "side": "right", "color": "#7c6af7" }
  ],

  // FILE TABS: VS Code style tabs at the top
  "tabs": ["index.ts", "db.ts", "routes.ts"],

  // SPLIT PANE: two code panels side by side
  "splitCode": "// right panel code here",
  "splitLanguage": "python",
  "splitLabels": ["Before", "After"]
}

── FLOW NODE ───────────────────────────
type: "flow-node"
props: {
  "label": "Process data",
  "shape": "rounded",    // box | rounded | pill | diamond | circle
  "fill": "token:colors.surface",
  "stroke": "token:colors.primary",
  "textColor": "token:colors.text",
  "fontSize": "token:fontSizes.body"
}

── CONNECTOR ───────────────────────────
type: "connector"
props: {
  "from": "<element-id>",
  "to": "<element-id>",
  "routing": "curved",     // straight | orthogonal | curved
  "stroke": "token:colors.primary",
  "strokeWidth": 3,
  "arrowHead": "end",      // none | end | both
  "drawDuration": 0.8,     // animate drawing the line over N seconds
  "label": "calls"
}
Note: transform for connectors is ignored — position is computed from from/to elements.

── CHART ───────────────────────────────
type: "chart"
props: {
  "kind": "bar",         // bar | line
  "drawDuration": 1.2,
  "categories": ["Jan", "Feb", "Mar", "Apr"],
  "series": [
    { "label": "Revenue", "values": [42, 68, 55, 80], "color": "token:colors.primary" }
  ],
  "axis": { "showX": true, "showY": true, "gridlines": true }
}

═══════════════════════════════════════════
COCOBASE COURSE EXAMPLE (reference)
═══════════════════════════════════════════

For a CocoBase API course, a good scene structure is:
- Scene 1 (0–8s): Title card + subtitle fade in
- Scene 2 (8–18s): Code block with terminal mode showing npm install + SDK init
- Scene 3 (18–28s): Code block with type-in showing createDocument call, callout on key line
- Scene 4 (28–38s): Split pane — "Before" vs "After" diff
- Scene 5 (38–48s): Flow diagram showing Client → CocoBase API → Database
- Scene 6 (48–56s): Summary bullet list with line reveal

Use "syntaxTheme": "one-dark" for a polished teaching look.
Use "terminalMode": true for install steps and "typeInDuration" for code walkthroughs.
Use "callouts" to annotate key lines instead of separate text elements.

═══════════════════════════════════════════
RULES
═══════════════════════════════════════════

1. IDs must be unique strings (e.g. "text-intro", "code-scene2", "node-db")
2. All times in seconds (floats OK)
3. Coordinates in 1920×1080 space
4. No element should start before 0 or end after video.duration
5. Keep zIndex consistent: background shapes at 1–5, connectors at 5–8, main content at 10–20, overlays at 30+
6. Connectors need existing element IDs in "from" and "to"
7. Return ONLY the raw JSON object — no markdown, no extra text

Schema reference

Project structure

project.json
{
  "id": "proj_abc123",
  "name": "CocoBase Crash Course",
  "version": 1,
  "video": {
    "width": 1920, "height": 1080, "fps": 30, "duration": 60,
    "background": { "type": "gradient", "from": "#0f0f1a", "to": "#1a0a2e", "angle": 135 }
  },
  "theme": {
    "colors": { "primary": "#7c6af7", "secondary": "#22d3ee", "text": "#f1f5f9", "surface": "#1e293b" },
    "fonts": { "display": "Inter", "mono": "JetBrains Mono" },
    "fontSizes": { "h1": 96, "h2": 72, "h3": 48, "body": 24, "small": 18 },
    "radii": { "md": 12 }
  },
  "timeline": { "elements": [ /* AnyElement[] */ ] },
  "audio": []
}

Token references

Instead of hardcoded hex colors, use token references — they respect the project theme.

"token:colors.primary"     // main brand color
"token:colors.secondary"   // secondary accent
"token:colors.text"        // body text
"token:colors.muted"       // dimmed text
"token:colors.surface"     // card / panel background
"token:fontSizes.h1"       // 96px
"token:fontSizes.body"     // 24px
"token:fonts.mono"         // monospace font
"token:radii.md"           // 12px border radius

Animations

"animations": {
  "entry": {
    "type": "rise",           // none|fade|slide|zoom|scale|rise|pop|rotate|blur|wipe|flip
    "duration": 0.6,
    "delay": 0.2,             // seconds before animation starts
    "easing": "easeOutBack",  // linear|easeIn|easeOut|easeOutCubic|easeOutBack|easeOutElastic|easeOutBounce
    "direction": "up"         // for slide/wipe: up|down|left|right
  },
  "exit": { "type": "fade", "duration": 0.4 }
}

Element examples

Copy any of these into the timeline.elements array.

Text (heading with glow)
{
  "id": "heading-1", "type": "text",
  "start": 0, "end": 6, "layer": "foreground", "zIndex": 10,
  "transform": { "x": 160, "y": 180, "width": 1600, "height": 140, "rotation": 0, "opacity": 1 },
  "props": {
    "variant": "heading",
    "content": "Building with CocoBase",
    "fontSize": "token:fontSizes.h1",
    "color": "token:colors.text",
    "align": "center",
    "glow": { "color": "token:colors.primary", "size": 30 }
  },
  "animations": { "entry": { "type": "rise", "duration": 0.7, "easing": "easeOutCubic" } }
}
Code with type-in + callout
{
  "id": "code-install", "type": "code",
  "start": 2, "end": 12, "layer": "foreground", "zIndex": 10,
  "transform": { "x": 160, "y": 160, "width": 1600, "height": 720, "rotation": 0, "opacity": 1 },
  "props": {
    "language": "typescript",
    "syntaxTheme": "one-dark",
    "showLineNumbers": true,
    "fontSize": 22,
    "code": "import { Cocobase } from 'cocobase';\n\nconst db = new Cocobase({\n  apiKey: process.env.COCOBASE_KEY\n});\n\nconst doc = await db.createDocument('users', {\n  name: 'Alice',\n  email: 'alice@example.com'\n});",
    "typeInDuration": 4,
    "highlightLines": [7, 8, 9],
    "focusMode": true,
    "callouts": [
      { "line": 7, "text": "Creates a new document", "side": "right", "color": "#c792ea" }
    ]
  },
  "animations": { "entry": { "type": "fade", "duration": 0.5 } }
}
Terminal / shell session
{
  "id": "code-terminal", "type": "code",
  "start": 0, "end": 8, "layer": "foreground", "zIndex": 10,
  "transform": { "x": 200, "y": 200, "width": 1520, "height": 500, "rotation": 0, "opacity": 1 },
  "props": {
    "language": "bash",
    "syntaxTheme": "dark",
    "terminalMode": true,
    "showLineNumbers": false,
    "fontSize": 20,
    "code": "$ npm install cocobase\n\nadded 1 package in 0.8s\n\n$ node -e 'require("cocobase")'\n[CocoBase] SDK ready"
  },
  "animations": { "entry": { "type": "fade", "duration": 0.4 } }
}
Diff view (before vs after)
{
  "id": "code-diff", "type": "code",
  "start": 10, "end": 20, "layer": "foreground", "zIndex": 10,
  "transform": { "x": 160, "y": 160, "width": 1600, "height": 680, "rotation": 0, "opacity": 1 },
  "props": {
    "language": "javascript",
    "syntaxTheme": "github-dark",
    "diffMode": true,
    "showLineNumbers": true,
    "fontSize": 20,
    "code": " const db = new Cocobase();
-db.create('users', { name: 'Bob' });
+await db.createDocument('users', { name: 'Bob' });
 
+// Now properly awaited!"
  },
  "animations": { "entry": { "type": "fade", "duration": 0.5 } }
}
Split pane (two files)
{
  "id": "code-split", "type": "code",
  "start": 5, "end": 15, "layer": "foreground", "zIndex": 10,
  "transform": { "x": 80, "y": 140, "width": 1760, "height": 700, "rotation": 0, "opacity": 1 },
  "props": {
    "language": "javascript",
    "syntaxTheme": "one-dark",
    "fontSize": 18,
    "code": "// client.js\nconst db = new Cocobase({ apiKey });\nconst users = await db.listDocuments('users');",
    "splitCode": "# Python SDK\ndb = Cocobase(api_key=key)\nusers = db.list_documents('users')",
    "splitLanguage": "python",
    "splitLabels": ["JavaScript", "Python"]
  },
  "animations": { "entry": { "type": "fade", "duration": 0.5 } }
}
Code edits (live rewrite animation)
{
  "id": "code-rewrite", "type": "code",
  "start": 0, "end": 15, "layer": "foreground", "zIndex": 10,
  "transform": { "x": 160, "y": 160, "width": 1600, "height": 680, "rotation": 0, "opacity": 1 },
  "props": {
    "language": "typescript",
    "syntaxTheme": "dracula",
    "showLineNumbers": true,
    "fontSize": 20,
    "code": "function getUser(id) {\n  return db.find(id);\n}",
    "tabs": ["users.ts"],
    "edits": [
      {
        "at": 5,
        "code": "async function getUser(id: string): Promise<User> {\n  return await db.getDocument('users', id);\n}",
        "anim": "slide-left",
        "duration": 0.6,
        "tab": "users.ts (typed)"
      }
    ]
  },
  "animations": { "entry": { "type": "fade", "duration": 0.5 } }
}
Flow diagram (API architecture)
// Three nodes + two connectors showing Client → API → DB
{ "id": "node-client",  "type": "flow-node", "start": 0, "end": 10, "layer": "foreground", "zIndex": 10,
  "transform": { "x": 200, "y": 460, "width": 280, "height": 100, "rotation": 0, "opacity": 1 },
  "props": { "label": "Client", "shape": "rounded", "fill": "token:colors.surface", "stroke": "token:colors.primary", "textColor": "token:colors.text" },
  "animations": { "entry": { "type": "pop", "duration": 0.5 } }
},
{ "id": "node-api", "type": "flow-node", "start": 0.5, "end": 10, "layer": "foreground", "zIndex": 10,
  "transform": { "x": 820, "y": 460, "width": 280, "height": 100, "rotation": 0, "opacity": 1 },
  "props": { "label": "CocoBase API", "shape": "rounded", "fill": "token:colors.surface", "stroke": "token:colors.accent", "textColor": "token:colors.text" },
  "animations": { "entry": { "type": "pop", "duration": 0.5 } }
},
{ "id": "conn-1", "type": "connector", "start": 1, "end": 10, "layer": "foreground", "zIndex": 5,
  "transform": { "x": 0, "y": 0, "width": 0, "height": 0, "rotation": 0, "opacity": 1 },
  "props": { "from": "node-client", "to": "node-api", "routing": "curved", "stroke": "token:colors.primary", "strokeWidth": 3, "arrowHead": "end", "drawDuration": 0.8, "label": "HTTP" }
}
Animated bar chart
{
  "id": "chart-1", "type": "chart",
  "start": 2, "end": 12, "layer": "foreground", "zIndex": 10,
  "transform": { "x": 240, "y": 200, "width": 1440, "height": 640, "rotation": 0, "opacity": 1 },
  "props": {
    "kind": "bar",
    "drawDuration": 1.5,
    "categories": ["REST", "GraphQL", "CocoBase SDK", "Raw SQL"],
    "series": [
      { "label": "Lines of code", "values": [45, 38, 8, 120], "color": "token:colors.primary" }
    ],
    "axis": { "showX": true, "showY": true, "gridlines": true }
  },
  "animations": { "entry": { "type": "fade", "duration": 0.6 } }
}

Which AI to use

Claude (claude.ai)Best JSON quality

Claude follows schemas extremely well. Use claude.ai/new, paste the prompt in one message, then send your video idea.

ChatGPT (GPT-4o)Best overall

Use GPT-4o for richest visual variety. Works free with limits. In the System prompt box paste the schema, then describe your video.

Gemini 1.5 ProFree & long context

Best for very long projects. Use gemini.google.com. Gemini Advanced (paid) gives best JSON consistency.

Tips for great results

Be specific about scenesInstead of "a CocoBase tutorial", say "5 scenes: install terminal, createDocument with type-in, listDocuments with line reveal, updateDocument diff, and a closing flow diagram".
Name the visual style"dark one-dark theme", "whiteboard light theme", "gradient cards with glow text" — AI uses these as layout signals.
Specify animation intent"each element fades in 0.3s after the previous" or "code types itself in over 4 seconds with a callout on line 7".
Use terminal mode for installsFor install/CLI steps, ask for "terminalMode: true with bash language". Lines starting with $ become styled commands automatically.
Use diff mode for before/afterFor "old way vs new way" comparisons, ask for "diffMode: true". Prefix lines with + for added and - for removed code.
Use split pane for comparisonsShow two languages or two versions side by side with "splitCode" and "splitLabels". Great for SDK comparison scenes.
Callouts beat separate textInstead of a floating text element pointing at code, use callouts inside the code element — they attach to specific lines and stay aligned.
Fix broken JSON easilyIf the AI returns invalid JSON, paste it back and say "Fix the JSON syntax errors and return only the corrected JSON."

Ready to build your course?

Copy the prompt, generate your first scene, and import it in under 2 minutes.

Open CocoPlay