Skip to content
Jump to
Agent tools · MCP

DemoTake MCP tools

DemoTake runs a Model Context Protocol server on your Mac. Your agent calls these 130 tools to plan a take, record it scene by scene, verify it, edit it and export it. Every stateful call takes explicit handles (take_…, scn_…, exp_…), and results come back as structured JSON with a one-line summary.

New to it? Read Connect your agent, give your agent the DemoTake skill, or call demotake_guide once for the whole workflow.

DemoTake Agent only (DemoTake Studio doesn't list these)
Connect · Claude Code
claude mcp add demotake -- /Applications/DemoTake.app/Contents/MacOS/demotake-mcp
Typical sequence

take_create → capture_start → take_start_scene → pointer_click → assert_text → take_checkpoint → capture_stop → edit_suggest_cuts → edit_apply → export_render

TOOLREAD-ONLYTargets and permissions

targets_list

List capture targets

List apps, windows, booted iOS Simulator devices and Android emulators/devices DemoTake can record. Use the returned target_id in take_create / capture tools. Windows are listed front-to-back; pick the app you just built. Simulator devices (kind "simulator", target_id "sim:<UDID>") and Android emulators or USB devices (kind "android", target_id "android:<serial>", with model, Android version and API level, screen in dp and pixels; found through adb) are recorded from the device screen itself (DemoTake Agent). Browser windows (Chrome, Edge, Brave, Arc, Safari) carry url and tabs: tabs:"active" (default in DemoTake Agent) reads each window's active tab with Accessibility; tabs:"all" lists every tab's title and URL through Apple Events (DemoTake Agent; macOS asks once per browser for Automation permission). Each window gets its own tabs, matched by title and frame; when two windows can't be told apart, tabs is null and tabs_note says why (never another window's tabs). Windows on another Space or minimized are listed with on_screen:false and a note; they can't be recorded until they're on this Space. DemoTake Studio can't use either: tabs:"active" reads each browser window's address bar with on-screen text recognition (slower; the address bar must be visible), otherwise only window titles are listed. To record a tab, pass take_create {target:{url_contains:"example.com"}}; browser_tab selects or isolates it first.

Plain words: Lists the apps, windows, booted iOS Simulator devices and connected Android emulators or phones DemoTake can record right now. Call it first and copy the target_id of the app you want to demo.

Parameters

include_displaysbooleanOPTIONAL
Also list whole displays.Default false.
appstringOPTIONAL
Only targets whose app name or bundle id contains this text.
tabsenumOPTIONAL
Browser tabs to read: none, active (each window's active tab), all (every tab; DemoTake Agent).One of none, active, all.

Good to know

An empty list usually means Screen Recording permission is missing; check permissions_status.

Request · what your agent sends
{
  "name": "targets_list",
  "arguments": {}
}
Response · structuredContent
3 target(s).
{
  "targets": [
    {
      "target_id": "window:4127",
      "kind": "window",
      "name": "Ledgerly — Invoices",
      "app_name": "Ledgerly",
      "bundle_id": "com.example.Ledgerly",
      "window_title": "Invoices",
      "window_id": 4127,
      "pid": 51234,
      "frame": {
        "x": 120,
        "y": 84,
        "width": 1280,
        "height": 800
      },
      "on_screen": true
    },
    {
      "target_id": "sim:6C1F0B7E-3A2D-4F4B-9C1E-2B7D5A8E9F10",
      "kind": "simulator",
      "name": "iPhone 17 Pro (iOS 26.0)",
      "app_name": "iPhone 17 Pro",
      "device_udid": "6C1F0B7E-3A2D-4F4B-9C1E-2B7D5A8E9F10",
      "runtime": "iOS 26.0",
      "screen": {
        "width": 402,
        "height": 874,
        "scale": 3
      },
      "on_screen": true
    },
    {
      "target_id": "android:emulator-5554",
      "kind": "android",
      "name": "Pixel 9 (Android 16 (API 36))",
      "app_name": "Pixel 9",
      "serial": "emulator-5554",
      "runtime": "Android 16 (API 36)",
      "screen": {
        "width": 411.4,
        "height": 914.3,
        "scale": 2.625,
        "unit": "dp",
        "pixels": {
          "width": 1080,
          "height": 2400
        }
      },
      "on_screen": true
    }
  ]
}
DEMOTAKE AGENT ONLYTargets and permissions

browser_tab

Select or isolate a browser tab

Make the tab showing a URL recordable before take_create / capture_start (DemoTake Agent; controls the browser with Apple Events, which macOS asks you to allow once per browser; no Accessibility needed). Finds the tab in any window of Chrome, Edge, Brave, Vivaldi, Arc or Safari, on any Space or profile. action "select": make it the active tab of its window (and bring that window to the front of the browser's windows); a window on another Space can't be selected into view, use isolate. action "isolate": open the tab's page in a new window sized and placed like the original, on this Space, and record that: other tabs and agents can't switch it away, and the person's own windows and tabs stay as they were. Isolate is non-destructive: the original tab is left in place (a page that needs unsaved form input or its back history should be selected instead); close_original:true closes it after the new window opens. Sign-ins carry over (cookies). With several Chrome profiles DemoTake checks that the new window is in the tab's profile; if not, it closes that window, tries once more with the browser in front, and otherwise fails with a message (use select then). Nothing happens when the tab is already active (select) or known to be alone in its window (isolate); when DemoTake can't read that window's tab list, isolate opens the new window rather than assume. Every process of a browser is asked separately (a second Chrome started with its own profile folder too), and changes go to the process that shows the tab; a process Apple Events can't reach is named in the error. Returns target_id of the window to record: pass it, or the same url_contains, to take_create. Arc can only select. Firefox isn't scriptable. DemoTake Studio doesn't control other apps.

Plain words: Gets a browser tab ready to record when it isn't the tab in front: makes it the active tab of its window, or opens its page in a new window of its own so other tabs can't take its place. Your own tabs stay where they are.

Parameters

url_containsstringREQUIRED
The tab whose URL contains this, e.g. "avendo.io".
actionenumREQUIRED
select: make it the active tab of its window; isolate: open it in its own new window.One of select, isolate.
appstringOPTIONAL
Only this browser (name or bundle id contains this), e.g. "Chrome".
close_originalbooleanOPTIONAL
isolate: close the original tab once the new window is open (loses that tab's history and unsaved input).Default false.

Good to know

DemoTake Agent only. macOS asks once whether DemoTake may control the browser. action "select" switches the window to the tab instead; close_original: true closes the original tab after isolating.

Request · what your agent sends
{
  "name": "browser_tab",
  "arguments": {
    "url_contains": "ledgerly.app",
    "action": "isolate"
  }
}
Response · structuredContent
Opened the page in its own window window:4188. Record that window.
{
  "outcome": "isolated",
  "target_id": "window:4188",
  "target": {
    "target_id": "window:4188",
    "kind": "window",
    "name": "Google Chrome — Invoices · Ledgerly",
    "app_name": "Google Chrome",
    "bundle_id": "com.google.Chrome",
    "window_title": "Invoices · Ledgerly",
    "window_id": 4188,
    "pid": 51877,
    "frame": {
      "x": 0,
      "y": 34,
      "width": 1440,
      "height": 866
    },
    "on_screen": true
  },
  "tab": {
    "title": "Invoices · Ledgerly",
    "url": "https://ledgerly.app/invoices"
  },
  "notes": [
    "The page opened in a new Google Chrome window; the original tab is still where it was."
  ],
  "next": "take_create {target:\"window:4188\", browser:{mode:\"page\"}} (or capture_start on an existing take with target \"window:4188\")."
}
Next call
TOOLREAD-ONLYTargets and permissions

targets_inspect

Inspect a target

Details for one target: app version/build, its windows, and what DemoTake can do with it (execution mode).

Plain words: Shows everything DemoTake knows about one app or window: its version and build, its other windows, and how DemoTake can work with it.

Parameters

targetstring | objectREQUIRED
Target app/window/device. Either a target_id from targets_list ("window:1234", "app:com.example.App", "pid:4321", "display:1", "sim:<UDID>" for a booted iOS Simulator device, "android:<serial>" for an Android emulator or device, a URL) or an object; {url_contains:"example.com"} picks the browser window whose tab shows that URL (and keeps following that window across navigations). target_id is accepted as an alias. Defaults to the take's target.
12 fields
target_idstringOPTIONAL
id from targets_list
bundle_idstringOPTIONAL
app_namestringOPTIONAL
window_titlestringOPTIONAL
window_idintegerOPTIONAL
pidintegerOPTIONAL
display_idintegerOPTIONAL
urlstringOPTIONAL
url_containsstringOPTIONAL
Browser window whose tab URL contains this text, e.g. a domain
device_udidstringOPTIONAL
iOS Simulator device UDID
serialstringOPTIONAL
Android adb serial (emulator-5554, a USB serial)
kindenumOPTIONAL
One of window, application, display, web, simulator, android.
target_idstring | objectOPTIONAL
Alias of target.
12 fields
target_idstringOPTIONAL
id from targets_list
bundle_idstringOPTIONAL
app_namestringOPTIONAL
window_titlestringOPTIONAL
window_idintegerOPTIONAL
pidintegerOPTIONAL
display_idintegerOPTIONAL
urlstringOPTIONAL
url_containsstringOPTIONAL
Browser window whose tab URL contains this text, e.g. a domain
device_udidstringOPTIONAL
iOS Simulator device UDID
serialstringOPTIONAL
Android adb serial (emulator-5554, a USB serial)
kindenumOPTIONAL
One of window, application, display, web, simulator, android.
Request · what your agent sends
{
  "name": "targets_inspect",
  "arguments": {
    "target": "window:4127"
  }
}
Response · structuredContent
{
  "target": {
    "target_id": "window:4127",
    "kind": "window",
    "name": "Ledgerly — Invoices",
    "app_name": "Ledgerly",
    "bundle_id": "com.example.Ledgerly",
    "window_title": "Invoices",
    "window_id": 4127,
    "pid": 51234,
    "frame": {
      "x": 120,
      "y": 84,
      "width": 1280,
      "height": 800
    },
    "on_screen": true
  },
  "capabilities": {
    "mode": "background_semantic",
    "mode_explanation": "Understands and operates the app in the background.",
    "edition": "agent",
    "can_capture": true,
    "can_observe_accessibility": true,
    "can_perform_semantic_actions": true,
    "can_synthesize_input": true,
    "is_minimized": false,
    "is_on_screen": true,
    "notes": [
      "Accessibility tree available (212+ elements, 31 actionable). Clicks and typing run in the background; your mouse stays yours."
    ]
  },
  "app_version": "2.3.1",
  "build_number": "418",
  "windows": [
    {
      "target_id": "window:4127",
      "kind": "window",
      "name": "Ledgerly — Invoices",
      "app_name": "Ledgerly",
      "bundle_id": "com.example.Ledgerly",
      "window_title": "Invoices",
      "window_id": 4127,
      "pid": 51234,
      "frame": {
        "x": 120,
        "y": 84,
        "width": 1280,
        "height": 800
      },
      "on_screen": true
    }
  ]
}
Next call
TOOLREAD-ONLYTargets and permissions

targets_capabilities

Target capabilities

How a take of this target will run: background_semantic (DemoTake operates the app via Accessibility without touching your mouse), background_capture_only (you/your agent operate it, DemoTake records), or foreground_required. Also what this Mac can record beside the screen: presenter_camera (camera access and the cameras, with ids for capture_start {camera_device}), and android (DemoTake Agent: whether adb was found and which Android emulators and devices are connected). Without target, only those.

Plain words: Tells you how a recording of this app will run: whether DemoTake can operate it quietly in the background, only record it while you or your agent operate it, or needs to take over the mouse.

Parameters

targetstring | objectOPTIONAL
Target app/window/device. Either a target_id from targets_list ("window:1234", "app:com.example.App", "pid:4321", "display:1", "sim:<UDID>" for a booted iOS Simulator device, "android:<serial>" for an Android emulator or device, a URL) or an object; {url_contains:"example.com"} picks the browser window whose tab shows that URL (and keeps following that window across navigations). target_id is accepted as an alias. Defaults to the take's target.
12 fields
target_idstringOPTIONAL
id from targets_list
bundle_idstringOPTIONAL
app_namestringOPTIONAL
window_titlestringOPTIONAL
window_idintegerOPTIONAL
pidintegerOPTIONAL
display_idintegerOPTIONAL
urlstringOPTIONAL
url_containsstringOPTIONAL
Browser window whose tab URL contains this text, e.g. a domain
device_udidstringOPTIONAL
iOS Simulator device UDID
serialstringOPTIONAL
Android adb serial (emulator-5554, a USB serial)
kindenumOPTIONAL
One of window, application, display, web, simulator, android.
target_idstring | objectOPTIONAL
Alias of target.
12 fields
target_idstringOPTIONAL
id from targets_list
bundle_idstringOPTIONAL
app_namestringOPTIONAL
window_titlestringOPTIONAL
window_idintegerOPTIONAL
pidintegerOPTIONAL
display_idintegerOPTIONAL
urlstringOPTIONAL
url_containsstringOPTIONAL
Browser window whose tab URL contains this text, e.g. a domain
device_udidstringOPTIONAL
iOS Simulator device UDID
serialstringOPTIONAL
Android adb serial (emulator-5554, a USB serial)
kindenumOPTIONAL
One of window, application, display, web, simulator, android.
Request · what your agent sends
{
  "name": "targets_capabilities",
  "arguments": {
    "target": "app:com.example.Ledgerly"
  }
}
Response · structuredContent
Semantic Background: Understands and operates the app in the background. 1 camera(s) for the presenter. 1 Android device(s).
{
  "mode": "background_semantic",
  "mode_explanation": "Understands and operates the app in the background.",
  "edition": "agent",
  "can_capture": true,
  "can_observe_accessibility": true,
  "can_perform_semantic_actions": true,
  "can_synthesize_input": true,
  "is_minimized": false,
  "is_on_screen": true,
  "notes": [
    "Accessibility tree available (212+ elements, 31 actionable). Clicks and typing run in the background; your mouse stays yours."
  ],
  "presenter_camera": {
    "authorization": "granted",
    "cameras": [
      {
        "id": "0x1420000005ac8600",
        "name": "FaceTime HD Camera",
        "default": true
      }
    ],
    "notes": "capture_start {camera:true} records the presenter camera beside the screen (one file per scene); presenter_set styles it; presenter_import adds a video recorded elsewhere."
  },
  "android": {
    "adb": "/Users/sam/Library/Android/sdk/platform-tools/adb",
    "available": true,
    "devices": [
      "Pixel 9 (Android 16 (API 36))"
    ],
    "notes": "Android targets are listed by targets_list as android:<serial>; DemoTake records the device screen and acts with adb input."
  }
}
TOOLREAD-ONLYTargets and permissions

permissions_status

Permission status

macOS permissions DemoTake needs (Screen Recording, Accessibility, Microphone), the edition/version running, and its licence (licence: the same as licence_status).

Plain words: Checks which macOS permissions DemoTake has (Screen Recording, Accessibility, Microphone, Camera), which edition and version is running, and its licence. Call it when recording or UI control fails.

Parameters

None.

Request · what your agent sends
{
  "name": "permissions_status",
  "arguments": {}
}
Response · structuredContent
All required permissions granted.
{
  "screen_recording": "granted",
  "accessibility": "granted",
  "microphone": "not_determined",
  "camera": "not_determined",
  "edition": "agent",
  "version": "1.2.0",
  "ui_control_available": true,
  "licence": {
    "edition": "agent",
    "version": "1.2.0",
    "state": "licensed",
    "plan": "Local",
    "source": "License key",
    "updates_until": "2027-10-26",
    "recording_blocked": false,
    "export_blocked": false,
    "watermarked_exports": false
  }
}
TOOLREAD-ONLYTargets and permissions

licence_status

Licence status

Whether DemoTake can record and export right now, and why not: edition and version, licence state (licensed, trial, trial_ended, trial_not_started), plan and what unlocks it (license key, cloud plan, App Store), trial days left (trial exports are watermarked), the updates window (newest builds the licence covers), and recording_blocked / export_blocked with the reason and what the person can do. Check it before a long recording. Also reachable as license_status.

Plain words: Says whether DemoTake can record and export right now, and if not, why and what the person can do. It also shows the plan, trial days left and the updates window. Check it before a long recording.

Parameters

None.

Good to know

Also reachable as license_status; permissions_status returns the same object as licence.

Request · what your agent sends
{
  "name": "licence_status",
  "arguments": {}
}
Response · structuredContent
DemoTake Agent 1.2.0: trial, 2 day(s) left (exports are watermarked). Recording and exporting work.
{
  "edition": "agent",
  "version": "1.2.0",
  "state": "trial",
  "trial_days_left": 2,
  "recording_blocked": false,
  "export_blocked": false,
  "watermarked_exports": true,
  "signed_in": false
}
TOOLREAD-ONLYProjects and takes

project_list

List projects

Projects in the DemoTake library.

Plain words: Lists the projects in your DemoTake library. A project is a folder of takes, usually one per product.

Parameters

None.

Request · what your agent sends
{
  "name": "project_list",
  "arguments": {}
}
Response · structuredContent
{
  "projects": [
    {
      "project_id": "prj_m119ecc0t4w8nq2h",
      "name": "Ledgerly",
      "summary": "Invoicing for freelancers",
      "updated_at": "2026-09-26T10:14:03Z"
    },
    {
      "project_id": "prj_m0zt3hq0f6kn2bwd",
      "name": "My Demos",
      "updated_at": "2026-09-12T16:31:47Z"
    }
  ]
}
TOOLProjects and takes

project_create

Create project

Create a project (a folder of takes, usually one per product). take_create can also create one implicitly via project_name.

Plain words: Creates a new project to keep a product's takes together. Optional: take_create can also create one for you when you pass project_name.

Parameters

namestringREQUIRED
Project name, e.g. the product name.
summarystringOPTIONAL
One-line description.
Request · what your agent sends
{
  "name": "project_create",
  "arguments": {
    "name": "Ledgerly",
    "summary": "Invoicing for freelancers"
  }
}
Response · structuredContent
Created project prj_m119ecc0t4w8nq2h.
{
  "project_id": "prj_m119ecc0t4w8nq2h",
  "name": "Ledgerly",
  "summary": "Invoicing for freelancers",
  "updated_at": "2026-08-27T09:40:00Z"
}
Next call
TOOLREAD-ONLYProjects and takes

take_list

List takes

Takes in the library, newest first. Existing takes can be re-recorded after UI changes instead of starting over.

Plain words: Lists the takes in your library, newest first. Use it to find an existing take to re-record after a UI change instead of starting over.

Parameters

project_idstringOPTIONAL
Only takes in this project.
limitintegerOPTIONAL
Max results.Default 30. Min 1, max 200.
projectstringOPTIONAL
Alias of project_id.
Request · what your agent sends
{
  "name": "take_list",
  "arguments": {
    "project_id": "prj_m119ecc0t4w8nq2h",
    "limit": 10
  }
}
Response · structuredContent
{
  "takes": [
    {
      "take_id": "take_m3ehbyc0k7qv2x9d",
      "project_id": "prj_m119ecc0t4w8nq2h",
      "name": "Create invoice",
      "goal": "Create an invoice for a new customer and export it as PDF.",
      "purpose": "marketing",
      "status": "verified",
      "scenes": 3,
      "scenes_recorded": 3,
      "duration": 41.8,
      "assertions": "3/3 passed",
      "target": "Ledgerly — Invoices",
      "updated_at": "2026-09-26T10:14:03Z",
      "package_path": "/Users/you/Movies/DemoTake/Projects/ledgerly--prj_m119ecc0t4w8nq2h/Takes/create-invoice--take_m3ehbyc0k7qv2x9d.take"
    }
  ],
  "total": 1
}
TOOLREAD-ONLYProjects and takes

take_get

Get take

Full state of a take: scenes, assertions, edits, exports, recent trace events and the suggested next step.

Plain words: Returns the full state of one take: its scenes, assertions, edits, exports, the latest trace events and a suggested next step. Think of a take as the video project and each scene as one shot you can retake on its own.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
recent_eventsintegerOPTIONAL
How many trailing trace events to include.Default 15. Min 0, max 200.
takestringOPTIONAL
Alias of take_id.

Good to know

Follow the next string when unsure what to call; it tracks the take's status.

Request · what your agent sends
{
  "name": "take_get",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "recent_events": 2
  }
}
Response · structuredContent
{
  "take_id": "take_m3ehbyc0k7qv2x9d",
  "project_id": "prj_m119ecc0t4w8nq2h",
  "name": "Create invoice",
  "goal": "Create an invoice for a new customer and export it as PDF.",
  "purpose": "marketing",
  "status": "verified",
  "ai_mode": "byo_agent",
  "execution_mode": "background_semantic",
  "target": {
    "target_id": "window:4127",
    "kind": "window",
    "name": "Ledgerly — Invoices",
    "bundle_id": "com.example.Ledgerly",
    "app_name": "Ledgerly",
    "window_title": "Invoices",
    "window_id": 4127,
    "pid": 51234
  },
  "scenes": [
    {
      "scene_id": "scn_m3ehbzb8a1fr6mzp",
      "index": 1,
      "title": "Sign in",
      "intent": "Sign in with the demo account",
      "status": "recorded",
      "attempts": 1,
      "duration": 11.8,
      "checkpoint": "Invoices list visible"
    },
    {
      "scene_id": "scn_m3ehbzb9d3kw7tbe",
      "index": 2,
      "title": "Create invoice",
      "intent": "Create an invoice for Northwind Studio",
      "status": "recorded",
      "attempts": 2,
      "duration": 24.3,
      "checkpoint": "Invoice INV-0042 open with 2 line items"
    },
    {
      "scene_id": "scn_m3ehbzbap5hn0cxv",
      "index": 3,
      "title": "Export PDF",
      "intent": "Export the invoice as PDF",
      "status": "recorded",
      "attempts": 1,
      "duration": 16.3,
      "checkpoint": "PDF saved to Downloads"
    }
  ],
  "assertions": [
    {
      "assertion_id": "ast_m3ehfkj0r9vb4ngs",
      "kind": "text",
      "title": "Invoice created",
      "status": "passed",
      "scene_id": "scn_m3ehbzb9d3kw7tbe",
      "expectation": "Invoice INV-0042 created",
      "evidence": "Text present in accessibility tree",
      "take_time": 34.62
    }
  ],
  "assertions_passed": "3/3",
  "event_count": 27,
  "recent_events": [
    {
      "event_id": "evt_m3ehwq1g2cbn7fyh",
      "scene_id": "scn_m3ehbzbap5hn0cxv",
      "time": 9.84,
      "kind": "click",
      "beat": "interaction",
      "label": "Click Export PDF",
      "source": "agent"
    },
    {
      "event_id": "evt_m3ehwt8g5jzr3mkp",
      "scene_id": "scn_m3ehbzbap5hn0cxv",
      "time": 12.31,
      "kind": "checkpoint_created",
      "beat": "confirmation",
      "label": "PDF saved to Downloads",
      "source": "system"
    }
  ],
  "source_duration": 52.4,
  "outputs": [
    "16:9",
    "9:16"
  ],
  "edits": {
    "compress_waits": {
      "threshold": 1,
      "to": 0.4
    },
    "trims": 1
  },
  "exports": [
    {
      "job_id": "exp_m3ej19z0b8mc3rkf",
      "take_id": "take_m3ehbyc0k7qv2x9d",
      "format": "16:9",
      "status": "completed",
      "progress": 1,
      "output_path": "/Users/you/Movies/DemoTake/Projects/ledgerly--prj_m119ecc0t4w8nq2h/Takes/create-invoice--take_m3ehbyc0k7qv2x9d.take/exports/create-invoice-16x9-20260926-101204.mp4",
      "duration": 41.8,
      "sha256": "3b7e5a0c9d14f2e86a1b47c3d9e0f5a2b6c8d1e4f7a0b3c6d9e2f5a8b1c4d7e0",
      "completed_at": "2026-09-26T10:12:31Z"
    }
  ],
  "updated_at": "2026-09-26T10:14:03Z",
  "next": "Edit (edit_* / edit_command), then export_render."
}
TOOLProjects and takes

take_create

Create take

Create a Semantic Take: a planned, re-recordable demo made of scenes (story beats bounded by stable app states). Returns take_id. Typical flow: take_create → (take_rehearse) → capture_start → per scene: take_start_scene → act → assert_* → take_checkpoint → capture_stop → edit_* → export_render. Web apps: browser:{mode:"page", address_bar:"drawn"} records only the page area of the browser window and draws a clean address bar (domain + path, never the query string) from the tab's URL instead of the real browser chrome: no tab strip, no automation infobars ("Chrome is being controlled by automated test software", "… is debugging this browser"); the crop follows the page as infobars come and go, and the address bar follows navigations and redirects across domains. target:{url_contains:"example.com"} records the window whose tab shows that URL. DemoTake Agent reads the page area and URL with Accessibility; DemoTake Studio finds them with on-screen text recognition of the toolbar (set browser.page_region if it's off, and log URL changes with take_log_event {kind:"navigation", url} if the address bar isn't readable). Platform review videos: purpose:"reviewer", platform (tiktok, meta_app_review, google_oauth, apple_review), app_url (the website URL in the review form) and scopes (permissions the app requests); mark the scene that shows each scope with scenes[].shows_scopes. review_check verifies the take against them and writes a paste-ready checklist. Presets caption each scene with its intent; TikTok exports default to quality:"upload", max_mb:45 (TikTok accepts MP4/MOV up to 50 MB).

Plain words: Plans a new demo recording (a take) as a list of scenes, before anything is recorded. Think of a take as the video project and each scene as one shot you can retake on its own.

Parameters

namestringREQUIRED
Short name, e.g. "Create invoice".
goalstringOPTIONAL
What the demo must show, in one or two sentences.
purposeenumOPTIONAL
marketing (polished), reviewer (App Store review: conservative edits + proof manifest), tutorial, test (DemoTest: assertions matter most).One of marketing, reviewer, tutorial, test. Default "marketing".
targetstring | objectOPTIONAL
Target app/window/device. Either a target_id from targets_list ("window:1234", "app:com.example.App", "pid:4321", "display:1", "sim:<UDID>" for a booted iOS Simulator device, "android:<serial>" for an Android emulator or device, a URL) or an object; {url_contains:"example.com"} picks the browser window whose tab shows that URL (and keeps following that window across navigations). target_id is accepted as an alias. Defaults to the take's target.
12 fields
target_idstringOPTIONAL
id from targets_list
bundle_idstringOPTIONAL
app_namestringOPTIONAL
window_titlestringOPTIONAL
window_idintegerOPTIONAL
pidintegerOPTIONAL
display_idintegerOPTIONAL
urlstringOPTIONAL
url_containsstringOPTIONAL
Browser window whose tab URL contains this text, e.g. a domain
device_udidstringOPTIONAL
iOS Simulator device UDID
serialstringOPTIONAL
Android adb serial (emulator-5554, a USB serial)
kindenumOPTIONAL
One of window, application, display, web, simulator, android.
scenesobject[]OPTIONAL
Ordered scenes. Each is a story beat bounded by stable app states and is the unit of retry.
3 fields
titlestringREQUIRED
Short scene title, e.g. "Sign in"
intentstringOPTIONAL
What the scene must accomplish / show.
shows_scopesstring[]OPTIONAL
Platform review presets: the scopes / permissions this scene shows (e.g. its consent screen).
outputsenum[]OPTIONAL
Output formats: "16:9" (landscape), "9:16" (vertical), "4:3", "1:1", "gif", "screenshots", "reviewer_pack" (conservative cut + manifest ZIP), "guide" (written step-by-step guide: guide.md + index.html + screenshots), "interactive" (click-through HTML demo: index.html + player + step images, folder + ZIP).One of 16:9, 9:16, 4:3, 1:1, gif, screenshots, reviewer_pack, guide, interactive, app_preview.
ai_modeenumOPTIONAL
byo_agent (you drive via MCP, default), assist, director (DemoTake's AI drives), manual.One of manual, byo_agent, assist, director. Default "byo_agent".
pointerenumOPTIONAL
Presentation pointer personality.One of calm, natural, precise, fast, presenter, invisible.
project_idstringOPTIONAL
Existing project (project_…).
project_namestringOPTIONAL
Project to use or create by name.
source_commitstringOPTIONAL
Git commit of the app being demoed; recorded in the proof manifest.
browserobjectOPTIONAL
Browser mode for web apps: record the page area only (no tab strip, toolbar or automation infobars) with an optional drawn address bar that follows the tab's URL. page_region fixes the page area by hand (normalized to the window) when it can't be detected. tab says what to do with a url_contains tab that isn't active.
5 fields
modeenumOPTIONAL
page: only the page area (default); window: the whole window (URL changes are still tracked).One of page, window. Default "page".
address_barenumOPTIONAL
drawn: a clean address bar (lock, domain, path) drawn above the page; none: no address bar.One of drawn, none. Default "drawn".
url_containsstringOPTIONAL
Record the browser window whose tab shows a URL containing this (e.g. "example.com"); it keeps following that window.
page_regionobjectOPTIONAL
Region {x, y, width, height} normalized to the recorded frame (0…1, top-left origin), not pixels. w/h are accepted for width/height; other keys are rejected.
4 fields
xnumberREQUIRED
left, 0…1Min 0, max 1.
ynumberREQUIRED
top, 0…1Min 0, max 1.
widthnumberREQUIRED
0…1Min 0, max 1.
heightnumberREQUIRED
0…1Min 0, max 1.
tabenumOPTIONAL
When the url_contains tab isn't the active tab of its window, or its window is on another Space (DemoTake Agent, Apple Events): select (make it the active tab), isolate (open its page in a new window sized like the original and record that; the original tab is left alone; also isolates an active tab that shares its window), require_active (fail instead, as in 1.3.0). Default: isolate for reviewer takes (platform presets), select otherwise; an active tab in a window on this Space is recorded where it is.One of select, isolate, require_active.
platformenumOPTIONAL
Platform review preset (with purpose reviewer).One of tiktok, meta_app_review, google_oauth, apple_review.
app_urlstringOPTIONAL
The website URL declared in the review form; the domain the video shows must match it.
scopesstring[]OPTIONAL
Scopes / permissions the review covers; each needs a scene whose shows_scopes lists it.
presenterobjectOPTIONAL
The presenter camera: record it with each scene and how it's drawn (presenter_set changes it later).
7 fields
camerabooleanOPTIONAL
Record the presenter camera with every scene (capture_start {camera} overrides it). Agents' captures use it only when the person allowed agents to use the camera in Settings › Privacy.
camera_devicestringOPTIONAL
Camera id from targets_capabilities cameras.
layoutenumOPTIONAL
bubble, split or full.One of bubble, split, full.
cornerenumOPTIONAL
Bubble corner.One of top_left, top_right, bottom_left, bottom_right.
shapeenumOPTIONAL
Bubble shape.One of circle, rounded.
sizeenumOPTIONAL
Bubble size.One of small, medium, large.
backgroundenumOPTIONAL
Background blur/removal (Mac renders).One of none, blur, remove.
target_idstring | objectOPTIONAL
Alias of target.
12 fields
target_idstringOPTIONAL
id from targets_list
bundle_idstringOPTIONAL
app_namestringOPTIONAL
window_titlestringOPTIONAL
window_idintegerOPTIONAL
pidintegerOPTIONAL
display_idintegerOPTIONAL
urlstringOPTIONAL
url_containsstringOPTIONAL
Browser window whose tab URL contains this text, e.g. a domain
device_udidstringOPTIONAL
iOS Simulator device UDID
serialstringOPTIONAL
Android adb serial (emulator-5554, a USB serial)
kindenumOPTIONAL
One of window, application, display, web, simulator, android.
projectstringOPTIONAL
Alias of project_id.

Good to know

With no scenes but a goal, DemoTake plans the scenes for you.

Request · what your agent sends
{
  "name": "take_create",
  "arguments": {
    "name": "Create invoice",
    "goal": "Create an invoice for a new customer and export it as PDF.",
    "purpose": "marketing",
    "target": "window:4127",
    "scenes": [
      {
        "title": "Sign in",
        "intent": "Sign in with the demo account"
      },
      {
        "title": "Create invoice",
        "intent": "Create an invoice for Northwind Studio"
      },
      {
        "title": "Export PDF",
        "intent": "Export the invoice as PDF"
      }
    ],
    "outputs": [
      "16:9",
      "9:16"
    ],
    "project_name": "Ledgerly"
  }
}
Response · structuredContent
Created take_m3ehbyc0k7qv2x9d with 3 scene(s).
{
  "take_id": "take_m3ehbyc0k7qv2x9d",
  "project_id": "prj_m119ecc0t4w8nq2h",
  "name": "Create invoice",
  "goal": "Create an invoice for a new customer and export it as PDF.",
  "purpose": "marketing",
  "status": "draft",
  "ai_mode": "byo_agent",
  "execution_mode": "background_semantic",
  "target": {
    "target_id": "window:4127",
    "kind": "window",
    "name": "Ledgerly — Invoices",
    "bundle_id": "com.example.Ledgerly",
    "app_name": "Ledgerly",
    "window_title": "Invoices",
    "window_id": 4127,
    "pid": 51234
  },
  "scenes": [
    {
      "scene_id": "scn_m3ehbzb8a1fr6mzp",
      "index": 1,
      "title": "Sign in",
      "intent": "Sign in with the demo account",
      "status": "pending",
      "attempts": 0
    },
    {
      "scene_id": "scn_m3ehbzb9d3kw7tbe",
      "index": 2,
      "title": "Create invoice",
      "intent": "Create an invoice for Northwind Studio",
      "status": "pending",
      "attempts": 0
    },
    {
      "scene_id": "scn_m3ehbzbap5hn0cxv",
      "index": 3,
      "title": "Export PDF",
      "intent": "Export the invoice as PDF",
      "status": "pending",
      "attempts": 0
    }
  ],
  "assertions": [],
  "assertions_passed": "0/0",
  "event_count": 0,
  "source_duration": 0,
  "outputs": [
    "16:9",
    "9:16"
  ],
  "edits": {
    "compress_waits": {
      "threshold": 1,
      "to": 0.4
    }
  },
  "updated_at": "2026-09-26T09:40:00Z",
  "next": "Optionally take_rehearse to dry-run, then capture_start."
}
TOOLProjects and takes

take_plan

Update take plan

Replace the scene list and/or change goal, purpose or target of a take that hasn't been recorded yet (recorded scenes keep their media when titles match).

Plain words: Changes the plan of a take that hasn't been recorded yet: replace the scene list, or change the goal, purpose or target app.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
scenesobject[]OPTIONAL
Ordered scenes. Each is a story beat bounded by stable app states and is the unit of retry.
3 fields
titlestringREQUIRED
Short scene title, e.g. "Sign in"
intentstringOPTIONAL
What the scene must accomplish / show.
shows_scopesstring[]OPTIONAL
Platform review presets: the scopes / permissions this scene shows (e.g. its consent screen).
goalstringOPTIONAL
New goal.
purposeenumOPTIONAL
New purpose.One of marketing, reviewer, tutorial, test.
targetstring | objectOPTIONAL
Target app/window/device. Either a target_id from targets_list ("window:1234", "app:com.example.App", "pid:4321", "display:1", "sim:<UDID>" for a booted iOS Simulator device, "android:<serial>" for an Android emulator or device, a URL) or an object; {url_contains:"example.com"} picks the browser window whose tab shows that URL (and keeps following that window across navigations). target_id is accepted as an alias. Defaults to the take's target.
12 fields
target_idstringOPTIONAL
id from targets_list
bundle_idstringOPTIONAL
app_namestringOPTIONAL
window_titlestringOPTIONAL
window_idintegerOPTIONAL
pidintegerOPTIONAL
display_idintegerOPTIONAL
urlstringOPTIONAL
url_containsstringOPTIONAL
Browser window whose tab URL contains this text, e.g. a domain
device_udidstringOPTIONAL
iOS Simulator device UDID
serialstringOPTIONAL
Android adb serial (emulator-5554, a USB serial)
kindenumOPTIONAL
One of window, application, display, web, simulator, android.
target_idstring | objectOPTIONAL
Alias of target.
12 fields
target_idstringOPTIONAL
id from targets_list
bundle_idstringOPTIONAL
app_namestringOPTIONAL
window_titlestringOPTIONAL
window_idintegerOPTIONAL
pidintegerOPTIONAL
display_idintegerOPTIONAL
urlstringOPTIONAL
url_containsstringOPTIONAL
Browser window whose tab URL contains this text, e.g. a domain
device_udidstringOPTIONAL
iOS Simulator device UDID
serialstringOPTIONAL
Android adb serial (emulator-5554, a USB serial)
kindenumOPTIONAL
One of window, application, display, web, simulator, android.
takestringOPTIONAL
Alias of take_id.

Good to know

Scenes whose titles match an existing scene keep their id and any recorded footage.

Request · what your agent sends
{
  "name": "take_plan",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "scenes": [
      {
        "title": "Sign in",
        "intent": "Sign in with the demo account"
      },
      {
        "title": "Add customer",
        "intent": "Add Northwind Studio as a customer"
      },
      {
        "title": "Create invoice",
        "intent": "Create an invoice for Northwind Studio"
      },
      {
        "title": "Export PDF",
        "intent": "Export the invoice as PDF"
      }
    ],
    "goal": "Add a customer, invoice them and export the invoice as PDF."
  }
}
Response · structuredContent
Plan updated.
{
  "take_id": "take_m3ehbyc0k7qv2x9d",
  "name": "Create invoice",
  "goal": "Add a customer, invoice them and export the invoice as PDF.",
  "purpose": "marketing",
  "status": "draft",
  "scenes": [
    {
      "scene_id": "scn_m3ehbzb8a1fr6mzp",
      "index": 1,
      "title": "Sign in",
      "intent": "Sign in with the demo account",
      "status": "pending",
      "attempts": 0
    },
    {
      "scene_id": "scn_m3ehgm30x4ty6pwa",
      "index": 2,
      "title": "Add customer",
      "intent": "Add Northwind Studio as a customer",
      "status": "pending",
      "attempts": 0
    },
    {
      "scene_id": "scn_m3ehbzb9d3kw7tbe",
      "index": 3,
      "title": "Create invoice",
      "intent": "Create an invoice for Northwind Studio",
      "status": "pending",
      "attempts": 0
    },
    {
      "scene_id": "scn_m3ehbzbap5hn0cxv",
      "index": 4,
      "title": "Export PDF",
      "intent": "Export the invoice as PDF",
      "status": "pending",
      "attempts": 0
    }
  ],
  "assertions_passed": "0/0",
  "outputs": [
    "16:9",
    "9:16"
  ],
  "next": "Optionally take_rehearse to dry-run, then capture_start."
}
TOOLProjects and takes

take_rehearse

Start rehearsal

Dry-run the flow without recording (preview only). Walk every scene with your own tools or ui_* tools, then call take_rehearse_finish. Rehearsal events are kept separately and never rendered.

Plain words: Starts a dry run: walk through every scene without recording, to find slow screens, popups or missing data before the real take. Nothing from a rehearsal ends up in the video.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
takestringOPTIONAL
Alias of take_id.
Request · what your agent sends
{
  "name": "take_rehearse",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d"
  }
}
Response · structuredContent
Rehearsing.
{
  "take_id": "take_m3ehbyc0k7qv2x9d",
  "name": "Create invoice",
  "status": "rehearsing",
  "scenes": [
    {
      "scene_id": "scn_m3ehbzb8a1fr6mzp",
      "index": 1,
      "title": "Sign in",
      "status": "pending",
      "attempts": 0
    },
    {
      "scene_id": "scn_m3ehbzb9d3kw7tbe",
      "index": 2,
      "title": "Create invoice",
      "status": "pending",
      "attempts": 0
    },
    {
      "scene_id": "scn_m3ehbzbap5hn0cxv",
      "index": 3,
      "title": "Export PDF",
      "status": "pending",
      "attempts": 0
    }
  ],
  "assertions_passed": "0/0",
  "next": "Walk through each scene, then take_rehearse_finish with findings."
}
TOOLProjects and takes

take_rehearse_finish

Finish rehearsal

End the rehearsal, recording what you learned (slow screens, popups, required data).

Plain words: Ends the dry run and saves what you learned (for example, a slow spinner or a required field) as notes for the real recording.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
findingsstringOPTIONAL
Notes for the real take.
takestringOPTIONAL
Alias of take_id.
Request · what your agent sends
{
  "name": "take_rehearse_finish",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "findings": "Sign-in shows a 2 s spinner; the PDF export sheet needs a customer selected first."
  }
}
Response · structuredContent
Rehearsal finished.
{
  "take_id": "take_m3ehbyc0k7qv2x9d",
  "name": "Create invoice",
  "status": "rehearsed",
  "scenes": [
    {
      "scene_id": "scn_m3ehbzb8a1fr6mzp",
      "index": 1,
      "title": "Sign in",
      "status": "rehearsed",
      "attempts": 0,
      "rehearsed_duration": 9.2
    },
    {
      "scene_id": "scn_m3ehbzb9d3kw7tbe",
      "index": 2,
      "title": "Create invoice",
      "status": "rehearsed",
      "attempts": 0,
      "rehearsed_duration": 21.7
    },
    {
      "scene_id": "scn_m3ehbzbap5hn0cxv",
      "index": 3,
      "title": "Export PDF",
      "status": "rehearsed",
      "attempts": 0,
      "rehearsed_duration": 14.1
    }
  ],
  "assertions_passed": "0/0",
  "next": "capture_start, then for each scene: take_start_scene → act → assert_* → take_checkpoint."
}
Next call
TOOLProjects and takes

take_start_scene

Start scene

Begin recording a scene (a new segment). Ends any scene still running. Capture must be running (capture_start). Get the app into the scene's starting state first.

Plain words: Starts recording one scene. Get the app into the scene's starting state first; any scene that is still running is ended.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
scenestringREQUIRED
Scene handle (the scn_… scene_id that take_create and take_get return), exact title, or 1-based index. scene_id is accepted as an alias.
scene_idstringOPTIONAL
Alias of scene.
takestringOPTIONAL
Alias of take_id.

Good to know

Capture must already be running (capture_start); the scene can be a scn_ handle, its exact title or its 1-based index.

Request · what your agent sends
{
  "name": "take_start_scene",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "scene": "Create invoice"
  }
}
Response · structuredContent
Recording scene "Create invoice" (attempt 1).
{
  "scene": {
    "scene_id": "scn_m3ehbzb9d3kw7tbe",
    "index": 2,
    "title": "Create invoice",
    "intent": "Create an invoice for Northwind Studio",
    "status": "recording",
    "attempts": 1
  },
  "take_status": "recording",
  "next": "Scene \"Create invoice\" is recording: act, assert, then take_checkpoint."
}
TOOLProjects and takes

take_checkpoint

Checkpoint scene

Finish the running scene at a stable state and describe it ("Dashboard visible with 3 projects"). Checkpoints are where a failed later scene can be retried from. screenshot:true also captures the stable screen into a Screenshot Set (for App Store / Google Play screenshots) named after the take unless screenshot_set is given.

Plain words: Ends the running scene at a stable point and describes what's on screen. If a later scene fails, you retry from here instead of starting over.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
descriptionstringREQUIRED
The stable state reached.
scenestringOPTIONAL
Scene to checkpoint (defaults to the running one).
screenshotbooleanOPTIONAL
Also capture this screen as a store screenshot (shot named after the scene).Default false.
screenshot_setstringOPTIONAL
Screenshot Set id (shots_…) or name for the capture. Default: "<take name> screenshots".
headlinestringOPTIONAL
Headline for the screenshot.
scene_idstringOPTIONAL
Alias of scene.
takestringOPTIONAL
Alias of take_id.

Good to know

Add screenshot: true to also capture the stable screen as a store screenshot, into a Screenshot Set named after the take (or screenshot_set). The result then has a screenshot {set_id, shot_id, path}.

Request · what your agent sends
{
  "name": "take_checkpoint",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "description": "Invoice INV-0042 open with 2 line items"
  }
}
Response · structuredContent
Checkpoint saved for "Create invoice".
{
  "scene": {
    "scene_id": "scn_m3ehbzb9d3kw7tbe",
    "index": 2,
    "title": "Create invoice",
    "intent": "Create an invoice for Northwind Studio",
    "status": "recorded",
    "attempts": 1,
    "duration": 24.3,
    "checkpoint": "Invoice INV-0042 open with 2 line items"
  },
  "take_status": "recording",
  "next": "take_start_scene \"Export PDF\" next."
}
TOOLProjects and takes

take_retry_scene

Retry scene

Mark a scene failed and prepare a fresh attempt. Only that scene is re-recorded; other scenes keep their footage. Restore the scene's starting state, then take_start_scene again.

Plain words: Throws away a scene that went wrong so you can record it again. Only that scene is redone; the other scenes keep their footage.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
scenestringREQUIRED
Scene handle (the scn_… scene_id that take_create and take_get return), exact title, or 1-based index. scene_id is accepted as an alias.
reasonstringOPTIONAL
What went wrong.
scene_idstringOPTIONAL
Alias of scene.
takestringOPTIONAL
Alias of take_id.

Good to know

Put the app back into the scene's starting state before calling take_start_scene again.

Request · what your agent sends
{
  "name": "take_retry_scene",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "scene": "2",
    "reason": "Typed the wrong customer name"
  }
}
Response · structuredContent
Scene "Create invoice" ready for attempt 2.
{
  "scene": {
    "scene_id": "scn_m3ehbzb9d3kw7tbe",
    "index": 2,
    "title": "Create invoice",
    "intent": "Create an invoice for Northwind Studio",
    "status": "failed",
    "attempts": 1,
    "notes": "Typed the wrong customer name"
  },
  "take_status": "recording",
  "next": "take_start_scene \"Create invoice\" next."
}
TOOLProjects and takes

take_log_event

Log trace event

Report what you just did with your OWN computer-use tools (BYO agent), so DemoTake can place the presentation pointer, zoom and edit semantically. Call right after each meaningful action. Prefer element or screen_point so the pointer lands correctly. iOS Simulator and Android targets: report taps as kind "click" (or "tap") with point normalized to the device screen (0…1), or device_point in device points (Android: dp); they render as a touch indicator. Set redact=true for anything secret; never put passwords in text. source says who acted: "agent" (you, default), "automation" (a browser/UI automation tool you drive, e.g. Playwright or Claude in Chrome) or "human" (the person, e.g. signing in); reviewer packs list it. take_relabel_events fixes the source of events already logged (e.g. clicks DemoTake observed as human input). Browser takes: log kind "navigation" with url when the page changes and DemoTake can't read the URL itself (DemoTake Studio); it is drawn in the address bar from that moment.

Plain words: Tells DemoTake what you just did in the app with your own tools (a click, typing, a wait), so the finished video can show a smooth pointer and zoom on the right spot. Call it right after each meaningful action.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
kindenumREQUIRED
What happened ("tap" = click on an iOS device).One of scene_started, scene_ended, click, double_click, right_click, type, key_press, scroll, drag, navigation, wait, appeared, action_performed, target_changed, assertion_passed, assertion_failed, checkpoint_created, human_input_required, scene_retried, error, marker, note, tap.
labelstringREQUIRED
Human label, e.g. "Click Export".
beatenumOPTIONAL
Story role; inferred from kind if omitted.One of navigation, interaction, form_entry, result, confirmation, error, waiting, other.
importanceenumOPTIONAL
Narrative importance (drives camera).One of low, normal, high.
durationnumberOPTIONAL
Seconds the action took (typing, waits).Min 0.
pointobjectOPTIONAL
Point normalized to the target window (0…1, top-left origin). For iOS Simulator and Android targets: normalized to the device screen.
2 fields
xnumberREQUIRED
0…1 from the window's left edgeMin 0, max 1.
ynumberREQUIRED
0…1 from the window's top edgeMin 0, max 1.
screen_pointobjectOPTIONAL
Global screen point in points (top-left origin), as used by computer-use tools.
2 fields
xnumberREQUIRED
points from the main display's left
ynumberREQUIRED
points from the top
device_pointobjectOPTIONAL
iOS Simulator targets: point in device points (top-left origin, e.g. from XCUITest or idb); Android targets: in dp. Converted with the device's screen size.
2 fields
xnumberREQUIRED
device points from the screen's leftMin 0.
ynumberREQUIRED
device points from the topMin 0.
elementobjectOPTIONAL
The element acted on, if known.
6 fields
rolestringOPTIONAL
AX role
titlestringOPTIONAL
title
labelstringOPTIONAL
label
identifierstringOPTIONAL
identifier
frameobjectOPTIONAL
Region {x, y, width, height} normalized to the recorded frame (0…1, top-left origin), not pixels. w/h are accepted for width/height; other keys are rejected.
4 fields
xnumberREQUIRED
left, 0…1Min 0, max 1.
ynumberREQUIRED
top, 0…1Min 0, max 1.
widthnumberREQUIRED
0…1Min 0, max 1.
heightnumberREQUIRED
0…1Min 0, max 1.
securebooleanOPTIONAL
secure field
textstringOPTIONAL
Typed text (non-secret only).
redactbooleanOPTIONAL
Hide this event's text/region in renders.Default false.
scenestringOPTIONAL
Scene handle; defaults to the running scene.
sourceenumOPTIONAL
Who acted.One of agent, automation, human. Default "agent".
urlstringOPTIONAL
Navigation events: the page URL now shown (drawn in a browser take's address bar).
scene_idstringOPTIONAL
Alias of scene.
takestringOPTIONAL
Alias of take_id.

Good to know

Never put passwords in text; set redact to true for anything secret. For iOS Simulator taps use kind "tap" with a device-normalized point or device_point.

Request · what your agent sends
{
  "name": "take_log_event",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "kind": "click",
    "label": "Click New Invoice",
    "screen_point": {
      "x": 1302,
      "y": 131
    },
    "element": {
      "role": "AXButton",
      "title": "New Invoice",
      "identifier": "new-invoice"
    }
  }
}
Response · structuredContent
{
  "event_id": "evt_m3ehep8g6yzk1mcd",
  "scene_id": "scn_m3ehbzb9d3kw7tbe",
  "time": 3.42,
  "kind": "click",
  "beat": "interaction",
  "label": "Click New Invoice",
  "source": "agent"
}
TOOLProjects and takes

take_relabel_events

Re-label who acted

Change the source of recorded events: who acted, as the reviewer pack reports it. Use it when DemoTake observed clicks as human input that a browser automation tool made, or to mark a person's sign-in as human. Select events by event_ids (timeline_get / take_get list them), or by scene with an optional scene-local start/end (source seconds), kinds and from_source. Scene lifecycle, checkpoint and assertion events keep their source.

Plain words: Changes who a take says acted: your agent, an automation tool or a person. Use it when clicks made by a browser automation tool were recorded as a person's, or to mark a sign-in as the person's own. Reviewer notes and manifests list it.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
sourceenumREQUIRED
Who acted.One of agent, automation, human.
event_idsstring[]OPTIONAL
Exactly these events.
scenestringOPTIONAL
Only events of this scene (handle, title or 1-based index).
startnumberOPTIONAL
Scene-local start seconds (needs scene).Min 0.
endnumberOPTIONAL
Scene-local end seconds (needs scene).Min 0.
kindsenum[]OPTIONAL
Only these kinds, e.g. ["click", "type"].One of scene_started, scene_ended, click, double_click, right_click, type, key_press, scroll, drag, navigation, wait, appeared, action_performed, target_changed, assertion_passed, assertion_failed, checkpoint_created, human_input_required, scene_retried, error, marker, note.
from_sourceenumOPTIONAL
Only events currently from this source.One of agent, human, automation, system, classifier.
scene_idstringOPTIONAL
Alias of scene.
takestringOPTIONAL
Alias of take_id.

Good to know

Select events by event_ids, or by scene with optional scene-local start/end, kinds and from_source. Scene, checkpoint and assertion events keep their source.

Request · what your agent sends
{
  "name": "take_relabel_events",
  "arguments": {
    "take_id": "take_m5tq2r8c0vk7wd3n",
    "scene": "Connect account",
    "kinds": [
      "click",
      "type"
    ],
    "from_source": "human",
    "source": "automation"
  }
}
Response · structuredContent
2 event(s) now automation.
{
  "changed": 2,
  "events": [
    {
      "event_id": "evt_m5tq3c1k7fz2nb8r",
      "kind": "click",
      "source": "automation",
      "label": "Connect TikTok"
    },
    {
      "event_id": "evt_m5tq3c2a9wq4hd1m",
      "kind": "click",
      "source": "automation",
      "label": "Continue"
    }
  ]
}
TOOLCapture

capture_start

Start capture

Start recording the take's target window (background-safe: the window may be covered, but must not be minimized). By default the first pending scene starts immediately.

Plain words: Starts recording the take's app window. The window can be covered by other windows but must not be minimized; by default the first pending scene starts right away.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
fpsintegerOPTIONAL
Frames per second.Default 60. Min 15, max 120.
app_audiobooleanOPTIONAL
Record the target app's audio (captured per app, not per window).Default false.
microphonebooleanOPTIONAL
Record the microphone.Default false.
auto_start_scenebooleanOPTIONAL
Start the first pending scene immediately.Default true.
camerabooleanOPTIONAL
Record the presenter camera beside the screen, one file per scene that follows its cuts (default: the take's setting from take_create {presenter}). Needs the person's consent: Settings › Privacy › Allow agents to use the camera (off by default; camera:true fails without it, the take's setting is skipped with a note). Asks for camera access the first time; turns the presenter overlay on; the recording HUD shows the camera is on.
camera_devicestringOPTIONAL
Camera id from targets_capabilities cameras (default: the take's choice, else the system camera).
pointerenumOPTIONAL
DemoTake's drawn pointer: auto (off when DemoTake isn't the one clicking: background_capture_only takes your agent drives with another tool, which usually draws its own cursor), on, off.One of auto, on, off. Default "auto".
browserobjectOPTIONAL
Browser mode for web apps: record the page area only (no tab strip, toolbar or automation infobars) with an optional drawn address bar that follows the tab's URL. page_region fixes the page area by hand (normalized to the window) when it can't be detected. tab says what to do with a url_contains tab that isn't active.
5 fields
modeenumOPTIONAL
page: only the page area (default); window: the whole window (URL changes are still tracked).One of page, window. Default "page".
address_barenumOPTIONAL
drawn: a clean address bar (lock, domain, path) drawn above the page; none: no address bar.One of drawn, none. Default "drawn".
url_containsstringOPTIONAL
Record the browser window whose tab shows a URL containing this (e.g. "example.com"); it keeps following that window.
page_regionobjectOPTIONAL
Region {x, y, width, height} normalized to the recorded frame (0…1, top-left origin), not pixels. w/h are accepted for width/height; other keys are rejected.
4 fields
xnumberREQUIRED
left, 0…1Min 0, max 1.
ynumberREQUIRED
top, 0…1Min 0, max 1.
widthnumberREQUIRED
0…1Min 0, max 1.
heightnumberREQUIRED
0…1Min 0, max 1.
tabenumOPTIONAL
When the url_contains tab isn't the active tab of its window, or its window is on another Space (DemoTake Agent, Apple Events): select (make it the active tab), isolate (open its page in a new window sized like the original and record that; the original tab is left alone; also isolates an active tab that shares its window), require_active (fail instead, as in 1.3.0). Default: isolate for reviewer takes (platform presets), select otherwise; an active tab in a window on this Space is recorded where it is.One of select, isolate, require_active.
takestringOPTIONAL
Alias of take_id.

Good to know

Pass auto_start_scene: false to arm the capture and start each scene yourself with take_start_scene.

Request · what your agent sends
{
  "name": "capture_start",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "fps": 60
  }
}
Response · structuredContent
Recording. Scene "Sign in" is live.
{
  "take_id": "take_m3ehbyc0k7qv2x9d",
  "state": "recording",
  "take_status": "recording",
  "current_scene_id": "scn_m3ehbzb8a1fr6mzp",
  "current_scene": "Sign in",
  "segment_elapsed": 0,
  "total_recorded": 0,
  "scenes_recorded": 0,
  "scenes_total": 3,
  "execution_mode": "background_semantic"
}
TOOLCapture

capture_pause

Pause capture

Pause recording (e.g. while fixing app state). Paused time is not recorded. With resume_when {text, timeout} it resumes by itself when that text appears on the target window (on-screen text recognition; works in both editions): use it for slow server work instead of polling, e.g. {text:"Upload complete", timeout:300}. Events: handoff_started, then handoff_ended {outcome}. take_wait does the same and can add an "A moment later" card.

Plain words: Pauses the recording, for example while you fix the app's state. Time spent paused is not recorded.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
resume_whenobjectOPTIONAL
Resume automatically when text appears on screen (on-screen text recognition, no Accessibility needed).
2 fields
textstringREQUIRED
Resume when this text appears on the target window (case-insensitive), e.g. "wants to access your account".
timeoutnumberOPTIONAL
Stop watching after this many seconds (the capture then stays paused).Min 1, max 7200.
takestringOPTIONAL
Alias of take_id.
Request · what your agent sends
{
  "name": "capture_pause",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d"
  }
}
Response · structuredContent
{
  "take_id": "take_m3ehbyc0k7qv2x9d",
  "state": "paused",
  "take_status": "paused",
  "current_scene_id": "scn_m3ehbzb9d3kw7tbe",
  "current_scene": "Create invoice",
  "segment_elapsed": 12.3,
  "total_recorded": 24.1,
  "scenes_recorded": 1,
  "scenes_total": 3,
  "execution_mode": "background_semantic"
}
TOOLCapture

capture_resume

Resume capture

Resume a paused recording. Also ends a hand-off or wait in progress (take_handoff / take_wait).

Plain words: Continues a paused recording right where it left off.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
takestringOPTIONAL
Alias of take_id.
Request · what your agent sends
{
  "name": "capture_resume",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d"
  }
}
Response · structuredContent
{
  "take_id": "take_m3ehbyc0k7qv2x9d",
  "state": "recording",
  "take_status": "recording",
  "current_scene_id": "scn_m3ehbzb9d3kw7tbe",
  "current_scene": "Create invoice",
  "segment_elapsed": 12.3,
  "total_recorded": 24.1,
  "scenes_recorded": 1,
  "scenes_total": 3,
  "execution_mode": "background_semantic"
}
TOOLCapture

take_handoff

Hand off to a person

A step that is the person's to do (signing in, pressing Allow on a consent screen): pauses the capture and shows message to the person inside DemoTake (a banner with a Resume button in the recording UI, on top of other windows), not only in your chat. It resumes automatically when resume_when.text appears on the target window (on-screen text recognition, which needs no Accessibility, so it works in DemoTake Studio too), when the person presses Resume, or when you call capture_resume. blur:true keeps recording instead and blurs the whole frame for that span (shows that a sign-in happened without showing it). Poll events_poll for handoff_ended (outcome text_appeared, resumed_by_person, resumed_by_agent, timed_out); capture_status shows the hand-off. A scene must be recording.

Plain words: Hands a step to the person, such as signing in or pressing Allow on a consent screen. DemoTake pauses the recording and shows your message in its own window, with a Resume button. It resumes when the text you name appears on screen, or when the person presses Resume.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
messagestringREQUIRED
What the person should do, e.g. "Sign in to TikTok and stop at the consent screen".
resume_whenobjectOPTIONAL
Resume automatically when text appears on screen (on-screen text recognition, no Accessibility needed).
2 fields
textstringREQUIRED
Resume when this text appears on the target window (case-insensitive), e.g. "wants to access your account".
timeoutnumberOPTIONAL
Stop watching after this many seconds (the capture then stays paused).Min 1, max 7200.
blurbooleanOPTIONAL
Keep recording, blurred, instead of pausing.Default false.
takestringOPTIONAL
Alias of take_id.

Good to know

Poll events_poll for handoff_ended (outcome text_appeared, resumed_by_person, resumed_by_agent or timed_out). blur:true keeps recording, blurred, instead of pausing. Text recognition needs no Accessibility, so it works in DemoTake Studio too.

Request · what your agent sends
{
  "name": "take_handoff",
  "arguments": {
    "take_id": "take_m5tq2r8c0vk7wd3n",
    "message": "Sign in to TikTok and stop at the consent screen",
    "resume_when": {
      "text": "wants to access your account",
      "timeout": 600
    }
  }
}
Response · structuredContent
Handed off: Sign in to TikTok and stop at the consent screen. Resumes when “wants to access your account” appears on screen.
{
  "take_id": "take_m5tq2r8c0vk7wd3n",
  "state": "paused",
  "take_status": "recording",
  "current_scene_id": "scn_m5tq2r9d4bx1kf6p",
  "current_scene": "Authorize",
  "segment_elapsed": 6.4,
  "total_recorded": 41.2,
  "scenes_recorded": 2,
  "scenes_total": 5,
  "execution_mode": "background_capture_only",
  "pointer": "off",
  "browser_url": "https://www.tiktok.com/login",
  "handoff": {
    "handoff_id": "hof_m5tq3k0p2vd8xc4a",
    "kind": "human",
    "message": "Sign in to TikTok and stop at the consent screen",
    "resume_when": {
      "text": "wants to access your account",
      "timeout": 600
    },
    "scene_id": "scn_m5tq2r9d4bx1kf6p",
    "started_at": "2026-10-26T14:08:12Z"
  }
}
TOOLCapture

take_wait

Wait for a slow result

Slow server work (an upload, a background job): pauses the capture so the wait isn't recorded, and resumes when resume_when.text appears on the target window (on-screen text recognition), or on capture_resume. card:"A moment later" captions the moment the recording picks up (for 2 seconds; an ordinary caption you can edit or revert). Events: handoff_started / handoff_ended.

Plain words: Waits out slow server work, like an upload, without recording the wait. The recording picks up when the text you name appears on screen, and can show a short card such as “A moment later”.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
resume_whenobjectREQUIRED
Resume automatically when text appears on screen (on-screen text recognition, no Accessibility needed).
2 fields
textstringREQUIRED
Resume when this text appears on the target window (case-insensitive), e.g. "wants to access your account".
timeoutnumberOPTIONAL
Stop watching after this many seconds (the capture then stays paused).Min 1, max 7200.
cardstringOPTIONAL
Short card shown when the recording resumes, e.g. "A moment later".
messagestringOPTIONAL
What is being waited for (shown in DemoTake).
takestringOPTIONAL
Alias of take_id.

Good to know

capture_pause {resume_when} does the same without a card. The card is an ordinary caption you can edit or revert.

Request · what your agent sends
{
  "name": "take_wait",
  "arguments": {
    "take_id": "take_m5tq2r8c0vk7wd3n",
    "resume_when": {
      "text": "Draft sent to your inbox",
      "timeout": 300
    },
    "card": "A moment later",
    "message": "Waiting for the upload to finish"
  }
}
Response · structuredContent
Paused; resumes when “Draft sent to your inbox” appears (up to 300 s).
{
  "take_id": "take_m5tq2r8c0vk7wd3n",
  "state": "paused",
  "take_status": "recording",
  "current_scene_id": "scn_m5tq2ra1h8nz3qte",
  "current_scene": "Draft in TikTok inbox",
  "segment_elapsed": 3.1,
  "total_recorded": 58.7,
  "scenes_recorded": 4,
  "scenes_total": 5,
  "handoff": {
    "handoff_id": "hof_m5tq4a7e1rb3yz6k",
    "kind": "wait",
    "message": "Waiting for the upload to finish",
    "resume_when": {
      "text": "Draft sent to your inbox",
      "timeout": 300
    },
    "card": "A moment later",
    "scene_id": "scn_m5tq2ra1h8nz3qte",
    "started_at": "2026-10-26T14:11:40Z"
  }
}
TOOLCapture

capture_stop

Stop capture

Stop recording, finalize the take and open it in the editor. Unrecorded scenes stay pending and can be recorded later.

Plain words: Stops recording and opens the take in the editor. Scenes you didn't record stay pending, so you can record them later.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
takestringOPTIONAL
Alias of take_id.

Good to know

The take finishes processing in the background (automatic redaction of sensitive text, final status); take_get shows when it is ready.

Request · what your agent sends
{
  "name": "capture_stop",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d"
  }
}
Response · structuredContent
Stopped. 3/3 scenes recorded, 52.4s.
{
  "take_id": "take_m3ehbyc0k7qv2x9d",
  "state": "idle",
  "take_status": "processing",
  "segment_elapsed": 0,
  "total_recorded": 52.4,
  "scenes_recorded": 3,
  "scenes_total": 3,
  "execution_mode": "background_semantic",
  "next": "Processing; poll take_get or events_poll."
}
TOOLREAD-ONLYCapture

capture_status

Capture status

Recording state, current scene and elapsed time, whether DemoTake draws its pointer, a hand-off or wait in progress, the browser URL being shown, and notes.

Plain words: Shows whether a take is recording, which scene is live and how much has been recorded so far.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
takestringOPTIONAL
Alias of take_id.

Good to know

state is one of idle, previewing, rehearsing, recording or paused.

Request · what your agent sends
{
  "name": "capture_status",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d"
  }
}
Response · structuredContent
{
  "take_id": "take_m3ehbyc0k7qv2x9d",
  "state": "recording",
  "take_status": "recording",
  "current_scene_id": "scn_m3ehbzb9d3kw7tbe",
  "current_scene": "Create invoice",
  "segment_elapsed": 8.6,
  "total_recorded": 20.4,
  "scenes_recorded": 1,
  "scenes_total": 3,
  "execution_mode": "background_semantic"
}
TOOLREAD-ONLYObserve

observe_state

Observe UI state

Compact text outline of the target window's UI (roles, titles, values, #identifiers, normalized frames), secrets redacted. Much cheaper than a screenshot; use it to find elements for pointer_click / assert_element. Falls back to OCR text when Accessibility isn't available (DemoTake Studio). Android targets: the app's UI hierarchy (uiautomator: classes, texts, resource ids, frames normalized to the screen); apps that draw their own UI (games, Flutter) fall back to OCR of the device screen.

Plain words: Reads the app window's interface as a short text outline (buttons, fields, labels and where they are), with secrets hidden. Much cheaper than a screenshot, and the way to find elements to click or check.

Parameters

take_idstringOPTIONAL
Take handle (take_…). When given, the take's target is used and the action is recorded in its trace.
targetstring | objectOPTIONAL
Target app/window/device. Either a target_id from targets_list ("window:1234", "app:com.example.App", "pid:4321", "display:1", "sim:<UDID>" for a booted iOS Simulator device, "android:<serial>" for an Android emulator or device, a URL) or an object; {url_contains:"example.com"} picks the browser window whose tab shows that URL (and keeps following that window across navigations). target_id is accepted as an alias. Defaults to the take's target.
12 fields
target_idstringOPTIONAL
id from targets_list
bundle_idstringOPTIONAL
app_namestringOPTIONAL
window_titlestringOPTIONAL
window_idintegerOPTIONAL
pidintegerOPTIONAL
display_idintegerOPTIONAL
urlstringOPTIONAL
url_containsstringOPTIONAL
Browser window whose tab URL contains this text, e.g. a domain
device_udidstringOPTIONAL
iOS Simulator device UDID
serialstringOPTIONAL
Android adb serial (emulator-5554, a USB serial)
kindenumOPTIONAL
One of window, application, display, web, simulator, android.
max_depthintegerOPTIONAL
Tree depth to walk.Default 12. Min 2, max 30.
target_idstring | objectOPTIONAL
Alias of target.
12 fields
target_idstringOPTIONAL
id from targets_list
bundle_idstringOPTIONAL
app_namestringOPTIONAL
window_titlestringOPTIONAL
window_idintegerOPTIONAL
pidintegerOPTIONAL
display_idintegerOPTIONAL
urlstringOPTIONAL
url_containsstringOPTIONAL
Browser window whose tab URL contains this text, e.g. a domain
device_udidstringOPTIONAL
iOS Simulator device UDID
serialstringOPTIONAL
Android adb serial (emulator-5554, a USB serial)
kindenumOPTIONAL
One of window, application, display, web, simulator, android.
takestringOPTIONAL
Alias of take_id.

Good to know

The outline itself arrives as the text content (lines like - button "New Invoice" #new-invoice @(0.88,0.06 0.09x0.04)); structuredContent carries only this metadata.

Request · what your agent sends
{
  "name": "observe_state",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "max_depth": 12
  }
}
Response · structuredContent
{
  "source": "ax",
  "window_title": "Invoices",
  "focused": {
    "role": "AXTextField",
    "label": "Customer",
    "value": "Northwind Studio",
    "identifier": "customer-field",
    "selector": "AXWindow/AXGroup[1]/AXTextField[0]",
    "frame": {
      "x": 0.312,
      "y": 0.184,
      "width": 0.34,
      "height": 0.042
    }
  },
  "node_count": 143,
  "captured_at": "2026-09-26T09:47:12Z"
}
TOOLREAD-ONLYObserve

observe_snapshot

Snapshot

A still image of the target window (secrets detected by OCR are blurred before it leaves DemoTake). Use sparingly; observe_state is cheaper.

Plain words: Takes a still picture of the app window, with detected secrets blurred before it leaves DemoTake. Use it sparingly; observe_state is cheaper when text is enough.

Parameters

take_idstringOPTIONAL
Take handle (take_…). When given, the take's target is used and the action is recorded in its trace.
targetstring | objectOPTIONAL
Target app/window/device. Either a target_id from targets_list ("window:1234", "app:com.example.App", "pid:4321", "display:1", "sim:<UDID>" for a booted iOS Simulator device, "android:<serial>" for an Android emulator or device, a URL) or an object; {url_contains:"example.com"} picks the browser window whose tab shows that URL (and keeps following that window across navigations). target_id is accepted as an alias. Defaults to the take's target.
12 fields
target_idstringOPTIONAL
id from targets_list
bundle_idstringOPTIONAL
app_namestringOPTIONAL
window_titlestringOPTIONAL
window_idintegerOPTIONAL
pidintegerOPTIONAL
display_idintegerOPTIONAL
urlstringOPTIONAL
url_containsstringOPTIONAL
Browser window whose tab URL contains this text, e.g. a domain
device_udidstringOPTIONAL
iOS Simulator device UDID
serialstringOPTIONAL
Android adb serial (emulator-5554, a USB serial)
kindenumOPTIONAL
One of window, application, display, web, simulator, android.
max_pixel_sizeintegerOPTIONAL
Longest edge of the returned image.Default 1024. Min 256, max 1600.
target_idstring | objectOPTIONAL
Alias of target.
12 fields
target_idstringOPTIONAL
id from targets_list
bundle_idstringOPTIONAL
app_namestringOPTIONAL
window_titlestringOPTIONAL
window_idintegerOPTIONAL
pidintegerOPTIONAL
display_idintegerOPTIONAL
urlstringOPTIONAL
url_containsstringOPTIONAL
Browser window whose tab URL contains this text, e.g. a domain
device_udidstringOPTIONAL
iOS Simulator device UDID
serialstringOPTIONAL
Android adb serial (emulator-5554, a USB serial)
kindenumOPTIONAL
One of window, application, display, web, simulator, android.
takestringOPTIONAL
Alias of take_id.

Good to know

The PNG itself is returned as an image content block next to this JSON.

Request · what your agent sends
{
  "name": "observe_snapshot",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "max_pixel_size": 1024
  }
}
Response · structuredContent
{
  "path": "/Users/you/Movies/DemoTake/Projects/ledgerly--prj_m119ecc0t4w8nq2h/Takes/create-invoice--take_m3ehbyc0k7qv2x9d.take/snapshots/….png",
  "width": 1024,
  "height": 640,
  "redacted_regions": 1
}
TOOLREAD-ONLYObserve

observe_wait_for

Wait for UI

Wait until an element appears/disappears, text becomes visible, or the UI is idle. During a recording the wait becomes a trace event that edits can compress ("remove waits > 1 s").

Plain words: Waits until something happens in the app: an element appears or goes away, some text shows up, or the screen stops changing. While recording, the wait is marked so the editor can shorten it later.

Parameters

take_idstringOPTIONAL
Take handle (take_…). When given, the take's target is used and the action is recorded in its trace.
targetstring | objectOPTIONAL
Target app/window/device. Either a target_id from targets_list ("window:1234", "app:com.example.App", "pid:4321", "display:1", "sim:<UDID>" for a booted iOS Simulator device, "android:<serial>" for an Android emulator or device, a URL) or an object; {url_contains:"example.com"} picks the browser window whose tab shows that URL (and keeps following that window across navigations). target_id is accepted as an alias. Defaults to the take's target.
12 fields
target_idstringOPTIONAL
id from targets_list
bundle_idstringOPTIONAL
app_namestringOPTIONAL
window_titlestringOPTIONAL
window_idintegerOPTIONAL
pidintegerOPTIONAL
display_idintegerOPTIONAL
urlstringOPTIONAL
url_containsstringOPTIONAL
Browser window whose tab URL contains this text, e.g. a domain
device_udidstringOPTIONAL
iOS Simulator device UDID
serialstringOPTIONAL
Android adb serial (emulator-5554, a USB serial)
kindenumOPTIONAL
One of window, application, display, web, simulator, android.
elementobjectOPTIONAL
Which UI element. All given fields must match. Use observe_state to see what's there. The target window is searched; the app's menu bar only when the query asks for a menu item (role menuitem, or a selector starting AXApplication/AXMenuBar). Among equal matches a tab in a tab strip comes before a tab group's header.
6 fields
rolestringOPTIONAL
AX role, with or without the AX prefix: button, textfield, checkbox, link, menuitem, row, cell, statictext…
titlestringOPTIONAL
Case-insensitive substring of the element's title (falls back to its label).
textstringOPTIONAL
Case-insensitive substring of title, label, value or placeholder.
identifierstringOPTIONAL
Exact accessibility identifier (shown as #id in observe_state).
selectorstringOPTIONAL
Structural path from observe_state (AXWindow/AXGroup[0]/AXButton[2]) or a CSS selector for web targets. Precise but brittle across UI changes.
indexintegerOPTIONAL
0-based index among matches (exact matches rank first).Min 0.
gonebooleanOPTIONAL
Wait for element to disappear instead.Default false.
textstringOPTIONAL
Wait for visible text.
idle_secondsnumberOPTIONAL
Wait until the UI stops changing for this long.Min 0.1, max 10.
timeoutnumberOPTIONAL
Seconds.Default 10. Min 0.1, max 120.
target_idstring | objectOPTIONAL
Alias of target.
12 fields
target_idstringOPTIONAL
id from targets_list
bundle_idstringOPTIONAL
app_namestringOPTIONAL
window_titlestringOPTIONAL
window_idintegerOPTIONAL
pidintegerOPTIONAL
display_idintegerOPTIONAL
urlstringOPTIONAL
url_containsstringOPTIONAL
Browser window whose tab URL contains this text, e.g. a domain
device_udidstringOPTIONAL
iOS Simulator device UDID
serialstringOPTIONAL
Android adb serial (emulator-5554, a USB serial)
kindenumOPTIONAL
One of window, application, display, web, simulator, android.
takestringOPTIONAL
Alias of take_id.

Good to know

Give exactly one of element, text or idle_seconds; a timeout returns satisfied: false with the summary "Timed out after 15.0s."

Request · what your agent sends
{
  "name": "observe_wait_for",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "text": "Invoice saved",
    "timeout": 15
  }
}
Response · structuredContent
Condition met.
{
  "satisfied": true
}
DEMOTAKE AGENT ONLYOperate (DemoTake Agent)

pointer_click

Click

Click an element (preferred) or a normalized point in the target window. Background-safe via Accessibility when possible (your mouse is untouched); the presentation pointer is synthesized in the render. Android targets: adb input on the device (an element is found in the UI hierarchy, or by its text on screen; button right = long press). Protected apps (terminals, password managers, System Settings, DemoTake) are refused unless the user allowed them in Settings.

Plain words: Clicks a button or other element in the app (DemoTake Agent only). It works through Accessibility in the background, so your own mouse isn't touched; the pointer you see in the video is added when rendering.

Parameters

elementobjectOPTIONAL
Which UI element. All given fields must match. Use observe_state to see what's there. The target window is searched; the app's menu bar only when the query asks for a menu item (role menuitem, or a selector starting AXApplication/AXMenuBar). Among equal matches a tab in a tab strip comes before a tab group's header.
6 fields
rolestringOPTIONAL
AX role, with or without the AX prefix: button, textfield, checkbox, link, menuitem, row, cell, statictext…
titlestringOPTIONAL
Case-insensitive substring of the element's title (falls back to its label).
textstringOPTIONAL
Case-insensitive substring of title, label, value or placeholder.
identifierstringOPTIONAL
Exact accessibility identifier (shown as #id in observe_state).
selectorstringOPTIONAL
Structural path from observe_state (AXWindow/AXGroup[0]/AXButton[2]) or a CSS selector for web targets. Precise but brittle across UI changes.
indexintegerOPTIONAL
0-based index among matches (exact matches rank first).Min 0.
pointobjectOPTIONAL
Point normalized to the target window (0…1, top-left origin). For iOS Simulator and Android targets: normalized to the device screen.
2 fields
xnumberREQUIRED
0…1 from the window's left edgeMin 0, max 1.
ynumberREQUIRED
0…1 from the window's top edgeMin 0, max 1.
buttonenumOPTIONAL
Mouse button.One of left, right. Default "left".
countintegerOPTIONAL
1 = click, 2 = double-click.Default 1. Min 1, max 2.
take_idstringOPTIONAL
Take handle (take_…). When given, the take's target is used and the action is recorded in its trace.
targetstring | objectOPTIONAL
Target app/window/device. Either a target_id from targets_list ("window:1234", "app:com.example.App", "pid:4321", "display:1", "sim:<UDID>" for a booted iOS Simulator device, "android:<serial>" for an Android emulator or device, a URL) or an object; {url_contains:"example.com"} picks the browser window whose tab shows that URL (and keeps following that window across navigations). target_id is accepted as an alias. Defaults to the take's target.
12 fields
target_idstringOPTIONAL
id from targets_list
bundle_idstringOPTIONAL
app_namestringOPTIONAL
window_titlestringOPTIONAL
window_idintegerOPTIONAL
pidintegerOPTIONAL
display_idintegerOPTIONAL
urlstringOPTIONAL
url_containsstringOPTIONAL
Browser window whose tab URL contains this text, e.g. a domain
device_udidstringOPTIONAL
iOS Simulator device UDID
serialstringOPTIONAL
Android adb serial (emulator-5554, a USB serial)
kindenumOPTIONAL
One of window, application, display, web, simulator, android.
labelstringOPTIONAL
Human-readable label for the trace/timeline, e.g. "Click New Project".
allow_foregroundbooleanOPTIONAL
Allow taking the real mouse/keyboard (activates the app) when no background-safe accessibility path exists. Ask the user first if they are working.Default false.
target_idstring | objectOPTIONAL
Alias of target.
12 fields
target_idstringOPTIONAL
id from targets_list
bundle_idstringOPTIONAL
app_namestringOPTIONAL
window_titlestringOPTIONAL
window_idintegerOPTIONAL
pidintegerOPTIONAL
display_idintegerOPTIONAL
urlstringOPTIONAL
url_containsstringOPTIONAL
Browser window whose tab URL contains this text, e.g. a domain
device_udidstringOPTIONAL
iOS Simulator device UDID
serialstringOPTIONAL
Android adb serial (emulator-5554, a USB serial)
kindenumOPTIONAL
One of window, application, display, web, simulator, android.
takestringOPTIONAL
Alias of take_id.

Good to know

If no background-safe path exists the call fails and says so; retry with allow_foreground: true only when the user isn't working.

Request · what your agent sends
{
  "name": "pointer_click",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "element": {
      "role": "button",
      "title": "New Invoice"
    },
    "label": "Click New Invoice"
  }
}
Response · structuredContent
{
  "success": true,
  "method": "semantic",
  "element": {
    "role": "AXButton",
    "title": "New Invoice",
    "identifier": "new-invoice",
    "selector": "AXWindow/AXToolbar[0]/AXButton[1]",
    "frame": {
      "x": 0.84,
      "y": 0.038,
      "width": 0.094,
      "height": 0.042
    }
  },
  "point": {
    "x": 0.887,
    "y": 0.059
  }
}
DEMOTAKE AGENT ONLYOperate (DemoTake Agent)

pointer_move

Move pointer

Move the real pointer to a normalized point (hover menus/tooltips). Needs foreground control, which only the user can turn on in DemoTake's Settings; for presentation motion you don't need this — the pointer is synthesized from clicks.

Plain words: Moves the real mouse pointer to a spot in the window, for hover menus or tooltips (DemoTake Agent only). Not needed for the video's pointer, which is drawn from your clicks.

Parameters

pointobjectREQUIRED
Point normalized to the target window (0…1, top-left origin). For iOS Simulator and Android targets: normalized to the device screen.
2 fields
xnumberREQUIRED
0…1 from the window's left edgeMin 0, max 1.
ynumberREQUIRED
0…1 from the window's top edgeMin 0, max 1.
take_idstringOPTIONAL
Take handle (take_…). When given, the take's target is used and the action is recorded in its trace.
targetstring | objectOPTIONAL
Target app/window/device. Either a target_id from targets_list ("window:1234", "app:com.example.App", "pid:4321", "display:1", "sim:<UDID>" for a booted iOS Simulator device, "android:<serial>" for an Android emulator or device, a URL) or an object; {url_contains:"example.com"} picks the browser window whose tab shows that URL (and keeps following that window across navigations). target_id is accepted as an alias. Defaults to the take's target.
12 fields
target_idstringOPTIONAL
id from targets_list
bundle_idstringOPTIONAL
app_namestringOPTIONAL
window_titlestringOPTIONAL
window_idintegerOPTIONAL
pidintegerOPTIONAL
display_idintegerOPTIONAL
urlstringOPTIONAL
url_containsstringOPTIONAL
Browser window whose tab URL contains this text, e.g. a domain
device_udidstringOPTIONAL
iOS Simulator device UDID
serialstringOPTIONAL
Android adb serial (emulator-5554, a USB serial)
kindenumOPTIONAL
One of window, application, display, web, simulator, android.
labelstringOPTIONAL
Human-readable label for the trace/timeline, e.g. "Click New Project".
allow_foregroundbooleanOPTIONAL
Allow taking the real mouse/keyboard (activates the app) when no background-safe accessibility path exists. Ask the user first if they are working.Default false.
target_idstring | objectOPTIONAL
Alias of target.
12 fields
target_idstringOPTIONAL
id from targets_list
bundle_idstringOPTIONAL
app_namestringOPTIONAL
window_titlestringOPTIONAL
window_idintegerOPTIONAL
pidintegerOPTIONAL
display_idintegerOPTIONAL
urlstringOPTIONAL
url_containsstringOPTIONAL
Browser window whose tab URL contains this text, e.g. a domain
device_udidstringOPTIONAL
iOS Simulator device UDID
serialstringOPTIONAL
Android adb serial (emulator-5554, a USB serial)
kindenumOPTIONAL
One of window, application, display, web, simulator, android.
takestringOPTIONAL
Alias of take_id.

Good to know

Requires allow_foreground: true because it takes the real pointer; ask the user first if they are working.

Request · what your agent sends
{
  "name": "pointer_move",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "point": {
      "x": 0.42,
      "y": 0.31
    },
    "label": "Hover over the due date",
    "allow_foreground": true
  }
}
Response · structuredContent
{
  "success": true,
  "method": "foreground_input",
  "point": {
    "x": 0.42,
    "y": 0.31
  }
}
DEMOTAKE AGENT ONLYOperate (DemoTake Agent)

pointer_scroll

Scroll

Scroll the target (positive dy scrolls content down). Amounts are in lines. Android targets: a swipe (10 lines ≈ a third of the screen) at point. Web pages in a browser (Chrome) don't scroll through Accessibility in the background: there it needs foreground control (only the user turns it on in Settings), or bring an element into view with ui_perform_action {element, action:"AXScrollToVisible"}.

Plain words: Scrolls the app's content (DemoTake Agent only). Positive dy scrolls down; amounts are in lines.

Parameters

dxnumberOPTIONAL
Horizontal lines.Default 0.
dynumberOPTIONAL
Vertical lines.Default 3.
pointobjectOPTIONAL
Point normalized to the target window (0…1, top-left origin). For iOS Simulator and Android targets: normalized to the device screen.
2 fields
xnumberREQUIRED
0…1 from the window's left edgeMin 0, max 1.
ynumberREQUIRED
0…1 from the window's top edgeMin 0, max 1.
take_idstringOPTIONAL
Take handle (take_…). When given, the take's target is used and the action is recorded in its trace.
targetstring | objectOPTIONAL
Target app/window/device. Either a target_id from targets_list ("window:1234", "app:com.example.App", "pid:4321", "display:1", "sim:<UDID>" for a booted iOS Simulator device, "android:<serial>" for an Android emulator or device, a URL) or an object; {url_contains:"example.com"} picks the browser window whose tab shows that URL (and keeps following that window across navigations). target_id is accepted as an alias. Defaults to the take's target.
12 fields
target_idstringOPTIONAL
id from targets_list
bundle_idstringOPTIONAL
app_namestringOPTIONAL
window_titlestringOPTIONAL
window_idintegerOPTIONAL
pidintegerOPTIONAL
display_idintegerOPTIONAL
urlstringOPTIONAL
url_containsstringOPTIONAL
Browser window whose tab URL contains this text, e.g. a domain
device_udidstringOPTIONAL
iOS Simulator device UDID
serialstringOPTIONAL
Android adb serial (emulator-5554, a USB serial)
kindenumOPTIONAL
One of window, application, display, web, simulator, android.
labelstringOPTIONAL
Human-readable label for the trace/timeline, e.g. "Click New Project".
allow_foregroundbooleanOPTIONAL
Allow taking the real mouse/keyboard (activates the app) when no background-safe accessibility path exists. Ask the user first if they are working.Default false.
target_idstring | objectOPTIONAL
Alias of target.
12 fields
target_idstringOPTIONAL
id from targets_list
bundle_idstringOPTIONAL
app_namestringOPTIONAL
window_titlestringOPTIONAL
window_idintegerOPTIONAL
pidintegerOPTIONAL
display_idintegerOPTIONAL
urlstringOPTIONAL
url_containsstringOPTIONAL
Browser window whose tab URL contains this text, e.g. a domain
device_udidstringOPTIONAL
iOS Simulator device UDID
serialstringOPTIONAL
Android adb serial (emulator-5554, a USB serial)
kindenumOPTIONAL
One of window, application, display, web, simulator, android.
takestringOPTIONAL
Alias of take_id.
Request · what your agent sends
{
  "name": "pointer_scroll",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "dy": 5,
    "point": {
      "x": 0.5,
      "y": 0.6
    },
    "label": "Scroll to line items"
  }
}
Response · structuredContent
{
  "success": true,
  "method": "semantic",
  "element": {
    "role": "AXScrollArea",
    "selector": "AXWindow/AXGroup[1]/AXScrollArea[0]",
    "frame": {
      "x": 0.25,
      "y": 0.12,
      "width": 0.75,
      "height": 0.88
    }
  },
  "point": {
    "x": 0.5,
    "y": 0.6
  }
}
DEMOTAKE AGENT ONLYOperate (DemoTake Agent)

keyboard_type

Type text

Type text into the focused element or the element matching element. Secure fields are detected automatically and never logged; set secure=true for any secret anyway. In web pages the field is read back: if the page ignored background typing (Chrome takes keystrokes only in its front window), DemoTake inserts the text through Accessibility, and otherwise fails saying foreground control is needed rather than reporting success. Background-safe via Accessibility when possible (your mouse is untouched); the presentation pointer is synthesized in the render. Android targets: adb input on the device (an element is found in the UI hierarchy, or by its text on screen; button right = long press). Protected apps (terminals, password managers, System Settings, DemoTake) are refused unless the user allowed them in Settings.

Plain words: Types text into the focused field or a field you name (DemoTake Agent only). Password fields are detected and never logged; mark any other secret with secure: true.

Parameters

textstringREQUIRED
Text to type.
elementobjectOPTIONAL
Which UI element. All given fields must match. Use observe_state to see what's there. The target window is searched; the app's menu bar only when the query asks for a menu item (role menuitem, or a selector starting AXApplication/AXMenuBar). Among equal matches a tab in a tab strip comes before a tab group's header.
6 fields
rolestringOPTIONAL
AX role, with or without the AX prefix: button, textfield, checkbox, link, menuitem, row, cell, statictext…
titlestringOPTIONAL
Case-insensitive substring of the element's title (falls back to its label).
textstringOPTIONAL
Case-insensitive substring of title, label, value or placeholder.
identifierstringOPTIONAL
Exact accessibility identifier (shown as #id in observe_state).
selectorstringOPTIONAL
Structural path from observe_state (AXWindow/AXGroup[0]/AXButton[2]) or a CSS selector for web targets. Precise but brittle across UI changes.
indexintegerOPTIONAL
0-based index among matches (exact matches rank first).Min 0.
securebooleanOPTIONAL
Treat as secret: never logged, masked in renders.Default false.
take_idstringOPTIONAL
Take handle (take_…). When given, the take's target is used and the action is recorded in its trace.
targetstring | objectOPTIONAL
Target app/window/device. Either a target_id from targets_list ("window:1234", "app:com.example.App", "pid:4321", "display:1", "sim:<UDID>" for a booted iOS Simulator device, "android:<serial>" for an Android emulator or device, a URL) or an object; {url_contains:"example.com"} picks the browser window whose tab shows that URL (and keeps following that window across navigations). target_id is accepted as an alias. Defaults to the take's target.
12 fields
target_idstringOPTIONAL
id from targets_list
bundle_idstringOPTIONAL
app_namestringOPTIONAL
window_titlestringOPTIONAL
window_idintegerOPTIONAL
pidintegerOPTIONAL
display_idintegerOPTIONAL
urlstringOPTIONAL
url_containsstringOPTIONAL
Browser window whose tab URL contains this text, e.g. a domain
device_udidstringOPTIONAL
iOS Simulator device UDID
serialstringOPTIONAL
Android adb serial (emulator-5554, a USB serial)
kindenumOPTIONAL
One of window, application, display, web, simulator, android.
labelstringOPTIONAL
Human-readable label for the trace/timeline, e.g. "Click New Project".
allow_foregroundbooleanOPTIONAL
Allow taking the real mouse/keyboard (activates the app) when no background-safe accessibility path exists. Ask the user first if they are working.Default false.
target_idstring | objectOPTIONAL
Alias of target.
12 fields
target_idstringOPTIONAL
id from targets_list
bundle_idstringOPTIONAL
app_namestringOPTIONAL
window_titlestringOPTIONAL
window_idintegerOPTIONAL
pidintegerOPTIONAL
display_idintegerOPTIONAL
urlstringOPTIONAL
url_containsstringOPTIONAL
Browser window whose tab URL contains this text, e.g. a domain
device_udidstringOPTIONAL
iOS Simulator device UDID
serialstringOPTIONAL
Android adb serial (emulator-5554, a USB serial)
kindenumOPTIONAL
One of window, application, display, web, simulator, android.
takestringOPTIONAL
Alias of take_id.
Request · what your agent sends
{
  "name": "keyboard_type",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "text": "Northwind Studio",
    "element": {
      "identifier": "customer-field"
    },
    "label": "Enter customer name"
  }
}
Response · structuredContent
{
  "success": true,
  "method": "semantic",
  "element": {
    "role": "AXTextField",
    "label": "Customer",
    "value": "Northwind Studio",
    "identifier": "customer-field",
    "selector": "AXWindow/AXGroup[1]/AXTextField[0]",
    "frame": {
      "x": 0.312,
      "y": 0.184,
      "width": 0.34,
      "height": 0.042
    }
  },
  "point": {
    "x": 0.482,
    "y": 0.205
  }
}
DEMOTAKE AGENT ONLYOperate (DemoTake Agent)

keyboard_key

Press keys

Press a key or combo: "return", "tab", "escape", "cmd+s", "cmd+shift+n", "down". Key presses are delivered to the target app's process. Android targets: adb key events, plus "back", "home", "recents", "menu", "ctrl+a" (Android 13+) or any KEYCODE_….

Plain words: Presses a key or shortcut such as return, tab, escape or cmd+s in the app (DemoTake Agent only).

Parameters

keysstringREQUIRED
Key combo, modifiers joined with +.
take_idstringOPTIONAL
Take handle (take_…). When given, the take's target is used and the action is recorded in its trace.
targetstring | objectOPTIONAL
Target app/window/device. Either a target_id from targets_list ("window:1234", "app:com.example.App", "pid:4321", "display:1", "sim:<UDID>" for a booted iOS Simulator device, "android:<serial>" for an Android emulator or device, a URL) or an object; {url_contains:"example.com"} picks the browser window whose tab shows that URL (and keeps following that window across navigations). target_id is accepted as an alias. Defaults to the take's target.
12 fields
target_idstringOPTIONAL
id from targets_list
bundle_idstringOPTIONAL
app_namestringOPTIONAL
window_titlestringOPTIONAL
window_idintegerOPTIONAL
pidintegerOPTIONAL
display_idintegerOPTIONAL
urlstringOPTIONAL
url_containsstringOPTIONAL
Browser window whose tab URL contains this text, e.g. a domain
device_udidstringOPTIONAL
iOS Simulator device UDID
serialstringOPTIONAL
Android adb serial (emulator-5554, a USB serial)
kindenumOPTIONAL
One of window, application, display, web, simulator, android.
labelstringOPTIONAL
Human-readable label for the trace/timeline, e.g. "Click New Project".
allow_foregroundbooleanOPTIONAL
Allow taking the real mouse/keyboard (activates the app) when no background-safe accessibility path exists. Ask the user first if they are working.Default false.
target_idstring | objectOPTIONAL
Alias of target.
12 fields
target_idstringOPTIONAL
id from targets_list
bundle_idstringOPTIONAL
app_namestringOPTIONAL
window_titlestringOPTIONAL
window_idintegerOPTIONAL
pidintegerOPTIONAL
display_idintegerOPTIONAL
urlstringOPTIONAL
url_containsstringOPTIONAL
Browser window whose tab URL contains this text, e.g. a domain
device_udidstringOPTIONAL
iOS Simulator device UDID
serialstringOPTIONAL
Android adb serial (emulator-5554, a USB serial)
kindenumOPTIONAL
One of window, application, display, web, simulator, android.
takestringOPTIONAL
Alias of take_id.

Good to know

Modifiers are joined with +, e.g. "cmd+shift+n"; keys go to the target app's process.

Request · what your agent sends
{
  "name": "keyboard_key",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "keys": "cmd+s",
    "label": "Save invoice"
  }
}
Response · structuredContent
{
  "success": true,
  "method": "background_input"
}
DEMOTAKE AGENT ONLYOperate (DemoTake Agent)

ui_perform_action

Accessibility action

Perform a named accessibility action on an element: AXPress, AXShowMenu, AXIncrement, AXDecrement, AXConfirm, AXCancel, AXRaise, AXPick.

Plain words: Triggers a named accessibility action on an element, such as pressing it, opening its menu or stepping a value up or down (DemoTake Agent only). Useful when a plain click isn't the right fit.

Parameters

elementobjectREQUIRED
Which UI element. All given fields must match. Use observe_state to see what's there. The target window is searched; the app's menu bar only when the query asks for a menu item (role menuitem, or a selector starting AXApplication/AXMenuBar). Among equal matches a tab in a tab strip comes before a tab group's header.
6 fields
rolestringOPTIONAL
AX role, with or without the AX prefix: button, textfield, checkbox, link, menuitem, row, cell, statictext…
titlestringOPTIONAL
Case-insensitive substring of the element's title (falls back to its label).
textstringOPTIONAL
Case-insensitive substring of title, label, value or placeholder.
identifierstringOPTIONAL
Exact accessibility identifier (shown as #id in observe_state).
selectorstringOPTIONAL
Structural path from observe_state (AXWindow/AXGroup[0]/AXButton[2]) or a CSS selector for web targets. Precise but brittle across UI changes.
indexintegerOPTIONAL
0-based index among matches (exact matches rank first).Min 0.
actionstringOPTIONAL
AX action name (the AX prefix is optional).Default "AXPress".
take_idstringOPTIONAL
Take handle (take_…). When given, the take's target is used and the action is recorded in its trace.
targetstring | objectOPTIONAL
Target app/window/device. Either a target_id from targets_list ("window:1234", "app:com.example.App", "pid:4321", "display:1", "sim:<UDID>" for a booted iOS Simulator device, "android:<serial>" for an Android emulator or device, a URL) or an object; {url_contains:"example.com"} picks the browser window whose tab shows that URL (and keeps following that window across navigations). target_id is accepted as an alias. Defaults to the take's target.
12 fields
target_idstringOPTIONAL
id from targets_list
bundle_idstringOPTIONAL
app_namestringOPTIONAL
window_titlestringOPTIONAL
window_idintegerOPTIONAL
pidintegerOPTIONAL
display_idintegerOPTIONAL
urlstringOPTIONAL
url_containsstringOPTIONAL
Browser window whose tab URL contains this text, e.g. a domain
device_udidstringOPTIONAL
iOS Simulator device UDID
serialstringOPTIONAL
Android adb serial (emulator-5554, a USB serial)
kindenumOPTIONAL
One of window, application, display, web, simulator, android.
labelstringOPTIONAL
Human-readable label for the trace/timeline, e.g. "Click New Project".
allow_foregroundbooleanOPTIONAL
Allow taking the real mouse/keyboard (activates the app) when no background-safe accessibility path exists. Ask the user first if they are working.Default false.
target_idstring | objectOPTIONAL
Alias of target.
12 fields
target_idstringOPTIONAL
id from targets_list
bundle_idstringOPTIONAL
app_namestringOPTIONAL
window_titlestringOPTIONAL
window_idintegerOPTIONAL
pidintegerOPTIONAL
display_idintegerOPTIONAL
urlstringOPTIONAL
url_containsstringOPTIONAL
Browser window whose tab URL contains this text, e.g. a domain
device_udidstringOPTIONAL
iOS Simulator device UDID
serialstringOPTIONAL
Android adb serial (emulator-5554, a USB serial)
kindenumOPTIONAL
One of window, application, display, web, simulator, android.
takestringOPTIONAL
Alias of take_id.
Request · what your agent sends
{
  "name": "ui_perform_action",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "element": {
      "role": "popupbutton",
      "title": "Currency"
    },
    "action": "AXShowMenu"
  }
}
Response · structuredContent
{
  "success": true,
  "method": "semantic",
  "element": {
    "role": "AXPopUpButton",
    "title": "Currency",
    "value": "USD",
    "identifier": "currency-picker",
    "selector": "AXWindow/AXGroup[1]/AXPopUpButton[0]",
    "frame": {
      "x": 0.66,
      "y": 0.184,
      "width": 0.12,
      "height": 0.042
    }
  },
  "point": {
    "x": 0.72,
    "y": 0.205
  }
}
DEMOTAKE AGENT ONLYOperate (DemoTake Agent)

ui_focus

Focus target

Bring the target app/window to the front. Only needed for foreground-only actions; recording works while the window is covered.

Plain words: Brings the app's window to the front (DemoTake Agent only). Recording doesn't need this; it's only for actions that must happen in the foreground.

Parameters

take_idstringOPTIONAL
Take handle (take_…). When given, the take's target is used and the action is recorded in its trace.
targetstring | objectOPTIONAL
Target app/window/device. Either a target_id from targets_list ("window:1234", "app:com.example.App", "pid:4321", "display:1", "sim:<UDID>" for a booted iOS Simulator device, "android:<serial>" for an Android emulator or device, a URL) or an object; {url_contains:"example.com"} picks the browser window whose tab shows that URL (and keeps following that window across navigations). target_id is accepted as an alias. Defaults to the take's target.
12 fields
target_idstringOPTIONAL
id from targets_list
bundle_idstringOPTIONAL
app_namestringOPTIONAL
window_titlestringOPTIONAL
window_idintegerOPTIONAL
pidintegerOPTIONAL
display_idintegerOPTIONAL
urlstringOPTIONAL
url_containsstringOPTIONAL
Browser window whose tab URL contains this text, e.g. a domain
device_udidstringOPTIONAL
iOS Simulator device UDID
serialstringOPTIONAL
Android adb serial (emulator-5554, a USB serial)
kindenumOPTIONAL
One of window, application, display, web, simulator, android.
labelstringOPTIONAL
Human-readable label for the trace/timeline, e.g. "Click New Project".
allow_foregroundbooleanOPTIONAL
Allow taking the real mouse/keyboard (activates the app) when no background-safe accessibility path exists. Ask the user first if they are working.Default false.
target_idstring | objectOPTIONAL
Alias of target.
12 fields
target_idstringOPTIONAL
id from targets_list
bundle_idstringOPTIONAL
app_namestringOPTIONAL
window_titlestringOPTIONAL
window_idintegerOPTIONAL
pidintegerOPTIONAL
display_idintegerOPTIONAL
urlstringOPTIONAL
url_containsstringOPTIONAL
Browser window whose tab URL contains this text, e.g. a domain
device_udidstringOPTIONAL
iOS Simulator device UDID
serialstringOPTIONAL
Android adb serial (emulator-5554, a USB serial)
kindenumOPTIONAL
One of window, application, display, web, simulator, android.
takestringOPTIONAL
Alias of take_id.
Request · what your agent sends
{
  "name": "ui_focus",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d"
  }
}
Response · structuredContent
{
  "success": true,
  "method": "semantic",
  "message": "Ledgerly brought to front."
}
TOOLVerify

assert_element

Assert element

Proof Assertion: DemoTake checks that an element exists right now (Accessibility, or OCR in Studio). Attached to the running scene and shown in the proof manifest.

Plain words: Checks that a specific element is on screen right now (for example, a Send Invoice button that only appears after saving) and records the result as proof in the take.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
elementobjectREQUIRED
Which UI element. All given fields must match. Use observe_state to see what's there. The target window is searched; the app's menu bar only when the query asks for a menu item (role menuitem, or a selector starting AXApplication/AXMenuBar). Among equal matches a tab in a tab strip comes before a tab group's header.
6 fields
rolestringOPTIONAL
AX role, with or without the AX prefix: button, textfield, checkbox, link, menuitem, row, cell, statictext…
titlestringOPTIONAL
Case-insensitive substring of the element's title (falls back to its label).
textstringOPTIONAL
Case-insensitive substring of title, label, value or placeholder.
identifierstringOPTIONAL
Exact accessibility identifier (shown as #id in observe_state).
selectorstringOPTIONAL
Structural path from observe_state (AXWindow/AXGroup[0]/AXButton[2]) or a CSS selector for web targets. Precise but brittle across UI changes.
indexintegerOPTIONAL
0-based index among matches (exact matches rank first).Min 0.
titlestringREQUIRED
What this proves, e.g. "Invoice created".
scenestringOPTIONAL
Scene handle; defaults to the running scene.
scene_idstringOPTIONAL
Alias of scene.
takestringOPTIONAL
Alias of take_id.
Request · what your agent sends
{
  "name": "assert_element",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "element": {
      "role": "button",
      "title": "Send Invoice"
    },
    "title": "Invoice created"
  }
}
Response · structuredContent
✓ Invoice created
{
  "assertion_id": "ast_m3ehfkj0r9vb4ngs",
  "kind": "element",
  "title": "Invoice created",
  "status": "passed",
  "scene_id": "scn_m3ehbzb9d3kw7tbe",
  "expectation": "{\"role\":\"button\",\"title\":\"Send Invoice\"}",
  "evidence": "Found AXButton “Send Invoice”",
  "take_time": 34.62,
  "detail": "role=button title=\"Send Invoice\""
}
TOOLVerify

assert_text

Assert text

Proof Assertion: DemoTake checks that text is visible in the target window (accessibility values, then OCR).

Plain words: Checks that some text is visible in the app window right now and records the result as proof in the take.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
textstringREQUIRED
Text that must be visible.
titlestringOPTIONAL
What this proves.
scenestringOPTIONAL
Scene handle; defaults to the running scene.
scene_idstringOPTIONAL
Alias of scene.
takestringOPTIONAL
Alias of take_id.

Good to know

Without a title the assertion is named “<text>” visible.

Request · what your agent sends
{
  "name": "assert_text",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "text": "Invoice INV-0042 created",
    "title": "Invoice created"
  }
}
Response · structuredContent
✓ Invoice created
{
  "assertion_id": "ast_m3ehfkj0r9vb4ngs",
  "kind": "text",
  "title": "Invoice created",
  "status": "passed",
  "scene_id": "scn_m3ehbzb9d3kw7tbe",
  "expectation": "Invoice INV-0042 created",
  "evidence": "Text present in accessibility tree",
  "take_time": 34.62
}
TOOLVerify

assert_state

Assert state

Record your own verdict about app state (e.g. checked via API or database). Give honest evidence; it appears in the proof manifest.

Plain words: Records your own verdict about something DemoTake can't see on screen, such as a row you confirmed in the database. Give honest evidence; it appears in the proof manifest.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
titlestringREQUIRED
Claim, e.g. "Record saved".
passedbooleanREQUIRED
Your verdict.
expectationstringOPTIONAL
What had to be true.
evidencestringOPTIONAL
How you know.
scenestringOPTIONAL
Scene handle; defaults to the running scene.
scene_idstringOPTIONAL
Alias of scene.
takestringOPTIONAL
Alias of take_id.
Request · what your agent sends
{
  "name": "assert_state",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "title": "Invoice saved",
    "expectation": "Invoice INV-0042 exists in the database with total $1,250.00",
    "passed": true,
    "evidence": "GET /api/invoices/INV-0042 returned 200 with total 1250.00"
  }
}
Response · structuredContent
✓ Invoice saved
{
  "assertion_id": "ast_m3ehfmq0t6cx2jwn",
  "kind": "state",
  "title": "Invoice saved",
  "status": "passed",
  "scene_id": "scn_m3ehbzb9d3kw7tbe",
  "expectation": "Invoice INV-0042 exists in the database with total $1,250.00",
  "evidence": "GET /api/invoices/INV-0042 returned 200 with total 1250.00",
  "take_time": 36.1
}
TOOLVerify

assert_success

Assert flow success

Final verdict that the whole flow succeeded. A take with all assertions passing becomes Proof Verified.

Plain words: Gives the final verdict on whether the whole flow worked. A take whose assertions all pass is marked Proof Verified.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
passedbooleanREQUIRED
Did the flow succeed?
titlestringOPTIONAL
Claim.Default "Flow completed successfully".
evidencestringOPTIONAL
Why.
takestringOPTIONAL
Alias of take_id.
Request · what your agent sends
{
  "name": "assert_success",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "passed": true,
    "evidence": "Invoice INV-0042 was created and the PDF was saved to Downloads."
  }
}
Response · structuredContent
✓ Flow completed successfully
{
  "assertion_id": "ast_m3ehz2k0w8fp5cdq",
  "kind": "success",
  "title": "Flow completed successfully",
  "status": "passed",
  "expectation": "Flow completed successfully",
  "evidence": "Invoice INV-0042 was created and the PDF was saved to Downloads."
}
TOOLVerify

assert_check

Re-check assertion

Re-evaluate an element/text assertion now.

Plain words: Runs an existing element or text assertion again right now, for example after fixing the app state.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
assertion_idstringREQUIRED
ast_… handle.
takestringOPTIONAL
Alias of take_id.
Request · what your agent sends
{
  "name": "assert_check",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "assertion_id": "ast_m3ehfkj0r9vb4ngs"
  }
}
Response · structuredContent
✗ Invoice created — Text not found
{
  "assertion_id": "ast_m3ehfkj0r9vb4ngs",
  "kind": "text",
  "title": "Invoice created",
  "status": "failed",
  "scene_id": "scn_m3ehbzb9d3kw7tbe",
  "expectation": "Invoice INV-0042 created",
  "evidence": "Text not found",
  "take_time": 41.2
}
TOOLEdit

edit_apply

Apply edits

Apply several non-destructive edits at once (source media is never modified). Each operation is {op, …fields}. ops: trim_scene{scene,head,tail} set_speed{scene,start,end,rate} compress_waits{enabled,threshold,compressed_to} edit_event{event_id,action:keep|compress|remove,mask,compress_to,hold_after,camera} hold{scene,at,duration | event_id,duration} camera{scene,mode:wide|focus|punch|none,start,end,region} clear_camera{scene} camera_intensity{intensity} redact{region,scene,start,end,style,reason} remove_redaction{id} set_redaction{id,enabled,region,style} (enabled:false turns off a Secret Guard suggestion the detector got wrong; it stays listed so it isn't suggested again; ids are in take_get's edits.redactions) pointer{personality,shape,size,color,highlight_ring,click_effects} caption{scene,text, start,end | at:scene_start|checkpoint|event, event_id, checkpoint_id, duration, offset} captions_from_intents{scenes,duration,replace} captions_enabled{enabled} remove_scene{scene} restore_scene{scene} reorder_scenes{scenes} rename_scene{scene,title} target_duration{seconds,allow_speedup,max_still_seconds} background{kind,colors,padding,corner_radius,shadow} add_rule{text,effect,beats,match,value} remove_rule{id} keep_blank_frames{enabled} device_frame{mode:auto|on|off} ripple_delete{scene,start,end} shorten_range{scene,start,end,seconds} crop_scene{scene,region | fit:true | reset:true} accept_suggestions{ids | all:true} reject_suggestions{ids} reset_suggestions{ids} keystrokes{mode:off|shortcuts|all,position,size,style,hold,fade | scene,mode} (typed keys and shortcuts on screen) presenter{enabled,layout:bubble|split|full,shape,corner,position,size,border,shadow,mirror,background:none|blur|remove,quality,split_side,offset,include_audio,volume | scene,layout:hidden|bubble|split|full|inherit} (the presenter camera). All operations apply atomically (all or none) and the result carries an edit_id that edit_revert undoes. To apply a reviewed cut plan from edit_suggest_cuts, send its accepted and rejected ids in one call. Regions (crop_scene, camera, redact) are {x, y, width, height} normalized to the recorded frame: 0…1, top-left origin, not pixels (w/h are accepted for width/height). Unknown or missing keys, pixel values, empty regions and regions outside the frame are rejected with an error. crop_scene shows exactly that region of the scene, in every format and on every frame including scene cuts (letterboxed when its shape differs from the canvas); fit:true frames the scene's visible content; reset:true removes the crop. camera focus/punch with a region frames exactly that region (zoomed to fill the frame, from the scene's first frame when the directive covers the whole scene); without a region it zooms gently on the middle. Camera directives also apply to reviewer takes, whose automatic camera is off. ripple_delete removes an interior range; shorten_range keeps its first seconds and the last second before it ends. Caption clock: start/end are scene-local SOURCE seconds (as recorded, like take_frame's time), each mapped through the cuts, so after cuts a caption can start late or end early. Anchored captions don't move when the cut changes and last duration OUTPUT seconds (default 3.5), never past their scene: at:"scene_start" (the scene's first seconds, + offset), at:"checkpoint" (ends with the scene: its checkpointed final state; checkpoint_id may name the scene or a checkpoint event), event_id (starts when that event happens in the output, + offset). captions_from_intents adds one scene_start caption per scene from its intent (replace:true redoes its own). timeline_get lists where every caption lands. target_duration only speeds material up, never cuts: it avoids visible pointer movement while it can, reports exactly which source ranges it sped up and by how much (target_duration in the result), allow_speedup:false forbids speed-ups (the result then says how far over the target the cut is), and max_still_seconds first shortens every still stretch longer than that (readable, consent and result screens and stills under a caption keep their reading time). The result has a small preview frame per crop/camera/caption edit (previews, up to three inline; preview:"path" = files only, "none" = skip) and warnings when an edit has no visible effect. Blank or stalled spans (a window that stopped drawing) are cut automatically; keep_blank_frames{enabled:true} keeps them. device_frame draws a phone bezel around iOS Simulator takes (auto = 9:16 only).

Plain words: Applies several edits in one go: trims, speed changes, camera moves, redactions, captions, accepted cut suggestions and more. Edits never touch the original recording, and the whole batch can be undone with its edit_id.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
operationsobject[]REQUIRED
Edit operations, applied in order.
1 fields
openumREQUIRED
Operation name.One of trim_scene, set_speed, compress_waits, edit_event, hold, hold_after_event, camera, clear_camera, camera_intensity, redact, remove_redaction, set_redaction, pointer, caption, captions_enabled, remove_scene, restore_scene, reorder_scenes, rename_scene, target_duration, background, add_rule, remove_rule, keep_blank_frames, device_frame, ripple_delete, shorten_range, crop_scene, accept_suggestions, reject_suggestions, reset_suggestions, captions_from_intents, keystrokes, presenter.
previewenumOPTIONAL
Preview frames of crop/camera/caption edits: inline (up to three small images, default), path (files only) or none.One of inline, path, none. Default "inline".
takestringOPTIONAL
Alias of take_id.

Good to know

All operations apply atomically (all or none); times are scene-local seconds and regions are normalized 0…1 from the top-left.

Request · what your agent sends
{
  "name": "edit_apply",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "operations": [
      {
        "op": "trim_scene",
        "scene": "Sign in",
        "head": 1.5
      },
      {
        "op": "camera",
        "scene": "Create invoice",
        "mode": "punch",
        "start": 12,
        "end": 15.5
      },
      {
        "op": "caption",
        "scene": "Export PDF",
        "start": 1,
        "end": 4,
        "text": "One click to a client-ready PDF"
      }
    ]
  }
}
Response · structuredContent
Applied: Trim scene (head 1.5s, tail –); Camera → punch; Caption “One click to a client-ready PDF”. Output 0:44. Edit id edt_m3ehy8a0h5tx2wqe (edit_revert undoes it).
{
  "take_id": "take_m3ehbyc0k7qv2x9d",
  "name": "Create invoice",
  "status": "verified",
  "scenes": [
    {
      "scene_id": "scn_m3ehbzb8a1fr6mzp",
      "index": 1,
      "title": "Sign in",
      "status": "recorded",
      "attempts": 1,
      "duration": 11.8,
      "checkpoint": "Invoices list visible"
    },
    {
      "scene_id": "scn_m3ehbzb9d3kw7tbe",
      "index": 2,
      "title": "Create invoice",
      "status": "recorded",
      "attempts": 2,
      "duration": 24.3,
      "checkpoint": "Invoice INV-0042 open with 2 line items"
    },
    {
      "scene_id": "scn_m3ehbzbap5hn0cxv",
      "index": 3,
      "title": "Export PDF",
      "status": "recorded",
      "attempts": 1,
      "duration": 16.3,
      "checkpoint": "PDF saved to Downloads"
    }
  ],
  "assertions_passed": "3/3",
  "source_duration": 52.4,
  "outputs": [
    "16:9",
    "9:16"
  ],
  "edits": {
    "trims": 1,
    "compress_waits": {
      "threshold": 1,
      "to": 0.4
    },
    "camera_directives": 1,
    "captions": 1
  },
  "next": "Edit (edit_* / edit_command), then export_render.",
  "edit_id": "edt_m3ehy8a0h5tx2wqe",
  "duration": 44.12
}
TOOLEdit

edit_trim

Trim scene

Trim seconds from the start (head) and/or end (tail) of a scene.

Plain words: Cuts seconds off the start and/or end of one scene.

Parameters

scenestringREQUIRED
Scene handle (the scn_… scene_id that take_create and take_get return), exact title, or 1-based index. scene_id is accepted as an alias.
take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
headnumberOPTIONAL
Seconds to cut from the start.Min 0.
tailnumberOPTIONAL
Seconds to cut from the end.Min 0.
scene_idstringOPTIONAL
Alias of scene.
takestringOPTIONAL
Alias of take_id.

Good to know

Give head, tail or both; the response is the whole take (trimmed here) plus edit_id and the new output duration.

Request · what your agent sends
{
  "name": "edit_trim",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "scene": "Sign in",
    "head": 1.5,
    "tail": 0.8
  }
}
Response · structuredContent
Applied: Trim scene (head 1.5s, tail 0.8s). Output 0:47. Edit id edt_m3ehy8a0h5tx2wqe (edit_revert undoes it).
{
  "take_id": "take_m3ehbyc0k7qv2x9d",
  "name": "Create invoice",
  "status": "verified",
  "assertions_passed": "3/3",
  "source_duration": 52.4,
  "edits": {
    "trims": 1,
    "compress_waits": {
      "threshold": 1,
      "to": 0.4
    }
  },
  "next": "Edit (edit_* / edit_command), then export_render.",
  "edit_id": "edt_m3ehy8a0h5tx2wqe",
  "duration": 47.36
}
TOOLEdit

edit_speed

Change speed

Speed up (or slow down) part of a scene; rate 0 removes the range (a ripple delete inside the scene). start/end are seconds within the scene's recorded segment (see timeline_get).

Plain words: Speeds up (or slows down) part of a scene, such as a long form being filled in. A rate of 0 removes that stretch entirely.

Parameters

scenestringREQUIRED
Scene handle (the scn_… scene_id that take_create and take_get return), exact title, or 1-based index. scene_id is accepted as an alias.
startnumberREQUIRED
Scene-local start seconds.Min 0.
endnumberREQUIRED
Scene-local end seconds.Min 0.
ratenumberREQUIRED
Playback rate, e.g. 2 = twice as fast.Min 0, max 16.
take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
scene_idstringOPTIONAL
Alias of scene.
takestringOPTIONAL
Alias of take_id.

Good to know

start and end are seconds within the scene's recording (see timeline_get), not the finished video.

Request · what your agent sends
{
  "name": "edit_speed",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "scene": "Export PDF",
    "start": 4,
    "end": 9.5,
    "rate": 3
  }
}
Response · structuredContent
Applied: Speed 3.0×. Output 0:45. Edit id edt_m3ehyf20c9qm4vtb (edit_revert undoes it).
{
  "take_id": "take_m3ehbyc0k7qv2x9d",
  "name": "Create invoice",
  "status": "verified",
  "assertions_passed": "3/3",
  "source_duration": 52.4,
  "edits": {
    "speed_ranges": 1,
    "compress_waits": {
      "threshold": 1,
      "to": 0.4
    }
  },
  "next": "Edit (edit_* / edit_command), then export_render.",
  "edit_id": "edt_m3ehyf20c9qm4vtb",
  "duration": 44.73
}
TOOLEdit

edit_compress_waits

Compress waits

Shorten loading/wait events longer than threshold seconds to compressed_to seconds (disclosed in reviewer manifests).

Plain words: Shortens loading spinners and other waits that run longer than a threshold, so viewers don't sit through them. Reviewer manifests disclose this.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
enabledbooleanOPTIONAL
Turn compression on/off.Default true.
thresholdnumberOPTIONAL
Waits longer than this are compressed.Default 1. Min 0.1.
compressed_tonumberOPTIONAL
Resulting wait length.Default 0.4. Min 0.
takestringOPTIONAL
Alias of take_id.

Good to know

Compression is on by default (waits over 1 s play for 0.4 s); pass enabled: false to keep waits at full length.

Request · what your agent sends
{
  "name": "edit_compress_waits",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "threshold": 0.8,
    "compressed_to": 0.3
  }
}
Response · structuredContent
Applied: Compress waits > 0.8s to 0.3s. Output 0:49. Edit id edt_m3ehyk70f2wd8nrs (edit_revert undoes it).
{
  "take_id": "take_m3ehbyc0k7qv2x9d",
  "name": "Create invoice",
  "status": "verified",
  "assertions_passed": "3/3",
  "source_duration": 52.4,
  "edits": {
    "compress_waits": {
      "threshold": 0.8,
      "to": 0.3
    }
  },
  "next": "Edit (edit_* / edit_command), then export_render.",
  "edit_id": "edt_m3ehyk70f2wd8nrs",
  "duration": 48.9
}
TOOLEdit

edit_camera

Direct camera

Override the automatic, intent-aware camera for a scene or range: wide (full window), focus (with region: frame exactly that region; without: gentle zoom on the middle), punch (tighter emphasis), none (no camera moves). A directive without start/end covers the whole scene and cuts in with it. Applies to reviewer takes too. start/end are seconds within the scene's recorded segment (see timeline_get).

Plain words: Overrides the automatic zoom for a scene or part of it: wide shows the whole window, focus gently zooms in, punch zooms in tight for a key moment, and none turns camera moves off.

Parameters

scenestringREQUIRED
Scene handle (the scn_… scene_id that take_create and take_get return), exact title, or 1-based index. scene_id is accepted as an alias.
modeenumREQUIRED
Camera mode.One of wide, focus, punch, none.
take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
startnumberOPTIONAL
Scene-local start seconds.Min 0.
endnumberOPTIONAL
Scene-local end seconds.Min 0.
regionobjectOPTIONAL
Region {x, y, width, height} normalized to the recorded frame (0…1, top-left origin), not pixels. w/h are accepted for width/height; other keys are rejected.
4 fields
xnumberREQUIRED
left, 0…1Min 0, max 1.
ynumberREQUIRED
top, 0…1Min 0, max 1.
widthnumberREQUIRED
0…1Min 0, max 1.
heightnumberREQUIRED
0…1Min 0, max 1.
scene_idstringOPTIONAL
Alias of scene.
takestringOPTIONAL
Alias of take_id.

Good to know

Omit start and end to direct the whole scene; omit region to follow the action.

Request · what your agent sends
{
  "name": "edit_camera",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "scene": "Create invoice",
    "mode": "focus",
    "start": 6,
    "end": 11,
    "region": {
      "x": 0.55,
      "y": 0.2,
      "width": 0.4,
      "height": 0.35
    }
  }
}
Response · structuredContent
Applied: Camera → focus. Output 0:50. Edit id edt_m3ehyq50n7gc1xkd (edit_revert undoes it).
{
  "take_id": "take_m3ehbyc0k7qv2x9d",
  "name": "Create invoice",
  "status": "verified",
  "assertions_passed": "3/3",
  "source_duration": 52.4,
  "edits": {
    "compress_waits": {
      "threshold": 1,
      "to": 0.4
    },
    "camera_directives": 1
  },
  "next": "Edit (edit_* / edit_command), then export_render.",
  "edit_id": "edt_m3ehyq50n7gc1xkd",
  "duration": 49.8
}
TOOLEdit

edit_redact

Redact region

Blur/pixelate/cover a region in renders. Omit scene for the whole take; omit start/end for the whole scene. start/end are seconds within the scene's recorded segment (see timeline_get).

Plain words: Blurs, pixelates or covers part of the screen in the finished video, such as a customer's email address. The original recording is untouched.

Parameters

regionobjectREQUIRED
Region {x, y, width, height} normalized to the recorded frame (0…1, top-left origin), not pixels. w/h are accepted for width/height; other keys are rejected.
4 fields
xnumberREQUIRED
left, 0…1Min 0, max 1.
ynumberREQUIRED
top, 0…1Min 0, max 1.
widthnumberREQUIRED
0…1Min 0, max 1.
heightnumberREQUIRED
0…1Min 0, max 1.
take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
scenestringOPTIONAL
Scene handle (optional).
startnumberOPTIONAL
Scene-local start seconds.Min 0.
endnumberOPTIONAL
Scene-local end seconds.Min 0.
styleenumOPTIONAL
Redaction style.One of blur, pixelate, solid. Default "blur".
reasonstringOPTIONAL
Why, e.g. "Customer email".
scene_idstringOPTIONAL
Alias of scene.
takestringOPTIONAL
Alias of take_id.

Good to know

Omit scene to redact across the whole take, and start/end to cover the whole scene.

Request · what your agent sends
{
  "name": "edit_redact",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "region": {
      "x": 0.31,
      "y": 0.26,
      "width": 0.24,
      "height": 0.04
    },
    "scene": "Create invoice",
    "style": "blur",
    "reason": "Customer email"
  }
}
Response · structuredContent
Applied: Redact: Customer email. Output 0:50. Edit id edt_m3ehz0t0p3bh6qws (edit_revert undoes it).
{
  "take_id": "take_m3ehbyc0k7qv2x9d",
  "name": "Create invoice",
  "status": "verified",
  "assertions_passed": "3/3",
  "source_duration": 52.4,
  "edits": {
    "compress_waits": {
      "threshold": 1,
      "to": 0.4
    },
    "redactions": [
      {
        "id": "red_m3ehn3b0y5kc9rvm",
        "reason": "Customer email",
        "automatic": false,
        "enabled": true
      }
    ]
  },
  "next": "Edit (edit_* / edit_command), then export_render.",
  "edit_id": "edt_m3ehz0t0p3bh6qws",
  "duration": 49.8
}
TOOLEdit

edit_pointer

Style pointer

Presentation pointer style. Motion is synthesized (minimum-jerk, target-aware), so this changes the whole take instantly.

Plain words: Changes how the video's pointer looks and moves: its personality (calm, fast, presenter…), shape, size, color, highlight ring and click ripples. It applies to the whole take at once.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
personalityenumOPTIONAL
Motion personality.One of calm, natural, precise, fast, presenter, invisible.
shapeenumOPTIONAL
Cursor shape.One of arrow, hand, dot, crosshair, ibeam, touch.
sizenumberOPTIONAL
Scale.Min 0.5, max 3.
colorstringOPTIONAL
Hex color, e.g. #3B82F6.
highlight_ringbooleanOPTIONAL
Ring around the pointer.
click_effectsbooleanOPTIONAL
Ripple on clicks.
takestringOPTIONAL
Alias of take_id.
Request · what your agent sends
{
  "name": "edit_pointer",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "personality": "calm",
    "shape": "arrow",
    "size": 1.4,
    "color": "#3B82F6",
    "highlight_ring": true
  }
}
Response · structuredContent
Applied: Pointer Calm. Output 0:50. Edit id edt_m3ehz5m0e8vr2tjc (edit_revert undoes it).
{
  "take_id": "take_m3ehbyc0k7qv2x9d",
  "name": "Create invoice",
  "status": "verified",
  "assertions_passed": "3/3",
  "source_duration": 52.4,
  "edits": {
    "compress_waits": {
      "threshold": 1,
      "to": 0.4
    }
  },
  "next": "Edit (edit_* / edit_command), then export_render.",
  "edit_id": "edt_m3ehz5m0e8vr2tjc",
  "duration": 49.8
}
TOOLEdit

presenter_set

Presenter overlay

Show the presenter: the camera recorded with each scene (capture_start {camera:true}) or a video imported with presenter_import. layout: bubble (circle or rounded square in a corner, or at position = the bubble's center normalized to the frame, as if dragged), split (screen and presenter side by side; stacked in 9:16) or full (the presenter fills the frame, e.g. intro/outro scenes). With scene, sets that scene's layout only (hidden leaves the presenter out of it; inherit follows the take). size small/medium/large, border none/white/accent, shadow, mirror (on by default for the recorded camera). background blur or remove uses Apple Vision person segmentation at render time on this Mac (quality fast/balanced/accurate; off by default; DemoTake Web shows the camera as recorded). The recorded camera follows cuts and speed changes exactly like the screen; an imported video plays in real time from offset output seconds (negative skips its start), with its sound (include_audio, volume).

Plain words: Shows you, the presenter, over the recording: a round bubble in a corner, the screen and you side by side, or just you for the intro. The camera follows every cut and speed change, and the room behind you can be blurred or replaced on the Mac.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
enabledbooleanOPTIONAL
Show the presenter (false hides it everywhere, keeping its settings).
scenestringOPTIONAL
Scene handle: set only this scene's layout.
layoutenumOPTIONAL
bubble, split or full (with scene: also hidden or inherit).One of hidden, bubble, split, full, inherit.
shapeenumOPTIONAL
Bubble shape.One of circle, rounded. Default "circle".
cornerenumOPTIONAL
Bubble corner (forgets a drag position).One of top_left, top_right, bottom_left, bottom_right. Default "bottom_right".
positionobjectOPTIONAL
Bubble center, normalized to the output frame (a drag).
2 fields
xnumberREQUIRED
0…1 from the leftMin 0, max 1.
ynumberREQUIRED
0…1 from the topMin 0, max 1.
reset_positionbooleanOPTIONAL
Back to corner.
sizeenumOPTIONAL
Bubble size.One of small, medium, large. Default "medium".
borderenumOPTIONAL
Ring around the bubble or card.One of none, white, accent. Default "white".
shadowbooleanOPTIONAL
Soft shadow.Default true.
mirrorbooleanOPTIONAL
Mirror the picture (selfie view).
backgroundenumOPTIONAL
Behind the person: as recorded, blurred, or replaced by the take's background (Mac renders only).One of none, blur, remove. Default "none".
qualityenumOPTIONAL
Person segmentation quality.One of fast, balanced, accurate. Default "balanced".
split_sideenumOPTIONAL
Presenter side in split (in 9:16: left = top).One of left, right. Default "right".
sourceenumOPTIONAL
camera (recorded with each scene) or imported (presenter_import).One of camera, imported.
offsetnumberOPTIONAL
Imported video: output second its first frame plays at (negative skips its start).
include_audiobooleanOPTIONAL
Imported video: play its sound.
volumenumberOPTIONAL
Imported video: volume 0…1.Min 0, max 1.
remove_importedbooleanOPTIONAL
Remove the imported video (back to the recorded camera).
scene_idstringOPTIONAL
Alias of scene.
takestringOPTIONAL
Alias of take_id.
Request · what your agent sends
{
  "name": "presenter_set",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "layout": "bubble",
    "corner": "bottom_right",
    "size": "medium",
    "background": "blur"
  }
}
Response · structuredContent
Applied: Presenter style. Output 0:50. Edit id edt_m3ei0k2s9q1d7xwf.
{
  "take_id": "take_m3ehbyc0k7qv2x9d",
  "name": "Create invoice",
  "status": "verified",
  "assertions_passed": "3/3",
  "source_duration": 52.4,
  "edits": {
    "presenter": {
      "enabled": true,
      "source": "camera",
      "layout": "bubble",
      "shape": "circle",
      "corner": "bottom_right",
      "size": "medium",
      "border": "white",
      "shadow": true,
      "mirror": true,
      "background": "blur",
      "quality": "balanced"
    }
  },
  "next": "Edit (edit_* / edit_command), then export_render.",
  "edit_id": "edt_m3ei0k2s9q1d7xwf",
  "duration": 49.8
}
TOOLEdit

presenter_import

Import presenter video

Copy a presenter video (.mov/.mp4/.m4v, e.g. a founder narrating an agent's take afterwards) into the take and show it as the presenter, aligned with offset (the output second its first frame plays at; negative skips its start; re-align later with presenter_set {offset}). Its sound plays too unless include_audio:false. The original file is never changed. Then style it with presenter_set (layout, corner, size…).

Plain words: Adds a video of you narrating the take, recorded afterwards, as the presenter. It plays from the second you choose, with your voice, and you can move it later.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
pathstringREQUIRED
Absolute path of the video on this Mac.
offsetnumberOPTIONAL
Output second where the video's first frame plays.Default 0.
include_audiobooleanOPTIONAL
Play the video's sound (the presenter's voice).Default true.
takestringOPTIONAL
Alias of take_id.
Request · what your agent sends
{
  "name": "presenter_import",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "path": "/Users/sam/Movies/founder-voiceover.mov",
    "offset": 1.5
  }
}
Response · structuredContent
Imported founder-voiceover.mov (46.2 s) as the presenter from 1.50 s.
{
  "take_id": "take_m3ehbyc0k7qv2x9d",
  "name": "Create invoice",
  "status": "verified",
  "assertions_passed": "3/3",
  "source_duration": 52.4,
  "edits": {
    "presenter": {
      "enabled": true,
      "source": "imported",
      "layout": "bubble",
      "corner": "bottom_right",
      "size": "medium",
      "mirror": false,
      "background": "none",
      "imported": {
        "file": "media/presenter-m3ej2p.mov",
        "name": "founder-voiceover.mov",
        "duration": 46.2,
        "offset": 1.5,
        "width": 1080,
        "height": 1920,
        "has_audio": true,
        "include_audio": true,
        "volume": 1
      }
    }
  },
  "next": "Edit (edit_* / edit_command), then export_render."
}
TOOLEdit

keystrokes_set

Show keystrokes

Show typed keys and shortcuts on screen, drawn from the take's logged typing and key events (keyboard_type, keyboard_key, take_log_event kind type/key_press, and a person's typing in DemoTake Agent). mode: off, shortcuts (⌘/⌃/⌥ combos and ↩ ⇥ ⎋; repeats merge as "⌘Z ×3") or all (typed text too, in short bursts). Typing into secure fields, masked events and anything Secret Guard marks secret (passwords, emails, keys, codes) is never shown. With scene, sets that scene's mode only (inherit = follow the take). Renders in previews and every video export (Mac and DemoTake Web); timeline_get lists the cards.

Plain words: Shows the keys pressed on screen, like ⌘Z ×3 or ↩, drawn from the typing and key presses the take logged. Shortcuts only, or typed text too in short bursts; per scene if you like. Typing in password fields and anything that looks secret is never shown.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
modeenumOPTIONAL
What to show (with scene: also inherit).One of off, shortcuts, all, inherit.
scenestringOPTIONAL
Scene handle: set only this scene's mode.
positionenumOPTIONAL
Where the card sits.One of bottom_center, bottom_left, bottom_right, top_left, top_center, top_right. Default "bottom_center".
sizeenumOPTIONAL
Card size.One of small, medium, large. Default "medium".
styleenumOPTIONAL
dark (like captions), light, or the take's accent color.One of dark, light, accent. Default "dark".
holdnumberOPTIONAL
Output seconds a key stays after it's pressed.Default 1.2. Min 0.3, max 5.
fadenumberOPTIONAL
Fade in/out, output seconds.Default 0.2. Min 0, max 1.
scene_idstringOPTIONAL
Alias of scene.
takestringOPTIONAL
Alias of take_id.
Request · what your agent sends
{
  "name": "keystrokes_set",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "mode": "shortcuts",
    "position": "bottom_center",
    "style": "dark",
    "size": "medium"
  }
}
Response · structuredContent
Applied: Keystrokes shortcuts. Output 0:50. Edit id edt_m3ei0k2s9q1d7xwe.
{
  "take_id": "take_m3ehbyc0k7qv2x9d",
  "name": "Create invoice",
  "status": "verified",
  "assertions_passed": "3/3",
  "source_duration": 52.4,
  "edits": {
    "compress_waits": {
      "threshold": 1,
      "to": 0.4
    },
    "keystrokes": {
      "mode": "shortcuts",
      "position": "bottom_center",
      "size": "medium",
      "style": "dark",
      "hold": 1.2,
      "fade": 0.2
    }
  },
  "next": "Edit (edit_* / edit_command), then export_render.",
  "edit_id": "edt_m3ei0k2s9q1d7xwe",
  "duration": 49.8
}
TOOLEdit

edit_command

Edit by instruction

Natural-language edit, like the editor's command bar: "make it 30 seconds", "remove the hesitation after login", "don't zoom on typing", "redo the login scene". Returns what was applied and any scenes that need re-recording.

Plain words: Edits the take from a plain-language instruction, like the editor's command bar: "make it 30 seconds", "don't zoom on typing" or "redo the login scene".

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
textstringREQUIRED
The instruction.
takestringOPTIONAL
Alias of take_id.

Good to know

Common phrasings are handled on your Mac (interpreter "local"); free-form requests need DemoTake AI ("ai"). Scenes listed in retry_scenes must be re-recorded.

Request · what your agent sends
{
  "name": "edit_command",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "text": "make it 30 seconds"
  }
}
Response · structuredContent
Done.
{
  "applied": [
    "Target length 30s"
  ],
  "message": "Done.",
  "interpreter": "local",
  "retry_scenes": []
}
TOOLREAD-ONLYEdit

timeline_get

Timeline

The edited timeline for an output format: scene placement in output seconds, surviving events with their edits and output times, zoom ranges, where each caption lands (and its clock), every source range played faster or removed with its cause (target_duration, suggestion, speed_range, wait_compression, event_edit, blank), what target_duration did, blank spans with what the capture saw, and keystroke cards. Use it to pick times for edits.

Plain words: Shows the edited timeline for one output format: where each scene lands in the finished video, the actions that survive the edit, and where the camera zooms. Use it to pick times for edits.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
formatenumOPTIONAL
Output format.One of 16:9, 9:16, 4:3, 1:1, gif, screenshots, reviewer_pack, guide, interactive, app_preview. Default "16:9".
takestringOPTIONAL
Alias of take_id.

Good to know

This result uses camelCase keys (takeID, outputStart…), unlike most tools; times here are output seconds, while edit tools take scene-local seconds.

Request · what your agent sends
{
  "name": "timeline_get",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "format": "16:9"
  }
}
Response · structuredContent
3 scene(s), 41.8s.
{
  "takeID": "take_m3ehbyc0k7qv2x9d",
  "format": "16:9",
  "duration": 41.8,
  "scenes": [
    {
      "sceneID": "scn_m3ehbzb8a1fr6mzp",
      "title": "Sign in",
      "outputStart": 0,
      "outputEnd": 9.6,
      "sourceDuration": 11.8,
      "attempts": 1,
      "status": "recorded"
    },
    {
      "sceneID": "scn_m3ehbzb9d3kw7tbe",
      "title": "Create invoice",
      "outputStart": 9.6,
      "outputEnd": 26.9,
      "sourceDuration": 24.3,
      "attempts": 2,
      "status": "recorded"
    },
    {
      "sceneID": "scn_m3ehbzbap5hn0cxv",
      "title": "Export PDF",
      "outputStart": 26.9,
      "outputEnd": 41.8,
      "sourceDuration": 16.3,
      "attempts": 1,
      "status": "recorded"
    }
  ],
  "events": [
    {
      "eventID": "evt_m3ehep8g6yzk1mcd",
      "sceneID": "scn_m3ehbzb9d3kw7tbe",
      "outputTime": 12.35,
      "kind": "click",
      "beat": "interaction",
      "label": "Click New Invoice",
      "camera": "focus"
    },
    {
      "eventID": "evt_m3ehes4g9rbt6kxh",
      "sceneID": "scn_m3ehbzb9d3kw7tbe",
      "outputTime": 13.1,
      "kind": "wait",
      "beat": "waiting",
      "label": "Waiting for invoice editor",
      "edit": {
        "action": "compress",
        "mask": false,
        "compressTo": 0.4
      }
    }
  ],
  "zooms": [
    {
      "start": 12.1,
      "end": 15.8
    }
  ],
  "blanks": []
}
TOOLREAD-ONLYReview

edit_suggest_cuts

Suggest cuts

Review a take's footage for dead space and return a cut plan. Doesn't change the video or its edits: the plan is saved as suggestions, so the editor shows the same bands. It looks at visual change (downscaled frame differences), clicks/typing/scrolls, logged events and on-screen text. A still screen is a candidate, not dead air: each suggestion shortens a stretch to keep_seconds (its start plus a little context before the next change), readable, consent and result screens keep reading time and are flagged needs_review, and nothing is cut across assertions, checkpoints or result states (protected). Times are scene-local seconds (start/end = the still stretch, cut_start/cut_end = what would be removed). planned_duration is the output length if every pending suggestion is accepted. Apply a reviewed plan atomically with edit_apply {operations:[{op:"accept_suggestions", ids:[…]}, {op:"reject_suggestions", ids:[…]}]}; it returns an edit_id for edit_revert. Also reports framing problems per scene (mostly black frames, content in a corner) with a suggested crop (edit_apply crop_scene{scene, fit:true}). max_still_seconds N: no still longer than N seconds — every unchanged stretch longer than N + 0.5 s is shortened to N, except readable, consent and result screens and stills under a caption, which keep their reading time (flagged needs_review); accept them with accept_suggestions{all:true}, or use edit_apply target_duration{seconds, max_still_seconds} to shorten stills and reach a length in one edit. On-screen text that wasn't read cleanly is never quoted in a reason. blank_spans lists the stretches where the recording went blank (cut automatically) with their cause (window_covered, window_hidden, app_not_drawing, tab_switched, screen_locked, capture_paused, unknown), inferred + confidence for recordings made before causes were recorded (worked out from the frames and the take's events; unknown rather than a guess), the evidence and a hint for the next recording.

Plain words: Reviews the footage for dead time (screens where nothing changes and nobody clicks) and suggests where to shorten, without changing anything. Readable, consent and result screens keep reading time and are flagged for a human look.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
keep_secondsnumberOPTIONAL
Seconds a shortened still stretch keeps playing.Default 4. Min 0.5, max 30.
min_staticnumberOPTIONAL
Only stretches at least this long are suggested.Default 4. Min 1, max 120.
contextnumberOPTIONAL
Seconds kept right before the screen changes again.Default 1. Min 0, max 5.
protect_readablebooleanOPTIONAL
Keep reading time on text-heavy, consent and result screens.Default true.
refreshbooleanOPTIONAL
Re-run the review even if a stored one matches.Default false.
scenestringOPTIONAL
Only list suggestions for this scene (handle, title or 1-based index).
max_still_secondsnumberOPTIONAL
Longest still to keep: shortens every unchanged stretch longer than this (sets keep_seconds to it and min_static just above).Min 0.5, max 30.
scene_idstringOPTIONAL
Alias of scene.
takestringOPTIONAL
Alias of take_id.

Good to know

Times are scene-local seconds; apply the reviewed plan in one edit_apply call with accept_suggestions and reject_suggestions.

Request · what your agent sends
{
  "name": "edit_suggest_cuts",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d"
  }
}
Response · structuredContent
2 pending, 0 accepted, 0 rejected suggestion(s). Output 1:12 now, 0:53 if all pending are accepted. 1 show readable, consent or result screens: look at them (take_frame) before accepting.
{
  "take_id": "take_m3ehbyc0k7qv2x9d",
  "analyzed_at": "2026-09-26T10:02:11Z",
  "current_duration": 72.4,
  "planned_duration": 53.2,
  "baseline_duration": 72.4,
  "pending_seconds": 19.2,
  "accepted_seconds": 0,
  "suggestions": [
    {
      "id": "cut_m3ehv6n0e4pa9sjt",
      "scene_id": "scn_m3ehbzb9d3kw7tbe",
      "scene_title": "Create invoice",
      "status": "pending",
      "start": 8.4,
      "end": 24.1,
      "cut_start": 12.4,
      "cut_end": 23.1,
      "keep_seconds": 5,
      "saved_seconds": 10.7,
      "confidence": 0.92,
      "kind": "still",
      "content": "plain",
      "needs_review": false,
      "reason": "Nothing changed on screen for 15.7 s and nobody clicked or typed. Keeps 5.0 s."
    },
    {
      "id": "cut_m3ehv6n1z7gq5wkb",
      "scene_id": "scn_m3ehbzb8a1fr6mzp",
      "scene_title": "Sign in",
      "status": "pending",
      "start": 2.1,
      "end": 18.6,
      "cut_start": 9.1,
      "cut_end": 17.6,
      "keep_seconds": 8,
      "saved_seconds": 8.5,
      "confidence": 0.67,
      "kind": "still",
      "content": "consent",
      "needs_review": true,
      "reason": "Consent screen “Ledgerly wants to access your Google Account” unchanged for 16.5 s. Keeps 8.0 s so it can be read.",
      "headline": "Ledgerly wants to access your Google Account",
      "words": 38
    }
  ],
  "protected": [
    {
      "scene_id": "scn_m3ehbzb8a1fr6mzp",
      "start": 2.1,
      "end": 10.1,
      "kind": "consent",
      "label": "Ledgerly wants to access your Google Account"
    },
    {
      "scene_id": "scn_m3ehbzb9d3kw7tbe",
      "start": 23.35,
      "end": 27.2,
      "kind": "assertion",
      "label": "Invoice created"
    },
    {
      "scene_id": "scn_m3ehbzbap5hn0cxv",
      "start": 12.3,
      "end": 16.3,
      "kind": "scene_end",
      "label": "PDF saved to Downloads"
    }
  ],
  "framing": [
    {
      "scene_id": "scn_m3ehbzb8a1fr6mzp",
      "scene_title": "Sign in",
      "issues": [],
      "summary": "Framing looks fine.",
      "black_fraction": 0.01,
      "black_frame_share": 0,
      "content_area": 0.98,
      "content_bounds": {
        "x": 0.01,
        "y": 0,
        "width": 0.98,
        "height": 1
      }
    }
  ],
  "apply": "edit_apply {take_id, operations:[{op:\"accept_suggestions\", ids:[…]}, {op:\"reject_suggestions\", ids:[…]}]}"
}
TOOLREAD-ONLYReview

take_contact_sheet

Contact sheet

A grid of frames sampled from each scene, to check framing and content before exporting (returned as an image, plus the file path). edited:true (default) shows frames as they will export (crop, background, camera) and labels them with OUTPUT times ("out 1:04.5", seconds in the edited video); edited:false shows them as recorded with scene-local SOURCE times ("rec 0:12.0"). time_base in the result says which. Scenes with framing problems found by edit_suggest_cuts are labeled. blank_segments lists spans where the recording showed nothing, with their cause (window_covered, window_hidden, app_not_drawing, tab_switched, screen_locked, capture_paused, unknown; inferred with a confidence for older recordings), the evidence and a hint.

Plain words: Makes a single image with a grid of frames from each scene, so you can check framing and content before exporting. By default the frames look as they will in the export.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
scenestringOPTIONAL
Only this scene (handle, title or 1-based index).
frames_per_sceneintegerOPTIONAL
Frames per scene.Default 6. Min 2, max 12.
editedbooleanOPTIONAL
As exported (true) or as recorded (false).Default true.
max_pixel_sizeintegerOPTIONAL
Longest edge of the returned image.Default 1600. Min 512, max 2400.
scene_idstringOPTIONAL
Alias of scene.
takestringOPTIONAL
Alias of take_id.

Good to know

The image is returned as an image content block; scenes with framing problems also get a framing array with a suggested crop.

Request · what your agent sends
{
  "name": "take_contact_sheet",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "frames_per_scene": 6
  }
}
Response · structuredContent
{
  "path": "/var/folders/…/T/DemoTake-Previews/take_m3ehbyc0k7qv2x9d/contact-sheet-all.png",
  "width": 1600,
  "height": 1068
}
TOOLREAD-ONLYReview

take_frame

Frame preview

One frame of a take as an image: scene + time (scene-local seconds, as recorded) or output_time (seconds in the edited output, as exported). Use it to check both sides of a cut before accepting it.

Plain words: Shows one frame of a take as an image, either at a time within a scene (as recorded) or at a time in the finished video (as exported). Handy for checking both sides of a cut.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
scenestringOPTIONAL
Scene handle (the scn_… scene_id that take_create and take_get return), exact title, or 1-based index. scene_id is accepted as an alias.
timenumberOPTIONAL
Scene-local seconds.Min 0.
output_timenumberOPTIONAL
Seconds in the edited output.Min 0.
max_pixel_sizeintegerOPTIONAL
Longest edge of the returned image.Default 1280. Min 256, max 2400.
scene_idstringOPTIONAL
Alias of scene.
takestringOPTIONAL
Alias of take_id.

Good to know

Give scene with time, or output_time on its own; the PNG is returned as an image content block.

Request · what your agent sends
{
  "name": "take_frame",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "scene": "Create invoice",
    "time": 12.5
  }
}
Response · structuredContent
{
  "path": "/var/folders/…/T/DemoTake-Previews/take_m3ehbyc0k7qv2x9d/frame-scn_m3ehbzb9d3kw7tbe-12.50.png",
  "width": 1280,
  "height": 800
}
TOOLREAD-ONLYReview

preview_frame

Preview frame

The whole composed frame of the edited timeline at an output time, as a PNG — what the export will show there: crop, camera, background, captions, overlays, cursor and redactions (the trial watermark is left out). Use it after edits instead of exporting: it also reports the scene and scene-local source time shown, the crop, the part of the recording in view (viewport, normalized source coordinates) and the caption. output_time is seconds in the edited output (timeline_get); aspect picks the format.

Plain words: Shows the finished video's frame at a time in the edited output, exactly as the export will draw it: crop, camera, captions, overlays, cursor and blurs. Use it after an edit instead of exporting.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
output_timenumberREQUIRED
Seconds in the edited output.Min 0.
aspectenumOPTIONAL
Output format.One of 16:9, 9:16, 4:3, 1:1. Default "16:9".
max_pixel_sizeintegerOPTIONAL
Longest edge of the returned image.Default 1280. Min 256, max 2400.
takestringOPTIONAL
Alias of take_id.

Good to know

The PNG is returned as an image content block. output_time is seconds in the edited video (timeline_get). The trial watermark is left out.

Request · what your agent sends
{
  "name": "preview_frame",
  "arguments": {
    "take_id": "take_m5tq2r8c0vk7wd3n",
    "output_time": 12.5,
    "aspect": "16:9"
  }
}
Response · structuredContent
{
  "path": "/var/folders/…/T/DemoTake-Previews/take_m5tq2r8c0vk7wd3n/edited-16x9-12.50.png",
  "width": 1280,
  "height": 720,
  "format": "16:9",
  "output_time": 12.5,
  "duration": 54.2,
  "time_base": "output",
  "scene_id": "scn_m5tq2r9d4bx1kf6p",
  "scene_title": "Authorize",
  "scene_time": 4.8,
  "viewport": {
    "x": 0,
    "y": 0,
    "width": 1,
    "height": 1
  },
  "caption": "TikTok asks for 2 permissions"
}
TOOLREAD-ONLYReview

preview_clip

Preview clip

A short, low-resolution MP4 of part of the edited timeline (start/end in output seconds, at most 60 s), rendered like the export (crop, camera, captions, overlays, cursor) but small and fast, into a temporary folder. Returns its path, size and frame rate. scale is the size relative to the format's canvas (0.5 = 960×540 for 16:9). Use it to check motion (camera moves, cursor, speed-ups, transitions) before exporting.

Plain words: Renders a short, small MP4 of part of the edited video, so you can check motion (camera moves, cursor, speed-ups, scene cuts) without a full export.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
startnumberREQUIRED
Output seconds where the clip starts.Min 0.
endnumberREQUIRED
Output seconds where it ends.Min 0.
scalenumberOPTIONAL
Size relative to the canvas.Default 0.5. Min 0.2, max 1.
aspectenumOPTIONAL
Output format.One of 16:9, 9:16, 4:3, 1:1. Default "16:9".
takestringOPTIONAL
Alias of take_id.

Good to know

At most 60 seconds. scale is relative to the format's canvas (0.5 = 960×540 for 16:9).

Request · what your agent sends
{
  "name": "preview_clip",
  "arguments": {
    "take_id": "take_m5tq2r8c0vk7wd3n",
    "start": 10,
    "end": 24,
    "scale": 0.5
  }
}
Response · structuredContent
Preview clip 10.0–24.0 s (960×540, 30 fps, 1.2 MB): …/clip-16x9-10.0-24.0.mp4
{
  "path": "/var/folders/…/T/DemoTake-Previews/take_m5tq2r8c0vk7wd3n/clip-16x9-10.0-24.0.mp4",
  "format": "16:9",
  "start": 10,
  "end": 24,
  "duration": 14,
  "width": 960,
  "height": 540,
  "fps": 30,
  "file_size_bytes": 1184322
}
TOOLReview

edit_revert

Revert edit

Revert one edit by the edit_id that edit_apply (or any edit_* tool) returned. Later edits that touched other things are kept; list recent ids with edit_history.

Plain words: Undoes one earlier edit by its edit_id. Later edits that changed other things are kept.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
edit_idstringREQUIRED
edt_… handle returned by edit_apply.
takestringOPTIONAL
Alias of take_id.
Request · what your agent sends
{
  "name": "edit_revert",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "edit_id": "edt_m3ehy8a0h5tx2wqe"
  }
}
Response · structuredContent
Reverted edt_m3ehy8a0h5tx2wqe. Output is now 0:50.
{
  "take_id": "take_m3ehbyc0k7qv2x9d",
  "name": "Create invoice",
  "status": "verified",
  "assertions_passed": "3/3",
  "source_duration": 52.4,
  "edits": {
    "compress_waits": {
      "threshold": 1,
      "to": 0.4
    }
  },
  "next": "Edit (edit_* / edit_command), then export_render.",
  "reverted_edit_id": "edt_m3ehy8a0h5tx2wqe",
  "duration": 49.8
}
TOOLREAD-ONLYReview

edit_history

Edit history

Recent edits applied through edit_apply / edit_* tools, newest first, with their edit_id (for edit_revert) and whether they were reverted.

Plain words: Lists recent edits to a take, newest first, with the edit_id you need to undo one and whether it was already undone.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
takestringOPTIONAL
Alias of take_id.

Good to know

source is "agent" for MCP edits, "editor" for edits made in the app and "command" for command-bar edits.

Request · what your agent sends
{
  "name": "edit_history",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d"
  }
}
Response · structuredContent
2 recent edit(s).
{
  "edits": [
    {
      "edit_id": "edt_m3ehz5m0e8vr2tjc",
      "applied_at": "2026-09-26T10:06:40Z",
      "source": "agent",
      "summary": [
        "Pointer Calm"
      ]
    },
    {
      "edit_id": "edt_m3ehy8a0h5tx2wqe",
      "applied_at": "2026-09-26T10:04:12Z",
      "source": "agent",
      "summary": [
        "Trim scene (head 1.5s, tail –)",
        "Camera → punch",
        "Caption “One click to a client-ready PDF”"
      ],
      "reverted_at": "2026-09-26T10:07:03Z"
    }
  ]
}
Next call
TOOLREAD-ONLYReview

review_check

Check for platform review

Check a reviewer take against what the platform's reviewer looks for, and get a short paste-ready checklist for the review form (checklist). Checks: the website domain the video shows (from browser-mode URLs or navigation events) matches app_url, and the address bar is visible; every declared scope has a scene in the cut that shows it (scenes[].shows_scopes); consent screens (scenes that show scopes, and consent screens edit_suggest_cuts found) stay on screen at least 3 s; and the latest export's format and size (TikTok app review: MP4 or MOV, at most 50 MB; for Meta, Google and Apple only the format is checked). Each check is pass, fail, warn or unknown with a fix. Uses the take's preset (take_create {platform, app_url, scopes}); platform/app_url/scopes passed here apply to this check only. Read-only: never changes the take (its preset, purpose, style or edits).

Plain words: Checks a review recording against what the platform's reviewer looks for: the website domain shown and the address bar, a scene for every scope, consent screens long enough to read, and the exported file. It also writes a checklist to paste into the review form. It never changes the take.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
platformenumOPTIONAL
Platform to check for (default: the take's preset; this check only).One of tiktok, meta_app_review, google_oauth, apple_review.
app_urlstringOPTIONAL
The website URL declared in the review form.
scopesstring[]OPTIONAL
Scopes / permissions the review covers.
takestringOPTIONAL
Alias of take_id.

Good to know

Uses the take's preset from take_create {platform, app_url, scopes}; platform, app_url and scopes passed here apply to this check only. Each check is pass, fail, warn or unknown, with a fix when it isn't a pass.

Request · what your agent sends
{
  "name": "review_check",
  "arguments": {
    "take_id": "take_m5tq2r8c0vk7wd3n"
  }
}
Response · structuredContent
Ready for TikTok for Developers app review. Checklist for the review form: …
{
  "take_id": "take_m5tq2r8c0vk7wd3n",
  "platform": "tiktok",
  "passed": true,
  "checks": [
    {
      "id": "domain",
      "title": "Website domain visible",
      "status": "pass",
      "detail": "Shows example.com and tiktok.com in the address bar; matches the app URL."
    },
    {
      "id": "scopes",
      "title": "Every scope demonstrated",
      "status": "pass",
      "detail": "user.info.basic and video.upload each have a scene in the cut."
    },
    {
      "id": "consent_readable",
      "title": "Consent screens readable",
      "status": "pass",
      "detail": "The consent screen stays on screen for 6.2 s."
    },
    {
      "id": "file",
      "title": "Video file within the upload limits",
      "status": "pass",
      "detail": "MP4, 31.4 MB (limit 50 MB)."
    }
  ],
  "domains_shown": [
    "example.com",
    "tiktok.com"
  ],
  "scope_scenes": {
    "user.info.basic": [
      "Authorize"
    ],
    "video.upload": [
      "Draft in TikTok inbox"
    ]
  },
  "export_path": "/Users/you/Movies/DemoTake/Projects/…/exports/tiktok-review-16x9-20261026-141902.mp4",
  "checklist": "Demo video: tiktok-review-16x9-20261026-141902.mp4 (MP4, 31.4 MB, 0:54)\nWebsite shown: example.com (matches the app URL https://example.com)\nSteps shown:\n…"
}
TOOLExport

export_render

Render

Render outputs locally (16:9, 9:16, 4:3, 1:1, gif, screenshots, reviewer_pack, guide, interactive). Returns job ids immediately; pass wait=true to block until done (progress is reported); export_cancel stops a job. Each video export preflights its clips, reads any clip that won't decode from a compatible H.264 copy (reported in fallbacks), and validates the finished MP4 before completing; failures carry a diagnosis. quality: "high" (default; 60 fps, large files) or "upload" (H.264 at 30 fps with a bitrate tuned for app recordings: small files for upload forms and review portals). max_mb picks the bitrate so the MP4 lands under that size (MB of 1,000,000 bytes; encoding again at a lower bitrate if the first encode comes out too big). Completed jobs report file_size_bytes / file_size_mb, over_limit (with max_mb), and platform_limits (TikTok app review: MP4 or MOV, at most 50 MB); an export still over max_mb is completed with a warning. Quality and max_mb apply to the video formats; GIF, screenshots and guides ignore them. A take with the TikTok review preset exports at quality "upload", max_mb 45 unless you pass quality or max_mb. subtitles:["srt","vtt","txt","md"] writes subtitle/transcript files next to each video (timed to the cut; listed in the job's side_files); embed_subtitles:true also adds a soft subtitle track players can switch on. subtitle_source: auto (the voiceover when there is one, else the captions), captions or narration. A Reviewer Pack always carries captions.vtt/.srt (when there's something said) and transcript.md. Localized takes: languages:["source","de","sv"] (or "all") renders each format once per language — the take written in that language, its voiceover and on-screen text callouts — with the language in the file name (-de, -sv) and per-language subtitles, transcripts, Guide and Reviewer Pack; subtitle_languages:["all"] with embed_subtitles:true puts one soft subtitle track per language (tagged with its language) into each MP4. "interactive" is the click-through demo (interactive_build / interactive_export): one job for all its languages, a folder with index.html and a ZIP. resolution: "1080p" (default), "2160p" (4K: 3840×2160 for 16:9, 2160×3840 for 9:16) or "native" (the recording's own pixels, 1080p up to 2160p, never upscaled). Everything drawn (pointer, captions, keystrokes, overlays) is laid out exactly as at 1080p, with more pixels. 4K from a smaller recording is upscaled and says so in warnings. format:"app_preview" makes an App Store app preview: device iphone_6_9 (886×1920), iphone_6_5, iphone_6_3, iphone_6_1, iphone_5_8, iphone_5_5 (1080×1920), iphone_4_7 (750×1334), ipad_13 / ipad_12_9 / ipad_11 / ipad_10_5 (1200×1600), ipad_9_7 (900×1200), mac and apple_tv (1920×1080), vision_pro (3840×2160); portrait or landscape; 30 fps H.264 High Profile Level 4.0 at about 11 Mbit/s with stereo 256 kbit/s AAC (silent when the take has no sound); the app fills the frame (no backdrop or device frame). Apple accepts 15–30 s: fit "speed" speeds a long cut up (target_duration) or holds the last frame of a short one, "trim" ends a long one at 29.5 s. A poster frame PNG (poster_time, default 5 s) is taken from the finished video, and app_preview in the job reports the check against Apple's specification (problems, warnings such as prices in on-screen text, the poster time code). app_preview_upload sends it to App Store Connect. codec: automatic (HEVC for high-quality exports above 1080p, H.264 otherwise), "h264" (most compatible; 4K60 needs H.264 level 5.2) or "hevc". max_mb still caps the file at any resolution. export_preflight {resolution} estimates the size first.

Plain words: Renders the finished outputs on your Mac: landscape or vertical video, GIF, screenshots, a reviewer pack or a written step-by-step guide. It returns job ids right away, or waits for the renders when wait is true.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
formatsenum[]OPTIONAL
Output formats: "16:9" (landscape), "9:16" (vertical), "4:3", "1:1", "gif", "screenshots", "reviewer_pack" (conservative cut + manifest ZIP), "guide" (written step-by-step guide: guide.md + index.html + screenshots), "interactive" (click-through HTML demo: index.html + player + step images, folder + ZIP).One of 16:9, 9:16, 4:3, 1:1, gif, screenshots, reviewer_pack, guide, interactive, app_preview.
qualityenumOPTIONAL
Encoding preset.One of high, upload. Default "high".
max_mbnumberOPTIONAL
Largest MP4 size in MB (1 MB = 1,000,000 bytes), e.g. 45 for a 50 MB upload limit.Min 1.
resolutionenumOPTIONAL
Output size of video formats.One of 1080p, 2160p, native. Default "1080p".
codecenumOPTIONAL
Video codec (default: HEVC for high-quality exports above 1080p, else H.264).One of h264, hevc.
formatenumOPTIONAL
One output format (instead of formats), e.g. "app_preview".One of 16:9, 9:16, 4:3, 1:1, gif, screenshots, reviewer_pack, guide, interactive, app_preview.
deviceenumOPTIONAL
app_preview: the App Store display family.One of iphone_6_9, iphone_6_5, iphone_6_3, iphone_6_1, iphone_5_8, iphone_5_5, iphone_4_7, ipad_13, ipad_12_9, ipad_11, ipad_10_5, ipad_9_7, mac, apple_tv, vision_pro. Default "iphone_6_9".
orientationenumOPTIONAL
app_preview: portrait or landscape (default: the recording's shape; Mac, Apple TV and Vision Pro are landscape).One of portrait, landscape.
poster_timenumberOPTIONAL
app_preview: output seconds of the poster frame (default 5, Apple's default).Min 0, max 30.
fitenumOPTIONAL
app_preview: land within 15–30 s by speeding up (or holding the last frame), trimming, or not at all.One of none, speed, trim. Default "none".
subtitlesenum[]OPTIONAL
Subtitle / transcript files.One of srt, vtt, txt, md.
subtitle_sourceenumOPTIONAL
What the subtitles say: auto (the voiceover when the take has one, else the captions), captions, narration.One of auto, captions, narration. Default "auto".
embed_subtitlesbooleanOPTIONAL
Add a soft subtitle track to the MP4.Default false.
languagesstring[]OPTIONAL
Export once per language (default: the take's own language).
subtitle_languagesstring[]OPTIONAL
With embed_subtitles: one subtitle track per language in each MP4.
waitbooleanOPTIONAL
Wait for the renders to finish.Default false.
timeoutnumberOPTIONAL
Max seconds to wait.Default 900. Min 5, max 3600.
takestringOPTIONAL
Alias of take_id.

Good to know

Without wait the jobs come back queued; poll export_status. Formats default to the take's outputs; a failed job carries a diagnosis. quality "upload" makes small H.264 files for upload forms, and max_mb keeps each MP4 under a size: jobs then report file_size_mb and over_limit. A take with the TikTok review preset exports at quality "upload", max_mb 45 unless you pass either.

Request · what your agent sends
{
  "name": "export_render",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "formats": [
      "16:9",
      "9:16"
    ],
    "wait": true
  }
}
Response · structuredContent
2 job(s): 2 completed.
{
  "jobs": [
    {
      "job_id": "exp_m3ej19z0b8mc3rkf",
      "take_id": "take_m3ehbyc0k7qv2x9d",
      "format": "16:9",
      "status": "completed",
      "progress": 1,
      "output_path": "/Users/you/Movies/DemoTake/Projects/ledgerly--prj_m119ecc0t4w8nq2h/Takes/create-invoice--take_m3ehbyc0k7qv2x9d.take/exports/create-invoice-16x9-20260926-101204.mp4",
      "validation": {
        "ok": true,
        "path": "/Users/you/Movies/DemoTake/Projects/ledgerly--prj_m119ecc0t4w8nq2h/Takes/create-invoice--take_m3ehbyc0k7qv2x9d.take/exports/create-invoice-16x9-20260926-101204.mp4",
        "duration": 41.8,
        "expected_duration": 41.8,
        "width": 1920,
        "height": 1080,
        "expected_width": 1920,
        "expected_height": 1080,
        "frames_decoded": [
          0,
          20.9,
          41.77
        ]
      },
      "duration": 41.8,
      "sha256": "3b7e5a0c9d14f2e86a1b47c3d9e0f5a2b6c8d1e4f7a0b3c6d9e2f5a8b1c4d7e0",
      "completed_at": "2026-09-26T10:12:31Z"
    },
    {
      "job_id": "exp_m3ej19z1q2dz7vhn",
      "take_id": "take_m3ehbyc0k7qv2x9d",
      "format": "9:16",
      "status": "completed",
      "progress": 1,
      "output_path": "/Users/you/Movies/DemoTake/Projects/ledgerly--prj_m119ecc0t4w8nq2h/Takes/create-invoice--take_m3ehbyc0k7qv2x9d.take/exports/create-invoice-9x16-20260926-101204.mp4",
      "duration": 41.8,
      "sha256": "9a41c0e7b2d85f36e1a9c4b07d2e8f5a3c6b9d0e1f4a7b2c5d8e0f3a6b9c2d5e",
      "completed_at": "2026-09-26T10:12:58Z"
    }
  ]
}
TOOLREAD-ONLYExport

export_preflight

Export preflight

Read-only check before exporting: decodes the first, middle and last frame of every clip range the cut uses (through the same pipeline export_render uses) and returns one result per clip: scene, clip file, codec, the ranges used, the frames sampled and, for a clip that fails, a diagnosis (source/output time, error domain/code, underlying error). export_render runs this automatically and reads a failing clip from a compatible H.264 copy. For video formats it also estimates the export (estimate: width, height, fps, codec, bitrate, estimated_mb, frame memory, and notes such as 4K upscaling a smaller recording) for the resolution, quality, max_mb and codec given.

Plain words: Checks, without exporting, that every recorded clip the edit uses can be read: it decodes the first, middle and last frame of each clip and explains any that fail.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
formatenumOPTIONAL
Output format to check.One of 16:9, 9:16, 4:3, 1:1, gif, screenshots, reviewer_pack, guide, interactive, app_preview. Default "16:9".
resolutionenumOPTIONAL
Output size to estimate.One of 1080p, 2160p, native. Default "1080p".
qualityenumOPTIONAL
Encoding preset to estimate.One of high, upload. Default "high".
max_mbnumberOPTIONAL
Size cap to estimate with, MB of 1,000,000 bytes.Min 1.
codecenumOPTIONAL
Video codec to estimate.One of h264, hevc.
takestringOPTIONAL
Alias of take_id.

Good to know

export_render runs this check itself; a clip that fails is read from a compatible H.264 copy and reported in fallbacks.

Request · what your agent sends
{
  "name": "export_preflight",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "format": "16:9"
  }
}
Response · structuredContent
All 3 clip(s) decode (9 frames checked).
{
  "take_id": "take_m3ehbyc0k7qv2x9d",
  "format": "16:9",
  "ok": true,
  "duration": 41.8,
  "clips": [
    {
      "scene_id": "scn_m3ehbzb8a1fr6mzp",
      "scene_title": "Sign in",
      "scene_number": 1,
      "segment_id": "seg_m3ehdrz0w2jq8rts",
      "clip_file": "media/seg_m3ehdrz0w2jq8rts.mov",
      "codec": "HEVC (hvc1)",
      "pixel_width": 2560,
      "pixel_height": 1600,
      "status": "ok",
      "used_ranges": [
        {
          "start": 1.5,
          "end": 11.8
        }
      ],
      "samples": [
        {
          "output_time": 0,
          "source_time": 1.5,
          "ok": true
        },
        {
          "output_time": 4.8,
          "source_time": 6.65,
          "ok": true
        },
        {
          "output_time": 9.58,
          "source_time": 11.78,
          "ok": true
        }
      ]
    }
  ]
}
Next call
TOOLREAD-ONLYExport

export_validate

Validate export

Check a finished video (job_id from export_render, or an MP4/MOV path): it opens, has a video track, its duration matches the edit plan (± a frame) and its size the format, and its first, middle and last frames decode. Reports the file size; with max_mb a bigger file is invalid ("over limit"), and files over a known platform limit (TikTok app review: MP4/MOV ≤ 50 MB) get a warning. export_render already does this before reporting a job completed.

Plain words: Double-checks a finished video: that it opens, has a picture, matches the planned length and size, and that its first, middle and last frames decode.

Parameters

job_idstringOPTIONAL
exp_… handle.
pathstringOPTIONAL
Absolute path of a video file.
max_mbnumberOPTIONAL
Size limit to check against, MB of 1,000,000 bytes.Min 1.
jobstringOPTIONAL
Alias of job_id.

Good to know

Give job_id or an absolute path to an MP4/MOV; export_render already runs this before it marks a job completed.

Request · what your agent sends
{
  "name": "export_validate",
  "arguments": {
    "job_id": "exp_m3ej19z0b8mc3rkf"
  }
}
Response · structuredContent
Valid video.
{
  "ok": true,
  "path": "/Users/you/Movies/DemoTake/Projects/ledgerly--prj_m119ecc0t4w8nq2h/Takes/create-invoice--take_m3ehbyc0k7qv2x9d.take/exports/create-invoice-16x9-20260926-101204.mp4",
  "duration": 41.8,
  "expected_duration": 41.8,
  "width": 1920,
  "height": 1080,
  "expected_width": 1920,
  "expected_height": 1080,
  "frames_decoded": [
    0,
    20.9,
    41.77
  ]
}
TOOLREAD-ONLYExport

app_preview_check

Check app preview

Check a video against Apple's App Store app preview specification for a display family: accepted size, 15–30 s, at most 30 fps, H.264 up to High Profile Level 4.0 (or ProRes 422 HQ in a MOV), stereo AAC at 44.1 or 48 kHz, MOV/M4V/MP4, at most 500 MB. Give an app_preview export's job_id (its device is known) or a path with a device. Returns ok, problems (what App Store Connect would reject) and warnings, plus the App Store Connect display type (preview_type).

Plain words: Checks a video against Apple's App Store app preview rules for one display (size, 15–30 seconds, frame rate, codec, stereo audio, file size) and lists anything App Store Connect would reject.

Parameters

job_idstringOPTIONAL
exp_… handle of an app_preview export.
pathstringOPTIONAL
Absolute path of a video file.
deviceenumOPTIONAL
Display family.One of iphone_6_9, iphone_6_5, iphone_6_3, iphone_6_1, iphone_5_8, iphone_5_5, iphone_4_7, ipad_13, ipad_12_9, ipad_11, ipad_10_5, ipad_9_7, mac, apple_tv, vision_pro.
jobstringOPTIONAL
Alias of job_id.
Request · what your agent sends
{
  "name": "app_preview_check",
  "arguments": {
    "job_id": "exp_m3ej2b8c0d1f4g5h"
  }
}
Response · structuredContent
Meets the iPhone 6.9" app preview specification.
{
  "device": "iphone_6_9",
  "device_name": "iPhone 6.9\"",
  "preview_type": "IPHONE_67",
  "orientation": "portrait",
  "ok": true,
  "problems": [],
  "poster_time": 5,
  "poster_time_code": "00:00:05:00",
  "poster_path": "/Users/you/Movies/DemoTake/Library/Ledgerly.take/exports/create-invoice-app_preview-20261027-1012-poster.png",
  "fitted": "Sped up from 41.3 s to 29.5 s to fit App Store's 30 s."
}
TOOLExport

app_preview_upload

Upload app preview

Upload a finished app_preview export to App Store Connect with the user's own API key (set up in DemoTake Settings › App Store Connect; the key stays in this Mac's Keychain and is never sent to DemoTake). It finds the app (bundle_id), its App Store version (version, in Prepare for Submission) and the locale's localization (created if missing), the preview set for the export's display type (created if missing; at most three previews each), reserves the preview, uploads it, and commits it with the poster frame time code. Apple then processes the video for up to 24 hours. Refuses a preview that fails app_preview_check unless force:true.

Plain words: Uploads a finished App Store preview to your app's version in App Store Connect, using the API key you added in DemoTake's settings, and sets its poster frame.

Parameters

job_idstringREQUIRED
exp_… handle of a completed app_preview export.
bundle_idstringREQUIRED
The app's bundle ID.
versionstringREQUIRED
App Store version string, e.g. 2.3.
localestringOPTIONAL
App Store locale.Default "en-US".
platformenumOPTIONAL
App Store Connect platform (default: from the device).One of IOS, MAC_OS, TV_OS, VISION_OS.
forcebooleanOPTIONAL
Upload even if the check found problems.Default false.
jobstringOPTIONAL
Alias of job_id.
Request · what your agent sends
{
  "name": "app_preview_upload",
  "arguments": {
    "job_id": "exp_m3ej2b8c0d1f4g5h",
    "bundle_id": "com.example.ledgerly",
    "version": "2.3",
    "locale": "en-US"
  }
}
Response · structuredContent
Uploaded IPHONE_67 preview a1b2c3d4-0000-1111-2222-333344445555 for com.example.ledgerly 2.3 (en-US): UPLOAD_COMPLETE. Apple processes it for up to 24 hours.
{
  "bundle_id": "com.example.ledgerly",
  "version": "2.3",
  "locale": "en-US",
  "preview_type": "IPHONE_67",
  "app_preview_id": "a1b2c3d4-0000-1111-2222-333344445555",
  "app_preview_set_id": "f0e1d2c3-4444-5555-6666-777788889999",
  "state": "UPLOAD_COMPLETE",
  "bytes": 40812233,
  "uploaded_at": "2026-10-27T10:14:02Z"
}
TOOLREAD-ONLYExport

export_status

Export status

Status of one render job (job_id), or all exports of a take (take_id) with output paths. A failed job carries diagnosis (scene, clip file, source/output time, codec, error domain/code, underlying error, whether a compatible copy was tried, and copyable details); a completed one lists fallbacks (clips read from a compatible copy) and its validation.

Plain words: Shows the progress of one render job, or every export of a take with its output file. Failed jobs explain what went wrong.

Parameters

job_idstringOPTIONAL
exp_… handle.
take_idstringOPTIONAL
Take handle.
takestringOPTIONAL
Alias of take_id.
jobstringOPTIONAL
Alias of job_id.

Good to know

With take_id instead of job_id you get {exports: [...], requested_outputs: [...]}; status is queued, rendering, completed, failed or cancelled.

Request · what your agent sends
{
  "name": "export_status",
  "arguments": {
    "job_id": "exp_m3ej19z0b8mc3rkf"
  }
}
Response · structuredContent
{
  "job_id": "exp_m3ej19z0b8mc3rkf",
  "take_id": "take_m3ehbyc0k7qv2x9d",
  "format": "16:9",
  "status": "rendering",
  "progress": 0.46,
  "phase": "rendering"
}
TOOLREAD-ONLYExport

export_manifest

Proof manifest

Verified Take manifest: app version/build, macOS version, scenes and attempts, assertion results with timestamps, video SHA-256, source commit and an honest list of edits applied. Suitable for App Store reviewers.

Plain words: Produces the proof manifest for a take: app version, macOS version, scenes and attempts, assertion results, the video's SHA-256 and an honest list of the edits applied. Made for App Store reviewers.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
takestringOPTIONAL
Alias of take_id.

Good to know

The manifest uses camelCase keys; the video hash comes from the latest completed 16:9 export.

Request · what your agent sends
{
  "name": "export_manifest",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d"
  }
}
Response · structuredContent
3/3 assertions passed.
{
  "takeID": "take_m3ehbyc0k7qv2x9d",
  "flow": "Create an invoice for a new customer and export it as PDF.",
  "appName": "Ledgerly",
  "bundleID": "com.example.Ledgerly",
  "appVersion": "2.3.1",
  "buildNumber": "418",
  "macOSVersion": "Version 26.0 (Build 25A354)",
  "timestamp": "2026-09-26T10:14:03Z",
  "assertionsPassed": 3,
  "assertionsTotal": 3,
  "assertions": [
    {
      "title": "Signed in",
      "status": "passed",
      "takeTime": 10.9
    },
    {
      "title": "Invoice created",
      "status": "passed",
      "takeTime": 34.62
    },
    {
      "title": "Flow completed successfully",
      "status": "passed"
    }
  ],
  "scenes": [
    {
      "title": "Sign in",
      "status": "recorded",
      "attempts": 1
    },
    {
      "title": "Create invoice",
      "status": "recorded",
      "attempts": 2
    },
    {
      "title": "Export PDF",
      "status": "recorded",
      "attempts": 1
    }
  ],
  "sourceCommit": "9f3c2e1a7b",
  "videoSHA256": "3b7e5a0c9d14f2e86a1b47c3d9e0f5a2b6c8d1e4f7a0b3c6d9e2f5a8b1c4d7e0",
  "videoFile": "create-invoice-16x9-20260926-101204.mp4",
  "demotakeVersion": "1.0.0",
  "edition": "agent",
  "editDisclosures": [
    "Waits over 1.0 s shortened to 0.4 s (still visible).",
    "Scene heads/tails trimmed.",
    "Some scenes were re-recorded; each scene is a single continuous take.",
    "Pointer is a presentation layer synthesized from recorded actions."
  ]
}
TOOLREAD-ONLYDemo as code

spec_validate

Validate demotake.json

Check a demotake.json spec (demo as code) and list errors/warnings with JSON paths. Pure check; nothing runs.

Plain words: Checks a demotake.json file (a demo written as code) and lists any errors or warnings with their JSON paths. Nothing runs.

Parameters

specobject | stringOPTIONAL
The demotake.json spec: an object, or its JSON text. See demotake schema / spec_validate for the format.
pathstringOPTIONAL
Path to a demotake.json readable by DemoTake (alternative to spec).

Good to know

Pass the spec inline as spec (object or JSON text) or point path at a file DemoTake can read.

Request · what your agent sends
{
  "name": "spec_validate",
  "arguments": {
    "spec": {
      "version": 1,
      "target": {
        "bundle_id": "com.example.Ledgerly"
      },
      "takes": [
        {
          "name": "Create invoice",
          "scenes": [
            {
              "title": "Sign in",
              "steps": [
                {
                  "action": "type",
                  "secret_env": "DEMO_PASSWORD",
                  "element": {
                    "identifier": "password-field"
                  }
                },
                {
                  "action": "key",
                  "keys": "return"
                },
                {
                  "action": "assert_text",
                  "text": "Invoices"
                }
              ]
            },
            {
              "title": "Create invoice",
              "steps": [
                {
                  "action": "click",
                  "element": {
                    "role": "button",
                    "title": "New Invoice"
                  }
                },
                {
                  "action": "type",
                  "text": "Northwind Studio",
                  "element": {
                    "identifier": "customer-field"
                  }
                },
                {
                  "action": "assert_text",
                  "text": "INV-0042"
                }
              ]
            }
          ]
        }
      ]
    }
  }
}
Response · structuredContent
Valid.
{
  "valid": true,
  "errors": [],
  "warnings": [],
  "takes": [
    {
      "name": "Create invoice",
      "scenes": 2,
      "steps": 6
    }
  ],
  "secret_env": [
    "DEMO_PASSWORD"
  ]
}
Next call
DEMOTAKE AGENT ONLYDemo as code

spec_run

Run demotake.json

Run a demotake.json spec: DemoTake operates the app scene by scene (Rehearse → Take), checkpoints each scene, retries only a failing scene, verifies assert_* steps and (with record=true) records and renders the outputs. record=false is a DemoTest run (no video). only_changed=true regenerates only scenes whose UI changed vs the last recording. Returns per-scene pass/fail with evidence. Long-running: send a progress token to stream progress.

Plain words: Runs a demotake.json spec from start to finish (DemoTake Agent only): DemoTake operates the app scene by scene, retries only a failing scene, checks the assertions and, when recording, renders the outputs. With record: false it's a test run with no video.

Parameters

specobject | stringOPTIONAL
The demotake.json spec: an object, or its JSON text. See demotake schema / spec_validate for the format.
pathstringOPTIONAL
Path to demotake.json (alternative to spec).
takestringOPTIONAL
Only this take of the spec (by name).
recordbooleanOPTIONAL
Record video. false = DemoTest: run the steps and assertions only.Default true.
rehearsebooleanOPTIONAL
Rehearsal pass before recording (defaults to the spec's defaults.rehearse).
only_changedbooleanOPTIONAL
Release regeneration: re-record only scenes whose UI changed vs the baseline take; unchanged scenes keep their footage and edits.Default false.
baseline_take_idstringOPTIONAL
Baseline take for diffs (default: the latest recorded take of the same spec take).
outputsenum[]OPTIONAL
Output formats: "16:9" (landscape), "9:16" (vertical), "4:3", "1:1", "gif", "screenshots", "reviewer_pack" (conservative cut + manifest ZIP), "guide" (written step-by-step guide: guide.md + index.html + screenshots), "interactive" (click-through HTML demo: index.html + player + step images, folder + ZIP).One of 16:9, 9:16, 4:3, 1:1, gif, screenshots, reviewer_pack, guide, interactive, app_preview.
wait_renderbooleanOPTIONAL
Wait for renders to finish before returning.Default true.
purposeenumOPTIONAL
Override the purpose.One of marketing, reviewer, tutorial, test.
attemptsintegerOPTIONAL
Attempts per scene before it fails.Min 1, max 10.
allow_foregroundbooleanOPTIONAL
Ask for real mouse/keyboard fallbacks when no background-safe path exists. Works only when the user turned on foreground control in DemoTake's Settings; otherwise the run fails with an error saying so.Default false.
secretsobjectOPTIONAL
Values for the spec's secret_env references, e.g. {"DEMO_PASSWORD": "…"}. Used for this run only; never logged or stored.
project_idstringOPTIONAL
Project for new takes.
source_commitstringOPTIONAL
Git commit being demoed/tested (recorded in manifests).
spec_pathstringOPTIONAL
Where the spec lives (for reports).
take_idstringOPTIONAL
Alias of take.
projectstringOPTIONAL
Alias of project_id.

Good to know

Long-running: send a progress token to stream scene-by-scene progress; secrets are used for this run only and never stored.

Request · what your agent sends
{
  "name": "spec_run",
  "arguments": {
    "path": "/Users/you/Code/ledgerly/demotake.json",
    "only_changed": true,
    "outputs": [
      "16:9"
    ],
    "secrets": {
      "DEMO_PASSWORD": "…"
    },
    "source_commit": "a41d9e7"
  }
}
Response · structuredContent
PASS Create invoice: PASS · 3 scene(s) · 1 of 3 scene(s) changed · 1 regenerated, 2 kept
{
  "passed": true,
  "takes": [
    {
      "name": "Create invoice",
      "take_id": "take_m3ekc4r0n6vd8pqa",
      "passed": true,
      "recorded": true,
      "rehearsed": false,
      "scenes": [
        {
          "title": "Sign in",
          "scene_id": "scn_m3ekc4r1b2hx7jmt",
          "status": "passed",
          "attempts": 0,
          "duration": 2.1,
          "failures": [],
          "assertions_passed": 1,
          "assertions_total": 1,
          "reused": true
        },
        {
          "title": "Create invoice",
          "scene_id": "scn_m3ekc4r2w9dq3fzn",
          "status": "passed",
          "attempts": 1,
          "duration": 27.4,
          "failures": [],
          "assertions_passed": 1,
          "assertions_total": 1,
          "reused": false
        },
        {
          "title": "Export PDF",
          "scene_id": "scn_m3ekc4r3k5vp8tgc",
          "status": "passed",
          "attempts": 0,
          "duration": 1.8,
          "failures": [],
          "assertions_passed": 1,
          "assertions_total": 1,
          "reused": true
        }
      ],
      "duration": 58.3,
      "exports": [
        {
          "id": "exp_m3ekd7s0t1mr4hwb",
          "takeID": "take_m3ekc4r0n6vd8pqa",
          "format": "16:9",
          "status": "completed",
          "progress": 1,
          "outputPath": "/Users/you/Movies/DemoTake/Projects/ledgerly--prj_m119ecc0t4w8nq2h/Takes/create-invoice--take_m3ekc4r0n6vd8pqa.take/exports/create-invoice-16x9-20260926-110842.mp4",
          "createdAt": "2026-09-26T11:08:13Z",
          "completedAt": "2026-09-26T11:08:42Z",
          "duration": 42.6
        }
      ],
      "diff": {
        "take_id": "take_m3ekc4r0n6vd8pqa",
        "baseline_take_id": "take_m3ehbyc0k7qv2x9d",
        "scenes": [
          {
            "title": "Sign in",
            "status": "unchanged",
            "score": 0.003,
            "reasons": []
          },
          {
            "title": "Create invoice",
            "status": "changed",
            "score": 0.31,
            "reasons": [
              "6.4% of the checkpoint snapshot changed"
            ]
          },
          {
            "title": "Export PDF",
            "status": "unchanged",
            "score": 0.002,
            "reasons": []
          }
        ]
      },
      "baseline_take_id": "take_m3ehbyc0k7qv2x9d"
    }
  ],
  "started_at": "2026-09-26T11:07:10Z",
  "duration": 92.5,
  "record": true,
  "spec_path": "/Users/you/Code/ledgerly/demotake.json"
}
DEMOTAKE AGENT ONLYDemo as code

take_replay

Replay a take

Re-perform a recorded take's steps (its demotake spec, or steps derived from its trace). record=true re-records it in place (only_changed keeps unchanged scenes' footage); record=false runs it as a DemoTest.

Plain words: Performs a recorded take's steps again (DemoTake Agent only). Use record: false to check the flow still works after a change, or record: true to re-record it in place.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
recordbooleanOPTIONAL
Record video. false = DemoTest: run the steps and assertions only.Default true.
rehearsebooleanOPTIONAL
Rehearsal pass before recording (defaults to the spec's defaults.rehearse).
only_changedbooleanOPTIONAL
Release regeneration: re-record only scenes whose UI changed vs the baseline take; unchanged scenes keep their footage and edits.Default false.
baseline_take_idstringOPTIONAL
Baseline take for diffs (default: the latest recorded take of the same spec take).
outputsenum[]OPTIONAL
Output formats: "16:9" (landscape), "9:16" (vertical), "4:3", "1:1", "gif", "screenshots", "reviewer_pack" (conservative cut + manifest ZIP), "guide" (written step-by-step guide: guide.md + index.html + screenshots), "interactive" (click-through HTML demo: index.html + player + step images, folder + ZIP).One of 16:9, 9:16, 4:3, 1:1, gif, screenshots, reviewer_pack, guide, interactive, app_preview.
wait_renderbooleanOPTIONAL
Wait for renders to finish before returning.Default true.
purposeenumOPTIONAL
Override the purpose.One of marketing, reviewer, tutorial, test.
attemptsintegerOPTIONAL
Attempts per scene before it fails.Min 1, max 10.
allow_foregroundbooleanOPTIONAL
Ask for real mouse/keyboard fallbacks when no background-safe path exists. Works only when the user turned on foreground control in DemoTake's Settings; otherwise the run fails with an error saying so.Default false.
secretsobjectOPTIONAL
Values for the spec's secret_env references, e.g. {"DEMO_PASSWORD": "…"}. Used for this run only; never logged or stored.
project_idstringOPTIONAL
Project for new takes.
source_commitstringOPTIONAL
Git commit being demoed/tested (recorded in manifests).
spec_pathstringOPTIONAL
Where the spec lives (for reports).
takestringOPTIONAL
Alias of take_id.
projectstringOPTIONAL
Alias of project_id.

Good to know

Steps come from the take's demotake spec, or are derived from its trace when it has none.

Request · what your agent sends
{
  "name": "take_replay",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "record": false
  }
}
Response · structuredContent
PASS Create invoice: PASS · 3 scene(s)
{
  "passed": true,
  "takes": [
    {
      "name": "Create invoice",
      "take_id": "take_m3ehbyc0k7qv2x9d",
      "passed": true,
      "recorded": false,
      "rehearsed": false,
      "scenes": [
        {
          "title": "Sign in",
          "scene_id": "scn_m3ehbzb8a1fr6mzp",
          "status": "passed",
          "attempts": 1,
          "duration": 9.4,
          "failures": [],
          "assertions_passed": 1,
          "assertions_total": 1,
          "reused": false
        },
        {
          "title": "Create invoice",
          "scene_id": "scn_m3ehbzb9d3kw7tbe",
          "status": "passed",
          "attempts": 1,
          "duration": 18.2,
          "failures": [],
          "assertions_passed": 1,
          "assertions_total": 1,
          "reused": false
        },
        {
          "title": "Export PDF",
          "scene_id": "scn_m3ehbzbap5hn0cxv",
          "status": "passed",
          "attempts": 1,
          "duration": 10.6,
          "failures": [],
          "assertions_passed": 1,
          "assertions_total": 1,
          "reused": false
        }
      ],
      "duration": 38.2,
      "exports": []
    }
  ],
  "started_at": "2026-09-26T11:03:10Z",
  "duration": 38.9,
  "record": false
}
TOOLREAD-ONLYDemo as code

take_diff

Demo Diff

Which scenes' UI changed between a take and a baseline (accessibility state + perceptual snapshot diff of each scene checkpoint, redactions ignored). Use it to decide what to re-record after a release.

Plain words: Compares a take with an earlier one and tells you which scenes' screens changed, so after a release you re-record only what's different.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
baseline_take_idstringOPTIONAL
Baseline take (default: the previous take of the same spec/flow).
takestringOPTIONAL
Alias of take_id.

Good to know

A scene without checkpoint evidence on both sides is unknown and treated as changed.

Request · what your agent sends
{
  "name": "take_diff",
  "arguments": {
    "take_id": "take_m3ekc4r0n6vd8pqa",
    "baseline_take_id": "take_m3ehbyc0k7qv2x9d"
  }
}
Response · structuredContent
1 of 3 scene(s) changed.
{
  "take_id": "take_m3ekc4r0n6vd8pqa",
  "baseline_take_id": "take_m3ehbyc0k7qv2x9d",
  "scenes": [
    {
      "title": "Sign in",
      "scene_id": "scn_m3ekc4r1b2hx7jmt",
      "baseline_scene_id": "scn_m3ehbzb8a1fr6mzp",
      "status": "unchanged",
      "score": 0.003,
      "text_score": 0,
      "visual_score": 0.003,
      "reasons": []
    },
    {
      "title": "Create invoice",
      "scene_id": "scn_m3ekc4r2w9dq3fzn",
      "baseline_scene_id": "scn_m3ehbzb9d3kw7tbe",
      "status": "changed",
      "score": 0.31,
      "text_score": 0.31,
      "visual_score": 0.064,
      "reasons": [
        "+ button \"Duplicate\"",
        "6.4% of the checkpoint snapshot changed"
      ]
    },
    {
      "title": "Export PDF",
      "scene_id": "scn_m3ekc4r3k5vp8tgc",
      "baseline_scene_id": "scn_m3ehbzbap5hn0cxv",
      "status": "unchanged",
      "score": 0.002,
      "text_score": 0,
      "visual_score": 0.002,
      "reasons": []
    }
  ]
}
TOOLDemo as code

take_to_spec

Save take as code

Convert a take into a demotake.json spec (steps with element queries, assertions, style and edit presets). Secrets become secret_env references. Commit it to the repo and run it with demotake run/test.

Plain words: Turns a recorded take into a demotake.json file (the demo as code: steps, element lookups and assertions) that you can commit and re-run. Secrets become environment-variable references.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
pathstringOPTIONAL
Also write the spec to this file (must be writable by DemoTake; an existing file is replaced).
takestringOPTIONAL
Alias of take_id.

Good to know

Omit path to get the spec back without writing a file; the folder must be writable by DemoTake.

Request · what your agent sends
{
  "name": "take_to_spec",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "path": "/Users/you/Code/ledgerly/demotake.json"
  }
}
Response · structuredContent
demotake.json with 5 step(s), written to /Users/you/Code/ledgerly/demotake.json.
{
  "spec": {
    "$schema": "https://demotake.app/schema/demotake-1.json",
    "version": 1,
    "target": {
      "bundle_id": "com.example.Ledgerly",
      "app_name": "Ledgerly"
    },
    "takes": [
      {
        "name": "Create invoice",
        "goal": "Create an invoice for a new customer and export it as PDF.",
        "outputs": [
          "16:9",
          "9:16"
        ],
        "scenes": [
          {
            "title": "Sign in",
            "intent": "Sign in with the demo account",
            "checkpoint": "Invoices list visible",
            "steps": [
              {
                "action": "type",
                "secret_env": "DEMO_PASSWORD",
                "element": {
                  "identifier": "password-field"
                }
              },
              {
                "action": "key",
                "keys": "return"
              },
              {
                "action": "assert_text",
                "text": "Invoices"
              }
            ]
          },
          {
            "title": "Create invoice",
            "checkpoint": "Invoice INV-0042 open with 2 line items",
            "steps": [
              {
                "action": "click",
                "element": {
                  "role": "button",
                  "title": "New Invoice"
                }
              },
              {
                "action": "type",
                "text": "Northwind Studio",
                "element": {
                  "identifier": "customer-field"
                }
              }
            ]
          }
        ]
      }
    ]
  },
  "path": "/Users/you/Code/ledgerly/demotake.json"
}
TOOLDemo as code

take_export_package

Export take package

Zip a take as a portable .take package (take.json, media, pointer tracks, snapshots; exports optional) for sharing, the Team Library or another Mac.

Plain words: Zips a take into a portable .take package (recording, pointer tracks, snapshots and plan) to share with a teammate, the Team Library or another Mac.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
include_exportsbooleanOPTIONAL
Include rendered exports.Default false.
takestringOPTIONAL
Alias of take_id.

Good to know

Stop any running capture on the take first; rendered exports are left out unless include_exports is true.

Request · what your agent sends
{
  "name": "take_export_package",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "include_exports": false
  }
}
Response · structuredContent
Package: /Users/you/Movies/DemoTake/Packages/create-invoice--take_m3ehbyc0k7qv2x9d.take.zip
{
  "path": "/Users/you/Movies/DemoTake/Packages/create-invoice--take_m3ehbyc0k7qv2x9d.take.zip",
  "bytes": 48213504
}
TOOLDemo as code

take_import_package

Import take package

Import a .take package (folder or .zip, e.g. from the Web Recorder or a teammate) into the library. A colliding take id gets a fresh one.

Plain words: Adds a .take package (a folder or .zip, for example from a teammate or the Web Recorder) to your library.

Parameters

pathstringREQUIRED
Absolute path of the .take folder or .zip.
project_idstringOPTIONAL
Project to import into (default: My Demos).
projectstringOPTIONAL
Alias of project_id.

Good to know

Without project_id the take goes to My Demos; a take id that already exists in the library gets a fresh one.

Request · what your agent sends
{
  "name": "take_import_package",
  "arguments": {
    "path": "/Users/you/Downloads/create-invoice--take_m3ehbyc0k7qv2x9d.take.zip",
    "project_id": "prj_m119ecc0t4w8nq2h"
  }
}
Response · structuredContent
Imported take_m3ehbyc0k7qv2x9d (“Create invoice”, 3 scene(s)).
{
  "take_id": "take_m3ehbyc0k7qv2x9d",
  "project_id": "prj_m119ecc0t4w8nq2h",
  "name": "Create invoice",
  "status": "verified",
  "scenes": [
    {
      "scene_id": "scn_m3ehbzb8a1fr6mzp",
      "index": 1,
      "title": "Sign in",
      "status": "recorded",
      "attempts": 1,
      "duration": 11.8
    },
    {
      "scene_id": "scn_m3ehbzb9d3kw7tbe",
      "index": 2,
      "title": "Create invoice",
      "status": "recorded",
      "attempts": 2,
      "duration": 24.3
    },
    {
      "scene_id": "scn_m3ehbzbap5hn0cxv",
      "index": 3,
      "title": "Export PDF",
      "status": "recorded",
      "attempts": 1,
      "duration": 16.3
    }
  ],
  "assertions_passed": "3/3",
  "source_duration": 52.4,
  "next": "Edit (edit_* / edit_command), then export_render."
}
TOOLREAD-ONLYStore screenshots

screenshot_formats

Screenshot formats

Store and web screenshot sizes DemoTake renders exactly: App Store (iPhone 6.9″/6.5″/6.3″/6.1″, iPad 13″, Mac, Apple TV, Vision Pro), Google Play (phone, 7″ and 10″ tablet, Chromebook, feature graphic) and web (16:9, Open Graph 1200 × 630, square). Each has an id, pixel size, default device frame and the store page it comes from.

Plain words: Lists every store and web screenshot size DemoTake can render exactly: App Store iPhone, iPad, Mac, Apple TV and Vision Pro, Google Play phone, tablet and Chromebook, and web sizes such as the 1200 × 630 link preview. Use the ids (or the short names) in screenshot_set_create, screenshot_compose and specs.

Parameters

storeenumOPTIONAL
Only this store.One of app_store, google_play, web.

Good to know

Store formats always export without transparency, because the App Store and Google Play reject images with an alpha channel.

Request · what your agent sends
{
  "name": "screenshot_formats",
  "arguments": {
    "store": "google_play"
  }
}
Response · structuredContent
6 format(s).
{
  "formats": [
    {
      "id": "play-phone",
      "store": "google_play",
      "name": "Phone, portrait (9:16)",
      "width": 1080,
      "height": 1920,
      "device_class": "phone",
      "default_frame": "phone",
      "required": false,
      "folder": "google-play/phone",
      "source": "https://support.google.com/googleplay/android-developer/answer/9866151"
    },
    {
      "id": "play-tablet-10",
      "store": "google_play",
      "name": "10-inch tablet (16:9)",
      "width": 2560,
      "height": 1440,
      "device_class": "tablet",
      "default_frame": "tablet",
      "required": false,
      "folder": "google-play/tablet-10",
      "source": "https://support.google.com/googleplay/android-developer/answer/9866151"
    }
  ],
  "aliases": {
    "iphone": [
      "appstore-iphone-6.9"
    ],
    "ipad": [
      "appstore-ipad-13"
    ],
    "play": [
      "play-phone"
    ],
    "og": [
      "web-og"
    ]
  }
}
TOOLStore screenshots

screenshot_set_create

Create screenshot set

Create a Screenshot Set: the captures (shots) of one app, their headlines, a style and the output formats. Stored in the library like takes. Then capture screens into it with screenshot_capture.

Plain words: Creates a Screenshot Set: the place where one app's screens, their headlines, a style and the output formats live. Pick the formats and the look now or later with screenshot_compose.

Parameters

namestringREQUIRED
Set name, e.g. "Tidewell App Store".
project_idstringOPTIONAL
Existing project (project_…).
project_namestringOPTIONAL
Project to use or create by name.
formatsstring[]OPTIONAL
Output formats. Each renders at its exact pixel size.
targetstring | objectOPTIONAL
Target app/window/device. Either a target_id from targets_list ("window:1234", "app:com.example.App", "pid:4321", "display:1", "sim:<UDID>" for a booted iOS Simulator device, "android:<serial>" for an Android emulator or device, a URL) or an object; {url_contains:"example.com"} picks the browser window whose tab shows that URL (and keeps following that window across navigations). target_id is accepted as an alias. Defaults to the take's target.
12 fields
target_idstringOPTIONAL
id from targets_list
bundle_idstringOPTIONAL
app_namestringOPTIONAL
window_titlestringOPTIONAL
window_idintegerOPTIONAL
pidintegerOPTIONAL
display_idintegerOPTIONAL
urlstringOPTIONAL
url_containsstringOPTIONAL
Browser window whose tab URL contains this text, e.g. a domain
device_udidstringOPTIONAL
iOS Simulator device UDID
serialstringOPTIONAL
Android adb serial (emulator-5554, a USB serial)
kindenumOPTIONAL
One of window, application, display, web, simulator, android.
backgroundstringOPTIONAL
Background: a preset (indigo, sky, lavender, mint, blush, sand, midnight, ocean, graphite, aurora, white, black), "transparent" (web formats only; store formats get white), a hex color "#0F172A" or a gradient "#0F172A,#1E3A8A".
device_frameenumOPTIONAL
Frame drawn around the capture (generic shapes, no product artwork). auto = phone for phone formats, tablet for tablets, laptop for Mac/Chromebook, window for web.One of auto, none, phone, tablet, laptop, window.
frame_toneenumOPTIONAL
Frame body color.One of graphite, silver.
typographyenumOPTIONAL
Type style of the headline.One of modern, rounded, editorial.
text_colorstringOPTIONAL
Headline color: "auto" (white on dark backgrounds, ink on light ones) or a hex color.
text_positionenumOPTIONAL
Headline above or below the device.One of top, bottom.
fitenumOPTIONAL
How the capture fills the device screen: smart (fill when the shapes are close, otherwise fit), fill (crop from the top) or fit (show everything).One of smart, fill, fit.
shadowbooleanOPTIONAL
Soft shadow under the device.
headlinestringOPTIONAL
Set-wide headline for shots that don't have their own ("" clears it).
subheadlinestringOPTIONAL
Set-wide subheadline ("" clears it).
target_idstring | objectOPTIONAL
Alias of target.
12 fields
target_idstringOPTIONAL
id from targets_list
bundle_idstringOPTIONAL
app_namestringOPTIONAL
window_titlestringOPTIONAL
window_idintegerOPTIONAL
pidintegerOPTIONAL
display_idintegerOPTIONAL
urlstringOPTIONAL
url_containsstringOPTIONAL
Browser window whose tab URL contains this text, e.g. a domain
device_udidstringOPTIONAL
iOS Simulator device UDID
serialstringOPTIONAL
Android adb serial (emulator-5554, a USB serial)
kindenumOPTIONAL
One of window, application, display, web, simulator, android.
projectstringOPTIONAL
Alias of project_id.
Request · what your agent sends
{
  "name": "screenshot_set_create",
  "arguments": {
    "name": "Ledgerly App Store",
    "formats": [
      "iphone",
      "ipad",
      "play",
      "og"
    ],
    "background": "midnight",
    "device_frame": "auto",
    "typography": "modern"
  }
}
Response · structuredContent
Created screenshot set shots_01j9w3k2m4n5p6q7 with 4 format(s).
{
  "set_id": "shots_01j9w3k2m4n5p6q7",
  "name": "Ledgerly App Store",
  "project_id": "prj_01j8k2v5t9x3r1m7",
  "formats": [
    {
      "id": "appstore-iphone-6.9",
      "name": "iPhone 6.9″ display",
      "size": "1320 × 2868"
    },
    {
      "id": "appstore-ipad-13",
      "name": "iPad 13″ display",
      "size": "2064 × 2752"
    },
    {
      "id": "play-phone",
      "name": "Phone, portrait (9:16)",
      "size": "1080 × 1920"
    },
    {
      "id": "web-og",
      "name": "Open Graph / link preview",
      "size": "1200 × 630"
    }
  ],
  "style": {
    "background": "midnight",
    "device_frame": "auto",
    "frame_tone": "graphite",
    "typography": "modern",
    "text_color": "auto",
    "text_position": "top",
    "fit": "smart",
    "shadow": true
  },
  "shots": [],
  "next": "screenshot_capture {set_id, target, shot} for each screen you want."
}
TOOLREAD-ONLYStore screenshots

screenshot_set_get

Get screenshot set

A Screenshot Set's shots (capture paths, sizes, headlines, redactions with ids, and what Secret Guard blurred: capture.secret_guard.regions with id, kind and whether it's blurred), style and formats. Without set_id or set_name, lists the sets in the library.

Plain words: Shows a Screenshot Set: each shot with its capture file, size, headline and hidden regions, plus the style and formats. Call it without a set to list every set in the library.

Parameters

set_idstringOPTIONAL
Screenshot Set handle (shots_…) from screenshot_set_create or screenshot_set_get.
set_namestringOPTIONAL
Set by name.
project_idstringOPTIONAL
When listing: only sets in this project.
screenshot_set_idstringOPTIONAL
Alias of set_id.
projectstringOPTIONAL
Alias of project_id.
Request · what your agent sends
{
  "name": "screenshot_set_get",
  "arguments": {
    "set_id": "shots_01j9w3k2m4n5p6q7"
  }
}
Response · structuredContent
{
  "set_id": "shots_01j9w3k2m4n5p6q7",
  "name": "Ledgerly App Store",
  "shots": [
    {
      "shot_id": "shot_01j9w3m8r2t4v6x8",
      "name": "Invoices",
      "headline": "Every invoice at a glance",
      "captured": true,
      "capture": {
        "path": "/Users/you/Movies/DemoTake/Projects/ledgerly--prj_01j8k2v5t9x3r1m7/Screenshots/ledgerly-app-store--shots_01j9w3k2m4n5p6q7.shots/captures/cap_01j9w3m8.png",
        "width": 2560,
        "height": 1600,
        "scale": 2,
        "source": "Ledgerly — Invoices",
        "secret_regions_blurred": 1
      },
      "redactions": []
    }
  ]
}
TOOLStore screenshots

screenshot_capture

Capture a screenshot

Capture one screen of the app into a Screenshot Set at native (Retina) resolution: a window or app (covered windows are captured where macOS allows), an iOS Simulator device (target "sim:<UDID>", DemoTake Agent), an Android emulator or device (target "android:<serial>", DemoTake Agent), a whole display, or a rectangle of the screen in points. Secret Guard blurs secrets it reads before the image is saved (redact:false turns that off; regions turned off with screenshot_compose's secret_guard.ignore stay off when the shot is captured again); redact_regions hides more at render time. Reusing a shot name replaces that shot's capture and keeps its words. DemoTake Agent can reach the screen first with steps (the demotake.json step vocabulary), e.g. steps:[{"click":"Settings"},{"wait":"Preferences"}]. Returns the capture and a small preview image.

Plain words: Takes one sharp screenshot of the real app and adds it to a set: a window (even when it's covered by other windows), an iOS Simulator device, a whole display or a rectangle of the screen. Secrets it can read are blurred before the image is saved. In DemoTake Agent it can first click its way to the right screen with steps, so "go to settings and capture it" is one call.

Parameters

set_idstringOPTIONAL
Screenshot Set handle (shots_…) from screenshot_set_create or screenshot_set_get.
set_namestringOPTIONAL
Set to add to by name (created if missing). Default: "Screenshots".
project_idstringOPTIONAL
Project for a set created here.
targetstring | objectOPTIONAL
Target app/window/device. Either a target_id from targets_list ("window:1234", "app:com.example.App", "pid:4321", "display:1", "sim:<UDID>" for a booted iOS Simulator device, "android:<serial>" for an Android emulator or device, a URL) or an object; {url_contains:"example.com"} picks the browser window whose tab shows that URL (and keeps following that window across navigations). target_id is accepted as an alias. Defaults to the take's target.
12 fields
target_idstringOPTIONAL
id from targets_list
bundle_idstringOPTIONAL
app_namestringOPTIONAL
window_titlestringOPTIONAL
window_idintegerOPTIONAL
pidintegerOPTIONAL
display_idintegerOPTIONAL
urlstringOPTIONAL
url_containsstringOPTIONAL
Browser window whose tab URL contains this text, e.g. a domain
device_udidstringOPTIONAL
iOS Simulator device UDID
serialstringOPTIONAL
Android adb serial (emulator-5554, a USB serial)
kindenumOPTIONAL
One of window, application, display, web, simulator, android.
displayintegerOPTIONAL
Capture a whole display (display id from targets_list include_displays; 0 = main display).Min 0.
rectobjectOPTIONAL
Capture this rectangle of the screen (global points, top-left origin). Uses display when given, else the display it's on.
4 fields
xnumberREQUIRED
points from the main display's left
ynumberREQUIRED
points from the top
widthnumberREQUIRED
pointsMin 1.
heightnumberREQUIRED
pointsMin 1.
shotstringOPTIONAL
Shot name, e.g. "Dashboard" (identifies it across captures and in file names).
scenestringOPTIONAL
Alias of shot (a take's scene title).
headlinestringOPTIONAL
Headline for this shot.
subheadlinestringOPTIONAL
Subheadline for this shot.
redactbooleanOPTIONAL
Secret Guard: blur text that looks secret (emails, keys, card numbers…) before saving.Default true.
redact_regionsobject[]OPTIONAL
Regions to hide in every rendered screenshot of the shot, normalized to the capture (0…1, top-left).
4 fields
xnumberREQUIRED
left, 0…1Min 0, max 1.
ynumberREQUIRED
top, 0…1Min 0, max 1.
widthnumberREQUIRED
0…1Min 0, max 1.
heightnumberREQUIRED
0…1Min 0, max 1.
stepsobject[]OPTIONAL
DemoTake Agent: steps to reach the screen first (click, type, key, scroll, wait, assert_*), as in demotake.json.
allow_foregroundbooleanOPTIONAL
Let steps take the real mouse/keyboard when no background-safe path exists (only when the user turned on foreground control in DemoTake's Settings).Default false.
secretsobjectOPTIONAL
Values for secret_env references in steps (this call only).
scene_idstringOPTIONAL
Alias of scene.
target_idstring | objectOPTIONAL
Alias of target.
12 fields
target_idstringOPTIONAL
id from targets_list
bundle_idstringOPTIONAL
app_namestringOPTIONAL
window_titlestringOPTIONAL
window_idintegerOPTIONAL
pidintegerOPTIONAL
display_idintegerOPTIONAL
urlstringOPTIONAL
url_containsstringOPTIONAL
Browser window whose tab URL contains this text, e.g. a domain
device_udidstringOPTIONAL
iOS Simulator device UDID
serialstringOPTIONAL
Android adb serial (emulator-5554, a USB serial)
kindenumOPTIONAL
One of window, application, display, web, simulator, android.
screenshot_set_idstringOPTIONAL
Alias of set_id.
projectstringOPTIONAL
Alias of project_id.
shot_idstringOPTIONAL
Alias of shot.

Good to know

Reusing a shot name replaces its image and keeps its headline and hidden regions. Pass display for a whole display, or rect {x, y, width, height} in screen points for an area. Steps need DemoTake Agent; in DemoTake Studio, open the screen with your own tools first.

Request · what your agent sends
{
  "name": "screenshot_capture",
  "arguments": {
    "set_id": "shots_01j9w3k2m4n5p6q7",
    "target": "window:4127",
    "shot": "Settings",
    "headline": "Reminders your way",
    "steps": [
      {
        "key": "cmd+,"
      },
      {
        "wait": "General"
      }
    ]
  }
}
Response · structuredContent
Captured “Settings” (2560 × 1600).
{
  "set_id": "shots_01j9w3k2m4n5p6q7",
  "shot": {
    "shot_id": "shot_01j9w3q1s3u5w7y9",
    "name": "Settings",
    "headline": "Reminders your way",
    "captured": true,
    "capture": {
      "width": 2560,
      "height": 1600,
      "scale": 2,
      "source": "Ledgerly — Settings",
      "secret_regions_blurred": 0
    }
  },
  "path": "/Users/you/Movies/DemoTake/Projects/ledgerly--prj_01j8k2v5t9x3r1m7/Screenshots/ledgerly-app-store--shots_01j9w3k2m4n5p6q7.shots/captures/cap_01j9w3q1.png",
  "created": true,
  "secret_regions_blurred": 0,
  "shots_in_set": 2
}
TOOLStore screenshots

screenshot_compose

Compose screenshots

Set how a Screenshot Set's shots are rendered: formats, background, device frame (generic phone, tablet, laptop or window), headline typography and per-shot headlines, subheadlines and redactions (add regions, remove them by id, or turn off a Secret Guard blur the detector got wrong with secret_guard:{ignore:["sg2"]}). Saves the set and returns downscaled previews of every shot × format (the first as an image) so you can check the result before screenshot_export.

Plain words: Sets how the screenshots look: the headline and subheadline on each shot, the background, the device frame, the type style and the formats. It saves the set and returns small previews of every shot in every format, with the first one as an image, so you can check the result before exporting.

Parameters

set_idstringREQUIRED
Screenshot Set handle (shots_…) from screenshot_set_create or screenshot_set_get.
formatsstring[]OPTIONAL
Output formats. Each renders at its exact pixel size.
shotsobject[]OPTIONAL
Per-shot words and redactions.
11 fields
shotstringREQUIRED
Shot id, name or 1-based index.
headlinestringOPTIONAL
Headline ("" clears it).
subheadlinestringOPTIONAL
Subheadline ("" clears it).
renamestringOPTIONAL
New shot name.
redact_regionsobject[]OPTIONAL
Regions to hide in every rendered screenshot of the shot, normalized to the capture (0…1, top-left).
4 fields
xnumberREQUIRED
left, 0…1Min 0, max 1.
ynumberREQUIRED
top, 0…1Min 0, max 1.
widthnumberREQUIRED
0…1Min 0, max 1.
heightnumberREQUIRED
0…1Min 0, max 1.
redaction_styleenumOPTIONAL
How added regions are hidden.One of pixelate, solid.
clear_redactionsbooleanOPTIONAL
Remove the shot's redactions first.
remove_redactionsstring[]OPTIONAL
Remove these redactions.
secret_guardobjectOPTIONAL
Turn Secret Guard's automatic blurs off or back on, per region. Only for regions the detector got wrong: a turned-off region shows its text in exports. Captures from DemoTake 1.2 and earlier have their blurs applied for good (editable: false).
2 fields
ignorestring[]OPTIONAL
Turn these blurs off (the text shows in every output). They stay off when the shot is captured again.
restorestring[]OPTIONAL
Turn these blurs back on.
excludedbooleanOPTIONAL
Leave this shot out of exports.
formatsstring[]OPTIONAL
Output formats. Each renders at its exact pixel size.
orderstring[]OPTIONAL
New shot order (shots not listed keep their relative order at the end).
previewbooleanOPTIONAL
Render previews.Default true.
max_pixel_sizeintegerOPTIONAL
Longest side of each preview.Default 640. Min 128, max 2048.
backgroundstringOPTIONAL
Background: a preset (indigo, sky, lavender, mint, blush, sand, midnight, ocean, graphite, aurora, white, black), "transparent" (web formats only; store formats get white), a hex color "#0F172A" or a gradient "#0F172A,#1E3A8A".
device_frameenumOPTIONAL
Frame drawn around the capture (generic shapes, no product artwork). auto = phone for phone formats, tablet for tablets, laptop for Mac/Chromebook, window for web.One of auto, none, phone, tablet, laptop, window.
frame_toneenumOPTIONAL
Frame body color.One of graphite, silver.
typographyenumOPTIONAL
Type style of the headline.One of modern, rounded, editorial.
text_colorstringOPTIONAL
Headline color: "auto" (white on dark backgrounds, ink on light ones) or a hex color.
text_positionenumOPTIONAL
Headline above or below the device.One of top, bottom.
fitenumOPTIONAL
How the capture fills the device screen: smart (fill when the shapes are close, otherwise fit), fill (crop from the top) or fit (show everything).One of smart, fill, fit.
shadowbooleanOPTIONAL
Soft shadow under the device.
headlinestringOPTIONAL
Set-wide headline for shots that don't have their own ("" clears it).
subheadlinestringOPTIONAL
Set-wide subheadline ("" clears it).
screenshot_set_idstringOPTIONAL
Alias of set_id.

Good to know

Frames are generic phone, tablet, laptop and window shapes drawn by DemoTake. device_frame: auto picks the right one per format.

Request · what your agent sends
{
  "name": "screenshot_compose",
  "arguments": {
    "set_id": "shots_01j9w3k2m4n5p6q7",
    "background": "ocean",
    "typography": "rounded",
    "shots": [
      {
        "shot": "Invoices",
        "headline": "Every invoice at a glance",
        "subheadline": "Paid, due and overdue on one screen."
      },
      {
        "shot": "Settings",
        "redact_regions": [
          {
            "x": 0.62,
            "y": 0.08,
            "width": 0.3,
            "height": 0.05
          }
        ]
      }
    ],
    "order": [
      "Invoices",
      "Settings"
    ]
  }
}
Response · structuredContent
Saved “Ledgerly App Store”: 2 shot(s) × 4 format(s).
{
  "set_id": "shots_01j9w3k2m4n5p6q7",
  "previews": [
    {
      "shot_id": "shot_01j9w3m8r2t4v6x8",
      "shot": "Invoices",
      "format": "appstore-iphone-6.9",
      "width": 295,
      "height": 640,
      "path": "/Users/you/…/previews/invoices--appstore-iphone-6.9.png"
    }
  ]
}
TOOLStore screenshots

screenshot_export

Export screenshots

Render every shot × format of a Screenshot Set at its exact store size into folders per store and device (app-store/iphone-6.9/01-dashboard.png …) with a manifest.json (sizes, SHA-256). PNG by default (no alpha for store formats, as the stores require), or JPEG. Identical inputs give identical files.

Plain words: Renders every shot in every format at its exact store size, into one folder per store and device, with a manifest.json listing each file's size and SHA-256. The same captures and settings always give the same files.

Parameters

set_idstringREQUIRED
Screenshot Set handle (shots_…) from screenshot_set_create or screenshot_set_get.
formatsstring[]OPTIONAL
Output formats. Each renders at its exact pixel size.
shotsstring[]OPTIONAL
Only these shots (default: every captured shot).
file_typeenumOPTIONAL
File type.One of png, jpeg. Default "png".
jpeg_qualitynumberOPTIONAL
JPEG quality.Default 0.92. Min 0.3, max 1.
out_dirstringOPTIONAL
Also copy the export tree to this folder (must be writable by DemoTake).
screenshot_set_idstringOPTIONAL
Alias of set_id.

Good to know

Pass file_type: "jpeg" for JPEG, formats or shots to export part of the set, and out_dir to also copy the files somewhere DemoTake can write.

Request · what your agent sends
{
  "name": "screenshot_export",
  "arguments": {
    "set_id": "shots_01j9w3k2m4n5p6q7"
  }
}
Response · structuredContent
Exported 8 screenshot(s) to /Users/you/…/exports.
{
  "set_id": "shots_01j9w3k2m4n5p6q7",
  "root": "/Users/you/Movies/DemoTake/Projects/ledgerly--prj_01j8k2v5t9x3r1m7/Screenshots/ledgerly-app-store--shots_01j9w3k2m4n5p6q7.shots/exports",
  "rendered": 8,
  "reused": 0,
  "manifest": {
    "version": 1,
    "generator": "DemoTake",
    "set": "Ledgerly App Store",
    "files": [
      {
        "path": "app-store/iphone-6.9/01-invoices.png",
        "format": "appstore-iphone-6.9",
        "shot": "Invoices",
        "width": 1320,
        "height": 2868,
        "bytes": 1482311,
        "sha256": "4b8e…",
        "headline": "Every invoice at a glance"
      }
    ],
    "warnings": []
  }
}
TOOLStore screenshots

screenshot_run

Run screenshots as code

Run the screenshots section of a demotake.json: for each shot, reach the screen with its steps (DemoTake Agent), capture it, compare it with the previous capture and render every format. only_changed:true keeps shots whose screen didn't change (same files, byte for byte). Returns per-shot pass/fail with diffs and the export manifest. Specs without steps also run in DemoTake Studio. This is what demotake screenshots run calls.

Plain words: Runs the screenshots section of a demotake.json: it reaches each screen with the shot's steps, captures it, compares it with the last capture and renders every format. With only_changed, screens that didn't change keep their files byte for byte. This is what demotake screenshots run calls in CI.

Parameters

specobject | stringOPTIONAL
The demotake.json spec: an object, or its JSON text. See demotake schema / spec_validate for the format.
pathstringOPTIONAL
Path to demotake.json (alternative to spec).
shotsstring[]OPTIONAL
Only these shots.
formatsstring[]OPTIONAL
Output formats. Each renders at its exact pixel size.
only_changedbooleanOPTIONAL
Keep shots whose screen didn't change since the last run.Default false.
file_typeenumOPTIONAL
File type.One of png, jpeg.
exportbooleanOPTIONAL
Render after capturing.Default true.
allow_foregroundbooleanOPTIONAL
Allow real mouse/keyboard fallbacks in steps (only when the user turned on foreground control in DemoTake's Settings).Default false.
secretsobjectOPTIONAL
Values for secret_env references (this run only; never stored).
project_idstringOPTIONAL
Project for a set created by this run.
spec_pathstringOPTIONAL
Where the spec lives (for reports).
projectstringOPTIONAL
Alias of project_id.

Good to know

Shots with steps need DemoTake Agent. A failing shot fails the run and nothing is exported, so a broken build never overwrites good screenshots.

Request · what your agent sends
{
  "name": "screenshot_run",
  "arguments": {
    "path": "/Users/you/code/ledgerly/demotake.json",
    "only_changed": true
  }
}
Response · structuredContent
PASS Ledgerly store screenshots: PASS · 2 scene(s) · 1 of 2 scene(s) changed · 1 regenerated, 1 kept
{
  "set_id": "shots_01j9w3k2m4n5p6q7",
  "run": {
    "passed": true,
    "takes": [
      {
        "name": "Ledgerly store screenshots",
        "take_id": "shots_01j9w3k2m4n5p6q7",
        "passed": true,
        "scenes": [
          {
            "title": "Invoices",
            "status": "passed",
            "reused": true,
            "diff": {
              "title": "Invoices",
              "status": "unchanged",
              "score": 0.002
            }
          },
          {
            "title": "Settings",
            "status": "passed",
            "reused": false,
            "diff": {
              "title": "Settings",
              "status": "changed",
              "score": 0.14,
              "reasons": [
                "14.0% of the checkpoint snapshot changed"
              ]
            }
          }
        ]
      }
    ]
  },
  "export": {
    "rendered": 4,
    "reused": 4
  }
}
TOOLREAD-ONLYOverlays

overlay_templates

Overlay templates

Built-in overlay templates (study/pomodoro timer, progress bar, lower third, title, callout, animated chart, number counter, spotlight, keyboard shortcut, confetti, end card) with their parameters and defaults, plus the authoring rules for custom HTML/CSS and 3D scenes (variables, bindings, limits). Read before overlay_add.

Plain words: Lists the built-in overlay templates (study timer, progress bar, lower third, title, callout, animated chart, number counter, spotlight, keyboard shortcut, confetti, end card) with every parameter and its default, plus the rules for custom HTML/CSS and 3D scenes.

Parameters

guidebooleanOPTIONAL
Include the full authoring guide (custom HTML/CSS, bindings, 3D schema).Default true.

Good to know

guide:true (the default) adds the authoring guide: CSS variables (--t, --p, --scene…), data-bind bindings and formats, sanitizer rules and the 3D scene schema.

Request · what your agent sends
{
  "name": "overlay_templates",
  "arguments": {
    "guide": false
  }
}
Response · structuredContent
{
  "templates": [
    {
      "id": "pomodoro-timer",
      "name": "Study timer",
      "category": "Timers",
      "aliases": [
        "pomodoro",
        "timer",
        "study-timer",
        "study-with-me"
      ],
      "default_placement": {
        "anchor": "top-right",
        "size": 0.26,
        "aspect": 1.55,
        "margin": 0.035
      },
      "params": [
        {
          "name": "focusMinutes",
          "label": "Focus",
          "kind": "number",
          "default": 25,
          "min": 1,
          "max": 240
        },
        {
          "name": "breakMinutes",
          "label": "Break",
          "kind": "number",
          "default": 5,
          "min": 0,
          "max": 120
        },
        {
          "name": "style",
          "label": "Style",
          "kind": "choice",
          "default": "glass",
          "options": [
            "minimal",
            "glass",
            "bold"
          ]
        }
      ]
    }
  ]
}
Next call
TOOLOverlays

overlay_add

Add overlay

Add an effects layer over the video: a built-in template with params (see overlay_templates), or custom html + css (sanitized: no scripts, no remote URLs; time via CSS variables --t/--p and data-bind bindings; animations are seeked frame-exactly), with timing (whole video, a scene, a range or an event) and placement. The overlay is validated and a test frame is rendered (blank or broken output is rejected); it's an ordinary edit (edit_id, edit_revert). 3D scenes: scene3d_create.

Plain words: Adds an effect over the video: a template with parameters, or your own HTML and CSS. DemoTake checks it, renders a test frame (a blank one is rejected) and saves it as an ordinary, undoable edit.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
templatestringOPTIONAL
Template id (pomodoro-timer, progress-bar, lower-third, title-card, callout, chart, counter, spotlight, keys, confetti, end-card).
paramsobjectOPTIONAL
Template (or custom) parameters; missing ones use defaults.
htmlstringOPTIONAL
Custom overlay markup (sanitized subset).
cssstringOPTIONAL
Custom overlay CSS (sanitized subset).
namestringOPTIONAL
Display name.
timingobjectOPTIONAL
When the overlay shows. Omit for the whole video.
5 fields
startnumberOPTIONAL
Take anchor: output seconds. Scene anchor: scene-local seconds. Event anchor: offset after the event.
endnumberOPTIONAL
End (same clock as start). Omit for the end of the take/scene.
durationnumberOPTIONAL
Seconds (event anchor, or instead of end).Min 0.
scenestringOPTIONAL
Anchor to a scene: id, title or 1-based number.
eventstringOPTIONAL
Anchor to an event: id or label ("Publish").
placementobjectOPTIONAL
Where the overlay sits. Omit for the template's default.
6 fields
fullbooleanOPTIONAL
Cover the whole frame.
anchorenumOPTIONAL
Corner/edge placement that keeps its shape in 16:9, 9:16 and 1:1.One of top-left, top, top-right, left, center, right, bottom-left, bottom, bottom-right.
sizenumberOPTIONAL
Anchor: height as a fraction of the frame's short side.Min 0.02, max 1.
aspectnumberOPTIONAL
Anchor: width ÷ height.Min 0.1, max 10.
marginnumberOPTIONAL
Anchor: margin as a fraction of the short side.Min 0, max 0.3.
rectobjectOPTIONAL
Region {x, y, width, height} normalized to the recorded frame (0…1, top-left origin), not pixels. w/h are accepted for width/height; other keys are rejected.
4 fields
xnumberREQUIRED
left, 0…1Min 0, max 1.
ynumberREQUIRED
top, 0…1Min 0, max 1.
widthnumberREQUIRED
0…1Min 0, max 1.
heightnumberREQUIRED
0…1Min 0, max 1.
layerenumOPTIONAL
Stacking: above everything (default), below captions, or below the cursor.One of top, below-captions, below-cursor.
zintegerOPTIONAL
Order within the layer (higher is on top).Min -100, max 100.
opacitynumberOPTIONAL
0–1.Min 0, max 1.
respect_redactionsbooleanOPTIONAL
Re-apply the take's redactions over this overlay.
takestringOPTIONAL
Alias of take_id.

Good to know

Custom overlays: pass html and css instead of template. Timing: {start, end} in output seconds, {scene: "3"} for a scene, or {event: "Publish", duration: 3}. Scripts, event handlers and remote URLs are removed.

Request · what your agent sends
{
  "name": "overlay_add",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "template": "pomodoro-timer",
    "params": {
      "focusMinutes": 50,
      "breakMinutes": 10,
      "label": "Chapter 3 notes"
    },
    "placement": {
      "anchor": "top-right"
    }
  }
}
Response · structuredContent
{
  "take_id": "take_m3ehbyc0k7qv2x9d",
  "overlay": {
    "id": "ovl_m3ek2c7h9d4pq1za",
    "name": "Study timer",
    "source": {
      "kind": "template",
      "template": "pomodoro-timer",
      "params": {
        "focusMinutes": 50,
        "breakMinutes": 10,
        "label": "Chapter 3 notes"
      }
    },
    "timing": {},
    "placement": {
      "anchor": "top-right",
      "size": 0.28,
      "aspect": 1.6,
      "margin": 0.04
    },
    "layer": "top",
    "z": 0,
    "opacity": 1,
    "enabled": true,
    "seed": 1,
    "output_range": {
      "start": 0,
      "end": 94.2
    },
    "pixel_rect_16x9": {
      "x": 1156,
      "y": 43,
      "width": 484,
      "height": 302
    }
  },
  "edit_id": "edt_m3ek2c7j0v6b3n8w"
}
TOOLOverlays

overlay_update

Update overlay

Change an overlay with a JSON merge patch of its fields: {"params":{…}} (template/custom params), {"html","css"}, {"timing":{…}}, {"placement":{…}}, {"layer"}, {"z"}, {"opacity"}, {"name"}, {"enabled":false} to hide it. Re-validated and render-checked; returns an edit_id.

Plain words: Changes an overlay: its parameters, HTML/CSS, timing, placement, layer, opacity or name. Only the fields you send change.

Parameters

overlay_idstringREQUIRED
Overlay handle (ovl_…).
take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
paramsobjectOPTIONAL
Merged into the params (null removes one).
htmlstringOPTIONAL
New custom markup.
cssstringOPTIONAL
New custom CSS.
enabledbooleanOPTIONAL
Show (true) or hide (false) without removing.
namestringOPTIONAL
Display name.
timingobjectOPTIONAL
When the overlay shows. Omit for the whole video.
5 fields
startnumberOPTIONAL
Take anchor: output seconds. Scene anchor: scene-local seconds. Event anchor: offset after the event.
endnumberOPTIONAL
End (same clock as start). Omit for the end of the take/scene.
durationnumberOPTIONAL
Seconds (event anchor, or instead of end).Min 0.
scenestringOPTIONAL
Anchor to a scene: id, title or 1-based number.
eventstringOPTIONAL
Anchor to an event: id or label ("Publish").
placementobjectOPTIONAL
Where the overlay sits. Omit for the template's default.
6 fields
fullbooleanOPTIONAL
Cover the whole frame.
anchorenumOPTIONAL
Corner/edge placement that keeps its shape in 16:9, 9:16 and 1:1.One of top-left, top, top-right, left, center, right, bottom-left, bottom, bottom-right.
sizenumberOPTIONAL
Anchor: height as a fraction of the frame's short side.Min 0.02, max 1.
aspectnumberOPTIONAL
Anchor: width ÷ height.Min 0.1, max 10.
marginnumberOPTIONAL
Anchor: margin as a fraction of the short side.Min 0, max 0.3.
rectobjectOPTIONAL
Region {x, y, width, height} normalized to the recorded frame (0…1, top-left origin), not pixels. w/h are accepted for width/height; other keys are rejected.
4 fields
xnumberREQUIRED
left, 0…1Min 0, max 1.
ynumberREQUIRED
top, 0…1Min 0, max 1.
widthnumberREQUIRED
0…1Min 0, max 1.
heightnumberREQUIRED
0…1Min 0, max 1.
layerenumOPTIONAL
Stacking: above everything (default), below captions, or below the cursor.One of top, below-captions, below-cursor.
zintegerOPTIONAL
Order within the layer (higher is on top).Min -100, max 100.
opacitynumberOPTIONAL
0–1.Min 0, max 1.
respect_redactionsbooleanOPTIONAL
Re-apply the take's redactions over this overlay.
takestringOPTIONAL
Alias of take_id.
overlaystringOPTIONAL
Alias of overlay_id.

Good to know

enabled:false hides an overlay without removing it.

Request · what your agent sends
{
  "name": "overlay_update",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "overlay_id": "ovl_m3ek2c7h9d4pq1za",
    "params": {
      "style": "bold"
    },
    "timing": {
      "scene": "Deep work"
    }
  }
}
Response · structuredContent
{
  "take_id": "take_m3ehbyc0k7qv2x9d",
  "overlay": {
    "id": "ovl_m3ek2c7h9d4pq1za",
    "name": "Study timer",
    "timing": {
      "scene": "scn_m3ehbzb9d3kw7tbe"
    }
  },
  "edit_id": "edt_m3ek2d1q8r2m5t0c"
}
TOOLOverlays

overlay_remove

Remove overlay

Remove an overlay (or a whole 3D scene). Returns an edit_id that edit_revert undoes.

Plain words: Removes an overlay (or a whole 3D scene) from the take.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
overlay_idstringREQUIRED
Overlay handle (ovl_…).
takestringOPTIONAL
Alias of take_id.
overlaystringOPTIONAL
Alias of overlay_id.
Request · what your agent sends
{
  "name": "overlay_remove",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "overlay_id": "ovl_m3ek2c7h9d4pq1za"
  }
}
Response · structuredContent
{
  "take_id": "take_m3ehbyc0k7qv2x9d",
  "overlays": [],
  "edit_id": "edt_m3ek2e5x3y7k1p9d"
}
Next call
TOOLREAD-ONLYOverlays

overlay_preview

Preview overlay

PNG of a frame with overlays, rendered exactly as the export will (same runtime, same time). Give overlay_id to center on that overlay (isolated:true renders it alone on transparency), and/or output_time.

Plain words: Returns a frame with its overlays as a PNG, rendered exactly as the export will draw it. Use it to check an overlay you just added.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
overlay_idstringOPTIONAL
Overlay handle (ovl_…).
output_timenumberOPTIONAL
Seconds in the edited output (default: into the overlay).Min 0.
isolatedbooleanOPTIONAL
Render just the overlay (transparent background).Default false.
max_pixel_sizeintegerOPTIONAL
Longest edge of the returned image.Default 1280. Min 256, max 2400.
takestringOPTIONAL
Alias of take_id.
overlaystringOPTIONAL
Alias of overlay_id.

Good to know

isolated:true renders the overlay alone on a transparent background.

Request · what your agent sends
{
  "name": "overlay_preview",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "overlay_id": "ovl_m3ek2c7h9d4pq1za",
    "output_time": 61.5
  }
}
Response · structuredContent
{
  "path": "/var/folders/…/T/DemoTake-Previews/take_m3ehbyc0k7qv2x9d/overlays-61.50.png",
  "width": 1280,
  "height": 720
}
TOOL3D scenes

scene3d_create

Create 3D scene

Add a 3D overlay rendered by DemoTake's bundled engine (deterministic, frame-exact; data, never code). Start from a preset (spinning-logo {text}, floating-screen — the recording on a tilted screen with a dolly-in, bar-columns, snow, sparkles, confetti, dust, bubbles, orbit-text) or pass a full scene (schema in overlay_templates' guide: objects, PBR materials, lights, camera, keyframe tracks, particles, recording planes, embedded .glb models/images). Validated against budgets and render-checked. Refine with scene3d_add_object / scene3d_update / scene3d_animate.

Plain words: Adds a 3D scene over the video from a preset (spinning logo, the recording on a floating tilted screen, rising 3D columns, snow and other particles) or from a full scene description.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
presetenumOPTIONAL
Preset.One of spinning-logo, floating-screen, bar-columns, snow, sparkles, confetti, orbit-text, dust, bubbles.
textstringOPTIONAL
Text for spinning-logo / orbit-text (default: the take's name).
sceneobjectOPTIONAL
A full 3D scene (version 1).
namestringOPTIONAL
Display name.
timingobjectOPTIONAL
When the overlay shows. Omit for the whole video.
5 fields
startnumberOPTIONAL
Take anchor: output seconds. Scene anchor: scene-local seconds. Event anchor: offset after the event.
endnumberOPTIONAL
End (same clock as start). Omit for the end of the take/scene.
durationnumberOPTIONAL
Seconds (event anchor, or instead of end).Min 0.
scenestringOPTIONAL
Anchor to a scene: id, title or 1-based number.
eventstringOPTIONAL
Anchor to an event: id or label ("Publish").
placementobjectOPTIONAL
Where the overlay sits. Omit for the template's default.
6 fields
fullbooleanOPTIONAL
Cover the whole frame.
anchorenumOPTIONAL
Corner/edge placement that keeps its shape in 16:9, 9:16 and 1:1.One of top-left, top, top-right, left, center, right, bottom-left, bottom, bottom-right.
sizenumberOPTIONAL
Anchor: height as a fraction of the frame's short side.Min 0.02, max 1.
aspectnumberOPTIONAL
Anchor: width ÷ height.Min 0.1, max 10.
marginnumberOPTIONAL
Anchor: margin as a fraction of the short side.Min 0, max 0.3.
rectobjectOPTIONAL
Region {x, y, width, height} normalized to the recorded frame (0…1, top-left origin), not pixels. w/h are accepted for width/height; other keys are rejected.
4 fields
xnumberREQUIRED
left, 0…1Min 0, max 1.
ynumberREQUIRED
top, 0…1Min 0, max 1.
widthnumberREQUIRED
0…1Min 0, max 1.
heightnumberREQUIRED
0…1Min 0, max 1.
layerenumOPTIONAL
Stacking: above everything (default), below captions, or below the cursor.One of top, below-captions, below-cursor.
zintegerOPTIONAL
Order within the layer (higher is on top).Min -100, max 100.
opacitynumberOPTIONAL
0–1.Min 0, max 1.
respect_redactionsbooleanOPTIONAL
Re-apply the take's redactions over this overlay.
scene_idobjectOPTIONAL
Alias of scene.
takestringOPTIONAL
Alias of take_id.

Good to know

Scenes are data (objects, materials, lights, camera, keyframe tracks) drawn by DemoTake's own engine; nothing you send runs as code.

Request · what your agent sends
{
  "name": "scene3d_create",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "preset": "floating-screen",
    "timing": {
      "scene": "1"
    }
  }
}
Response · structuredContent
{
  "take_id": "take_m3ehbyc0k7qv2x9d",
  "overlay": {
    "id": "ovl_m3ek3a0c4f8h2j6k",
    "name": "Floating Screen",
    "source": {
      "kind": "scene3d",
      "scene": {
        "version": 1,
        "background": {
          "kind": "take",
          "colors": []
        },
        "objects": [
          {
            "id": "screen",
            "type": "recording",
            "size": [
              3.4,
              1.9125,
              0
            ]
          }
        ]
      }
    },
    "layer": "below-cursor"
  },
  "edit_id": "edt_m3ek3a0d1g5h9k2m"
}
TOOL3D scenes

scene3d_add_object

Add 3D object

Add (or replace, same id) an object in a 3D scene: {id, type: box|roundedBox|sphere|cylinder|torus|plane|text|particles|model|image|recording, position, rotation (degrees), scale, size, radius, text, font, material {color, metalness, roughness, emissive, opacity}, particles {preset, count, seed}, asset}.

Plain words: Adds an object to a 3D scene, or replaces the object with the same id: a shape, 3D text, particles, an image, a model you imported, or the recording itself on a plane.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
overlay_idstringREQUIRED
3D overlay handle (ovl_…).
objectobjectREQUIRED
The object.
takestringOPTIONAL
Alias of take_id.
overlaystringOPTIONAL
Alias of overlay_id.
Request · what your agent sends
{
  "name": "scene3d_add_object",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "overlay_id": "ovl_m3ek3a0c4f8h2j6k",
    "object": {
      "id": "badge",
      "type": "text",
      "text": "v2.0",
      "position": [
        1.9,
        1.1,
        0.3
      ],
      "size": [
        0,
        0.35,
        0.1
      ],
      "material": {
        "color": "#FFD166",
        "metalness": 0.6,
        "roughness": 0.25
      }
    }
  }
}
Response · structuredContent
{
  "take_id": "take_m3ehbyc0k7qv2x9d",
  "overlay": {
    "id": "ovl_m3ek3a0c4f8h2j6k"
  },
  "edit_id": "edt_m3ek3b2n6p0r4s8t"
}
TOOL3D scenes

scene3d_update

Update 3D scene

JSON merge patch on a 3D scene's state: {"camera":{"fov":30}}, {"background":{"kind":"color","colors":["#0b0f1a"]}}, {"post":{"vignette":0.4}}; per-object patches go in {"objects_by_id":{"logo":{"position":[0,1,0],"material":{"color":"#FF7AB6"}}}} (null removes that object). Validated and render-checked.

Plain words: Changes part of a 3D scene: the camera, lighting, background, or one object's position, color or text.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
overlay_idstringREQUIRED
3D overlay handle (ovl_…).
patchobjectREQUIRED
Merge patch.
takestringOPTIONAL
Alias of take_id.
overlaystringOPTIONAL
Alias of overlay_id.

Good to know

A null value removes a field (or, under objects_by_id, the object).

Request · what your agent sends
{
  "name": "scene3d_update",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "overlay_id": "ovl_m3ek3a0c4f8h2j6k",
    "patch": {
      "camera": {
        "fov": 30
      },
      "objects_by_id": {
        "badge": {
          "material": {
            "color": "#5EEAD4"
          }
        }
      }
    }
  }
}
Response · structuredContent
{
  "take_id": "take_m3ehbyc0k7qv2x9d",
  "overlay": {
    "id": "ovl_m3ek3a0c4f8h2j6k"
  },
  "edit_id": "edt_m3ek3c9w1x5z7a3b"
}
TOOL3D scenes

scene3d_animate

Animate 3D scene

Add keyframe tracks ({target:"logo.rotation", keyframes:[{t:0,value:[0,0,0]},{t:3,value:[0,360,0],ease:"easeInOut"}], loop}) — tracks for the same target are replaced — and/or a camera move preset (orbit, dolly, push-in) from start for duration seconds, e.g. "orbit the camera around the logo over 3 s".

Plain words: Animates a 3D scene: add keyframes for any object, light or the camera, or a ready-made camera move (orbit, dolly, push-in).

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
overlay_idstringREQUIRED
3D overlay handle (ovl_…).
tracksobject[]OPTIONAL
Keyframe tracks.
cameraenumOPTIONAL
Camera move preset.One of orbit, dolly, push-in.
startnumberOPTIONAL
Camera move start (seconds from the overlay's start).Default 0. Min 0.
durationnumberOPTIONAL
Camera move length in seconds.Default 3. Min 0.2.
takestringOPTIONAL
Alias of take_id.
overlaystringOPTIONAL
Alias of overlay_id.

Good to know

Times are seconds from the overlay's start. Eases: linear, easeIn, easeOut, easeInOut, spring, step.

Request · what your agent sends
{
  "name": "scene3d_animate",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "overlay_id": "ovl_m3ek3a0c4f8h2j6k",
    "camera": "orbit",
    "start": 0.5,
    "duration": 3,
    "tracks": [
      {
        "target": "badge.rotation",
        "keyframes": [
          {
            "t": 0,
            "value": [
              0,
              -90,
              0
            ]
          },
          {
            "t": 1.2,
            "value": [
              0,
              0,
              0
            ],
            "ease": "spring"
          }
        ]
      }
    ]
  }
}
Response · structuredContent
{
  "take_id": "take_m3ehbyc0k7qv2x9d",
  "overlay": {
    "id": "ovl_m3ek3a0c4f8h2j6k"
  },
  "edit_id": "edt_m3ek3d4e8f2g6h0j"
}
TOOL3D scenes

scene3d_remove

Remove 3D object or scene

Remove one object (and its tracks) from a 3D scene, or the whole 3D overlay when object_id is omitted.

Plain words: Removes one object from a 3D scene, or the whole scene when you leave out object_id.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
overlay_idstringREQUIRED
3D overlay handle (ovl_…).
object_idstringOPTIONAL
Object id inside the scene.
takestringOPTIONAL
Alias of take_id.
overlaystringOPTIONAL
Alias of overlay_id.
Request · what your agent sends
{
  "name": "scene3d_remove",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "overlay_id": "ovl_m3ek3a0c4f8h2j6k",
    "object_id": "badge"
  }
}
Response · structuredContent
{
  "take_id": "take_m3ehbyc0k7qv2x9d",
  "overlays": [
    {
      "id": "ovl_m3ek3a0c4f8h2j6k",
      "name": "Floating Screen",
      "kind": "scene3d"
    }
  ]
}
TOOLREAD-ONLY3D scenes

scene3d_preview

Preview 3D scene

PNG of a 3D overlay's frame (composited over the video, or isolated:true alone), exactly as exported.

Plain words: Returns a frame of a 3D scene as a PNG, over the video or on its own, exactly as it will export.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
overlay_idstringREQUIRED
3D overlay handle (ovl_…).
output_timenumberOPTIONAL
Seconds in the edited output.Min 0.
isolatedbooleanOPTIONAL
Render just the scene.Default false.
max_pixel_sizeintegerOPTIONAL
Longest edge.Default 1280. Min 256, max 2400.
takestringOPTIONAL
Alias of take_id.
overlaystringOPTIONAL
Alias of overlay_id.
Request · what your agent sends
{
  "name": "scene3d_preview",
  "arguments": {
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "overlay_id": "ovl_m3ek3a0c4f8h2j6k",
    "output_time": 2.4
  }
}
Response · structuredContent
{
  "path": "/var/folders/…/T/DemoTake-Previews/take_m3ehbyc0k7qv2x9d/overlays-2.40.png",
  "width": 1280,
  "height": 720
}
Next call
TOOLControl

permissions_request

Request permission

Ask macOS for a permission DemoTake needs (shows the system prompt or opens System Settings › Privacy & Security). The user must approve; check permissions_status afterwards.

Plain words: Asks macOS for a permission DemoTake needs, which shows the system prompt or opens System Settings. The person at the Mac has to approve it.

Parameters

permissionenumREQUIRED
Which permission.One of screen_recording, microphone, accessibility, camera.

Good to know

state is granted, denied, not_determined or unavailable; check permissions_status after the user approves.

Request · what your agent sends
{
  "name": "permissions_request",
  "arguments": {
    "permission": "accessibility"
  }
}
Response · structuredContent
Accessibility isn't granted yet. Ask the user to approve it in System Settings › Privacy & Security (DemoTake may need a relaunch for Screen Recording).
{
  "permission": "accessibility",
  "state": "not_determined"
}
TOOLControl

export_cancel

Cancel render

Cancel a queued or running render job (from export_render). Finished jobs are returned unchanged.

Plain words: Stops a render job that is queued or running. A job that already finished is returned unchanged.

Parameters

job_idstringREQUIRED
exp_… handle.
jobstringOPTIONAL
Alias of job_id.
Request · what your agent sends
{
  "name": "export_cancel",
  "arguments": {
    "job_id": "exp_m3ej19z1q2dz7vhn"
  }
}
Response · structuredContent
Job exp_m3ej19z1q2dz7vhn: cancelled.
{
  "job_id": "exp_m3ej19z1q2dz7vhn",
  "take_id": "take_m3ehbyc0k7qv2x9d",
  "format": "9:16",
  "status": "cancelled",
  "progress": 0.38
}
TOOLOne call, events and help

demo_create

Create a demo (one call)

The one-call path: DemoTake plans scenes from the goal, rehearses, records, verifies and renders on its own (Director mode; needs DemoTake AI, hosted or with your own key, and DemoTake Agent to operate the app). Use the take_* / capture_* primitives instead if you want to drive the app yourself.

Plain words: The one-call path: describe what to show and DemoTake plans the scenes, rehearses, records, checks and renders the demo on its own. It needs DemoTake AI (hosted or with your own key) and DemoTake Agent to operate the app.

Parameters

goalstringREQUIRED
What to show, e.g. "Sign in, create a project, export an invoice".
targetstring | objectOPTIONAL
Target app/window/device. Either a target_id from targets_list ("window:1234", "app:com.example.App", "pid:4321", "display:1", "sim:<UDID>" for a booted iOS Simulator device, "android:<serial>" for an Android emulator or device, a URL) or an object; {url_contains:"example.com"} picks the browser window whose tab shows that URL (and keeps following that window across navigations). target_id is accepted as an alias. Defaults to the take's target.
12 fields
target_idstringOPTIONAL
id from targets_list
bundle_idstringOPTIONAL
app_namestringOPTIONAL
window_titlestringOPTIONAL
window_idintegerOPTIONAL
pidintegerOPTIONAL
display_idintegerOPTIONAL
urlstringOPTIONAL
url_containsstringOPTIONAL
Browser window whose tab URL contains this text, e.g. a domain
device_udidstringOPTIONAL
iOS Simulator device UDID
serialstringOPTIONAL
Android adb serial (emulator-5554, a USB serial)
kindenumOPTIONAL
One of window, application, display, web, simulator, android.
stylestringOPTIONAL
Free-form style: "calm, 45 seconds, no zoom on typing".
purposeenumOPTIONAL
Purpose.One of marketing, reviewer, tutorial, test. Default "marketing".
outputsenum[]OPTIONAL
Output formats: "16:9" (landscape), "9:16" (vertical), "4:3", "1:1", "gif", "screenshots", "reviewer_pack" (conservative cut + manifest ZIP), "guide" (written step-by-step guide: guide.md + index.html + screenshots), "interactive" (click-through HTML demo: index.html + player + step images, folder + ZIP).One of 16:9, 9:16, 4:3, 1:1, gif, screenshots, reviewer_pack, guide, interactive, app_preview.
target_durationnumberOPTIONAL
Target length in seconds.Min 3.
project_namestringOPTIONAL
Project to file the take under.
target_idstring | objectOPTIONAL
Alias of target.
12 fields
target_idstringOPTIONAL
id from targets_list
bundle_idstringOPTIONAL
app_namestringOPTIONAL
window_titlestringOPTIONAL
window_idintegerOPTIONAL
pidintegerOPTIONAL
display_idintegerOPTIONAL
urlstringOPTIONAL
url_containsstringOPTIONAL
Browser window whose tab URL contains this text, e.g. a domain
device_udidstringOPTIONAL
iOS Simulator device UDID
serialstringOPTIONAL
Android adb serial (emulator-5554, a USB serial)
kindenumOPTIONAL
One of window, application, display, web, simulator, android.

Good to know

It returns as soon as the take is planned and the Director keeps working in the background; if DemoTake AI or DemoTake Agent isn't available you get a planned take (ai_mode byo_agent) to drive yourself.

Request · what your agent sends
{
  "name": "demo_create",
  "arguments": {
    "goal": "Sign in, create an invoice for Northwind Studio and export it as PDF",
    "target": "window:4127",
    "style": "calm, no zoom on typing",
    "outputs": [
      "16:9"
    ],
    "target_duration": 45,
    "project_name": "Ledgerly"
  }
}
Response · structuredContent
Demo take take_m3ehbyc0k7qv2x9d: Draft.
{
  "take_id": "take_m3ehbyc0k7qv2x9d",
  "project_id": "prj_m119ecc0t4w8nq2h",
  "name": "Sign in, create an invoice for",
  "goal": "Sign in, create an invoice for Northwind Studio and export it as PDF",
  "purpose": "marketing",
  "status": "draft",
  "ai_mode": "director",
  "execution_mode": "background_semantic",
  "target": {
    "target_id": "window:4127",
    "kind": "window",
    "name": "Ledgerly — Invoices",
    "bundle_id": "com.example.Ledgerly",
    "app_name": "Ledgerly",
    "window_title": "Invoices",
    "window_id": 4127,
    "pid": 51234
  },
  "scenes": [
    {
      "scene_id": "scn_m3ehbzb8a1fr6mzp",
      "index": 1,
      "title": "Sign in",
      "status": "pending",
      "attempts": 0
    },
    {
      "scene_id": "scn_m3ehbzb9d3kw7tbe",
      "index": 2,
      "title": "Create invoice",
      "status": "pending",
      "attempts": 0
    },
    {
      "scene_id": "scn_m3ehbzbap5hn0cxv",
      "index": 3,
      "title": "Export PDF",
      "status": "pending",
      "attempts": 0
    }
  ],
  "assertions": [],
  "assertions_passed": "0/0",
  "event_count": 0,
  "source_duration": 0,
  "outputs": [
    "16:9"
  ],
  "edits": {
    "compress_waits": {
      "threshold": 1,
      "to": 0.4
    },
    "target_duration": 45
  },
  "updated_at": "2026-09-26T09:40:00Z",
  "next": "Optionally take_rehearse to dry-run, then capture_start."
}
TOOLREAD-ONLYOne call, events and help

events_poll

Poll events

Realtime events after a cursor (scene_started, action_performed, classification, assertion_passed/failed, checkpoint_created, human_input_required, handoff_started / handoff_ended {outcome}, page changes of browser takes (info, data.url), render_progress…). Pass the returned cursor next time. Clients with notification support also receive these as notifications/message.

Plain words: Fetches what happened since your last check (scenes starting, actions, assertions, checkpoints, render progress, requests for a human). Pass the returned cursor next time to get only newer events.

Parameters

afterintegerOPTIONAL
Cursor from the previous call (0 = from the start of the buffer).Default 0. Min 0.
take_idstringOPTIONAL
Only events for this take.
limitintegerOPTIONAL
Max events.Default 100. Min 1, max 500.
takestringOPTIONAL
Alias of take_id.

Good to know

Clients that support MCP notifications also receive these as notifications/message, so polling is optional.

Request · what your agent sends
{
  "name": "events_poll",
  "arguments": {
    "after": 40,
    "take_id": "take_m3ehbyc0k7qv2x9d",
    "limit": 50
  }
}
Response · structuredContent
{
  "events": [
    {
      "id": 41,
      "kind": "scene_started",
      "level": "info",
      "take_id": "take_m3ehbyc0k7qv2x9d",
      "scene_id": "scn_m3ehbzb9d3kw7tbe",
      "message": "Recording scene “Create invoice”",
      "at": "2026-09-26T09:46:02Z",
      "data": {
        "segment_id": "seg_m3ehe1k0v7nq4cxz"
      }
    },
    {
      "id": 42,
      "kind": "assertion_passed",
      "level": "success",
      "take_id": "take_m3ehbyc0k7qv2x9d",
      "scene_id": "scn_m3ehbzb9d3kw7tbe",
      "message": "✓ Invoice created",
      "at": "2026-09-26T09:46:25Z",
      "data": {
        "assertion_id": "ast_m3ehfkj0r9vb4ngs"
      }
    },
    {
      "id": 43,
      "kind": "checkpoint_created",
      "level": "success",
      "take_id": "take_m3ehbyc0k7qv2x9d",
      "scene_id": "scn_m3ehbzb9d3kw7tbe",
      "message": "Checkpoint: Invoice INV-0042 open with 2 line items",
      "at": "2026-09-26T09:46:27Z"
    }
  ],
  "cursor": 43,
  "latest": 43
}
TOOLREAD-ONLYOne call, events and help

demotake_guide

How to use DemoTake

Workflow guide for recording a demo with DemoTake. Read once if unsure which tools to call.

Plain words: Returns DemoTake's short workflow guide: which tools to call, in what order, to record, edit and export a demo. Read it once if you're unsure where to start.

Parameters

None.

Good to know

Returns plain text only (no structuredContent), so the response above shows the MCP content block; the guide adapts to the edition that is running.

Request · what your agent sends
{
  "name": "demotake_guide",
  "arguments": {}
}
Response · structuredContent
{
  "content": [
    {
      "type": "text",
      "text": "DemoTake — your agent's camera crew (DemoTake Agent).\n\nWorkflow\n1. targets_list → pick the app window. targets_capabilities tells you the execution mode.\n2. take_create {name, goal, target, scenes:[{title,intent}], outputs:[\"16:9\",\"9:16\"]} → take_id.\n…"
    }
  ]
}
TOOLMusic and compositions

music_generate

Generate background music

Generate AI background music for a take and put it on the music lane (looped, loudness-normalised to -16 LUFS, ducked under narration). tracks > 1 makes a playlist of distinct tracks in one style, crossfaded and looped to fill long videos (use 6–10 for multi-hour compositions; one generation per track). Uses DemoTake AI on hosted plans (its own monthly song allowance, never the AI edit credits) or the user's own AI provider key (BYOK). dry_run:true returns the cost estimate and the allowance without generating; show it to the user before generating many tracks. Music is instrumental unless instrumental:false. Generated music carries an inaudible AI watermark; see the licensing notes in the docs before monetizing.

Plain words: Adds instrumental AI background music to a take: looped under the whole video, loudness-matched and lowered automatically while someone speaks. Ask for several tracks to get a crossfaded playlist for long videos; pass dry_run first to see what it uses of the monthly song allowance.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
promptstringOPTIONAL
Mood, instruments, tempo, setting: "chill lofi, rainy night, soft Rhodes".
styleenumOPTIONAL
Style preset: lofi (chill lofi), ambient, piano (soft piano), corporate (upbeat product), electronic (focus electronic), jazz (coffee-shop jazz), cinematic.One of lofi, ambient, piano, corporate, electronic, jazz, cinematic.
lengthenumOPTIONAL
clip (~30 s, loops) or song (a full 2–3 minute track).One of clip, song. Default "song".
instrumentalbooleanOPTIONAL
No vocals or lyrics.Default true.
tracksintegerOPTIONAL
Distinct tracks (1 = one looping track; more = a playlist).Default 1. Min 1, max 12.
seedintegerOPTIONAL
Seed for regeneration (the model may ignore it).Min 0.
placebooleanOPTIONAL
Put the music on the music lane (replacing what it played).Default true.
dry_runbooleanOPTIONAL
Only return the estimate and remaining allowance.Default false.
takestringOPTIONAL
Alias of take_id.
Request · what your agent sends
{
  "name": "music_generate",
  "arguments": {
    "take_id": "take_m11a2b3c4d5e6f7g",
    "prompt": "rainy night, soft Rhodes",
    "style": "lofi",
    "tracks": 1
  }
}
Response · structuredContent
Added "Chill lofi" (2:28), looping under the take. About 29 songs left this month.
{
  "assets": [
    {
      "asset_id": "aud_m11a9k2h7q3v5x8z",
      "title": "Chill lofi",
      "source": "generated",
      "file": "audio/aud_m11a9k2h7q3v5x8z.mp3",
      "duration": 148.2,
      "loudness_lufs": -11.4,
      "prompt": "rainy night, soft Rhodes",
      "style": "lofi",
      "model": "music"
    }
  ],
  "estimate": {
    "tracks": 1,
    "length": "song",
    "songs_of_allowance": 1
  },
  "allowance": "About 29 songs left this month",
  "route": "hosted"
}
TOOLMusic and compositions

music_add

Add or adjust music

Add the user's own audio file (path on this Mac; MP3/M4A/WAV/AIFF/FLAC) as background music (lane "music", looped), narration (lane "voice": ducks the music) or a sound effect (lane "sfx"); and/or adjust the music lane: volume (linear 0–1, or volume_db to change relatively, e.g. -3), ducking (duck:true/false, duck_db e.g. -15 = how far it drops under speech), fade_in/fade_out seconds, mute. "Lower the music under my voice" = duck:true, duck_db:-15.

Plain words: Uses your own audio file as background music, narration or a sound effect, or adjusts the music: volume, fades, mute, and how far it dips while you speak ("lower the music under my voice").

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
pathstringOPTIONAL
Audio file to import (absolute path or ~/…).
laneenumOPTIONAL
Where the file goes.One of music, voice, sfx. Default "music".
loopbooleanOPTIONAL
Loop the file to fill the take (music default true).
volumenumberOPTIONAL
Music lane volume, linear (1 = unity; the default is 0.28).Min 0, max 4.
volume_dbnumberOPTIONAL
Change the music volume by this many dB (negative = quieter).Min -40, max 12.
duckbooleanOPTIONAL
Lower the music under narration / recorded voice.
duck_dbnumberOPTIONAL
How far the music drops under voice (dB, negative).Min -40, max 0.
fade_innumberOPTIONAL
Fade-in seconds.Min 0.
fade_outnumberOPTIONAL
Fade-out seconds.Min 0.
mutebooleanOPTIONAL
Mute or unmute the music lane.
takestringOPTIONAL
Alias of take_id.
Request · what your agent sends
{
  "name": "music_add",
  "arguments": {
    "take_id": "take_m11a2b3c4d5e6f7g",
    "duck": true,
    "duck_db": -15,
    "volume_db": -3
  }
}
Response · structuredContent
Duck music under voice (-15 dB); Music 3 dB quieter. edit_revert undoes the last change.
{
  "take_id": "take_m11a2b3c4d5e6f7g",
  "music": {
    "lanes": [
      {
        "kind": "music",
        "volume": 0.2,
        "ducking": "-15 dB",
        "loudness_target": -16
      }
    ]
  }
}
TOOLMusic and compositions

music_remove

Remove music

Remove one music clip (clip_id), every use of one audio file (asset_id), or all music (neither). Files stay in the take; edit_revert restores.

Plain words: Takes music off the take: one clip, every use of one file, or all of it. The files stay in the take, and edit_revert brings the music back.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
clip_idstringOPTIONAL
A clip id from the take's music.clips.
asset_idstringOPTIONAL
An audio file id from the take's music.assets.
takestringOPTIONAL
Alias of take_id.
Request · what your agent sends
{
  "name": "music_remove",
  "arguments": {
    "take_id": "take_m11a2b3c4d5e6f7g"
  }
}
Response · structuredContent
Remove music.
{
  "take_id": "take_m11a2b3c4d5e6f7g"
}
TOOLMusic and compositions

composition_create

Create a composition (study-with-me video)

Create a Composition: a long-form video made from media instead of a screen recording, e.g. a study-with-me / pomodoro video. Either pass request in plain words ("2.5-hour study-with-me video, 45/10 pomodoro, rainy cozy room, lofi music") or the fields. Builds the schedule (whole focus phases; 2.5 h at 45/10 = 3 cycles, 2:35:00), a timer, phase-change chimes (synthesized by DemoTake, royalty-free), YouTube chapters and the background (background_path: an image or looping video on this Mac; otherwise a calm gradient matching the scene). music:"generate" makes a playlist (music_tracks, default ~1 per 15 min, max 10) — call with music:"estimate" first to show the cost; music_path uses the user's own file. Export with export_render {take_id} (1080p or 4K HEVC MP4 + chapters.txt + thumbnail.jpg).

Plain words: Makes a long-form video without a screen recording, such as a study-with-me video: a background picture or looping clip, a pomodoro timer, a soft chime at every change between focus and break, and YouTube chapters. Describe it in plain words; music can be estimated first and generated after.

Parameters

requeststringOPTIONAL
Plain-language description (parsed offline).
namestringOPTIONAL
Take name.
total_minutesnumberOPTIONAL
Target length in minutes (rounded to whole focus phases).Min 1, max 720.
focus_minutesnumberOPTIONAL
Focus phase length.Min 1, max 240.
break_minutesnumberOPTIONAL
Break length.Min 0, max 120.
cyclesintegerOPTIONAL
Focus phases (overrides total_minutes).Min 1, max 48.
long_break_minutesnumberOPTIONAL
Long break length.Min 0, max 120.
long_break_everyintegerOPTIONAL
A long break after every N focus phases.Min 1, max 12.
scenestringOPTIONAL
The scene in words ("rainy cozy room"): picks the fallback gradient; kept for later scene generation.
background_pathstringOPTIONAL
Image or video file for the background.
timer_styleenumOPTIONAL
Timer look.One of minimal, card, ring. Default "card".
timer_positionenumOPTIONAL
Timer position.One of center, top_left, top_right, bottom_left, bottom_right, bottom_center. Default "center".
chimeenumOPTIONAL
Phase-change chime.One of bell, bowl, marimba, digital. Default "bell".
resolutionenumOPTIONAL
Export preset.One of 1080p, 4k. Default "1080p".
musicenumOPTIONAL
generate (AI playlist), estimate (only show the cost), none.One of generate, estimate, none. Default "estimate".
music_promptstringOPTIONAL
Music description ("lofi, mellow keys").
music_styleenumOPTIONAL
Style preset: lofi (chill lofi), ambient, piano (soft piano), corporate (upbeat product), electronic (focus electronic), jazz (coffee-shop jazz), cinematic.One of lofi, ambient, piano, corporate, electronic, jazz, cinematic.
music_tracksintegerOPTIONAL
Distinct tracks for the playlist.Min 1, max 12.
music_pathstringOPTIONAL
Use this audio file as the music instead.
projectstringOPTIONAL
Project name (created if missing).
scene_idstringOPTIONAL
Alias of scene.
project_idstringOPTIONAL
Alias of project.
Request · what your agent sends
{
  "name": "composition_create",
  "arguments": {
    "request": "make a 2.5-hour study-with-me video, 45/10 pomodoro, rainy cozy room, lofi music",
    "background_path": "~/Pictures/rainy-room.jpg",
    "music": "estimate"
  }
}
Response · structuredContent
Created composition take_m11b7c2d9e4f1g6h, 2:35:00: 3 × 45 min focus / 10 min break. Music: 10 tracks would use 10 songs of the monthly allowance; call music_generate {take_id, tracks:10} to make them.
{
  "take": {
    "take_id": "take_m11b7c2d9e4f1g6h",
    "name": "Study with me — 2.6 h (45/10)",
    "composition": {
      "duration": 9300,
      "schedule": {
        "focus_minutes": 45,
        "break_minutes": 10,
        "cycles": 3
      }
    }
  },
  "chapters": "0:00 Focus 1\n45:00 Break 1\n55:00 Focus 2\n1:40:00 Break 2\n1:50:00 Focus 3\n",
  "music": {
    "generated": false,
    "tracks": 10,
    "songs_of_allowance": 10,
    "allowance": "About 30 songs left this month"
  }
}
TOOLREAD-ONLYVoiceover and subtitles

voices_list

List voices

Voices for the voiceover. engine "device": the Mac's own voices for language (best first: Premium, then Enhanced; free and offline — the user can install better ones in System Settings › Accessibility › Spoken Content). engine "hosted": DemoTake's AI voices (each speaks the language of the text; available says whether this account can use them, with the remaining voice minutes). Without engine both are listed.

Plain words: Lists the voices a voiceover can use: the Mac's own voices for a language (free and offline, best quality first), and DemoTake's AI voices with how many voice minutes are left this month.

Parameters

engineenumOPTIONAL
device = the Mac's own voices (free, offline; Enhanced/Premium voices where installed). hosted = DemoTake's AI voices (Director/Team/Enterprise plans: monthly voice minutes; or the user's own AI provider key).One of device, hosted.
languagestringOPTIONAL
BCP-47 language of the voiceover, e.g. en-US, de-DE, ja-JP (default: the take's voiceover language, else its declared original language, else the language its scene text is written in; English when unclear — never the Mac's locale). One of the take's translation languages (take_languages_set) works on that language's voiceover instead.
Request · what your agent sends
{
  "name": "voices_list",
  "arguments": {
    "language": "en-US"
  }
}
Response · structuredContent
{
  "engines": [
    {
      "engine": "device",
      "available": true,
      "default_voice": "com.apple.voice.premium.en-US.Ava",
      "allowance": "Free, on this Mac",
      "voices": [
        {
          "id": "com.apple.voice.premium.en-US.Ava",
          "name": "Ava (Premium)",
          "language": "en-US",
          "quality": "premium",
          "gender": "female"
        },
        {
          "id": "com.apple.voice.enhanced.en-US.Evan",
          "name": "Evan (Enhanced)",
          "language": "en-US",
          "quality": "enhanced",
          "gender": "male"
        }
      ]
    },
    {
      "engine": "hosted",
      "available": true,
      "default_voice": "Charon",
      "note": "Every voice speaks the language of the text.",
      "allowance": "About 96 AI voice minutes left this month",
      "voices": [
        {
          "id": "Charon",
          "name": "Charon",
          "quality": "hosted",
          "tone": "Informative"
        },
        {
          "id": "Sulafat",
          "name": "Sulafat",
          "quality": "hosted",
          "tone": "Warm"
        }
      ]
    }
  ]
}
TOOLVoiceover and subtitles

voiceover_script

Write the voiceover script

Write (or rewrite) the voiceover: one short spoken line per scene, from the scene's intent, captions and steps. With DemoTake AI set up (or use_ai:true) the lines are written by DemoTake AI within each scene's word budget (its edited length at a natural ~150 words per minute); otherwise from the intents ("First, sign in…"). You can also write lines yourself with voiceover_update. Lines are anchored to their scene's start, so they follow trims and cuts. Returns the lines with their estimated timing and fit warnings; nothing is spoken until voiceover_generate.

Plain words: Writes the voiceover: one short spoken line per scene from what the scene shows, sized to fit the scene at a natural speaking pace. Edit any line afterwards; nothing is spoken until the voice is generated.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
scenesstring[]OPTIONAL
Only these scenes (default: every scene in the cut).
styleenumOPTIONAL
concise, tutorial (first/next/finally) or friendly.One of concise, tutorial, friendly.
languagestringOPTIONAL
BCP-47 language of the voiceover, e.g. en-US, de-DE, ja-JP (default: the take's voiceover language, else its declared original language, else the language its scene text is written in; English when unclear — never the Mac's locale). One of the take's translation languages (take_languages_set) works on that language's voiceover instead.
use_aibooleanOPTIONAL
Write with DemoTake AI (true), from intents only (false). Default: AI when it's set up.
instructionsstringOPTIONAL
Extra guidance for DemoTake AI (audience, terms to use, things to mention).
replacebooleanOPTIONAL
Rewrite existing lines (false: only fill scenes without one).Default true.
takestringOPTIONAL
Alias of take_id.
Request · what your agent sends
{
  "name": "voiceover_script",
  "arguments": {
    "take_id": "take_m11a2b3c4d5e6f7g",
    "style": "tutorial",
    "language": "en-US"
  }
}
Response · structuredContent
{
  "language": "en-US",
  "style": "tutorial",
  "lines": [
    {
      "line_id": "nar_m11b1c2d3e4f5g6h",
      "scene_id": "scn_m11a3b4c5d6e7f8g",
      "scene": "Sign in",
      "text": "First, sign in with the demo account.",
      "audio": "none",
      "seconds": 2.4,
      "start": 0,
      "end": 2.4,
      "estimated": true
    },
    {
      "line_id": "nar_m11b7h8j9k0m1n2p",
      "scene_id": "scn_m11a9h8g7f6e5d4c",
      "scene": "Create a project",
      "text": "Then create a project from the sidebar.",
      "audio": "none",
      "seconds": 2.4,
      "start": 6.4,
      "end": 8.8,
      "estimated": true
    }
  ]
}
TOOLVoiceover and subtitles

voiceover_generate

Speak the voiceover

Turn the voiceover lines into speech and put them on the voice lane (music ducks under them). Writes the script from the intents first if there is none. engine "device" (default) uses the Mac's own voices — free, offline; "hosted" uses DemoTake's AI voices (monthly voice minutes on Director/Team/Enterprise, or the user's own AI key). voice: an id or name from voices_list (default: the take's voice, else the best one for the language). Only lines without current audio are spoken unless regenerate:true or the voice changes. Audio is never sped up: lines that run past their scene are reported in warnings; fit:true holds the scene's last frame just long enough. dry_run:true reports the lines and the estimated seconds without speaking. When the take's captions follow the voiceover (voiceover_update {sync_captions:true}) they're rewritten per sentence. Localized takes: language set to one of the take's languages (take_languages_set) speaks that language's translated voiceover (translate_take first) with its own voice — the Mac's voice for that language (voices_list {language}) or the AI voices, which speak every language — without touching the take's own voiceover.

Plain words: Speaks the voiceover and puts it on the voice track, with the music dipping under it. Uses the Mac's own voices (free) or DemoTake's AI voices; lines too long for their scene are reported, and the scene can hold its last frame instead of the voice being sped up.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
engineenumOPTIONAL
device = the Mac's own voices (free, offline; Enhanced/Premium voices where installed). hosted = DemoTake's AI voices (Director/Team/Enterprise plans: monthly voice minutes; or the user's own AI provider key).One of device, hosted.
voicestringOPTIONAL
Voice id or name (voices_list).
languagestringOPTIONAL
BCP-47 language of the voiceover, e.g. en-US, de-DE, ja-JP (default: the take's voiceover language, else its declared original language, else the language its scene text is written in; English when unclear — never the Mac's locale). One of the take's translation languages (take_languages_set) works on that language's voiceover instead.
scenesstring[]OPTIONAL
Only these scenes (default: every scene in the cut).
line_idsstring[]OPTIONAL
Only these lines.
regeneratebooleanOPTIONAL
Speak lines again even if their audio is current.Default false.
fitbooleanOPTIONAL
Hold scenes whose line runs past their end.Default false.
dry_runbooleanOPTIONAL
Only report what would be spoken.Default false.
takestringOPTIONAL
Alias of take_id.
Request · what your agent sends
{
  "name": "voiceover_generate",
  "arguments": {
    "take_id": "take_m11a2b3c4d5e6f7g",
    "engine": "device",
    "voice": "Ava"
  }
}
Response · structuredContent
{
  "voiceover": {
    "language": "en-US",
    "voice": {
      "engine": "device",
      "id": "com.apple.voice.premium.en-US.Ava",
      "name": "Ava (Premium)"
    },
    "style": "tutorial",
    "lines": [
      {
        "line_id": "nar_m11b1c2d3e4f5g6h",
        "scene_id": "scn_m11a3b4c5d6e7f8g",
        "scene": "Sign in",
        "text": "First, sign in with the demo account.",
        "audio": "current",
        "seconds": 2.6,
        "start": 0,
        "end": 2.6
      },
      {
        "line_id": "nar_m11b7h8j9k0m1n2p",
        "scene_id": "scn_m11a9h8g7f6e5d4c",
        "scene": "Create a project",
        "text": "Then create a project from the sidebar.",
        "audio": "current",
        "seconds": 2.6,
        "start": 6.4,
        "end": 9
      }
    ]
  },
  "spoken": [
    "nar_m11b1c2d3e4f5g6h",
    "nar_m11b7h8j9k0m1n2p"
  ],
  "seconds": 5.2,
  "engine": "device",
  "allowance": "Free, on this Mac"
}
TOOLVoiceover and subtitles

voiceover_update

Edit the voiceover

Change one voiceover line (line_id, or the line of scene; empty text removes it; a new scene gets a new line), where it starts (at: scene_start | checkpoint | event with event_id, offset seconds), and/or voiceover options: mute_microphone (silence the recording's microphone in scenes with a voiceover), sync_captions (captions = the voiceover, one per sentence, timed with the speech; true rewrites them now), volume (linear, 1 = unity), style, language. fit:true holds scenes whose line runs past their end (never speeds audio up). Changed text needs voiceover_generate to be spoken again. With language set to one of the take's translation languages, text (with line_id) edits that language's line and fit:true holds scenes in that language only. edit_revert undoes it.

Plain words: Changes one voiceover line or the voiceover's options: the words, where the line starts, silencing the microphone under it, captions that follow it, or holding scenes so every line fits.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
line_idstringOPTIONAL
Voiceover line id (nar_…), from take_get / voiceover_script.
scenestringOPTIONAL
Scene handle (the scn_… scene_id that take_create and take_get return), exact title, or 1-based index. scene_id is accepted as an alias.
textstringOPTIONAL
The spoken line (empty removes it).
atenumOPTIONAL
Where the line starts.One of scene_start, checkpoint, event.
event_idstringOPTIONAL
Event the line starts at (at:"event").
offsetnumberOPTIONAL
Seconds after the anchor (for a checkpoint: before the scene ends).Min 0.
mute_microphonebooleanOPTIONAL
Silence the microphone in scenes with a voiceover.
sync_captionsbooleanOPTIONAL
Captions follow the voiceover (one per sentence).
volumenumberOPTIONAL
Voiceover volume, linear (1 = unity).Min 0, max 4.
styleenumOPTIONAL
Script style for later voiceover_script runs.One of concise, tutorial, friendly.
languagestringOPTIONAL
BCP-47 language of the voiceover, e.g. en-US, de-DE, ja-JP (default: the take's voiceover language, else its declared original language, else the language its scene text is written in; English when unclear — never the Mac's locale). One of the take's translation languages (take_languages_set) works on that language's voiceover instead.
fitbooleanOPTIONAL
Hold scenes whose line runs past their end.
scene_idstringOPTIONAL
Alias of scene.
takestringOPTIONAL
Alias of take_id.
Request · what your agent sends
{
  "name": "voiceover_update",
  "arguments": {
    "take_id": "take_m11a2b3c4d5e6f7g",
    "scene": "2",
    "text": "Then create a project straight from the sidebar.",
    "mute_microphone": true
  }
}
Response · structuredContent
{
  "language": "en-US",
  "style": "tutorial",
  "mute_microphone": true,
  "lines": [
    {
      "line_id": "nar_m11b1c2d3e4f5g6h",
      "scene_id": "scn_m11a3b4c5d6e7f8g",
      "scene": "Sign in",
      "text": "First, sign in with the demo account.",
      "audio": "current",
      "seconds": 2.6,
      "start": 0,
      "end": 2.6
    },
    {
      "line_id": "nar_m11b7h8j9k0m1n2p",
      "scene_id": "scn_m11a9h8g7f6e5d4c",
      "scene": "Create a project",
      "text": "Then create a project straight from the sidebar.",
      "audio": "stale",
      "seconds": 2.4,
      "start": 6.4,
      "end": 8.8,
      "estimated": true
    }
  ]
}
TOOLVoiceover and subtitles

voiceover_remove

Remove the voiceover

Remove voiceover lines (line_id, or every line of scene), or the whole voiceover (neither). Audio files stay in the take; edit_revert restores.

Plain words: Removes voiceover lines, or the whole voiceover. The audio files stay in the take, so undoing brings it back.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
line_idstringOPTIONAL
Voiceover line id (nar_…).
scenestringOPTIONAL
Scene handle (the scn_… scene_id that take_create and take_get return), exact title, or 1-based index. scene_id is accepted as an alias.
scene_idstringOPTIONAL
Alias of scene.
takestringOPTIONAL
Alias of take_id.
Request · what your agent sends
{
  "name": "voiceover_remove",
  "arguments": {
    "take_id": "take_m11a2b3c4d5e6f7g",
    "scene": "2"
  }
}
Response · structuredContent
{
  "language": "en-US",
  "style": "tutorial",
  "lines": [
    {
      "line_id": "nar_m11b1c2d3e4f5g6h",
      "scene_id": "scn_m11a3b4c5d6e7f8g",
      "scene": "Sign in",
      "text": "First, sign in with the demo account.",
      "audio": "current",
      "seconds": 2.6,
      "start": 0,
      "end": 2.6
    }
  ]
}
TOOLVoiceover and subtitles

export_subtitles

Export subtitles and transcript

Write subtitle and transcript files for the take's current cut into its exports folder, timed in output time (after trims, cuts, speed changes and holds): srt, vtt (WebVTT), txt (plain transcript), md (Markdown transcript with scene headings). source: auto (the voiceover when there is one, else the captions — shown or not), captions or narration. Subtitle files are skipped when there's nothing to say. Also available on export_render {subtitles:[…], embed_subtitles:true} next to a video.

Plain words: Writes subtitle files (SRT, WebVTT) and transcripts timed to the edited video, from the voiceover or the captions.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
formatsenum[]OPTIONAL
Subtitle / transcript files.One of srt, vtt, txt, md.
formatenumOPTIONAL
One format (alias of formats).One of srt, vtt, txt, md.
sourceenumOPTIONAL
What the subtitles say: auto (the voiceover when the take has one, else the captions), captions, narration.One of auto, captions, narration. Default "auto".
languagestringOPTIONAL
One of the take's translation languages (default: the take's own); file names end in it (-de).
takestringOPTIONAL
Alias of take_id.
Request · what your agent sends
{
  "name": "export_subtitles",
  "arguments": {
    "take_id": "take_m11a2b3c4d5e6f7g",
    "formats": [
      "srt",
      "vtt",
      "md"
    ]
  }
}
Response · structuredContent
{
  "files": [
    "~/Movies/DemoTake/Takes/Checkout.take/exports/checkout-20261027-101500.srt",
    "~/Movies/DemoTake/Takes/Checkout.take/exports/checkout-20261027-101500.vtt",
    "~/Movies/DemoTake/Takes/Checkout.take/exports/checkout-20261027-101500-transcript.md"
  ]
}
TOOLLanguages

take_languages_set

Set the take's languages

Localized takes: one take, many languages. Set the languages the take is translated into (languages: replaces the list; add / remove change it), the language the take is written in (source_language; default: the voiceover's, else en-US) and the glossary: terms kept as written in every language (product names, button labels the app keeps in English), or translated one fixed way ({term:"Projects", translations:{de:"Projekte"}}). Removing a language drops its translations and voiceover (edit_revert brings them back). Then translate_take translates, voiceover_generate {language} speaks a language, export_render {languages} exports a video per language. Returns the localization status per language.

Plain words: Chooses the languages a take is translated into, the language it's written in, and the glossary of names and button labels that stay as written (or translate one fixed way).

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
languagesstring[]OPTIONAL
Languages.
addstring[]OPTIONAL
Languages.
removestring[]OPTIONAL
Languages.
source_languagestringOPTIONAL
Language the take's own texts are in (BCP-47). Empty = automatic.
glossaryobject[]OPTIONAL
Replaces the glossary. Items may also be plain strings (kept as written).
3 fields
termstringREQUIRED
The term as written.
translationsobjectOPTIONAL
Fixed translations by language tag, e.g. {"de": "Projekte"}. Missing = keep as written.
case_sensitivebooleanOPTIONAL
Match case exactly.Default false.
takestringOPTIONAL
Alias of take_id.
Request · what your agent sends
{
  "name": "take_languages_set",
  "arguments": {
    "take_id": "take_m11a2b3c4d5e6f7g",
    "add": [
      "de",
      "sv"
    ],
    "glossary": [
      "Aurora",
      {
        "term": "Projects",
        "translations": {
          "de": "Projekte"
        }
      }
    ]
  }
}
Response · structuredContent
{
  "source_language": "en-US",
  "languages": [
    {
      "language": "de",
      "name": "German",
      "translated": 0,
      "changed": 0,
      "missing": 9
    },
    {
      "language": "sv",
      "name": "Swedish",
      "translated": 0,
      "changed": 0,
      "missing": 9
    }
  ],
  "glossary": [
    {
      "term": "Aurora"
    },
    {
      "term": "Projects",
      "translations": {
        "de": "Projekte"
      }
    }
  ]
}
TOOLLanguages

translate_take

Translate the take

Translate the take into its languages (take_languages_set first): captions, the voiceover lines (each within its scene's word budget in that language), the guide's scene titles and descriptions, overlay text, selected on-screen text (onscreen_text_scan) and interactive demo tips (kinds:["interactive"]). engine "ai" (DemoTake AI on Director/Team/Enterprise, which counts toward the plan's DemoTake AI use; or the user's own AI provider key) or "device" (Apple's on-device translation, macOS 26+, languages installed in System Settings › General › Language & Region; free and offline). Glossary terms, names, numbers, keyboard shortcuts, placeholders ({name}, %@), URLs, emails and anything Secret Guard flags are kept on the Mac and restored exactly; never any pixels. Only missing and changed translations are translated; force:true redoes machine translations too. Translations written by hand (translation_update) are kept unless their source text changed. Returns per language what was translated, translations to check (a protected name/number was lost) and warnings (voiceover lines too long for their scene: shorten, or voiceover_update {fit:true, language}).

Plain words: Translates the take's captions, voiceover lines, guide steps, overlay text, chosen on-screen text and interactive demo tips into its languages with AI translation or on the Mac. Names, numbers, shortcuts and placeholders stay exactly as written, and edits made by hand are kept.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
languagesstring[]OPTIONAL
Languages.
kindsenum[]OPTIONAL
What to translate (default: everything).One of captions, narration, guide, overlays, onscreen, interactive.
engineenumOPTIONAL
ai (DemoTake AI) or device (on this Mac, macOS 26+). Default: ai when it's set up.One of ai, device.
forcebooleanOPTIONAL
Retranslate current machine translations too (hand edits stay).Default false.
keysstring[]OPTIONAL
Only these texts.
instructionsstringOPTIONAL
Guidance for DemoTake AI, e.g. "informal du", "for developers".
dry_runbooleanOPTIONAL
Only list what would be translated.Default false.
takestringOPTIONAL
Alias of take_id.
Request · what your agent sends
{
  "name": "translate_take",
  "arguments": {
    "take_id": "take_m11a2b3c4d5e6f7g",
    "languages": [
      "de"
    ],
    "kinds": [
      "captions",
      "narration",
      "guide"
    ]
  }
}
Response · structuredContent
{
  "engine": "ai",
  "characters": 412,
  "results": [
    {
      "language": "de",
      "translated": [
        "take/name",
        "scene/scn_m11a3b4c5d6e7f8g/title",
        "caption/edt_m11c2d3e4f5g6h7j",
        "narration/nar_m11b1c2d3e4f5g6h"
      ],
      "kept_edits": 1,
      "warnings": [
        "German: the voiceover of “Create a project” runs 0.8 s past the end of the scene. Shorten it, or hold the scene (voiceover_update {fit: true, language})."
      ]
    }
  ]
}
TOOLLanguages

translation_update

Edit a translation

Write or correct translations by hand (kept when the take is translated again, unless the source text changes). Give key + text for one, or updates: [{key, text}] for several; keys come from take_get (localization.languages[].texts[].key, e.g. "caption/edt_…", "narration/nar_…", "scene/scn_…/title", "onscreen/ost_…"). Empty text removes the translation. A changed voiceover line needs voiceover_generate {language} to be spoken again. edit_revert undoes it.

Plain words: Writes or corrects one translation by hand. Hand edits survive translating again unless the original text changes.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
languagestringREQUIRED
One of the take's languages.
keystringOPTIONAL
Translation key.
textstringOPTIONAL
The translation (empty removes it).
updatesobject[]OPTIONAL
Several at once.
2 fields
keystringREQUIRED
Translation key.
textstringREQUIRED
The translation.
takestringOPTIONAL
Alias of take_id.
Request · what your agent sends
{
  "name": "translation_update",
  "arguments": {
    "take_id": "take_m11a2b3c4d5e6f7g",
    "language": "de",
    "key": "narration/nar_m11b1c2d3e4f5g6h",
    "text": "Melde dich zuerst mit dem Demo-Konto an."
  }
}
Response · structuredContent
{
  "source_language": "en-US",
  "languages": [
    {
      "language": "de",
      "name": "German",
      "translated": 9,
      "changed": 0,
      "missing": 0,
      "edited": 1,
      "texts": [
        {
          "key": "narration/nar_m11b1c2d3e4f5g6h",
          "kind": "narration",
          "scene": "Sign in",
          "source": "First, sign in with the demo account.",
          "text": "Melde dich zuerst mit dem Demo-Konto an.",
          "state": "current",
          "edited": true
        }
      ]
    }
  ]
}
TOOLLanguages

onscreen_text_scan

Find text on screen

Read the text visible in each scene of the cut (on-screen text recognition on this Mac, a few frames per scene) so it can be shown translated: each selected string becomes a small callout beside the text it translates in every language's video (it follows the camera and never covers the text). Text inside or touching a redaction is never read (redactions are painted over first), anything Secret Guard flags is skipped, and no pixels leave the Mac — only the selected strings are translated (translate_take {kinds: ["onscreen"]}). Large text and text near a click or the focused element are selected by default; select / deselect change that without scanning again. Scanning again keeps ids, selections and translations of text found again.

Plain words: Reads the text shown on screen in each scene (never inside blurred areas, and no images leave the Mac) and picks the large text and the text near clicks, so it can appear translated in a small label beside the original.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
scenesstring[]OPTIONAL
Only these scenes (default: every scene in the cut).
selectstring[]OPTIONAL
Select these for translation (no scan).
deselectstring[]OPTIONAL
Deselect these (no scan).
takestringOPTIONAL
Alias of take_id.
Request · what your agent sends
{
  "name": "onscreen_text_scan",
  "arguments": {
    "take_id": "take_m11a2b3c4d5e6f7g"
  }
}
Response · structuredContent
{
  "found": 3,
  "selected": 2,
  "texts": [
    {
      "id": "ost_m11d1e2f3g4h5j6k",
      "scene_id": "scn_m11a3b4c5d6e7f8g",
      "scene": "Sign in",
      "text": "Welcome back",
      "selected": true,
      "prominence": 1
    },
    {
      "id": "ost_m11d7k8m9n0p1q2r",
      "scene_id": "scn_m11a3b4c5d6e7f8g",
      "scene": "Sign in",
      "text": "Continue with email",
      "selected": true,
      "near_focus": true,
      "prominence": 0.42
    },
    {
      "id": "ost_m11d3s4t5v6w7x8y",
      "scene_id": "scn_m11a3b4c5d6e7f8g",
      "scene": "Sign in",
      "text": "Terms of use",
      "selected": false,
      "prominence": 0.3
    }
  ]
}
TOOLInteractive demos

interactive_build

Build the interactive demo

Interactive (click-through) demo of a recorded take: a still per step, a pulsing hotspot where the click happened and a short tooltip; viewers click the hotspot (or Next). Steps come from the cut in output order: each scene's start (a chapter title), every click, typing (the still shows the typed text) and the scene's checkpoint; cut-out ranges, removed events and excluded scenes have none. Hotspots come from the clicked element (or a small square around the click) mapped through crop and camera; tooltips from the caption on screen, else the voiceover sentence, else a sentence about the click, else the scene's intent. Stills are rendered from the edited, redacted output (captions off: the tooltip says it). reset:false (default) keeps your edits, order and deletions and adds steps for new clicks; reset:true starts over. Then interactive_update edits steps, interactive_export writes the offline HTML demo, interactive_share makes a link with an embed code. edit_revert undoes it.

Plain words: Turns the recorded take into a click-through demo: a title for each scene, a step for every click and typing, and the result each scene ends on, with a pulsing hotspot where the click happened and a short tooltip.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
resetbooleanOPTIONAL
Start over (drops edits, order and deletions).Default false.
takestringOPTIONAL
Alias of take_id.
Request · what your agent sends
{
  "name": "interactive_build",
  "arguments": {
    "take_id": "take_m11a2b3c4d5e6f7g"
  }
}
Response · structuredContent
{
  "built": true,
  "language": "en-US",
  "title": "Create a project",
  "canvas": {
    "width": 1920,
    "height": 1080
  },
  "options": {
    "voiceover": true,
    "chapters": true
  },
  "steps": [
    {
      "step_id": "ist_scn_m11a3b4c5d6e7f8g",
      "number": 1,
      "kind": "chapter",
      "scene": "New project",
      "scene_id": "scn_m11a3b4c5d6e7f8g",
      "output_time": 0,
      "text": "Create a project from the dashboard",
      "text_from": "chapter",
      "advance": "click"
    },
    {
      "step_id": "ist_evt_m11e1f2g3h4j5k6m",
      "number": 2,
      "kind": "click",
      "scene": "New project",
      "scene_id": "scn_m11a3b4c5d6e7f8g",
      "event_id": "evt_m11e1f2g3h4j5k6m",
      "output_time": 1.18,
      "hotspot": {
        "x": 0.8125,
        "y": 0.0954,
        "width": 0.0315,
        "height": 0.056
      },
      "text": "Click New Project to start",
      "text_from": "caption",
      "advance": "click"
    },
    {
      "step_id": "ist_evt_m11e7f8g9h0j1k2m",
      "number": 3,
      "kind": "type",
      "scene": "New project",
      "scene_id": "scn_m11a3b4c5d6e7f8g",
      "event_id": "evt_m11e7f8g9h0j1k2m",
      "output_time": 3.42,
      "hotspot": {
        "x": 0.36,
        "y": 0.38,
        "width": 0.18,
        "height": 0.04
      },
      "text": "Type “Launch plan” in Project name.",
      "text_from": "event",
      "advance": "click"
    },
    {
      "step_id": "ist_cp_scn_m11a3b4c5d6e7f8g",
      "number": 4,
      "kind": "checkpoint",
      "scene": "New project",
      "scene_id": "scn_m11a3b4c5d6e7f8g",
      "output_time": 5.95,
      "text": "The project opens with its first board.",
      "text_from": "event",
      "advance": "click"
    }
  ]
}
TOOLREAD-ONLYInteractive demos

interactive_get

Get the interactive demo

The interactive demo's steps as the export shows them: step_id, kind (chapter, click, type, checkpoint), the still's output_time, the hotspot normalized to the still (null = a Next button), the tooltip text and where it comes from (text_from: caption, narration, event, intent, chapter or custom), advance (click or auto), edited fields, without_zoom (the camera hid the hotspot, so that still is drawn without camera moves), plus steps whose frame was cut (skipped) and warnings (a hotspot off-screen even without zoom). language: one of the take's languages (texts translated; translate_take {kinds:["interactive"]} translates custom and event tooltips). Works before interactive_build (derived on the fly; built:false). preview_frame {output_time} shows a step's still (with captions; the export hides them).

Plain words: Lists the demo's steps as viewers will see them: when the picture is taken, where the hotspot is, the tooltip and where its text comes from.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
languagestringOPTIONAL
A language of the take (default: its own).
takestringOPTIONAL
Alias of take_id.
Request · what your agent sends
{
  "name": "interactive_get",
  "arguments": {
    "take_id": "take_m11a2b3c4d5e6f7g",
    "language": "de"
  }
}
Response · structuredContent
{
  "built": true,
  "language": "de",
  "title": "Create a project",
  "canvas": {
    "width": 1920,
    "height": 1080
  },
  "options": {
    "voiceover": true,
    "chapters": true
  },
  "steps": [
    {
      "step_id": "ist_scn_m11a3b4c5d6e7f8g",
      "number": 1,
      "kind": "chapter",
      "scene": "New project",
      "scene_id": "scn_m11a3b4c5d6e7f8g",
      "output_time": 0,
      "text": "Create a project from the dashboard",
      "text_from": "chapter",
      "advance": "click"
    },
    {
      "step_id": "ist_evt_m11e1f2g3h4j5k6m",
      "number": 2,
      "kind": "click",
      "scene": "New project",
      "scene_id": "scn_m11a3b4c5d6e7f8g",
      "event_id": "evt_m11e1f2g3h4j5k6m",
      "output_time": 1.18,
      "hotspot": {
        "x": 0.8125,
        "y": 0.0954,
        "width": 0.0315,
        "height": 0.056
      },
      "text": "Click New Project to start",
      "text_from": "caption",
      "advance": "click"
    },
    {
      "step_id": "ist_evt_m11e7f8g9h0j1k2m",
      "number": 3,
      "kind": "type",
      "scene": "New project",
      "scene_id": "scn_m11a3b4c5d6e7f8g",
      "event_id": "evt_m11e7f8g9h0j1k2m",
      "output_time": 3.42,
      "hotspot": {
        "x": 0.36,
        "y": 0.38,
        "width": 0.18,
        "height": 0.04
      },
      "text": "Type “Launch plan” in Project name.",
      "text_from": "event",
      "advance": "click"
    },
    {
      "step_id": "ist_cp_scn_m11a3b4c5d6e7f8g",
      "number": 4,
      "kind": "checkpoint",
      "scene": "New project",
      "scene_id": "scn_m11a3b4c5d6e7f8g",
      "output_time": 5.95,
      "text": "The project opens with its first board.",
      "text_from": "event",
      "advance": "click"
    }
  ]
}
TOOLInteractive demos

interactive_update

Edit the interactive demo

Edit interactive demo steps (step ids from interactive_get). One step: text (the tooltip; reset_text goes back to the looked-up text), hotspot {x,y,width,height} normalized to the step's still (remove_hotspot: a Next button instead; reset_hotspot: the click's own), output_time (show another frame of the same scene; reset_frame), placement (auto, top, bottom, left, right), advance ("auto": not clickable, moves on after duration seconds or its voiceover; "click"). Several: delete [ids], merge [ids] (into the first: its frame and hotspot, tooltips joined), order [ids] (these first, in this order), restore (bring deleted and merged steps back). options {voiceover, chapters}. Edits survive interactive_build refreshes; edit_revert undoes them. Returns the steps.

Plain words: Changes steps: a tooltip's words, where the hotspot is, which frame is shown, or whether a step moves on by itself; deletes, merges and reorders steps.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
step_idstringOPTIONAL
The step to change (ist_…).
textstringOPTIONAL
New tooltip text.
reset_textbooleanOPTIONAL
Back to the caption / voiceover / event text.
hotspotobjectOPTIONAL
Normalized to the step's still (the 1920×1080 output canvas), top-left origin.
4 fields
xnumberREQUIRED
Left edge, 0…1 of the still's width.
ynumberREQUIRED
Top edge, 0…1 of the still's height.
widthnumberREQUIRED
0…1 of the still's width.
heightnumberREQUIRED
0…1 of the still's height.
remove_hotspotbooleanOPTIONAL
No hotspot: the step shows a Next button.
reset_hotspotbooleanOPTIONAL
Back to the click's own hotspot.
output_timenumberOPTIONAL
Show the frame at this output second (same scene).Min 0.
reset_framebooleanOPTIONAL
Back to the step's own frame.
placementenumOPTIONAL
Where the tooltip goes.One of auto, top, bottom, left, right.
advanceenumOPTIONAL
click: the viewer clicks; auto: the step moves on by itself.One of click, auto.
durationnumberOPTIONAL
Seconds an auto step stays (0 = its voiceover's length).Min 0, max 60.
deletestring[]OPTIONAL
Delete these steps.
mergestring[]OPTIONAL
Merge these steps into the first of them.
orderstring[]OPTIONAL
Put these steps first, in this order.
restorebooleanOPTIONAL
Bring deleted and merged steps back.
optionsobjectOPTIONAL
Demo options.
2 fields
voiceoverbooleanOPTIONAL
Play each step's voiceover (viewers turn sound on).Default true.
chaptersbooleanOPTIONAL
A title step at each scene's start.Default true.
takestringOPTIONAL
Alias of take_id.
Request · what your agent sends
{
  "name": "interactive_update",
  "arguments": {
    "take_id": "take_m11a2b3c4d5e6f7g",
    "step_id": "ist_evt_m11e7f8g9h0j1k2m",
    "text": "Name the project"
  }
}
Response · structuredContent
{
  "built": true,
  "language": "en-US",
  "title": "Create a project",
  "canvas": {
    "width": 1920,
    "height": 1080
  },
  "options": {
    "voiceover": true,
    "chapters": true
  },
  "steps": [
    {
      "step_id": "ist_scn_m11a3b4c5d6e7f8g",
      "number": 1,
      "kind": "chapter",
      "scene": "New project",
      "scene_id": "scn_m11a3b4c5d6e7f8g",
      "output_time": 0,
      "text": "Create a project from the dashboard",
      "text_from": "chapter",
      "advance": "click"
    },
    {
      "step_id": "ist_evt_m11e1f2g3h4j5k6m",
      "number": 2,
      "kind": "click",
      "scene": "New project",
      "scene_id": "scn_m11a3b4c5d6e7f8g",
      "event_id": "evt_m11e1f2g3h4j5k6m",
      "output_time": 1.18,
      "hotspot": {
        "x": 0.8125,
        "y": 0.0954,
        "width": 0.0315,
        "height": 0.056
      },
      "text": "Click New Project to start",
      "text_from": "caption",
      "advance": "click"
    },
    {
      "step_id": "ist_evt_m11e7f8g9h0j1k2m",
      "number": 3,
      "kind": "type",
      "scene": "New project",
      "scene_id": "scn_m11a3b4c5d6e7f8g",
      "event_id": "evt_m11e7f8g9h0j1k2m",
      "output_time": 3.42,
      "hotspot": {
        "x": 0.36,
        "y": 0.38,
        "width": 0.18,
        "height": 0.04
      },
      "text": "Name the project",
      "text_from": "custom",
      "advance": "click",
      "edited": [
        "text"
      ]
    },
    {
      "step_id": "ist_cp_scn_m11a3b4c5d6e7f8g",
      "number": 4,
      "kind": "checkpoint",
      "scene": "New project",
      "scene_id": "scn_m11a3b4c5d6e7f8g",
      "output_time": 5.95,
      "text": "The project opens with its first board.",
      "text_from": "event",
      "advance": "click"
    }
  ]
}
TOOLInteractive demos

interactive_export

Export the interactive demo

Write the interactive demo as an offline HTML demo: a folder (index.html opens from file:// with no server; the player, JPEG stills at 1920 and 960 px wide, voiceover clips, manifest.json) and a ZIP next to it, in the take's exports. Stills are rendered from the edited, redacted output. languages:["source","de"] (or "all") puts every language in one demo with a language switch. The same as export_render {formats:["interactive"]}. The export is validated (every image present, manifest, hotspots inside the stills) before it completes; export_validate {job_id} checks it again.

Plain words: Saves the demo as a small website that opens offline from its index.html, plus a ZIP to send or upload. Every chosen language is in one demo with a language switch.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
languagesstring[]OPTIONAL
Languages in the demo (default: the take's own).
waitbooleanOPTIONAL
Wait for the export.Default true.
timeoutnumberOPTIONAL
Max seconds to wait.Default 600. Min 5, max 3600.
takestringOPTIONAL
Alias of take_id.
Request · what your agent sends
{
  "name": "interactive_export",
  "arguments": {
    "take_id": "take_m11a2b3c4d5e6f7g",
    "languages": [
      "source",
      "de"
    ]
  }
}
Response · structuredContent
{
  "job_id": "exp_m11f1g2h3j4k5m6n",
  "take_id": "take_m11a2b3c4d5e6f7g",
  "format": "interactive",
  "status": "completed",
  "progress": 1,
  "output_path": "/Users/you/Movies/DemoTake/Exports/create-a-project-interactive-20261027-101500",
  "side_files": [
    "/Users/you/Movies/DemoTake/Exports/create-a-project-interactive-20261027-101500.zip"
  ],
  "languages": [
    "en-US",
    "de"
  ],
  "file_size_bytes": 1843200,
  "file_size_mb": 1.8
}
TOOLInteractive demos

interactive_share

Share the interactive demo

Upload the interactive demo to DemoTake Cloud and create a share link (the DemoTake app must be signed in; the same plans as video share links). Uses the latest interactive export (job_id to pick one; exports first when there's none). visibility: public (default), code (an access code: access_code, or one is generated) or invite (invite: emails). expires_in_days (default 30; null = no expiry on subscriptions), allow_download (the offline ZIP). Returns the link, the embed URL and a responsive <iframe> embed code for websites and docs. Revoke or change the link in the app's Share sheet.

Plain words: Uploads the demo to DemoTake Cloud and gives back a link and a snippet to embed it on a website or in docs, with the same privacy options as video links.

Parameters

take_idstringREQUIRED
Take handle (take_…) returned by take_create, demo_create or take_list.
job_idstringOPTIONAL
A completed interactive export (default: the latest).
titlestringOPTIONAL
Link title (default: the take's name).
visibilityenumOPTIONAL
Who can open it.One of public, code, invite.
access_codestringOPTIONAL
Access code for visibility code (4+ characters).
invitestring[]OPTIONAL
People to invite (visibility invite).
expires_in_daysnumberOPTIONAL
Days the link works (1–365); null = no expiry (subscriptions).Min 1, max 365.
allow_downloadbooleanOPTIONAL
Let viewers download the offline demo (ZIP).Default true.
takestringOPTIONAL
Alias of take_id.
jobstringOPTIONAL
Alias of job_id.
Request · what your agent sends
{
  "name": "interactive_share",
  "arguments": {
    "take_id": "take_m11a2b3c4d5e6f7g",
    "visibility": "public",
    "expires_in_days": 30
  }
}
Response · structuredContent
{
  "share_id": "shr_m11g1h2j3k4m5n6p",
  "url": "https://demotake.my/s/Qm9vb2xlYW5fZGVtb19saW5r",
  "embed_url": "https://demotake.my/s/Qm9vb2xlYW5fZGVtb19saW5r/embed",
  "embed_code": "<div style=\"position:relative;width:100%;max-width:1200px;aspect-ratio:16/10.4\"><iframe src=\"https://demotake.my/s/Qm9vb2xlYW5fZGVtb19saW5r/embed\" title=\"Create a project\" loading=\"lazy\" allow=\"autoplay; fullscreen\" referrerpolicy=\"strict-origin-when-cross-origin\" style=\"position:absolute;inset:0;width:100%;height:100%;border:0\"></iframe></div>",
  "visibility": "public",
  "expires_at": "2026-11-26T10:15:00.000Z",
  "status": "ready"
}
TOOLREAD-ONLYShare links: embeds, CTAs, analytics

share_list

List share links

DemoTake Cloud share links of the signed-in workspace (the DemoTake app must be signed in), newest first; take_id limits it to one take's links. Each link has its url, status, visibility, unique viewers (views), analytics_enabled, show_badge, cta, and for videos and interactive demos embed_url and embed_html (a responsive <iframe> to paste into websites and docs; share_embed adds autoplay, a start time or hides the title). capabilities says what the plan allows (full or basic analytics, calls to action, hiding the badge).

Plain words: Lists your DemoTake Cloud share links with how many people watched them, and the code to embed each video or interactive demo on a website.

Parameters

take_idstringOPTIONAL
Only this take's links (the local take handle or its DemoTake Web id).
takestringOPTIONAL
Alias of take_id.
Request · what your agent sends
{
  "name": "share_list",
  "arguments": {
    "take_id": "take_m11a2b3c4d5e6f7g"
  }
}
Response · structuredContent
1 link (1 live).
{
  "shares": [
    {
      "share_id": "shr_m11g1h2j3k4m5n6p",
      "take_id": "take_m11a2b3c4d5e6f7g",
      "title": "Tidewell: plan a route",
      "kind": "video",
      "url": "https://demotake.my/s/Qm9vb2xlYW5fZGVtb19saW5r",
      "embed_url": "https://demotake.my/s/Qm9vb2xlYW5fZGVtb19saW5r/embed",
      "embed_html": "<div style=\"position:relative;width:100%;max-width:1280px;aspect-ratio:16/9\"><iframe src=\"https://demotake.my/s/Qm9vb2xlYW5fZGVtb19saW5r/embed\" title=\"Tidewell: plan a route\" loading=\"lazy\" allow=\"autoplay; fullscreen; picture-in-picture\" allowfullscreen referrerpolicy=\"strict-origin-when-cross-origin\" style=\"position:absolute;inset:0;width:100%;height:100%;border:0\"></iframe></div>",
      "status": "ready",
      "visibility": "public",
      "allow_download": true,
      "expires_at": "2026-11-26T10:15:00.000Z",
      "width": 1920,
      "height": 1080,
      "duration": 96.4,
      "views": 214,
      "analytics_enabled": true,
      "show_badge": true,
      "cta": null,
      "chapters": [
        {
          "title": "Harbors",
          "start": 0
        },
        {
          "title": "Routes",
          "start": 38.2
        },
        {
          "title": "Share the plan",
          "start": 71.5
        }
      ],
      "capabilities": {
        "analytics": "full",
        "cta": true,
        "hide_badge": true
      }
    }
  ]
}
TOOLREAD-ONLYShare links: embeds, CTAs, analytics

share_embed

Embed code for a share link

A responsive <iframe> snippet for a video or interactive demo link, for websites, docs and help centers. Options (videos): autoplay (starts muted), start (seconds); show_title false hides the title. Public links play right away; access-code links ask for the code inside the frame; invite-only links show a link to the share page. Unfurlers such as Notion, Slack and Medium also pick the player up from the link itself (oEmbed).

Plain words: Gives back a snippet that plays the video on any website or help center, optionally starting muted, at a given time, or without the title.

Parameters

share_idstringREQUIRED
The link's shr_… handle or its public slug (the last part of the /s/… URL).
autoplaybooleanOPTIONAL
Start playing, muted (videos).Default false.
startnumberOPTIONAL
Start time in seconds (videos).Min 0.
show_titlebooleanOPTIONAL
Show the title over the video.Default true.

Good to know

Pasting the plain link into Notion, Slack or Medium embeds the player too (oEmbed).

Request · what your agent sends
{
  "name": "share_embed",
  "arguments": {
    "share_id": "shr_m11g1h2j3k4m5n6p",
    "autoplay": true,
    "start": 40,
    "show_title": false
  }
}
Response · structuredContent
Embed code for “Tidewell: plan a route”.
{
  "share_id": "shr_m11g1h2j3k4m5n6p",
  "url": "https://demotake.my/s/Qm9vb2xlYW5fZGVtb19saW5r",
  "kind": "video",
  "embed_url": "https://demotake.my/s/Qm9vb2xlYW5fZGVtb19saW5r/embed?autoplay=1&t=40&title=0",
  "embed_html": "<div style=\"position:relative;width:100%;max-width:1280px;aspect-ratio:16/9\"><iframe src=\"https://demotake.my/s/Qm9vb2xlYW5fZGVtb19saW5r/embed?autoplay=1&amp;t=40&amp;title=0\" title=\"Tidewell: plan a route\" loading=\"lazy\" allow=\"autoplay; fullscreen; picture-in-picture\" allowfullscreen referrerpolicy=\"strict-origin-when-cross-origin\" style=\"position:absolute;inset:0;width:100%;height:100%;border:0\"></iframe></div>",
  "visibility": "public"
}
TOOLShare links: embeds, CTAs, analytics

share_update

Change a share link

Change a link's title, downloads, expiry, analytics, badge or calls to action. analytics false stops recording for this link (any plan). show_badge false hides “Made with DemoTake” on the share page and embeds; cta sets an end-screen button (plus an optional secondary link) and a link part-way through (at seconds for videos, after_step for interactive demos), with optional UTM parameters: both need Director, Team or Enterprise (402 otherwise). Links must be https; they open in a new tab. cta null removes them. Turn a link off or invite people in the app's Share sheet.

Plain words: Adds a “Book a demo” button at the end of the video and a small link part-way through, or turns analytics or the DemoTake badge off for one link.

Parameters

share_idstringREQUIRED
The link's shr_… handle or its public slug.
titlestringOPTIONAL
New title.
allow_downloadbooleanOPTIONAL
Let viewers download the file.
expires_in_daysnumberOPTIONAL
Days from now the link works (1–365); null = no expiry (subscriptions).Min 1, max 365.
analyticsbooleanOPTIONAL
Record privacy-first analytics for this link.
show_badgebooleanOPTIONAL
Show the “Made with DemoTake” badge (false needs Director, Team or Enterprise).
ctaobjectOPTIONAL
Calls to action. Director, Team and Enterprise plans. null removes them all.
3 fields
endobjectOPTIONAL
Button on the end screen (null removes it).
4 fields
kindenumOPTIONAL
link (default) or lead (a highlighted ask such as Book a demo; it only links out).One of link, lead.
textstringREQUIRED
Button text, one line, up to 60 characters.
urlstringREQUIRED
https link (no javascript:, http: or credentials; up to 2,000 characters).
secondaryobjectOPTIONAL
Optional second link under the button.
2 fields
textstringREQUIRED
Link text.
urlstringREQUIRED
https link.
midobjectOPTIONAL
A small link part-way through (null removes it).
5 fields
kindenumOPTIONAL
link or lead.One of link, lead.
textstringREQUIRED
Link text, up to 60 characters.
urlstringREQUIRED
https link.
atnumberOPTIONAL
Videos: seconds into the video when it appears.Min 0.
after_stepnumberOPTIONAL
Interactive demos: it appears after this step (1-based, before the last step).Min 1.
utmobjectOPTIONAL
Append UTM parameters to the links (existing utm_* parameters win).
3 fields
sourcestringOPTIONAL
utm_source (default demotake).
mediumstringOPTIONAL
utm_medium (default share).
campaignstringOPTIONAL
utm_campaign (optional).

Good to know

Links must be https; they open in a new tab. Calls to action and hiding the badge need Director, Team or Enterprise.

Request · what your agent sends
{
  "name": "share_update",
  "arguments": {
    "share_id": "shr_m11g1h2j3k4m5n6p",
    "cta": {
      "end": {
        "kind": "lead",
        "text": "Book a demo",
        "url": "https://tidewell.example/demo",
        "secondary": {
          "text": "See pricing",
          "url": "https://tidewell.example/pricing"
        }
      },
      "mid": {
        "text": "Try Tidewell free",
        "url": "https://tidewell.example/start",
        "at": 38
      },
      "utm": {
        "campaign": "launch"
      }
    }
  }
}
Response · structuredContent
Updated “Tidewell: plan a route” (cta).
{
  "share_id": "shr_m11g1h2j3k4m5n6p",
  "take_id": "take_m11a2b3c4d5e6f7g",
  "title": "Tidewell: plan a route",
  "kind": "video",
  "url": "https://demotake.my/s/Qm9vb2xlYW5fZGVtb19saW5r",
  "embed_url": "https://demotake.my/s/Qm9vb2xlYW5fZGVtb19saW5r/embed",
  "embed_html": "<div style=\"position:relative;width:100%;max-width:1280px;aspect-ratio:16/9\"><iframe src=\"https://demotake.my/s/Qm9vb2xlYW5fZGVtb19saW5r/embed\" title=\"Tidewell: plan a route\" loading=\"lazy\" allow=\"autoplay; fullscreen; picture-in-picture\" allowfullscreen referrerpolicy=\"strict-origin-when-cross-origin\" style=\"position:absolute;inset:0;width:100%;height:100%;border:0\"></iframe></div>",
  "status": "ready",
  "visibility": "public",
  "allow_download": true,
  "expires_at": "2026-11-26T10:15:00.000Z",
  "width": 1920,
  "height": 1080,
  "duration": 96.4,
  "views": 214,
  "analytics_enabled": true,
  "show_badge": true,
  "cta": {
    "end": {
      "kind": "lead",
      "text": "Book a demo",
      "url": "https://tidewell.example/demo",
      "secondary": {
        "text": "See pricing",
        "url": "https://tidewell.example/pricing"
      }
    },
    "mid": {
      "kind": "link",
      "text": "Try Tidewell free",
      "url": "https://tidewell.example/start",
      "at": 38
    },
    "utm": {
      "source": "demotake",
      "medium": "share",
      "campaign": "launch"
    }
  },
  "chapters": [
    {
      "title": "Harbors",
      "start": 0
    },
    {
      "title": "Routes",
      "start": 38.2
    },
    {
      "title": "Share the plan",
      "start": 71.5
    }
  ],
  "capabilities": {
    "analytics": "full",
    "cta": true,
    "hide_badge": true
  }
}
TOOLREAD-ONLYShare links: embeds, CTAs, analytics

share_analytics

Share link analytics

Privacy-first analytics of one link for the last 7, 30 or 90 days: views (page vs embed), unique viewers (per day), average watch time, completion rate, the drop-off curve (5% steps of a video, or each step of an interactive demo) mapped to scene titles with the biggest drop, scenes reached, top referrer hosts, countries, devices, languages and CTA clicks. Plans without full analytics get views and unique viewers (level "basic"). DemoTake stores daily counts only: no cookies, IP addresses or user agents.

Plain words: Tells you how a shared demo is doing: views, unique viewers, how long people watch, how many finish, and the scene where most of them stop watching.

Parameters

share_idstringOPTIONAL
The link's shr_… handle or its public slug.
slugstringOPTIONAL
The public slug, if you only have the URL (same as share_id).
rangenumberOPTIONAL
Days: 7, 30 (default) or 90.Default 30. Min 7, max 90.

Good to know

Daily counts only: no cookies, IP addresses or user agents. Plans without full analytics get views and unique viewers (level basic).

Request · what your agent sends
{
  "name": "share_analytics",
  "arguments": {
    "share_id": "shr_m11g1h2j3k4m5n6p",
    "range": 30
  }
}
Response · structuredContent
Last 30 days: 214 views, 187 unique viewers, 40% completed, 52 s watched on average. Most viewers drop off around 45% in (scene “Routes”): 27% of those who started.
{
  "share_id": "shr_m11g1h2j3k4m5n6p",
  "title": "Tidewell: plan a route",
  "url": "https://demotake.my/s/Qm9vb2xlYW5fZGVtb19saW5r",
  "kind": "video",
  "level": "full",
  "analytics_enabled": true,
  "range_days": 30,
  "from": "2026-09-28",
  "to": "2026-10-27",
  "totals": {
    "views": 214,
    "page_views": 161,
    "embed_views": 53,
    "unique_viewers": 187,
    "plays": 176,
    "watch_seconds": 9152,
    "avg_watch_seconds": 52,
    "completions": 71,
    "completion_rate": 0.403,
    "cta_clicks": 19,
    "cta_click_through": 0.089
  },
  "daily": [
    {
      "date": "2026-10-26",
      "views": 12,
      "unique_viewers": 11
    },
    {
      "date": "2026-10-27",
      "views": 9,
      "unique_viewers": 9
    }
  ],
  "all_time": {
    "views": 402,
    "unique_viewers": 355
  },
  "drop_off": {
    "unit": "percent",
    "started": 176,
    "completed": 71,
    "points": [
      {
        "at": 0,
        "time": 0,
        "viewers": 176,
        "share": 1,
        "scene": "Harbors"
      },
      {
        "at": 40,
        "time": 38.6,
        "viewers": 149,
        "share": 0.847,
        "scene": "Routes"
      },
      {
        "at": 45,
        "time": 43.4,
        "viewers": 102,
        "share": 0.58,
        "scene": "Routes"
      }
    ],
    "biggest_drop": {
      "from": 40,
      "to": 45,
      "lost": 0.267,
      "scene": "Routes"
    }
  },
  "scenes": [
    {
      "title": "Harbors",
      "start": 0,
      "reached": 1
    },
    {
      "title": "Routes",
      "start": 38.2,
      "reached": 0.847
    },
    {
      "title": "Share the plan",
      "start": 71.5,
      "reached": 0.44
    }
  ],
  "referrers": [
    {
      "host": null,
      "views": 88
    },
    {
      "host": "help.tidewell.example",
      "views": 53
    },
    {
      "host": "news.ycombinator.com",
      "views": 31
    }
  ],
  "countries": [
    {
      "country": "NO",
      "views": 61
    },
    {
      "country": "SE",
      "views": 44
    },
    {
      "country": "DE",
      "views": 30
    }
  ],
  "devices": [
    {
      "device": "desktop",
      "views": 151
    },
    {
      "device": "phone",
      "views": 55
    },
    {
      "device": "tablet",
      "views": 8
    }
  ],
  "languages": [
    {
      "language": "en",
      "views": 120
    },
    {
      "language": "de",
      "views": 24
    }
  ],
  "ctas": [
    {
      "id": "end",
      "clicks": 14
    },
    {
      "id": "mid",
      "clicks": 5
    }
  ]
}
TOOLScheduled re-recording

schedule_create

Schedule re-recording

Re-record a take on a schedule or on every deploy (DemoTake Cloud, Team plan). The take must be in DemoTake Cloud (sync it first). A run replays the take's steps (or spec), re-records only scenes whose UI changed (only_changed), keeps your edits, exports the formats you ask for, compares each scene with the last run, and can update the take's share links in place (publish_mode auto, or approval). Runs execute on a runner: a Mac with DemoTake Agent (Settings › Account › Use this Mac as a runner) or demotake runner in CI on a Mac. executor "cloud" checks web specs in DemoTake's cloud browser without a Mac (checks only). With webhook true the result has trigger_token and hook_url, shown once: call POST <webhook.url> with Authorization: Bearer <token> after a deploy, or paste hook_url into Vercel/Netlify.

Plain words: Re-records a synced take every weekday morning and after each deploy. Only scenes whose UI changed are recorded again, edits stay, and the take's share links update after someone approves. The trigger token is shown once.

Parameters

take_idstringREQUIRED
The take (local handle of a synced take, or its DemoTake Cloud id).
namestringOPTIONAL
A name for the schedule (default: “<take> re-recording”).
cronstringOPTIONAL
When it runs: a 5-field cron expression (minute hour day-of-month month day-of-week) or @daily, @weekly, @hourly, e.g. "0 9 * * 1-5" (weekdays 09:00). Omit for deploy-webhook / on-demand only. Team: at least 60 minutes apart.
timezonestringOPTIONAL
IANA time zone for cron (default UTC), e.g. Europe/Stockholm.
webhookbooleanOPTIONAL
Accept deploy webhooks (POST …/trigger). The trigger token and hook URL are shown once in the result: store them as CI secrets.
specobjectOPTIONAL
A demotake.json to run (object). Omit to replay the take's own recorded steps (take_to_spec), which is usually what you want.
spec_takestringOPTIONAL
Which take of the spec to run (default: the first).
only_changedbooleanOPTIONAL
Re-record only scenes whose UI changed since the last run (take_diff); the rest keep their footage.Default true.
recordbooleanOPTIONAL
false = test only (DemoTest): run steps and checks, compare, record and publish nothing.Default true.
target_urlstringOPTIONAL
Open this URL instead of the spec's target (staging, a preview deploy). Web takes only.
languagesstring[]OPTIONAL
Also export these languages (the take must have them).
formatsenum[]OPTIONAL
Formats to export (default 16:9).One of 16:9, 9:16, 4:3, 1:1, gif, reviewer_pack.
interactivebooleanOPTIONAL
Also rebuild the interactive click-through demo (and update interactive links).
executorenumOPTIONAL
runner (default): a Mac runner records, exports and publishes. cloud: DemoTake's cloud browser runs a web spec's checks only (record false, public URL, no secret steps); no Mac needed.One of runner, cloud.
publish_modeenumOPTIONAL
What a successful run does to the take's share links: approval (default: wait for someone to approve it), auto (update the links at once: same URL and analytics, new version, rollback kept), off.One of approval, auto, off.
share_idsstring[]OPTIONAL
Only update these links (default: every live link of the take).
notify_onenumOPTIONAL
When to notify: changes (default: failures, changes, approvals, publishes), always, failures, never.One of changes, always, failures, never.
slack_urlstringOPTIONAL
Slack incoming webhook (https://hooks.slack.com/…). Empty string removes it.
webhook_urlstringOPTIONAL
An https endpoint that gets signed JSON for each run (X-DemoTake-Signature). The signing secret is shown once. Empty string removes it.
emailenumOPTIONAL
Who gets email: admins (default), creator or none.One of admins, creator, none.
enabledbooleanOPTIONAL
Pause (false) or resume a schedule.
takestringOPTIONAL
Alias of take_id.
Request · what your agent sends
{
  "name": "schedule_create",
  "arguments": {
    "take_id": "take_m11a2b3c4d5e6f7g",
    "cron": "0 7 * * 1-5",
    "timezone": "Europe/Stockholm",
    "webhook": true,
    "only_changed": true,
    "formats": [
      "16:9",
      "9:16"
    ],
    "publish_mode": "approval",
    "notify_on": "changes",
    "slack_url": "https://hooks.slack.com/services/T000/B000/XXXXXXXX"
  }
}
Response · structuredContent
{
  "schedule_id": "sch_m12a1b2c3d4e5f6g",
  "take_id": "take_m11a2b3c4d5e6f7g",
  "name": "Tidewell: funnel report re-recording",
  "enabled": true,
  "cron": "0 7 * * 1-5",
  "timezone": "Europe/Stockholm",
  "next_run_at": "2026-10-28T06:00:00.000Z",
  "webhook": {
    "enabled": true,
    "url": "https://api.demotake.my/v1/schedules/sch_m12a1b2c3d4e5f6g/trigger",
    "token_hint": "…h2Kp"
  },
  "options": {
    "only_changed": true,
    "record": true,
    "target_url": null,
    "languages": [],
    "formats": [
      "16:9",
      "9:16"
    ],
    "interactive": false
  },
  "executor": "runner",
  "publish": {
    "mode": "approval",
    "share_ids": null
  },
  "notify": {
    "on": "changes",
    "email": "admins",
    "slack": {
      "hint": "hooks.slack.com/…XXXX"
    },
    "webhook": null
  },
  "trigger_token": "dtt_…(shown once)",
  "hook_url": "https://api.demotake.my/v1/hooks/schedules/dtt_…"
}
TOOLREAD-ONLYScheduled re-recording

schedule_list

List schedules

Schedules of the signed-in workspace (one take's with take_id): cadence, next run, deploy webhook, options, publish mode, last status; plus this month's usage (runs, run minutes), the plan's limits and how many runners are online.

Plain words: Lists the workspace's schedules (or one take's) with their cadence and last status, this month's runs and run minutes, the plan's limits and how many runners are online.

Parameters

take_idstringOPTIONAL
Only this take's schedules (local handle or DemoTake Cloud id).
takestringOPTIONAL
Alias of take_id.
Request · what your agent sends
{
  "name": "schedule_list",
  "arguments": {
    "take_id": "take_m11a2b3c4d5e6f7g"
  }
}
Response · structuredContent
{
  "available": true,
  "schedules": [
    {
      "schedule_id": "sch_m12a1b2c3d4e5f6g",
      "name": "Tidewell: funnel report re-recording",
      "cron": "0 7 * * 1-5",
      "timezone": "Europe/Stockholm",
      "last_status": "succeeded"
    }
  ],
  "usage": {
    "period": "2026-10",
    "runs": 14,
    "run_minutes": 38.5
  },
  "limits": {
    "runs_month": 600,
    "min_interval_minutes": 60,
    "max_concurrent_runs": 3
  },
  "runners_online": 1
}
TOOLScheduled re-recording

schedule_update

Change a schedule

Change a schedule's cadence, webhook, options, publishing or notifications, or pause it (enabled false). Only the fields you pass change. Turning webhook on returns a new trigger token once.

Plain words: Changes a schedule: here it pauses the nightly run and switches the links to update automatically. Only the fields you pass change.

Parameters

schedule_idstringREQUIRED
sch_… handle.
namestringOPTIONAL
A name for the schedule (default: “<take> re-recording”).
cronstringOPTIONAL
When it runs: a 5-field cron expression (minute hour day-of-month month day-of-week) or @daily, @weekly, @hourly, e.g. "0 9 * * 1-5" (weekdays 09:00). Omit for deploy-webhook / on-demand only. Team: at least 60 minutes apart.
timezonestringOPTIONAL
IANA time zone for cron (default UTC), e.g. Europe/Stockholm.
webhookbooleanOPTIONAL
Accept deploy webhooks (POST …/trigger). The trigger token and hook URL are shown once in the result: store them as CI secrets.
specobjectOPTIONAL
A demotake.json to run (object). Omit to replay the take's own recorded steps (take_to_spec), which is usually what you want.
spec_takestringOPTIONAL
Which take of the spec to run (default: the first).
only_changedbooleanOPTIONAL
Re-record only scenes whose UI changed since the last run (take_diff); the rest keep their footage.Default true.
recordbooleanOPTIONAL
false = test only (DemoTest): run steps and checks, compare, record and publish nothing.Default true.
target_urlstringOPTIONAL
Open this URL instead of the spec's target (staging, a preview deploy). Web takes only.
languagesstring[]OPTIONAL
Also export these languages (the take must have them).
formatsenum[]OPTIONAL
Formats to export (default 16:9).One of 16:9, 9:16, 4:3, 1:1, gif, reviewer_pack.
interactivebooleanOPTIONAL
Also rebuild the interactive click-through demo (and update interactive links).
executorenumOPTIONAL
runner (default): a Mac runner records, exports and publishes. cloud: DemoTake's cloud browser runs a web spec's checks only (record false, public URL, no secret steps); no Mac needed.One of runner, cloud.
publish_modeenumOPTIONAL
What a successful run does to the take's share links: approval (default: wait for someone to approve it), auto (update the links at once: same URL and analytics, new version, rollback kept), off.One of approval, auto, off.
share_idsstring[]OPTIONAL
Only update these links (default: every live link of the take).
notify_onenumOPTIONAL
When to notify: changes (default: failures, changes, approvals, publishes), always, failures, never.One of changes, always, failures, never.
slack_urlstringOPTIONAL
Slack incoming webhook (https://hooks.slack.com/…). Empty string removes it.
webhook_urlstringOPTIONAL
An https endpoint that gets signed JSON for each run (X-DemoTake-Signature). The signing secret is shown once. Empty string removes it.
emailenumOPTIONAL
Who gets email: admins (default), creator or none.One of admins, creator, none.
enabledbooleanOPTIONAL
Pause (false) or resume a schedule.
Request · what your agent sends
{
  "name": "schedule_update",
  "arguments": {
    "schedule_id": "sch_m12a1b2c3d4e5f6g",
    "enabled": false,
    "publish_mode": "auto"
  }
}
Response · structuredContent
{
  "schedule_id": "sch_m12a1b2c3d4e5f6g",
  "enabled": false,
  "next_run_at": null,
  "publish": {
    "mode": "auto",
    "share_ids": null
  }
}
TOOLScheduled re-recording

schedule_delete

Delete a schedule

Delete a schedule and its run history. Share links keep the version they show.

Plain words: Deletes a schedule and its run history. Share links keep showing the version they show now.

Parameters

schedule_idstringREQUIRED
sch_… handle.
Request · what your agent sends
{
  "name": "schedule_delete",
  "arguments": {
    "schedule_id": "sch_m12a1b2c3d4e5f6g"
  }
}
Response · structuredContent
{
  "deleted": true,
  "schedule_id": "sch_m12a1b2c3d4e5f6g"
}
TOOLScheduled re-recording

schedule_run

Run a schedule now

Queue a run of a schedule now (Run now). If one is already queued, that run is returned (coalesced). A runner picks it up; follow it with schedule_runs.

Plain words: Queues a run now. A runner picks it up; if a run is already waiting, that one is returned instead of a second.

Parameters

schedule_idstringREQUIRED
sch_… handle.
Request · what your agent sends
{
  "name": "schedule_run",
  "arguments": {
    "schedule_id": "sch_m12a1b2c3d4e5f6g"
  }
}
Response · structuredContent
{
  "run": {
    "run_id": "run_m13a1b2c3d4e5f6g",
    "status": "queued",
    "trigger": "manual"
  },
  "coalesced": false
}
TOOLREAD-ONLYScheduled re-recording

schedule_runs

Run history

A schedule's recent runs (newest first), or one run with run_id: status (queued, running, succeeded, failed, cancelled, expired), publish_status (pending_approval, published, rolled_back, …), per-scene changed / unchanged / failed with reasons and before/after stills of the rendered (redacted) export, checks, exports, duration, the runner, and the review URL in DemoTake Web.

Plain words: Shows what a run did: which scenes changed (with before and after pictures from the rendered, redacted export), whether checks passed, the exports, and what happened to the share links.

Parameters

schedule_idstringOPTIONAL
sch_… handle (list its runs).
run_idstringOPTIONAL
run_… handle (one run, with its log for the schedule's managers).
limitintegerOPTIONAL
Runs to list (1–100).Default 10. Min 1, max 100.
Request · what your agent sends
{
  "name": "schedule_runs",
  "arguments": {
    "run_id": "run_m13a1b2c3d4e5f6g"
  }
}
Response · structuredContent
{
  "run_id": "run_m13a1b2c3d4e5f6g",
  "status": "succeeded",
  "publish_status": "pending_approval",
  "trigger": "webhook",
  "trigger_meta": {
    "source": "github",
    "ref": "main",
    "sha": "8c1f2e9"
  },
  "runner": {
    "id": "rnr_m10a1b2c3d4e5f6g",
    "name": "Studio Mac mini"
  },
  "run_seconds": 168,
  "summary": {
    "passed": true,
    "changed": 1,
    "regenerated": 1,
    "assertions": {
      "passed": 3,
      "total": 3,
      "failed": []
    },
    "scenes": [
      {
        "title": "Sign in",
        "status": "unchanged",
        "score": 0,
        "reasons": []
      },
      {
        "title": "Create a report",
        "status": "changed",
        "score": 0.18,
        "reasons": [
          "New: Cohort",
          "Gone: Funnel (beta)"
        ],
        "still_url": "https://api.demotake.my/v1/media/…",
        "before_url": "https://api.demotake.my/v1/media/…"
      }
    ]
  },
  "review_url": "https://demotake.my/app/take/take_m11a2b3c4d5e6f7g?schedules=sch_m12a1b2c3d4e5f6g&run=run_m13a1b2c3d4e5f6g"
}
TOOLScheduled re-recording

run_approve

Approve a run

Publish a run that waits for approval: the take's share links switch to its exports (same URLs, analytics kept). reject true keeps the current version instead.

Plain words: Approves a run that waits for approval: the take's share links switch to its exports, keeping their URLs, embeds and analytics.

Parameters

run_idstringREQUIRED
run_… handle.
rejectbooleanOPTIONAL
Reject instead of approve.Default false.
Request · what your agent sends
{
  "name": "run_approve",
  "arguments": {
    "run_id": "run_m13a1b2c3d4e5f6g"
  }
}
Response · structuredContent
{
  "run_id": "run_m13a1b2c3d4e5f6g",
  "status": "succeeded",
  "publish_status": "published",
  "published": [
    {
      "share_id": "shr_m11g1h2j3k4m5n6p",
      "from_version": 1,
      "to_version": 2
    }
  ]
}
TOOLScheduled re-recording

run_rollback

Roll back a run

Undo a published run: its share links show the version they showed before (as a new version; URLs and analytics stay).

Plain words: Undoes a published run: its links show the version they showed before. URLs and analytics stay.

Parameters

run_idstringREQUIRED
run_… handle of a published run.
Request · what your agent sends
{
  "name": "run_rollback",
  "arguments": {
    "run_id": "run_m13a1b2c3d4e5f6g"
  }
}
Response · structuredContent
{
  "run_id": "run_m13a1b2c3d4e5f6g",
  "publish_status": "rolled_back",
  "restored": [
    {
      "share_id": "shr_m11g1h2j3k4m5n6p",
      "from_version": 2,
      "to_version": 3
    }
  ]
}
DEMOTAKE AGENT ONLYScheduled re-recording

runner_run

Run one scheduled run here

Runner mode (DemoTake Agent): claim the oldest queued run of the runner's workspace, execute it on this Mac (re-record, export, compare, upload) and report it. Pass the runner token (dtr_…, from DemoTake Web › Schedules › Runners) or leave it out to use this Mac's own runner registration. Returns the finished run, or idle true when nothing was queued. demotake runner calls this in a loop.

Plain words: Runs one queued scheduled run on this Mac with a runner token, then reports it. demotake runner calls this in a loop for CI on a Mac.

Parameters

tokenstringOPTIONAL
Runner token (dtr_…). Defaults to this Mac's runner.
Request · what your agent sends
{
  "name": "runner_run",
  "arguments": {
    "token": "dtr_…"
  }
}
Response · structuredContent
{
  "run_id": "run_m13a1b2c3d4e5f6g",
  "status": "succeeded",
  "publish_status": "pending_approval",
  "summary": {
    "changed": 1
  }
}