Overview
During a run, Ottili Coder can drive a real browser through Playwright*. This lets Coder verify user interfaces, capture screenshots, fill in forms and run browser flows – rather than only reading code. The browser integration is a built-in Coder capability: it runs inside a Coder workspace and shares the same mission, task queue, logs and audit trail as the rest of the Coder run.
The integration is deliberately operations-focused: every browser run is correlation-aware, credit-metered, approval-gated for external targets and resilient against slow dependencies. It reports honestly when a dependency is unreachable instead of silently pretending success.
What the browser integration can do
- Verify UI*: Coder navigates to a URL, inspects visible elements and reads text and state.
- Screenshots*: Individual steps or full pages are captured as images.
- Drive forms*: clicks, inputs, selects and waits are executed as a sequence.
- Run flows*: multiple steps in a row – for example login → navigation → action → screenshot.
- Evaluate code*: via an evaluation step, Coder can query values from the page context.
The engine is stateless per call: you pass a list of steps, Coder executes them against the configured browser profile and returns the result.
How it works
The browser integration is bound to a Coder workspace*. Each workspace has a browser profile, including a default Playwright environment. If you do not supply an explicit profile_id, Coder uses the workspace's default profile.
A browser run is triggered through the browser-execute endpoint of the Ottili Coder workspace API:
POST …/workspaces/{slug}/browser/executeThe request body contains:
profile_id*(optional)* – which browser profile to use; defaults to the workspace profile when omitted.steps– the list of steps to execute (see below).timeout_ms– total timeout for the run, in milliseconds.approval_ref*(optional)* – approval reference once a step touches an external target (see Approvals).
The response contains a per-step result plus a correlation_id you can use to trace the entire run across the platform.
Steps and actions
Each step is an object with an action and optional fields (url, selector, text, key, timeout_ms). Supported actions:
navigate– go to a URL (relative to the profile'sbase_urlor absolute); optionalwait_until.click– click an element byselector.type– enter a value (text) into a field (selector).press– press a key (key).wait_for– wait for an element (selector) or a duration.snapshot– capture the page title, URL and visible text (optionally the HTML).screenshot– capture a screenshot of the current state (formatpng, optionalfull_page).
A profile can define allowed_origins. Navigations within allowed origins run directly; targets outside require an approval (see below). Note: at navigate the engine already checks whether the URL is allowed by the profile – otherwise the step is rejected with a clear error.
Credits and billing
Browser runs are credit-metered*. A run reserves a bounded, limited budget from the shared company credit wallet (product surface ottili_coder). Billing is idempotent: reserve → charge on success, refund on failure. A single run consumes only a small, bounded budget – browser launches are resource-heavy, so the budget is intentionally kept low.
If the wallet is unreachable, the run does not fail silently: Coder reports an honest degraded state (degraded) and still executes the run rather than faking success.
Approvals for external navigation
When a step navigates to a host outside the profile's allowed_origins, it is a protected external effect*. Coder then consults the existing approval model:
- Without
approval_ref, the run is blocked with a notice that an approval is required. - With
approval_ref, Coder checks whether the approval isapprovedfor exactly this company. An approval from a different company never satisfies the condition. - If the approval service is unreachable, fail-safe applies: the external step must not run.
This keeps control of a third-party host always approval-driven, never silent.
Correlation ID and observability
Every browser run carries a stable `X-Correlation-ID`*. It is carried upstream (dashboard, CLI or desktop) and stays continuous across the whole chain – Unified API, credits, approvals and audit. Start, result, duration and failure (without secrets) are written to Core telemetry and structured logs, so you can fully trace a single browser run.
Resilience and degraded states
Every cross-service call (credits, approval) runs through bounded timeouts and circuit breakers. A slow or failing dependency can never block a browser request indefinitely. If a dependency fails, Coder reports an explicitly recoverable state (degraded) – never a silent success and never an unhandled 500.
Status and availability
The browser integration is a built-in Coder capability* (available in the Coder workspace). Requirements:
- A Coder workspace with an enabled browser profile.
- Sufficient credits in the shared company wallet.
- A valid approval for navigations outside allowed origins.
It is currently not a standalone section on the public Coder page*; it is used from within the Coder workspace. The capability continues to evolve – check the status and product pages for the current state. How Ottili ONE publicly labels maturity is described in [Understanding feature-status labels](/docs/understand-feature-status-labels).
Related articles
- [Ottili Coder – Overview](/docs/ottili-coder)
- [Coder modes](/docs/coder-modes)
- [Local, cloud and hybrid runs](/docs/coder-local-cloud-hybrid-runs)
- [Security](/docs/coder-security)
- [Validation](/docs/coder-validation)
- [Troubleshooting](/docs/coder-troubleshooting)
- [Understanding feature-status labels](/docs/understand-feature-status-labels)
Was this article helpful?
