Skip to main content
This is the loop agents run: snapshot the page to get a compact digest of interactable elements, each with a ref (e1, e2, …); act on a ref — click, fill, type; re-snapshot after the page changes; repeat. The digest is the model’s ground truth, and refs keep actions deterministic where coordinates would not. CLI and cURL examples assume $RT holds a browser-small runtime id with browser b1 open (see Browser Sessions).

Endpoints

Snapshot

snapshot returns {url, title, viewport, rev, elements} — every visible element the page offers for interaction (links, buttons, inputs, and anything with a role, click handler, or tabindex), reduced to what a model needs: ref, tag, role, accessible name, bounding box, enabled/visible, plus href/text/input_type where they exist. Each snapshot re-issues the tab’s refs.
Snapshot parameters viewport is {width, height}; rev increments on every snapshot of the tab. A snapshot returns at most 500 elements. Each element in elements:

Targeting elements

Every action takes a target. A ref string ("e3") from the latest snapshot is the common case — fast, and it pins the exact element the model saw. The other forms reach elements without a snapshot: Shorthand: TypeScript accepts {x: 640, y: 420} and Python the tuple (640, 420) for coords. On css targets, pierce: true searches through shadow roots; any CSS selector also supports host >>> inner for one explicit shadow-root hop. The CLI takes e3, css:…, text:…, xpath:…, role:…, or x,y.

Actions

POST .../actions/{verb} where verb is one of click, dblclick, hover, fill, type, press, hotkey, scroll. Actions wait for the element to be actionable (visible, stable, enabled, receiving events — editable too for fill/type), dispatch real input events, then wait for the page to settle, and return an ActionResult. An element that never becomes actionable is not an HTTP error: the result comes back ok: false with reason naming the failed check. The examples use a small inline page so every target resolves:
Common action options (every verb accepts them) Per-verb fields

Typing secrets

fill with secret_ref types the value of a secret without it ever reaching your client, logs, or model context. The name is a secret key in an Identity provider attached to the runtime; a name that is not attached returns 400.

Evaluate

evaluate runs a JavaScript expression in the page and returns {value, error, is_error} (isError in TypeScript) — value is the result as JSON. Use it for page data, DOM reads, or scroll positions the digest doesn’t expose. Returned promises are awaited.
A thrown exception comes back as is_error: true with the message in error, not as an HTTP error.

Dialogs

alert, confirm, and prompt dialogs are dismissed automatically about four seconds after they open, so an unanswered dialog never wedges the page. To answer one yourself, call dialog while it is open — the call waits briefly for a dialog to appear and returns 404 if none does. accept confirms (true in the SDKs; omitted on the wire means dismiss), prompt_text fills a prompt(), and auto_dismiss: true dismisses any open dialog immediately.

Notes

  • Act on fresh refs. Each snapshot re-issues the tab’s refs, and a ref points at the element’s position in the DOM — after a navigation or a re-render, snapshot again before acting. A ref the tab has never issued returns 404.
  • If an action returns ok: false, check reason — visible, enabled, editable, receives-events, or stable. The element is hidden, disabled, covered, or still animating; scroll it into view, wait, or pass force as a last resort.
  • settle: false (--no-settle) skips the post-action wait — useful when an action starts a long navigation you’ll wait for with navigate or display.wait_stable instead.
  • evaluate is full code execution in the page — treat the expression as code you ship, not as user input.