Browser drives a real Chrome browser from your code. Use it for pages that only show their content after JavaScript runs, such as single-page apps, price widgets, and dashboards, where a plain fetch returns an empty shell. There are three ways in:
Browser.readopens one page, waits for it, and returns its title and content in one call.Browser.executegives the browser a task in plain words and lets it work through the pages step by step.- The step-by-step methods (
navigate,click,fill,get, and the rest) drive a page one command at a time.
Browser is off until you turn it on with browser on the agent, or attach a named browser. It works in tools, jobs, webhooks, triggers, device triggers, processors, web routes, and workflow code steps. It is not available in tool conditions, model resolvers, or MCP server resolvers.
Quick example
src/agent.ts
lua browser read.
Where pages open
Every command runs on one of two browsers:- The user’s desktop browser, when the Lua desktop app is running with its browser connected. Pages open with the user’s own logins.
- The Lua cloud browser, a fresh Chrome that Lua runs for you. Each session starts empty, with no cookies or logins, and is deleted when it closes.
engine setting decides which one runs:
The retry on Browser-Use applies to the commands that open or look at a page:
session_open, navigate, and snapshot, including the ones Browser.execute runs. The session then stays on Browser-Use, and a fallback row is written to the logs. Browser.read does not move to Browser-Use; it returns the page it got.
Jobs, webhooks, triggers, web routes, and workflow steps run with no user at a desktop, so they always use the Lua cloud browser. When the desktop browser doesn’t answer as a session opens, Browser.read and the commands that open a page (session_open, navigate) continue on the Lua cloud browser and a fallback row is written to the logs. If the desktop stops answering later, in the middle of a read or for any other command, the call fails with session_lost.
Configuration
Set these on the agent’sbrowser option. browser: true uses the defaults. A named browser takes the same settings.
'auto' | 'agent-browser' | 'browser-use'
Which browser runs the commands; see Where pages open. Default
'auto'.'browser-use' | 'none'
What happens when the Lua cloud browser can’t get past a page.
'browser-use' (default) retries the command once on Browser-Use. 'none' keeps every page on the Lua cloud browser, and the command returns the page it got. Browser-Use is never used when engine is 'agent-browser' or allowedDomains is set.string
A two-letter country code, such as
'gb' or 'de', for the country Browser-Use browses from. It applies only to work that runs on Browser-Use.string[]
Hosts the browser may open. List each host the pages need, or use a wildcard such as
*.ikea.com for a domain and its subdomains. The list is checked before every command that opens a URL, Browser.read and Browser.execute included; a blocked URL fails with BROWSER_DOMAIN_NOT_ALLOWED. On the Lua cloud browser it also applies to redirects and everything a page loads (scripts, images, requests), so include the hosts a page loads its content from. On the desktop browser, Browser.read also checks the page it ended on after redirects and fails with BROWSER_DOMAIN_NOT_ALLOWED when that host is not allowed. Empty or unset allows all public sites. Setting it turns off the Browser-Use retry, because the list can’t be enforced on a remote browser.string[]
Actions that must be approved before they run.
Browser.execute checks these categories: navigate, click, fill, type, select, press, scroll, and submit. submit covers clicking a button such as Buy, Pay, Place order, Sign in, or Send, and pressing Enter. When a run reaches one of them it stops with stopReason: 'confirmation_required' and a pendingAction; see execute. For the step-by-step commands the list goes to the browser, which holds a matching command until you call Browser.confirm({ id }) or Browser.deny({ id }). On engine 'browser-use', a non-empty list makes Browser.execute fail with BROWSER_USE_CONFIRM_UNSUPPORTED, because Browser-Use runs can’t pause for approval.'summary' | 'full' | 'none'
How much page content the browser log rows keep:
'summary' (default) keeps titles and sizes, 'full' also keeps page text (shortened), 'none' keeps neither.'always' | 'onError' | 'never'
When a log row carries a screenshot reference. Default
'onError'.number
How long a Lua cloud browser session may stay open, in whole minutes. Default 10, maximum 60. On
browser, a larger value is cut to 60 when the session opens. On a named browser, a value over 60 fails lua compile.number
How long a Lua cloud browser session may go without a command before it closes, in whole seconds. Default 120, maximum 900. On
browser, a larger value is cut to 900 when the session opens. On a named browser, a value over 900 fails lua compile.credentials is accepted but not enforced yet. A named browser also accepts maxConcurrentSessions (1 to 100) and persist; both are stored and not enforced yet.
Named browsers
A named browser is aLuaBrowser with its own settings. Attach one or more to the agent with browsers, then pick one per call with browser: '<name>'. Use them when different jobs need different rules, such as one browser locked to a supplier site and another that can open anything.
src/browsers/supplier.ts
src/agent.ts
- Attaching a browser turns the browser on.
browser: trueis not needed whenbrowsershas at least one entry. - Every method takes
browser.Browser.readtakes it in its options;Browser.executeand the step-by-step methods take it in their input object. - Calls without
browseruse thebrowseroption’s settings when the agent setsbrowser, and the first browser inbrowserswhen it doesn’t. - An unknown name fails with
BROWSER_PROFILE_NOT_FOUND:Browser.readthrows it, and the other methods return it incode. - Names start with a letter or digit and use only letters, digits,
_, and-, up to 64 characters. The constructor throws on any other name.defineBrowser({...})is the same asnew LuaBrowser({...}). lua compilechecks every setting. An unknownengineorfallback, aproxyCountrythat isn’t two letters, a limit that isn’t a whole number in range, two browsers with the same name, or an entry inbrowsersthat isn’t aLuaBrowserfails the compile.
lua push browser --name supplier-portal, then lua push agent so the agent picks up its browsers list. lua push all pushes browsers with everything else. lua browsers lists and deletes them.
Methods
read(url, options?)
Reads one page in a new browser session and closes that session when it is done, whether the read succeeded or not. Steps: open the URL, wait forwaitFor if given, then read the page title, the final URL, and the content of selector.
string
required
An absolute
http:// or https:// URL.'load' | 'networkidle' | string
What to wait for after the page opens.
'load' waits for the load event, 'networkidle' waits until the page stops making requests, and any other string is a CSS selector to wait for, such as '.price'. Unset reads as soon as the page has opened.string
CSS selector of the element to read. Default
'body', the whole page. On the Lua cloud browser with format: 'text', every match is read, in page order, up to 200 matches, joined by a blank line, with empty matches skipped. With format: 'html' the cloud browser reads the first match. The desktop browser reads the first match in both formats.'text' | 'html'
'text' (default) returns the visible text, 'html' returns the element’s inner HTML.number
Time budget for the whole read, from opening the browser session to the last read. Default 60000. A value under 1000 is raised to 1000 and a value over 100000 is cut to 100000. When the budget runs out, the read fails with
timeout.string
A label for the session in your logs. Every read still gets its own new session.
string
The named browser to read with.
BrowserReadResult
read throws an error with name: 'BrowserError', a code, and for http_error the page’s status; see Errors. Closing the session after the read takes up to 10 more seconds.
In a tool
src/tools/ReadPageTool.ts
In a scheduled job
src/jobs/PriceCheckJob.ts
In a webhook
src/webhooks/PageChangedWebhook.ts
execute(input)
Gives the browser a task in plain words. A model looks at the page, picks the next action (navigate, click, fill, read), and repeats until the task is done or a limit is reached. Use it when you can describe what you want but not the exact clicks.execute input
string
required
What the browser should do, in plain words. An empty task rejects with
name: 'BrowserExecuteError' and code BROWSER_EXECUTE_INVALID_INPUT.string
The page the run starts on. Unless you set
allowedDomains or allowAnyDomain, and the agent has no allowedDomains of its own, the run stays on this page’s domain.object
A JSON Schema the
output must match. The model gets a chance to fix output that doesn’t match; if it still doesn’t, the run fails with BROWSER_OUTPUT_SCHEMA_MISMATCH. A schema that is not an object rejects with BROWSER_EXECUTE_INVALID_INPUT.number
The most actions the run may take. Default 25, between 1 and 60.
number
The most the run may spend on the model, in US dollars. Default 1, at most 10. Zero or less fails with
invalid_argument.number
The most time the run may take. Default 300000 (5 minutes), at most 900000 (15 minutes).
string
A model code to drive the run. Unset uses the platform’s default. A model the agent can’t use fails with
MODEL_NOT_AVAILABLE.string
Run in the session with this key, for example one you opened and signed in to with the step-by-step methods. That session stays open after the run. Without it, the run opens its own session and closes it at the end.
string[]
Hosts this run may visit. When the agent has its own
allowedDomains, only hosts on both lists are allowed.boolean
true lets the run leave the startUrl domain. The agent’s allowedDomains still apply.string
The named browser to run with.
maxSteps, maxCostUsd, and timeoutMs are moved to the nearest allowed value.
execute result
execute returns a result instead of throwing when the run fails. Check status.
BrowserExecuteResult
execute runs at a time for each user. Another run fails with BROWSER_EXECUTE_CONCURRENCY. On engine 'browser-use', execute runs as a Browser-Use task: steps is 0, there is no history, and confirmActions must be empty.
Step-by-step commands
For pages you need to interact with,Browser also has one method per browser command. Each takes one object, with an optional sessionKey and browser, and returns { engine, data?, error?, code? }. These methods do not throw when a command fails; check error and code.
The input type of every method is exported as
BrowserCommandInputs['<method>']. Commands with the same sessionKey share one session for the length of one conversation or run. A command that needs a page before one is open fails with no_page; open one with navigate or session_open first. On the Lua cloud browser, these commands are not available and fail with unsupported: upload, extract, pdf, download, auth, state, act with a natural-language instruction, wait with fn, screenshot with path, and network with action: 'har'. On engine 'browser-use', every command except close returns an error that starts with BROWSER_STEPWISE_UNSUPPORTED.
Limits
The session limits are defaults. Raise them withmaxSessionMinutes and idleTimeoutSeconds on browser or on a named browser, up to the maximum. The Browser.read and Browser.execute limits are set per call. The concurrency limits are set by the platform.
When a Lua cloud browser session reaches its length or idle limit it closes, and the next command fails with
session_lost; open the page again. The Lua cloud browser never opens private or internal network addresses.
Logs
Every browser command writes rows to the agent’s logs under thebrowser source:
Arguments that look like secrets are redacted. Page text appears only with
logContent: 'full'. Rows written by lua browser carry the dev channel.
Errors
Browser.read throws an error with name: 'BrowserError' and one of these codes. Browser.execute and the step-by-step methods return the code in code instead. Every method rejects with BROWSER_DISABLED and BROWSER_UNAVAILABLE.
On engine
'browser-use', the step-by-step commands return no code; their error starts with BROWSER_STEPWISE_UNSUPPORTED.
Browser.execute adds these codes:
Testing
lua test does not open a browser: every Browser method, execute included, rejects with BrowserError with code BROWSER_UNAVAILABLE. Try a page or a task from the terminal with lua browser read and lua browser run, or push the agent and run the tool, job, or webhook on the platform, then read lua logs --type browser.
Types
These types are exported fromlua-cli:
BrowserApi,BrowserStepwiseApi,BrowserStepwiseCommandName,BrowserSessionInput,BrowserCommandInputs,BrowserCommandResultBrowserApiReadOptions,BrowserReadOptions,BrowserReadResult,BrowserReadFormat,BrowserReadLoadStateBrowserExecuteInput,BrowserExecuteResult,BrowserExecuteStatus,BrowserExecuteStopReason,BrowserExecuteStep,BrowserExecutePendingActionBrowserErrorCode,BrowserErrorFieldsBrowserSwitchConfig,LuaBrowserConfig,LuaBrowserSettings,BrowserProfileOption
See also
LuaAgent— thebrowserandbrowsersoptionslua browser— read a page or run a task from the terminal, and list or delete named browsers- Logs and debugging — reading agent logs

