CAPABILITY · DOM
A compact indexed map of the page, not raw HTML
The live page is serialized into a numerically-indexed list of its interactive elements under a token budget, so the planner reasons over signal instead of markup.
POST /api/v1/observeCapability
Inside token-efficient dom state
Feeding raw HTML to a model is slow and expensive — most of a page is layout, scripts and decoration. The engine walks the live DOM for actionable elements, records their role and label, assigns each a stable numeric index, and trims the result to a token budget. The planner then emits "click [4]" rather than a CSS selector, which is both cheaper to reason about and more robust to cosmetic change.
Interactive elements only
Buttons, links, inputs, comboboxes and ARIA roles are extracted with their labels. Layout containers, scripts and decoration are dropped before the model sees anything.
Numeric addressing
Actions reference [1], [2], [3] — indices into the observed map — rather than CSS or XPath. A compiled path survives class-name churn that would break a selector.
A budget, not a hope
The map is trimmed to fit a token budget regardless of page size, so a huge listing page costs about the same to plan against as a small form.
Observable on its own
POST /api/v1/observe returns the indexed state without taking any action, which is how you inspect what the planner will see before you let it act.
How it works
The mechanism, in execution order
4 stages, in the order the runtime performs them — not a summary of them.
- 1Load and settleThe engine drives a real browser to the URL and waits for the interactive state to settle before reading anything.
- 2Walk for actionablesThe DOM is traversed for elements a person could act on, with their roles and accessible labels.
- 3Index and trimEach survivor gets a stable numeric index; the list is trimmed to the token budget.
- 4Plan by indexThe planner chooses an action against an index, and the executor maps that index back to the real element.
In practice
A call you can paste and run
A live page reduced to the four things you can act on — the same state the planner receives, and nothing else.
curl -X POST https://twin-browser.com/api/v1/observe \
-H "Authorization: Bearer $TWIN_API_KEY" \
-H "content-type: application/json" \
-d '{"url":"https://app.example.com/calendar"}'
# {
# "indexedState": {
# "elements": [
# { "i": 1, "role": "link", "label": "Calendar" },
# { "i": 2, "role": "button", "label": "Tuesday" },
# { "i": 3, "role": "combobox", "label": "Time slot" },
# { "i": 4, "role": "button", "label": "Reserve" }
# ]
# },
# "credits_charged": 1
# }- Load and settledone
- Walk for actionablesrunning
- Index and trimqueued
- Plan by indexqueued
What it costs, how to switch it on
Priced from the same rate card the API serves
Every credit figure on this page is read from the rate card behind GET /api/v1/pricing — it is not typed into the copy, so it cannot drift from what you are billed.
1 credit per observation
POST /api/v1/observe bills a flat 1-credit floor and makes no model call — it serializes, it does not reason. The same serialization happens inside every planned run, where it is part of the 10-credit run rather than a separate charge.
Turning it on
- 1Nothing to enableIndexed state is how the runtime sees every page. There is no flag.
- 2Inspect it directlyPOST /api/v1/observe with a URL when you want to see the map before letting an agent act on it.
- 3Use it as a cheap probeOver MCP, observe_page is the read-only tool an agent can call to check a page without spending a run.
- 4Pair it with a monitorA monitor with check_type "observe" watches this same serialization on a schedule and only fires when it changes.
At a glance
The contract, in the fewest rows that say it
| Property | Twin Browser |
|---|---|
| Endpoint | POST /api/v1/observe |
| Input | `url` (the authorization signal) |
| Output | Indexed interactive map |
| Addressing | Stable numeric indices |
| Dropped | Layout, scripts, decoration |
| Actions taken | None |
Limits
Where it stops, and what it deliberately does not do
A capabilities page with no limits section is a brochure. These are the ceilings, the defaults that will surprise you, and the things this capability is not.
Limits and defaults
- The map is capped to a token budget. On a very large page the tail is trimmed, and the elements you want may not be in the first screenful of state.
- Indices are stable for one observation, not across page navigations — a compiled path re-observes as it goes.
- Elements rendered only after an interaction (a menu that opens on click) are not in the initial map by definition.
- A page that never settles is bounded by the readiness wait, not by the page.
What it does not do
- It does not return the page HTML. If you want the markup, that is not this endpoint.
- It does not extract data. A structured read is POST /api/v1/extract; observe returns the interactive surface, not the content.
- It does not take an action, click anything, or leave a session behind.
- It does not set a token-count response header — the model-facing budget is internal, and no route publishes it.
FAQ
Questions about token-efficient dom state
Why not just send the model the HTML?
What keeps a compiled path from breaking on a layout tweak?
How big can a page be?
Can I see the state without running anything?
Keep reading
The rest of the platform
The capabilities this one works with, the tools that expose it, the guides that use it end to end, and the vocabulary behind it.
Structured extraction
Ask for fields or a JSON schema and get typed data back — or match a per-host template, expand a row selector, or capture the page's own XHR, and pay no model cost at all.
Deterministic replay
A successful run is minimized into a named, versioned skill — an ordered action path with its variable parts lifted out — and replaying it is a program, not a prompt.
Change monitoring
A monitor reads a value on a cadence, hashes it, compares it to last time, and posts an HMAC-signed webhook only when it actually moved.
Tools that expose it
Guides
Related reading
Put your agent to work. Keep the decision.
Start free. Hand your agent a goal on a site you authorize, set the guardrails, and let the first successful run compile the skill every run after it replays.