Embed the live view
Show a machine inside your own product, like a session viewer. Create a short-lived link and put it in an <iframe>. Your users can watch the agent work or, if you allow it, take control.
#Create a link
POST /api/machines/{id}/live-view
Authenticate with your API key, or with the machine's own mcpToken (so an agent can share its screen).
| Body field | Type | Default | |
|---|---|---|---|
mode |
string | desktop |
desktop (whole screen), app (one window, cropped), or browser (the machine's browser) |
interactive |
boolean | false |
false = watch only. Input is blocked on the machine, not just in the page. true = the viewer can use the mouse and keyboard. |
app |
string | — | For mode: "app": part of the window's class or title to show (for example gimp). Defaults to the focused window. |
ttlSeconds |
number | 3600 |
60 to 86,400 (24 hours) |
allowedOrigins |
string[] | any | Origins allowed to embed the link, for example ["https://app.example.com"]. Enforced with Content-Security-Policy: frame-ancestors. |
showControls |
boolean | true |
Show the small status pill and fullscreen button |
region |
object | — | Only stream this area: {"x", "y", "width", "height"} in whole pixels. Screen pixels for desktop; for browser, CSS pixels of the 1280×800 browser viewport. See Stream part of the screen. |
selector |
string | — | mode: "browser" only: stream just this element (a CSS selector such as #agenda), following it as the page scrolls or changes |
curl -X POST https://burrowbox.dev/api/machines/2f6aeedcd3/live-view \
-H "Authorization: Bearer $BURROWBOX_KEY" \
-H "Content-Type: application/json" \
-d '{"mode": "browser", "interactive": false, "ttlSeconds": 900, "allowedOrigins": ["https://app.example.com"]}'
{
"url": "https://burrowbox.dev/embed/2f6aeedcd3?t=…",
"expiresAt": 1790800000000,
"mode": "browser",
"interactive": false,
"iframe": "<iframe src=\"https://burrowbox.dev/embed/2f6aeedcd3?t=…\" …></iframe>"
}
#Stream part of the screen
Use region (desktop or browser) or selector (browser) to share only part of the machine, such as a single panel, a table or a form, without exposing the rest.
# Only the agenda table in the browser, watch only
curl -X POST https://burrowbox.dev/api/machines/2f6aeedcd3/live-view \
-H "Authorization: Bearer $BURROWBOX_KEY" -H "Content-Type: application/json" \
-d '{"mode": "browser", "selector": "#agenda", "interactive": false}'
# The top-left quarter of the desktop
curl -X POST https://burrowbox.dev/api/machines/2f6aeedcd3/live-view \
-H "Authorization: Bearer $BURROWBOX_KEY" -H "Content-Type: application/json" \
-d '{"mode": "desktop", "region": {"x": 0, "y": 0, "width": 720, "height": 450}}'
- Enforced on the machine: the area is cut out before anything is sent, so pixels outside it never reach the viewer, even if someone inspects the page. Browser frames are cropped, and desktop update requests are limited to the area.
- Interactive areas: clicks and typing work inside the area, and clicks outside it are dropped. A browser area can't navigate, go back or switch tabs, and doesn't show the page's URL or title.
- Selector: the stream follows the element as it moves. Until it's on screen, the viewer shows "Waiting for that part of the page".
- Dashboard: in Share → Area → Part of it…, drag a rectangle on a live screenshot, or enter a selector for the browser.
- Platform MCP:
machine_live_viewtakes the sameregionandselector.
#Embed it
<iframe
src="https://burrowbox.dev/embed/2f6aeedcd3?t=…"
style="width: 100%; aspect-ratio: 16 / 10; border: 0"
allow="clipboard-read; clipboard-write; fullscreen">
</iframe>
Create links on your server (your API key must never reach the browser), then pass the URL to your front end. Links are signed and expire on their own; anyone who has one can watch until then, so keep TTLs short.
#Events
The viewer posts messages to the embedding page:
window.addEventListener("message", (e) => {
if (e.origin !== "https://burrowbox.dev" || e.data?.source !== "burrowbox") return;
switch (e.data.type) {
case "connected": /* stream is live: e.data.mode */ break;
case "disconnected": /* reconnecting automatically */ break;
case "url": /* browser mode: e.data.url, e.data.title */ break;
case "expired": /* create a new link */ break;
}
});
#MCP
The platform MCP has the same capability as machine_live_view (id, mode, interactive, app, ttl_seconds, allowed_origins). An agent can hand a human a link to watch or take over.