Drive GodBrowser Cortex from your AI client
Run anti-fingerprint browser & scrape workflows across your own node cluster — at scale — straight from Claude or any MCP client. Point your client at one URL, authorize in your browser, and Cortex shards the run across the nodes you've enrolled.
Connect
A remote, streamable-HTTP MCP server — zero install, no local process. Add it to Claude Code with one command:
claude mcp add --transport http godbrowser-mcp \
https://mcp.godbrowser.ioOr drop this into any MCP client's mcpServers config:
{
"mcpServers": {
"godbrowser-mcp": {
"type": "http",
"url": "https://mcp.godbrowser.io"
}
}
}Tools
Each tool scopes to your account via your authorized session — submit, poll, fetch. The surface never exposes a node, our internals, or a browser-control url; it's strictly your workflows.
godbrowser_helpLearns you GodBrowser end to end. Call it bare for a compact onboarding guide — install, auth, the two surfaces, captcha and workflows — plus the automation playbooks and an index of the flag catalog. Pass section to read one topic (install, auth, surfaces, captcha, workflows, playbook, params, or a family name like persona/persist/proxy), or a query to filter the --bot-* flags. The full flag catalog is large, so fetch it deliberately with section:"params" or a query. Same corpus as the godbrowser://params/all resource.2 parameters
queryoptionala param name or keyword to filter the --bot-* flag catalog, e.g. "persist", "--bot-os", "proxy"sectionoptionalread one topic: "install" | "auth" | "surfaces" | "captcha" | "proxy" (the account egress pool + proxy flags) | "workflows" | "playbook" | "params" (the full flag catalog, large) | a family name (persona/persist/autoclean/ai/busymate/cdp). Omit both query and section for the onboarding guide + index.godbrowser_meReturns the authenticated account's identity (account_id, owner_user_id, email, name, role) — who this API key / session is operating as. Owner-scoped: returns only the caller's own identity, never another tenant, never a secret.godbrowser_workflowsList the built-in workflows + the persona/manifest schema + an example — self-describing, so call it first. It also documents custom_targets: how to run your OWN url + field map at scale (extract, the scrape templates, a saved recipe, and the requests-only playbook) rather than only the curated demo datasets.godbrowser_closeEnd the session and free its slot; returns the duration and how many actions ran.1 parameter · 1 required
session_idrequiredthe session_id from godbrowser_launchgodbrowser_launchStart a live instance under a coherent per-seed device persona; returns a session_id to thread through the calls below. Choose the egress at launch with proxy (any provider format) or proxy_provider/proxy_country to pick an exit out of your configured pool. When this machine is signed in to a GodBrowser account, persist now defaults to ON — the session's logins are saved to a stable default profile and are restorable from any computer. Pass persist:false for a throwaway session that leaves nothing behind.26 parameters
osoptionaldevice OS: windows | macos | linux (the node OS matches the persona so the host fingerprint stays coherent)browseroptionalbrowser engine: chrome | edge | firefox | safariseedoptionala stable seed string -> a stable, repeatable device identity (same seed = same device). It is ALSO the name this session is saved under: give each account its own seed and you can restore that exact login later; reuse one seed for two accounts and the second overwrites the first. The seed actually used comes back as persona_seed — record it with the account.persistoptionalDEFAULT ON when this machine is signed in to a GodBrowser account: your logins are saved and restorable from any computer. Pass false for a throwaway session that must leave no trace in your account.countryoptionalpreferred region/country for node placement, e.g. "us"captcha_provideroptionalcaptcha solver for this session: "2captcha" (the default, applied when you omit this) or "anticaptcha" — or "none"/"off" to launch with the solver DISARMED, which is the negative control. The fleet resolves the matching key server-side; solve_captcha reports the provider it cleared with. ⛔ Until T-1649 (2026-09-19) omitting this left the native solver at --bot-captcha-auto=off while the docs claimed it was armed, so a detected challenge was never solved; if you are reading an older captcha verdict, check whether its launch named a provider before believing it.headedoptionallocal only: show a real browser WINDOW (default) or run it invisibly. true = visible window you can watch; false = headless, no window. ⛔ ON THE HOSTED FLEET THIS IS NOT A CHOICE AND headed:false DOES NOT MAKE A SESSION HEADLESS: every fleet drive session is HEADED, always, and this parameter is discarded. That is deliberate — a headless launch renders WebGL through SwiftShader, and that renderer string is a fingerprint tell — so a host is only placeable for driving when it can actually render a headed browser. A fleet host advertising free HEADLESS slots therefore cannot take a drive session at all; if that is what you are hitting, the refusal now says so (blocked_by:"no_headed_slot_for_persona_os").evasionoptionalEVASION TIER — refuse to run on a host without a REAL GPU. OFF by default. A GPU-less or virtual-display host renders WebGL through SwiftShader, so UNMASKED_RENDERER reads "SwiftShader" under a desktop persona: a universally-read fingerprint tell. Pass true for work that faces a live site under scrutiny — registering an account, signing in, anything you will bank — and the scheduler will REFUSE (blocked_by:"no_real_gpu_node_for_persona_os") rather than place you on a SwiftShader host. ⚠️ The refusal is the feature: without this flag such a launch SUCCEEDS and serves a silently fingerprint-degraded session. Leave it off for interactive testing and authoring, where a SwiftShader host is an accepted trade.window_positionoptionalput the window exactly here, "X,Y" in display pixels (e.g. "120,80"). Overrides window_spread for the POSITION only — your value is used verbatim and nothing is emitted over it; the answer reports it under window.caller_wins.window_sizeoptionalmake the window exactly this big, "W,H" (e.g. "1280,800"). Overrides window_spread for the SIZE only. ⚠️ This does NOT change what a page reads as window.outerWidth/outerHeight/innerWidth/innerHeight — those come from the persona's own screen and are unaffected by any window size (measured). It DOES change document.documentElement.clientWidth/clientHeight, so a value far from the persona's inner size is a visible mismatch; window_spread picks a fitting one for you.verifyoptionalrestore this seed's banked session READ-ONLY, to check whether a saved login still works WITHOUT any risk to it. ⛔ An ordinary persist relaunch that finds itself logged out BANKS THE GUEST STATE OVER THE GOOD ROW (measured: v14/1043 B overwritten by v16/799 B and reported `banked`), so checking a bank used to be able to destroy it. With verify:true the session store refuses every write for this launch and the close answers bank_outcome:"read_only" — the banked row is exactly as it was. A write that somehow lands is reported as "read_only_VIOLATED", never folded into a normal verdict. Implies persist:true. Fleet only.window_spreadoptionalspread parallel browser windows so they do not land on top of each other. OFF by default. The geometry is DERIVED FROM THE PROFILE SEED, so the same seed returns to the same place on every relaunch (a returning profile whose window moved is less coherent than one that did not) while different seeds land apart. Position is chosen for spread; SIZE is chosen to track the persona's own declared screen -- never randomised, because document.documentElement.clientWidth reports the REAL window while window.innerWidth reports the persona's, and every pixel between them is a measurable mismatch. Always fully inside the display work area (macOS menu bar respected), never larger than the persona's declared screen, single display only. Your own --window-position / --window-size in extra args still WINS, per axis, and is never overridden. The launch answer reports the geometry MEASURED IN THE PAGE plus its coherence cost.proxyoptionaluse THIS proxy for the session, in whatever format your provider gave you: scheme://user:pass@host:port, user:pass@host:port, host:port, or host:port:user:pass. A form with no scheme is used as http:// — the same thing the browser itself does with it — and the answer says so (egress.scheme_defaulted); pass socks5:// or https:// explicitly if that is what it is. A provider pool URL is also accepted and is expanded inside the browser. ⛔ The persona's timezone and locale are MEASURED through this proxy before the browser starts; if that measurement cannot run, the launch is REFUSED (error:"exit_geo_unmeasured") rather than presenting the seed's geo on your exit (T-1712).proxy_typeoptionalBusyIP only — the exit's NETWORK CLASS: "mobile" (carrier/cellular ASN), "residential", or "any" (default). Pair it with the persona: a mobile persona (os "android"/"ios") on a mobile exit is a coherent device+network pair, while an android persona on a datacenter exit is a contradiction. Ignored by pool providers, which have no such marker.proxy_modeoptionalBusyIP only — PIN THE EXIT DEVICE or draw a new one per request. "rotate" (the historical default) gives A DIFFERENT EXIT IP FOR EVERY REQUEST: measured 2026-09-13, 15 serial requests returned 15 distinct IPs across multiple ASNs. Since a page opens one tunnel per connection (measured fan-out: example.com 6, Wikipedia 13, bbc.com/news 29), a rotate page load arrives at the origin as ~30 different addresses at once — which breaks server-side sessions and is the shape anti-bot is built to flag. "sticky" pins ONE DEVICE (measured: 1 distinct IP across 15 serial requests) and is what you want for any flow with state: a signup, a login, a cart, a dashboard. ⚠️ It pins a DEVICE, NOT AN ADDRESS — a carrier renumber can still move it (2 IPs were observed inside one 30-request burst), so never treat it as a stable IP or mint an IP-bound token across it without bracketing.proxy_sessionoptionalBusyIP only — an explicit session id to pin to (1-32 alphanumerics, NO dashes: a dash collides with the next marker in the username grammar and would silently pin a different session than you asked for). Implies sticky. Omit and pass proxy_mode:"sticky" to have one derived from the seed, which is usually what you want since it makes the pin reproducible for the same profile.proxy_provideroptionalpick an exit from your configured pool by provider, e.g. "nstproxy", "myprivateproxy"/"mpp", "2captcha", "oxylabs", "brightdata". Also accepts "busyip", which does NOT come from the pool: BusyIP has no proxy line to pick -- one gate, one base username, and the targeting (country, type, session) composed per launch from your account link, so pair it with proxy_country. BusyIP usually needs NO SETUP: if the account has no link of its own, the operator default is applied automatically, so proxy_provider:"busyip" generally just works. Call godbrowser_proxy FIRST to see whether it is available and whether it is your own link or the shared default — that answer also lists what to pass. A busyip launch REFUSES rather than falling through to direct egress when NEITHER a link nor a default is available, so a success is never secretly a direct connection.proxy_countryoptionalpick an exit whose provider string states this ISO-2 country, e.g. "US". An exit that states NO country is excluded rather than assumed to match, so you never silently egress from elsewhere.directoptional⚠️ EGRESS FROM THIS MACHINE'S OWN PUBLIC IP, with no proxy at all. The site sees the host address, so this is a DIAGNOSTIC CONTROL — use it to find out whether a block (a Cloudflare challenge loop, say) is IP-based, not as a normal way to browse. It overrides the account pool, which a launch with no proxy argument would otherwise still use. Off by default, and never chosen for you.resource_modeoptionalLIGHTWEIGHT PAGE LOAD (opt-in, OFF by default). "lite" drops non-essential FIRST-PARTY subresources before they hit the network -- images, fonts, media, stylesheet, beacons, pings, prefetch, cross-origin iframes -- for a faster, lower-proxy-bandwidth load; the page renders as unstyled-but-functional HTML. Main-frame HTML, XHR/fetch, and scripts always load. ⛔ FINGERPRINT RISK: a real Chrome always fetches its own images/fonts/CSS -- a session that never does is a distinguishing tell some detectors watch for (missing tracking pixel, unresolved fonts, a CSSOM mismatch). Use only for scrape/automation work, never a session meant to look like an ordinary visit.block_resourcesoptionalgranular override of resource_mode="lite" -- comma-separated tokens to block: images, fonts, media, stylesheet, beacons, pings, prefetch, iframes-3p. Same fingerprint risk as resource_mode.direct_resourcesoptional⛔ EGRESS SPLIT -- an IP-EXPOSURE lever, not a bandwidth lever. Direct-dials CROSS-ORIGIN static assets OUTSIDE the proxy instead of blocking them. MEASURED live, control-vs-switch on the same page load (T-1599, 2026-09-05): the direct-dialled third-party host sees THIS MACHINE'S REAL PUBLIC IP at the same moment the page origin sees the proxy exit, with Referer/Sec-Fetch-Site tying the two together (page/XHR egress 107.166.119.174 = the exit; the direct asset 89.28.43.197 = the real host IP; socket peer the origin itself, no proxy in path). A CDN or shared static host present on BOTH legs therefore learns the real IP behind your exit DIRECTLY -- that is de-anonymisation, not a coherence tell. ⛔ AND IT BUYS ALMOST NOTHING: the browser-side gate (T-0802) direct-dials only requests that are credential-less AND cross-origin AND not a vendor host, which excludes essentially every real page asset (a plain <script src> carries credentials and stays on the proxy). Measured direct-routed share: python.org 1 request / 9 KB of 500 -- bbc.com/news 6 of 213 (~3%) -- ikea.com 0 of 526 requests, 0 bytes. Same token grammar as block_resources plus "script". Unset by default; leave it unset unless you have deliberately decided that a named third party may learn your real IP.block_trackersoptionalDrop THIRD-PARTY ad/tracker requests, the way a real uBlock-Origin user does. ⭐ THE DEFAULT DEPENDS ON THE INTENT (T-1712, 2026-09-25): ON for an ordinary launch (browse / scrape / QA), OFF for a launch that declares a sign-up or sign-in — intent:"register"/"login", evasion:true, or verify:true. Pass true/false to decide yourself. WHY OFF FOR SIGN-UP/SIGN-IN: the blocklist carries googletagmanager.com — as a real default uBlock Origin install does (EasyPrivacy `||googletagmanager.com^`, Peter Lowe's list) — and sites load their FRAUD VENDORS through it: measured on ksl.com, PerimeterX and Sift arrive only via GTM, so with blocking on they never ran and the sign-up would have reached the site with no vendor token or device data, which is a risk signal in itself. WHY ON OTHERWISE: ad-tech, not the site, exhausts a proxy's CONCURRENT-STREAM cap — measured on bbc.com/news: ads/trackers/CMP were 61% of requests and 83% of bytes, peak tunnels ~59 -> ~23 with blocking, and the overflow surfaces as 429 too_many_streams / a bare ERR_TUNNEL_CONNECTION_FAILED. It DROPS requests rather than rerouting them, so there is no IP to split (unlike direct_resources). Needs persona_class to take effect (defaulted alongside it). The answer's `tracker_blocking` says what this session got and why.intentoptionalwhat this session is FOR: "register" (creating an account), "login" (signing in, or checking a saved login), "browse", or "scrape". "register" and "login" turn tracker blocking OFF by default, so the site's own risk vendors — including ones it loads through a tag manager, like PerimeterX and Sift on ksl.com — load exactly as they do for an ordinary Chrome visitor; a sign-up on which the site's fraud vendor never ran is a risk signal by itself. evasion:true and verify:true imply the same. Omit for an ordinary launch.screencastoptionalallow this session to be WATCHED live and RECORDED (default off). true = godbrowser_screencast can stream it to a local URL and save replayable recordings; the capability is granted here and cannot be added later. Capture is still OFF until you call godbrowser_screencast action:"start" -- this is permission, not the act. Works headless too: frames come from the renderer, so no window is needed.persona_classoptionalrequired to make block_trackers actually block anything. "adblock-desktop": blocks like a real desktop uBlock Origin user (ERR_BLOCKED_BY_CLIENT) -- desktop OS only, a coherent everyday persona (~40% of desktop users run an adblocker). "trusted-scrape": operator-asserted non-adversarial automation (empty-200 stub instead), any OS. ⭐ DEFAULTS to "adblock-desktop" on a DESKTOP persona whenever block_trackers is on — which it is by default for an ordinary launch and NOT for a register/login one (see intent). Pass it explicitly to override, or pass block_trackers:false to turn the pair off. On a MOBILE persona nothing is defaulted: the browser resolves adblock-desktop to kOff there anyway (desktop-OS-only, fail-closed), so defaulting it would be a no-op wearing the costume of a setting.godbrowser_linkBuild — or open — a gb:// link that launches GodBrowser already configured: a saved profile, a device, a locale, an egress country, a landing page. action:"build" returns the link to share or paste; action:"open" also dispatches it on this machine. It percent-encodes the values for you, which is the point: a landing URL carrying its own & would otherwise be cut short and the page would look like the site misbehaving. A link deliberately cannot carry a proxy credential (name a provider instead) or a non-http(s) landing page — the full contract is on the parameter reference.11 parameters
actionoptional"build" (default) returns the link; "open" also launches it on this machineprofileoptionala saved session to restore — implies persist, and brings back its device, locale and egress countryosoptionalwindows | macos | linux | android | iosbrowseroptionalchrome | safari | firefox | edge | brave …localeoptionale.g. "en-GB" — drives navigator.languages AND Accept-Languageproxy_provideroptionalnstproxy | mpp | 2captcha | … — a NAME, never a credentialproxy_countryoptionalISO-2 egress country, e.g. "US"proxy_typeoptionalBusyIP only — the exit's network class: "mobile" | "residential" | "any". Pair a mobile exit with a mobile persona (os "android"/"ios"); the two together are what makes the device coherent.urloptionalthe page to land on (http/https only). Encoded for you.persistoptionalsave the session to your account (default on when signed in)headedoptionaltrue = a visible window (default), false = no windowgodbrowser_personasList the device personas GodBrowser can present — every supported OS and browser engine, and which combinations are coherent. Call it before a launch when you want a specific device rather than the seed-derived default: an incoherent pair is itself a fingerprinting tell, because no such device exists.1 parameter
osoptionaloptional: show only the browsers coherent with this OSgodbrowser_proxiesCheck whether this account has proxies configured and how many usable exits the pool holds — a read-only status count. For the per-provider detail, the exit countries and the parser, use godbrowser_proxy.5 parameters
dialoptionalACTUALLY DIAL an exit and report LIVE or DEAD instead of only parsing the stored lines (default false). Each probe opens a real connection through the pool AND FETCHES THE EXIT ADDRESS -- a CONNECT that answers is NOT proof of egress, so a proxy whose measured exit equals this machine's own address is reported REFUSED (egress-is-host-ip), never LIVE. Costs a few seconds and a little proxy bandwidth per provider. Use it before promising a run "through a proxy"; leave it off for a cheap "is anything configured?" read.dial_provideroptionalwith dial:true, probe only this provider (e.g. "nstproxy", "busyip") instead of one exit per provider.dial_countryoptionalwith dial:true, ISO-2 country to request for providers whose targeting is composed per session (BusyIP). ⚠️ Asking for a country whose exits sit on the SAME ISP as the calling machine can legitimately return that machine's own address, which this tool then refuses -- that is the instrument working, not the pool failing.dial_typeoptionalwith dial:true, the BusyIP NETWORK CLASS to dial: "mobile" | "residential" | "any". Capacity is per (country,type) and they differ sharply — measured 2026-09-10, type=mobile had exits in UZ and MD and NONE in us/de/gb/fr/it/es/pl/ro/tr/br — so a liveness answer that ignores the class is answering a different question than you asked.dial_timeout_msoptionalper-probe timeout in ms (default 15000, clamped 3000-60000).godbrowser_proxyInspect and choose your egress. Shows whether a proxy is configured, which providers you have, the exit country of each, whether it is sticky or rotating and how often it rotates, and which lines are pool sources (expanded inside the browser) versus direct exits. It also parses any proxy string you paste, in any provider format, and tells you what it is. It never returns a password. Call it before godbrowser_launch to pick proxy_provider / proxy_country.4 parameters
actionoptional"info" (default) = what is configured; "parse" = classify the string in `proxy`; "providers" = one row per providerproxyoptionalfor action:"parse" — any proxy string: scheme://user:pass@host:port, user:pass@host:port, host:port, host:port:user:pass, or a provider pool URLprovideroptionalfilter to one provider, e.g. "nstproxy" / "mpp" / "2captcha"countryoptionalfilter to exits stating this ISO-2 country, e.g. "US"godbrowser_sessionManage saved logins — list (filter by name_contains, site_contains, updated_within_days; sort, limit), restore, save, or clear. A restore reproduces the whole identity, not just the cookies: the device it was banked on (OS/browser/persona), its locale, and — where recorded — the egress country it was created from (same exit, then any exit in that country, then an honest fallback to this machine, reported as egress_continuity). Do not pass os/browser to a restore unless you deliberately mean to override the banked device: doing so reintroduces exactly the device mismatch the restore exists to remove. The response reports persona_restored, persona_banked and egress_continuity so you can see what you actually got. action:"clear" empties a profile's session — the cookies, localStorage and IndexedDB — while keeping the profile itself: its name, the persona (OS / browser / locale) it was banked on and its recorded egress country are unchanged, so the same name relaunches as the same device with a clean cookie jar. It is destructive and cannot be undone, so it requires confirm:true — without it the call is a dry run that reports what would be removed, per store, and changes nothing. scope selects which store is emptied: local (the on-disk profile directory on this machine), banked (the session saved on your GodBrowser account), or both (default). Clearing only local does NOT retire the session: the next restore pulls the banked copy back. Each store reports its own status (cleared, already_clear, refused or not_requested) and the top-level cleared is true only if every requested store succeeded; a browser running on the profile is a refusal, never a kill. Local mode in v1.19 parameters · 1 required
actionrequired"live" | "list" | "restore" | "save" | "clear". ⚠️ "live" and "list" answer DIFFERENT questions: "live" enumerates the browsers RUNNING RIGHT NOW (session_id, persona/seed, current url, age, and the typing cadence you would pass to godbrowser_typing) — use it when you need to address or retune a session you did not launch; "list" enumerates SAVED logins on disk, which is a question about the past. restore and clear need session_name (the profile shown by list); save takes session_id (or session_name) and CHECKS whether the session is banked — it is a measurement, not an instruction.scopeoptionalclear: which store to empty — "local" (the on-disk profile directory on this machine), "banked" (the session saved on your GodBrowser account), or "both" (default). ⛔ Clearing only "local" does NOT retire the session: the next restore pulls the banked copy back.confirmoptionalclear: must be true. A clear destroys session state and cannot be undone, so it does nothing without an explicit confirm — the same convention as every other destructive verb here.name_containsoptionallist filter: only sessions whose profile NAME contains this (case-insensitive)site_containsoptionallist filter: only sessions with a recorded SITE/host containing this, e.g. "stripe" or "claude.ai"updated_within_daysoptionallist filter: only sessions banked within the last N days (freshness)sortoptionallist order: "recent" (default, newest first), "name", or "size"limitoptionallist: max rows to return (default 50)session_nameoptionalthe saved session/persona name (for restore/save)osoptionalpersona OS for restore: windows | macos | linuxbrowseroptionalpersona browser for restoreseedoptionalpersona seed for restore (identifies which saved login)account_keyoptionaloptional account key selecting which stored session to restore (server-side; never logged)screencastoptionalrestore-and-watch: allow the restored session to be WATCHED live and RECORDED (default off). Same capability as godbrowser_launch { screencast: true } -- it can only be granted as the session is created, so it must be asked for HERE, not after the restore returns.evasionoptionalEVASION TIER for the restored session — refuse to run on a host without a REAL GPU. OFF by default (unchanged). A GPU-less host renders WebGL through SwiftShader, so UNMASKED_RENDERER reads as a software renderer under a desktop persona while navigator.gpu.requestAdapter() returns null — a cross-API contradiction. Pass true when this restored login will face a live site under scrutiny and the scheduler will REFUSE (blocked_by:"no_real_gpu_node_for_persona_os") rather than place you on a degraded host. ⚠️ Capacity is narrow: only real-GPU hosts qualify, so a true here can legitimately come back as no_capacity. Whatever you get, the answer reports `real_gpu` so a degraded placement is never silent.session_idoptionalsave: the live session_id from godbrowser_launch. Preferred over session_name — it also lets the check tell "not banked YET" apart from "this browser holds no writer lease and will NEVER bank".domainoptionalsave: assert the banked session actually covers this site, e.g. "github.com". A CONTENT check, not a timing bet — a bank that does not list the site is reported as not_yet, never as a yes.sinceoptionalsave: an ISO timestamp — usually the moment your login completed. The check then requires a bank written AFTER it, so an older row from a previous session cannot be mistaken for the state you just created.wait_msoptionalsave: keep checking until the bank lands, up to this many ms (max 60000), then return the honest state. A logged-in session is durable within ~10s on its own and in well under a second on a graceful close, so 12000 is generous. Waiting longer is not safer — it just delays a `read_only` or `bank_failed` you could already have acted on.godbrowser_set_personaSwitch to a different device persona — relaunches a fresh, coherent instance and returns a new session_id.6 parameters · 1 required
session_idrequiredthe current session_id (it will be closed)osoptionalnew device OS: windows | macos | linuxbrowseroptionalnew browser: chrome | edge | firefox | safariseedoptionalnew stable seed -> a new stable device identitycountryoptionalpreferred region/country for placementevasionoptionalEVASION TIER for the RELAUNCHED session — refuse to place on a host without a REAL GPU. OFF by default. ⚠️ This is NOT inherited from the session being replaced: a relaunch is a fresh placement, so if the session you are switching was launched with evasion:true you must say so again here or the new one may land on a SwiftShader host. The answer reports `real_gpu` either way.godbrowser_go_backGo back one history entry (the Back button) and wait for load. Returns whether it navigated + the URL before/after.1 parameter · 1 required
session_idrequiredthe session_id from godbrowser_launchgodbrowser_go_forwardGo forward one history entry (the Forward button) and wait for load. Returns whether it navigated + the URL before/after.1 parameter · 1 required
session_idrequiredthe session_id from godbrowser_launchgodbrowser_navigateNavigate the session to a URL and wait for load; returns the final (post-redirect) URL.4 parameters · 2 required
session_idrequiredthe session_id from godbrowser_launchurlrequiredthe URL to open (http/https)wait_untiloptionalload condition to wait for (advisory; the session waits for document-complete by default)allow_direct_signupoptionalpermit a DIRECT navigation to a sign-up/register url. Refused by default: the rule is home page -> click -> register page. Set this only for a deliberate diagnostic where arriving cold is the thing being measured, and say so in your report, because a cold hit is not evidence about the front-door path.godbrowser_reloadReload the current page (the Refresh button) and wait for load; hard skips the cache. Returns the URL.2 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchhardoptionalskip the cache (a hard reload)godbrowser_scrollScroll by a pixel amount, to top/bottom, or a selector into view — reveal lazy-loaded content.4 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchbyoptionalscroll by this many pixels (positive = down)tooptional"top" or "bottom"selectoroptionalscroll the element matching this CSS selector into viewgodbrowser_wait_forWait for a page condition before you read or click — locate by ANY of: CSS selector, visible text, role+name, label, placeholder, testid, or xpath. Choose a state: visible (default), present (in the DOM), hidden (was shown, now gone, e.g. a spinner), or absent (removed). Polls until it holds or times out; or pass ms alone for a fixed delay. Use on dynamic / SPA pages.15 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchselectoroptionala CSS selector to wait fortextoptionalwait for an element by VISIBLE text, e.g. "Loading"roleoptionalan ARIA role (pair with name); or, with text, scope the match to "button"/"link"/"any"nameoptionalthe accessible name to match when role is setlabeloptionala labelled control by its label textplaceholderoptionalan input placeholdertestidoptionala data-testid valuepierceoptionalalso search inside OPEN shadow roots (a CLOSED shadow root is unreachable from script by design)xpathoptionalan XPath expressionmatchoptionaltext/name match mode: "icontains" (default), "contains", "equals", "iequals", "starts_with", "ends_with", "regex"stateoptionalthe condition: "visible" (default, appears+shown), "present" (in DOM), "hidden" (goes hidden), or "absent" (removed from DOM)msoptionalinstead of a locator, wait this many milliseconds (a fixed sleep)timeout_msoptionalmax time to wait for the condition (default ~10000)poll_msoptionalpoll interval while waiting (default ~150)godbrowser_wait_for_element_countWait until the matched-element count meets expected (default gte = at least N appeared) — e.g. results / rows rendered — clean ok:false on timeout (no throw). comparator: gte (default) / equals / lte / gt / lt. Full universal locator.17 parameters · 2 required
session_idrequiredthe session_id from godbrowser_launchexpectedrequiredthe element count to wait forcomparatoroptionalhow to compare the actual count to expected: "gte" (default), "equals", "lte", "gt", "lt"pierceoptionalalso search inside OPEN shadow roots for this locator (a CLOSED shadow root is unreachable from script by design, and is reported as not-found rather than guessed at)withinoptionala CSS selector for a CONTAINER (usually a form) to search INSIDE — the locator then resolves only within it. Take it from godbrowser_read_page mode:"actions" forms[].selector. Use it whenever a page has more than one form or two similar-looking buttons; omit it for today's whole-page behaviour. A container that is not on the page is reported as within_not_found, never widened back to the whole page.selectoroptionala CSS selector for the elementtextoptionallocate by VISIBLE text (like getByText), e.g. "Subscribe"roleoptionalan ARIA role (like getByRole), pair with name; with text, scopes it to "button"/"link"/"any"nameoptionalthe accessible name to match when role is setlabeloptionala labelled control by its label text, e.g. "Email address"placeholderoptionalan input placeholdertestidoptionala data-testid / data-test-id valuexpathoptionalan XPath expressionmatchoptionaltext/name match mode: "icontains" (default), "contains", "equals", "iequals", "starts_with", "ends_with", "regex"nthoptionalwhen several elements match, pick this one (0-based); omit to require a single matchtimeout_msoptionalmax ms to auto-wait for a match to appear (default ~8000)poll_msoptionalpoll interval while waiting (default ~150)godbrowser_wait_for_functionWait until a JS predicate you supply returns truthy, then return its value — the readiness wait for SPAs whose ready is a JS state flag / store / counter rather than a visible element (use godbrowser_wait_for for element state). Give an expression (e.g. window.__APP_READY__===true, document.querySelectorAll('.item').length>=10) or a function. Polls until truthy or timeout. Returns {ok:true, value, elapsed_ms} on success, {ok:false, timed_out:true, elapsed_ms} on timeout — a clean result, never an error; a predicate that throws is treated as not-yet-true and polling continues. The returned value is circular/size-capped. First-party / operator-only in v1 (runs caller JS — the godbrowser_eval trust posture).5 parameters · 2 required
session_idrequiredthe session_id from godbrowser_launchexpressionrequireda JS predicate — an expression (e.g. "window.__READY__===true") or a function (e.g. "() => document.querySelectorAll('.row').length>=5"); polled until it returns truthytimeout_msoptionalmax ms to wait (default 30000, ceiling 120000)poll_interval_msoptionalpoll interval in ms (default 150)argsoptionaloptional arguments passed into the predicate when it is a functiongodbrowser_wait_for_navigationWait for the top-frame URL to change (a navigation to commit) — or, with expected, to reach it — after a submit / link click. Clean ok:false on timeout, never an error (no throw). match (with expected): contains (default) / equals / prefix / regex.5 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchexpectedoptionaloptional target URL (or fragment, per match) to wait for; omit to wait for ANY navigation away from the current URLmatchoptionalmatch mode when expected is set: "contains" (default), "equals", "prefix", "regex"timeout_msoptionalmax ms to wait for the navigation (default ~10000)poll_msoptionalpoll interval while waiting (default ~150)godbrowser_wait_for_urlWait for the top URL to match expected, polling until it does or timeout_ms — clean ok:false on timeout, never an error (no throw). match: contains (default) / equals / prefix / regex.5 parameters · 2 required
session_idrequiredthe session_id from godbrowser_launchexpectedrequiredthe URL (or fragment, per match) to wait formatchoptionalmatch mode: "contains" (default), "equals", "prefix", "regex"timeout_msoptionalmax ms to wait (default ~10000)poll_msoptionalpoll interval while waiting (default ~150)godbrowser_close_tabClose a tab (by target_id / index / url / title, or omit all to close the current tab). Closing the active tab resets the context to a remaining tab (the launch tab if still open) + the top frame.6 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchtarget_idoptionalthe tab target_id to close (from list_tabs)indexoptionalthe 0-based tab index to closeurloptionalclose the tab whose URL matches this (per match)titleoptionalclose the tab whose title matches this (per match)matchoptionalmatch mode for url/title: "icontains" (default, case-insensitive), "contains", "equals", "prefix", "regex"godbrowser_enter_frameEnter a same-origin iframe so subsequent Drive verbs target elements inside it. Identify by CSS selector (the iframe), 0-based frame_index, or text (its name / src / id / title); omit all when the page has exactly one iframe. Call exit_frame (or navigate) to return to the top. A cross-origin frame returns a clean ok:false (frame_cross_origin) — same-origin frames only in v1.5 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchselectoroptionala CSS selector matching the <iframe> elementframe_indexoptionalthe 0-based iframe index from list_framestextoptionalmatch the frame by a substring of its name / src / id / titlexpathoptionalan XPath matching the <iframe> elementgodbrowser_exit_frameLeave the current iframe and return the Drive context to the top frame (undoes enter_frame); a no-op if not in a frame.1 parameter · 1 required
session_idrequiredthe session_id from godbrowser_launchgodbrowser_list_framesList the iframes on the current tab — each with index, name, id, src, same_origin, url. Cross-origin frames are listed (same_origin:false) but cannot be driven in v1.3 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchtimeout_msoptionalmax ms to wait for frames to mount (default 3000). Only paid when fewer than min_count frames exist. Pass 0 for an immediate, un-waited snapshot.min_countoptionalstop waiting once this many frames exist (default 1)godbrowser_list_tabsList the open tabs (page targets) in the session — each with index, target_id, url, title, active. Find a tab a click opened in the background (a pop-up / target=_blank) before switching to it.1 parameter · 1 required
session_idrequiredthe session_id from godbrowser_launchgodbrowser_switch_tabSet the active tab for subsequent Drive calls — every following navigate / click / type / read acts on it. Identify by target_id (from list_tabs), 0-based index, a url match, or a title match. Switching resets the frame context to the top frame; clean ok:false if none matched (no throw).6 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchtarget_idoptionalthe tab target_id from list_tabsindexoptionalthe 0-based tab index from list_tabsurloptionalmatch the tab whose URL matches this (per match)titleoptionalmatch the tab whose title matches this (per match)matchoptionalmatch mode for url/title: "icontains" (default, case-insensitive), "contains", "equals", "prefix", "regex"godbrowser_autocomplete_selectFill an autocomplete / typeahead and pick a suggestion — standard typeaheads AND custom Web Components (shadow-DOM / portal option lists that render detached from the input). Type the query, wait (generous, tunable via list_timeout_ms) for the list, then commit the matching option (option_text, defaults to the typed text) — trying a matching option element, a deep-pierced portal / shadow option row, then keyboard ArrowDown + Enter — fire input + change, verify the value committed, and retry up to retry times. option_selector / option_regex for the option elements (a >>> frame/shadow path is supported); verify_text to require the committed value contain a string. Locate the input with the universal locator.24 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchtextoptionallocate by VISIBLE text (like getByText), e.g. "Subscribe"option_textoptionalthe visible text of the suggestion to pick (defaults to the typed text)option_selectoroptionaloptional CSS selector for the option elements, if not standard [role=option]/link/button (a ">>>" frame/shadow path is supported)option_regexoptionaloptional case-insensitive regex to pick the option row by text when observing the rendered listoption_nthoptionalwhen several options match, pick this one (0-based)verify_textoptionalrequire the committed field value to contain this text before reporting successhumanoptionaltype the query with realistic human keystroke timinglist_timeout_msoptionalmax ms to wait for the suggestion list to render (default ~6000)retryoptionalbounded clear + re-type + re-open retries if the value does not commit (default 2, max 3)arrow_stepsoptionalhow many ArrowDown presses before Enter in the keyboard fallback (default 1)pierceoptionalalso search inside OPEN shadow roots for this locator (a CLOSED shadow root is unreachable from script by design, and is reported as not-found rather than guessed at)withinoptionala CSS selector for a CONTAINER (usually a form) to search INSIDE — the locator then resolves only within it. Take it from godbrowser_read_page mode:"actions" forms[].selector. Use it whenever a page has more than one form or two similar-looking buttons; omit it for today's whole-page behaviour. A container that is not on the page is reported as within_not_found, never widened back to the whole page.selectoroptionala CSS selector for the elementroleoptionalan ARIA role (like getByRole), pair with name; with text, scopes it to "button"/"link"/"any"nameoptionalthe accessible name to match when role is setlabeloptionala labelled control by its label text, e.g. "Email address"placeholderoptionalan input placeholdertestidoptionala data-testid / data-test-id valuexpathoptionalan XPath expressionmatchoptionaltext/name match mode: "icontains" (default), "contains", "equals", "iequals", "starts_with", "ends_with", "regex"nthoptionalwhen several elements match, pick this one (0-based); omit to require a single matchtimeout_msoptionalmax ms to auto-wait for a match to appear (default ~8000)poll_msoptionalpoll interval while waiting (default ~150)godbrowser_checkbox_setSet a checkbox to a desired state (checked / unchecked) — idempotent: a real, trusted click that fires change only when the current state differs (verify-and-retry). Native <input type=checkbox> + role=checkbox / aria-checked widgets. Returns whether it changed. Full universal locator.17 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchstateoptionaldesired state: true = checked (default), false = uncheckedcheckedoptionalalias for `state` — accepted because this verb RETURNS a field called `checked`, so reading the result and calling back with it is the obvious movepierceoptionalalso search inside OPEN shadow roots for this locator (a CLOSED shadow root is unreachable from script by design, and is reported as not-found rather than guessed at)withinoptionala CSS selector for a CONTAINER (usually a form) to search INSIDE — the locator then resolves only within it. Take it from godbrowser_read_page mode:"actions" forms[].selector. Use it whenever a page has more than one form or two similar-looking buttons; omit it for today's whole-page behaviour. A container that is not on the page is reported as within_not_found, never widened back to the whole page.selectoroptionala CSS selector for the elementtextoptionallocate by VISIBLE text (like getByText), e.g. "Subscribe"roleoptionalan ARIA role (like getByRole), pair with name; with text, scopes it to "button"/"link"/"any"nameoptionalthe accessible name to match when role is setlabeloptionala labelled control by its label text, e.g. "Email address"placeholderoptionalan input placeholdertestidoptionala data-testid / data-test-id valuexpathoptionalan XPath expressionmatchoptionaltext/name match mode: "icontains" (default), "contains", "equals", "iequals", "starts_with", "ends_with", "regex"nthoptionalwhen several elements match, pick this one (0-based); omit to require a single matchtimeout_msoptionalmax ms to auto-wait for a match to appear (default ~8000)poll_msoptionalpoll interval while waiting (default ~150)godbrowser_clearEmpty a field with real, trusted keys (focus, caret-to-end + delete) without typing anything new — for a search box or pre-filled input you want blank. Never JS-overwrites; use clear_and_type to overwrite in one step. Full universal locator.15 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchpierceoptionalalso search inside OPEN shadow roots for this locator (a CLOSED shadow root is unreachable from script by design, and is reported as not-found rather than guessed at)withinoptionala CSS selector for a CONTAINER (usually a form) to search INSIDE — the locator then resolves only within it. Take it from godbrowser_read_page mode:"actions" forms[].selector. Use it whenever a page has more than one form or two similar-looking buttons; omit it for today's whole-page behaviour. A container that is not on the page is reported as within_not_found, never widened back to the whole page.selectoroptionala CSS selector for the elementtextoptionallocate by VISIBLE text (like getByText), e.g. "Subscribe"roleoptionalan ARIA role (like getByRole), pair with name; with text, scopes it to "button"/"link"/"any"nameoptionalthe accessible name to match when role is setlabeloptionala labelled control by its label text, e.g. "Email address"placeholderoptionalan input placeholdertestidoptionala data-testid / data-test-id valuexpathoptionalan XPath expressionmatchoptionaltext/name match mode: "icontains" (default), "contains", "equals", "iequals", "starts_with", "ends_with", "regex"nthoptionalwhen several elements match, pick this one (0-based); omit to require a single matchtimeout_msoptionalmax ms to auto-wait for a match to appear (default ~8000)poll_msoptionalpoll interval while waiting (default ~150)godbrowser_clear_and_typeReplace a field's entire contents — focus, select-all + delete with real trusted keys (End + Backspace, OS-independent), then type the new text (firing input) — for a pre-filled field you must overwrite. Never JS-overwrites the value; set human for a realistic cadence. Full universal locator.18 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchtextoptionallocate by VISIBLE text (like getByText), e.g. "Subscribe"humanoptionaltype with realistic human keystroke timing instead of one bulk insertwpmoptionalapproximate typing speed in words per minute when human is set — the rate ACTUALLY TYPED, key-hold dwell included (default 85 ≈ 82 wpm measured, 1.5x faster than the previous build). Raising it further has little headroom: a ~120ms human key-hold dwell is ~83% of the per-character cost and is deliberately not shortened, because a sub-human dwell is itself a detection tell. For genuinely faster input use human:false (an openly non-human bulk insert)jitteroptionaltiming-variance factor when human is set, 0..1 (default ~0.35)pierceoptionalalso search inside OPEN shadow roots for this locator (a CLOSED shadow root is unreachable from script by design, and is reported as not-found rather than guessed at)withinoptionala CSS selector for a CONTAINER (usually a form) to search INSIDE — the locator then resolves only within it. Take it from godbrowser_read_page mode:"actions" forms[].selector. Use it whenever a page has more than one form or two similar-looking buttons; omit it for today's whole-page behaviour. A container that is not on the page is reported as within_not_found, never widened back to the whole page.selectoroptionala CSS selector for the elementroleoptionalan ARIA role (like getByRole), pair with name; with text, scopes it to "button"/"link"/"any"nameoptionalthe accessible name to match when role is setlabeloptionala labelled control by its label text, e.g. "Email address"placeholderoptionalan input placeholdertestidoptionala data-testid / data-test-id valuexpathoptionalan XPath expressionmatchoptionaltext/name match mode: "icontains" (default), "contains", "equals", "iequals", "starts_with", "ends_with", "regex"nthoptionalwhen several elements match, pick this one (0-based); omit to require a single matchtimeout_msoptionalmax ms to auto-wait for a match to appear (default ~8000)poll_msoptionalpoll interval while waiting (default ~150)godbrowser_clickClick an element via a real, trusted pointer — locate it by ANY of: CSS selector, visible text (getByText), role+name (getByRole), label, placeholder, testid, or xpath. With a non-selector locator it auto-waits for a visible match, then clicks (works on dynamic pages). Match modes: icontains (default) / contains / equals / iequals / starts_with / ends_with / regex. Returns the URL after the click. Deep-piercing locator (T-1023): reach across nested cross-origin iframes (OOPIFs) and open OR closed shadow roots in one flat selector via the >>> frame-descent combinator (e.g. iframe#a >>> iframe#b >>> button.target), or structured with frame_path[] + selector, or shadow-only with pierce:true — then land a trusted click through the innermost frame. First-party / operator-only.20 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchselectoroptionala CSS selector for the element. Deep-piercing: use " >>> " between iframe steps to descend into nested cross-origin iframes and open/closed shadow roots in one call, e.g. "iframe#outer >>> iframe#inner >>> button[aria-label='Start']" — the trusted click is hit-tested into the innermost framepierceoptionalpierce open AND closed shadow roots when resolving the selector in the current frame (no frame descent) — reaches an element inside a mode:"closed" shadow root that a normal selector cannotframe_pathoptionalstructured deep descent: an ordered list of iframe CSS selectors to cross (equivalent to the inline " >>> " form) before matching the terminal selector; descends nested cross-origin OOPIFstextoptionalclick by VISIBLE text, e.g. "Accept cookies"roleoptionalan ARIA role, e.g. "button" / "link" / "textbox"; pair with name for getByRole. (With text, scopes the text match to "button"/"link"/"any".)nameoptionalthe accessible name to match when role is set, e.g. "Submit"labeloptionalthe label text of a labelled control, e.g. "Email address"placeholderoptionalan input placeholder, e.g. "Search"testidoptionala data-testid / data-test-id valuexpathoptionalan XPath expressionwithinoptionala CSS selector for a CONTAINER (usually a form) to search INSIDE — the locator resolves only within it, so "the submit button" means THIS form's submit and not another form's. Take it from godbrowser_read_page mode:"actions" forms[].selector. Use it on any page with more than one form, or where a similar control sits beside the one you want (a "Continue with Google" next to "Create account"). Omit for today's whole-page behaviour.matchoptionaltext/name match mode: "icontains" (default), "contains", "equals", "iequals", "starts_with", "ends_with", or "regex"nthoptionalwhen several elements match, pick this one (0-based); omit to require a single matchwait_foroptionalactionability before clicking: "visible" (default) or "clickable" (also not covered by an overlay)timeout_msoptionalmax ms to auto-wait for a match to appear (default ~8000)poll_msoptionalpoll interval while waiting (default ~150)expect_nameoptionalthe LABEL you saw on this element in godbrowser_read_page. Pass it whenever you click by ref: refs of elements without an id are POSITIONAL, so any re-render (typing into a form re-renders it) can move a different element under the same ref, and the click then lands on that one and reports success. With expect_name the click is refused instead, telling you what is actually there now.allow_destructiveoptionalpermit clicking a control whose label says it deletes, removes, deactivates, terminates, revokes or unsubscribes. Refused by default — a ref that has become a delete control is usually a ref that moved, and the mistake is not undoable.modifiersoptionalmodifier keys held during the click: "shift", "ctrl", "alt", "meta" (or "cmd"/"option"/"control"), a list like ["shift","meta"], or a combined string "ctrl+shift". Use shift to extend a range selection in a table or list, ctrl/meta to toggle one item or open a link in a new tab.godbrowser_click_if_presentClick an element only if it appears within a short wait; otherwise return cleanly — a graceful no-op, not an error — for optional / intermittent controls (a survey prompt, a maybe-later, an interstitial). Full universal locator.15 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchpierceoptionalalso search inside OPEN shadow roots for this locator (a CLOSED shadow root is unreachable from script by design, and is reported as not-found rather than guessed at)withinoptionala CSS selector for a CONTAINER (usually a form) to search INSIDE — the locator then resolves only within it. Take it from godbrowser_read_page mode:"actions" forms[].selector. Use it whenever a page has more than one form or two similar-looking buttons; omit it for today's whole-page behaviour. A container that is not on the page is reported as within_not_found, never widened back to the whole page.selectoroptionala CSS selector for the elementtextoptionallocate by VISIBLE text (like getByText), e.g. "Subscribe"roleoptionalan ARIA role (like getByRole), pair with name; with text, scopes it to "button"/"link"/"any"nameoptionalthe accessible name to match when role is setlabeloptionala labelled control by its label text, e.g. "Email address"placeholderoptionalan input placeholdertestidoptionala data-testid / data-test-id valuexpathoptionalan XPath expressionmatchoptionaltext/name match mode: "icontains" (default), "contains", "equals", "iequals", "starts_with", "ends_with", "regex"nthoptionalwhen several elements match, pick this one (0-based); omit to require a single matchtimeout_msoptionalmax ms to auto-wait for a match to appear (default ~8000)poll_msoptionalpoll interval while waiting (default ~150)godbrowser_dismiss_cookie_bannerDismiss a cookie-consent / GDPR banner so it stops covering the page — clicks its Accept all (default) or reject control. Tries common consent frameworks (OneTrust / Cookiebot / Didomi / Osano / Quantcast / Usercentrics) then a conservative accept-button match scoped to a consent container (never opens a preferences dialog); scans the main document + same-origin iframes. Call it once right after navigating, before you read or click. A page with no banner is a normal no-op, not an error.5 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchrejectoptionalclick the REJECT / decline control instead of accept (default: accept all)selectorsoptionalextra CSS selectors for the accept/reject button to try FIRST (for a site the built-in list misses)timeout_msoptionalmax ms to auto-wait for a late-rendered banner (default ~3000; 0 = check once and return). The wait is only SPENT when the page shows evidence of a consent layer — see always_poll.always_polloptionalspend the full timeout_ms window even when the page shows no evidence of a consent layer. By default a page with no CMP API, no consent-looking container, no CMP script and a finished document answers in a few ms instead of ~3000 — set this when you believe a banner is there anyway and want the old behaviour.godbrowser_double_clickDouble-click an element via a real, trusted pointer (two quick clicks) — open an item, select a word, fire a dblclick handler. Full universal locator + auto-wait. Supports the deep-piercing locator (T-1023): the >>> frame-descent combinator (or frame_path[] + selector, or shadow-only pierce:true) reaches across nested cross-origin iframes (OOPIFs) and open OR closed shadow roots in one flat selector — first-party / operator-only.15 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchpierceoptionalalso search inside OPEN shadow roots for this locator (a CLOSED shadow root is unreachable from script by design, and is reported as not-found rather than guessed at)withinoptionala CSS selector for a CONTAINER (usually a form) to search INSIDE — the locator then resolves only within it. Take it from godbrowser_read_page mode:"actions" forms[].selector. Use it whenever a page has more than one form or two similar-looking buttons; omit it for today's whole-page behaviour. A container that is not on the page is reported as within_not_found, never widened back to the whole page.selectoroptionala CSS selector for the elementtextoptionallocate by VISIBLE text (like getByText), e.g. "Subscribe"roleoptionalan ARIA role (like getByRole), pair with name; with text, scopes it to "button"/"link"/"any"nameoptionalthe accessible name to match when role is setlabeloptionala labelled control by its label text, e.g. "Email address"placeholderoptionalan input placeholdertestidoptionala data-testid / data-test-id valuexpathoptionalan XPath expressionmatchoptionaltext/name match mode: "icontains" (default), "contains", "equals", "iequals", "starts_with", "ends_with", "regex"nthoptionalwhen several elements match, pick this one (0-based); omit to require a single matchtimeout_msoptionalmax ms to auto-wait for a match to appear (default ~8000)poll_msoptionalpoll interval while waiting (default ~150)godbrowser_dropdown_pick_optionPick an option from a custom (non-native) dropdown / combobox — a div / listbox widget or a shadow-DOM / portal Web Component; use godbrowser_select for a native <select> — trusted-click the trigger to open, wait for the option list, commit the matching option (option_text) via a matching element or a deep-pierced portal / shadow row, fire change, then verify the trigger shows the choice (or the list closed) and retry up to retry times. option_selector supports a >>> frame/shadow path. Locate the trigger with the universal locator.22 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchoption_textoptionalthe visible text of the option to pickoption_selectoroptionaloptional CSS selector for the option elements (a ">>>" frame/shadow path is supported)option_regexoptionaloptional case-insensitive regex to pick the option row by text when observing the rendered listoption_nthoptionalwhen several options match, pick this one (0-based)list_timeout_msoptionalmax ms to wait for the option list to render (default ~6000)retryoptionalbounded re-open + re-select retries if the choice does not commit (default 2, max 3)arrow_stepsoptionalopt into a keyboard ArrowDown+Enter fallback with this many ArrowDown pressespierceoptionalalso search inside OPEN shadow roots for this locator (a CLOSED shadow root is unreachable from script by design, and is reported as not-found rather than guessed at)withinoptionala CSS selector for a CONTAINER (usually a form) to search INSIDE — the locator then resolves only within it. Take it from godbrowser_read_page mode:"actions" forms[].selector. Use it whenever a page has more than one form or two similar-looking buttons; omit it for today's whole-page behaviour. A container that is not on the page is reported as within_not_found, never widened back to the whole page.selectoroptionala CSS selector for the elementtextoptionallocate by VISIBLE text (like getByText), e.g. "Subscribe"roleoptionalan ARIA role (like getByRole), pair with name; with text, scopes it to "button"/"link"/"any"nameoptionalthe accessible name to match when role is setlabeloptionala labelled control by its label text, e.g. "Email address"placeholderoptionalan input placeholdertestidoptionala data-testid / data-test-id valuexpathoptionalan XPath expressionmatchoptionaltext/name match mode: "icontains" (default), "contains", "equals", "iequals", "starts_with", "ends_with", "regex"nthoptionalwhen several elements match, pick this one (0-based); omit to require a single matchtimeout_msoptionalmax ms to auto-wait for a match to appear (default ~8000)poll_msoptionalpoll interval while waiting (default ~150)godbrowser_fillAlias of type — fill a field with real key input, located by ANY of: CSS selector, role+name, label, placeholder, testid, or xpath. Set human for a realistic per-key typing cadence instead of one bulk insert; optional submit to press Enter. Deep-piercing locator (T-1023): target a field across nested cross-origin iframes (OOPIFs) and open OR closed shadow roots in one flat selector via the >>> frame-descent combinator (or frame_path[] + selector, or shadow-only pierce:true) — trusted-focusing the field (typing works for shadow-pierce + same-process frames; char delivery into a cross-process OOPIF is a v1 follow-up). First-party / operator-only.19 parameters · 2 required
session_idrequiredthe session_id from godbrowser_launchselectoroptionala CSS selector for the input/textarea (or a locator below). Deep-piercing: use " >>> " between iframe steps to reach a field inside nested cross-origin iframes and open/closed shadow rootspierceoptionalpierce open AND closed shadow roots when resolving the selector in the current frame (no frame descent)frame_pathoptionalstructured deep descent: an ordered list of iframe CSS selectors to cross before matching the field selector (equivalent to the inline " >>> " form)textrequiredthe text to enterroleoptionalan ARIA role for the field (pair with name)nameoptionalthe accessible name when role is setlabeloptionalthe field's label text, e.g. "Email address"placeholderoptionalthe field's placeholdertestidoptionala data-testid valuexpathoptionalan XPath expressionwithinoptionala CSS selector for a CONTAINER (usually a form) to search INSIDE — the field locator then resolves only within it, so "the email field" means THIS form's email field. Take it from godbrowser_read_page mode:"actions" forms[].selector. Use it on any page carrying more than one form; omit for today's whole-page behaviour.nthoptionalwhen several fields match, pick this one (0-based); omit to require a single matchmatchoptionallocator match mode: "icontains" (default), "contains", "equals", "iequals", "starts_with", "ends_with", "regex"humanoptionaltype with realistic human keystroke timing (per-key dwell + variable inter-key delays) instead of one bulk insertwpmoptionalapproximate typing speed in words per minute when human is set — the rate ACTUALLY TYPED, key-hold dwell included (default 85 ≈ 82 wpm measured, 1.5x faster than the previous build). Raising it further has little headroom: a ~120ms human key-hold dwell is ~83% of the per-character cost and is deliberately not shortened, because a sub-human dwell is itself a detection tell. For genuinely faster input use human:false (an openly non-human bulk insert)jitteroptionaltiming-variance factor when human is set, 0..1 (default ~0.35)clearoptionalempty the field before filling (trusted keys). Typing APPENDS to whatever is already there, so a pre-filled field silently produces a merged value. DEFAULTS TO TRUE — pass clear:false only when you mean to append.submitoptionalpress Enter after fillinggodbrowser_focusMove keyboard focus to a field or control — idempotent (a no-op if it is already focused). Full universal locator + auto-wait.15 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchpierceoptionalalso search inside OPEN shadow roots for this locator (a CLOSED shadow root is unreachable from script by design, and is reported as not-found rather than guessed at)withinoptionala CSS selector for a CONTAINER (usually a form) to search INSIDE — the locator then resolves only within it. Take it from godbrowser_read_page mode:"actions" forms[].selector. Use it whenever a page has more than one form or two similar-looking buttons; omit it for today's whole-page behaviour. A container that is not on the page is reported as within_not_found, never widened back to the whole page.selectoroptionala CSS selector for the elementtextoptionallocate by VISIBLE text (like getByText), e.g. "Subscribe"roleoptionalan ARIA role (like getByRole), pair with name; with text, scopes it to "button"/"link"/"any"nameoptionalthe accessible name to match when role is setlabeloptionala labelled control by its label text, e.g. "Email address"placeholderoptionalan input placeholdertestidoptionala data-testid / data-test-id valuexpathoptionalan XPath expressionmatchoptionaltext/name match mode: "icontains" (default), "contains", "equals", "iequals", "starts_with", "ends_with", "regex"nthoptionalwhen several elements match, pick this one (0-based); omit to require a single matchtimeout_msoptionalmax ms to auto-wait for a match to appear (default ~8000)poll_msoptionalpoll interval while waiting (default ~150)godbrowser_force_clickClick an element at its position even when a normal click reports it covered — a control under a decorative / transparent overlay, a sticky header, or a conservative not-clickable check. Prefer godbrowser_click first; use this when it reports the target covered. Full universal locator. Supports the deep-piercing locator (T-1023): the >>> frame-descent combinator (or frame_path[] + selector, or shadow-only pierce:true) reaches across nested cross-origin iframes (OOPIFs) and open OR closed shadow roots in one flat selector — first-party / operator-only.15 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchpierceoptionalalso search inside OPEN shadow roots for this locator (a CLOSED shadow root is unreachable from script by design, and is reported as not-found rather than guessed at)withinoptionala CSS selector for a CONTAINER (usually a form) to search INSIDE — the locator then resolves only within it. Take it from godbrowser_read_page mode:"actions" forms[].selector. Use it whenever a page has more than one form or two similar-looking buttons; omit it for today's whole-page behaviour. A container that is not on the page is reported as within_not_found, never widened back to the whole page.selectoroptionala CSS selector for the elementtextoptionallocate by VISIBLE text (like getByText), e.g. "Subscribe"roleoptionalan ARIA role (like getByRole), pair with name; with text, scopes it to "button"/"link"/"any"nameoptionalthe accessible name to match when role is setlabeloptionala labelled control by its label text, e.g. "Email address"placeholderoptionalan input placeholdertestidoptionala data-testid / data-test-id valuexpathoptionalan XPath expressionmatchoptionaltext/name match mode: "icontains" (default), "contains", "equals", "iequals", "starts_with", "ends_with", "regex"nthoptionalwhen several elements match, pick this one (0-based); omit to require a single matchtimeout_msoptionalmax ms to auto-wait for a match to appear (default ~8000)poll_msoptionalpoll interval while waiting (default ~150)godbrowser_hoverHover the pointer over an element (a real, trusted mouse move that fires mouseover / mouseenter) and dwell without clicking — reveal a hover-gated menu, tooltip, or control. Full universal locator + auto-wait. Supports the deep-piercing locator (T-1023): the >>> frame-descent combinator (or frame_path[] + selector, or shadow-only pierce:true) reaches across nested cross-origin iframes (OOPIFs) and open OR closed shadow roots in one flat selector — first-party / operator-only.15 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchpierceoptionalalso search inside OPEN shadow roots for this locator (a CLOSED shadow root is unreachable from script by design, and is reported as not-found rather than guessed at)withinoptionala CSS selector for a CONTAINER (usually a form) to search INSIDE — the locator then resolves only within it. Take it from godbrowser_read_page mode:"actions" forms[].selector. Use it whenever a page has more than one form or two similar-looking buttons; omit it for today's whole-page behaviour. A container that is not on the page is reported as within_not_found, never widened back to the whole page.selectoroptionala CSS selector for the elementtextoptionallocate by VISIBLE text (like getByText), e.g. "Subscribe"roleoptionalan ARIA role (like getByRole), pair with name; with text, scopes it to "button"/"link"/"any"nameoptionalthe accessible name to match when role is setlabeloptionala labelled control by its label text, e.g. "Email address"placeholderoptionalan input placeholdertestidoptionala data-testid / data-test-id valuexpathoptionalan XPath expressionmatchoptionaltext/name match mode: "icontains" (default), "contains", "equals", "iequals", "starts_with", "ends_with", "regex"nthoptionalwhen several elements match, pick this one (0-based); omit to require a single matchtimeout_msoptionalmax ms to auto-wait for a match to appear (default ~8000)poll_msoptionalpoll interval while waiting (default ~150)godbrowser_pick_datePick a date in a calendar / date-picker — standard pickers AND custom Web Components (shadow-DOM / portal calendars) whose field is read-only. Trusted-click to open, then: by DEFAULT click any enabled day in the month shown (any valid date will do — zero navigation); or, with a specific date (YYYY-MM-DD / DD/MM/YYYY), header-jump (Month YYYY header → year grid → month → day). Never steps month-by-month and never writes the value directly into a read-only field. Verifies the field then holds a value; any_enabled forces the default strategy. Locate the input with the universal locator.18 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchdateoptionala specific date to pick, "YYYY-MM-DD" or "DD/MM/YYYY" (omit to accept any selectable day in the shown month)any_enabledoptionalforce the any-selectable-day strategy (default: true when no date is given, false when a specific date is given)open_timeout_msoptionalmax ms to wait for the calendar to open (default ~3500)pierceoptionalalso search inside OPEN shadow roots for this locator (a CLOSED shadow root is unreachable from script by design, and is reported as not-found rather than guessed at)withinoptionala CSS selector for a CONTAINER (usually a form) to search INSIDE — the locator then resolves only within it. Take it from godbrowser_read_page mode:"actions" forms[].selector. Use it whenever a page has more than one form or two similar-looking buttons; omit it for today's whole-page behaviour. A container that is not on the page is reported as within_not_found, never widened back to the whole page.selectoroptionala CSS selector for the elementtextoptionallocate by VISIBLE text (like getByText), e.g. "Subscribe"roleoptionalan ARIA role (like getByRole), pair with name; with text, scopes it to "button"/"link"/"any"nameoptionalthe accessible name to match when role is setlabeloptionala labelled control by its label text, e.g. "Email address"placeholderoptionalan input placeholdertestidoptionala data-testid / data-test-id valuexpathoptionalan XPath expressionmatchoptionaltext/name match mode: "icontains" (default), "contains", "equals", "iequals", "starts_with", "ends_with", "regex"nthoptionalwhen several elements match, pick this one (0-based); omit to require a single matchtimeout_msoptionalmax ms to auto-wait for a match to appear (default ~8000)poll_msoptionalpoll interval while waiting (default ~150)godbrowser_pressPress a single key in the session (Enter, Tab, Escape, ArrowDown…).4 parameters · 2 required
session_idrequiredthe session_id from godbrowser_launchkeyrequiredthe key name, e.g. "Enter", "Tab", "Escape", "ArrowDown"timesoptionalrepeat the key this many times (default 1, max 100). Each repeat is a separate trusted keydown/keyup with a short human gap. Read `pressed` in the answer to confirm how many actually went out.delay_msoptionalmilliseconds between repeats (default ~45ms plus jitter). Raise it for a listbox or autocomplete that debounces and drops keys sent too fast.godbrowser_press_enter_to_submitFocus a field and press Enter with a real, trusted key that carries the carriage return, so a form's implicit submit fires — the type-into-the-box-and-hit-Enter flow. Returns the URL after. Full universal locator.15 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchpierceoptionalalso search inside OPEN shadow roots for this locator (a CLOSED shadow root is unreachable from script by design, and is reported as not-found rather than guessed at)withinoptionala CSS selector for a CONTAINER (usually a form) to search INSIDE — the locator then resolves only within it. Take it from godbrowser_read_page mode:"actions" forms[].selector. Use it whenever a page has more than one form or two similar-looking buttons; omit it for today's whole-page behaviour. A container that is not on the page is reported as within_not_found, never widened back to the whole page.selectoroptionala CSS selector for the elementtextoptionallocate by VISIBLE text (like getByText), e.g. "Subscribe"roleoptionalan ARIA role (like getByRole), pair with name; with text, scopes it to "button"/"link"/"any"nameoptionalthe accessible name to match when role is setlabeloptionala labelled control by its label text, e.g. "Email address"placeholderoptionalan input placeholdertestidoptionala data-testid / data-test-id valuexpathoptionalan XPath expressionmatchoptionaltext/name match mode: "icontains" (default), "contains", "equals", "iequals", "starts_with", "ends_with", "regex"nthoptionalwhen several elements match, pick this one (0-based); omit to require a single matchtimeout_msoptionalmax ms to auto-wait for a match to appear (default ~8000)poll_msoptionalpoll interval while waiting (default ~150)godbrowser_radio_chooseSelect a radio in a group — by locator, by value (optionally with the group name), or by label / text. A trusted click that fires change; a no-op if it is already selected. Returns whether it changed. Full universal locator.16 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchvalueoptionalchoose the radio in the group by its value attribute (optionally with name)pierceoptionalalso search inside OPEN shadow roots for this locator (a CLOSED shadow root is unreachable from script by design, and is reported as not-found rather than guessed at)withinoptionala CSS selector for a CONTAINER (usually a form) to search INSIDE — the locator then resolves only within it. Take it from godbrowser_read_page mode:"actions" forms[].selector. Use it whenever a page has more than one form or two similar-looking buttons; omit it for today's whole-page behaviour. A container that is not on the page is reported as within_not_found, never widened back to the whole page.selectoroptionala CSS selector for the elementtextoptionallocate by VISIBLE text (like getByText), e.g. "Subscribe"roleoptionalan ARIA role (like getByRole), pair with name; with text, scopes it to "button"/"link"/"any"nameoptionalthe accessible name to match when role is setlabeloptionala labelled control by its label text, e.g. "Email address"placeholderoptionalan input placeholdertestidoptionala data-testid / data-test-id valuexpathoptionalan XPath expressionmatchoptionaltext/name match mode: "icontains" (default), "contains", "equals", "iequals", "starts_with", "ends_with", "regex"nthoptionalwhen several elements match, pick this one (0-based); omit to require a single matchtimeout_msoptionalmax ms to auto-wait for a match to appear (default ~8000)poll_msoptionalpoll interval while waiting (default ~150)godbrowser_right_clickRight-click (context-click) an element via a real, trusted pointer to open its context menu / fire contextmenu. Full universal locator + auto-wait. Supports the deep-piercing locator (T-1023): the >>> frame-descent combinator (or frame_path[] + selector, or shadow-only pierce:true) reaches across nested cross-origin iframes (OOPIFs) and open OR closed shadow roots in one flat selector — first-party / operator-only.15 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchpierceoptionalalso search inside OPEN shadow roots for this locator (a CLOSED shadow root is unreachable from script by design, and is reported as not-found rather than guessed at)withinoptionala CSS selector for a CONTAINER (usually a form) to search INSIDE — the locator then resolves only within it. Take it from godbrowser_read_page mode:"actions" forms[].selector. Use it whenever a page has more than one form or two similar-looking buttons; omit it for today's whole-page behaviour. A container that is not on the page is reported as within_not_found, never widened back to the whole page.selectoroptionala CSS selector for the elementtextoptionallocate by VISIBLE text (like getByText), e.g. "Subscribe"roleoptionalan ARIA role (like getByRole), pair with name; with text, scopes it to "button"/"link"/"any"nameoptionalthe accessible name to match when role is setlabeloptionala labelled control by its label text, e.g. "Email address"placeholderoptionalan input placeholdertestidoptionala data-testid / data-test-id valuexpathoptionalan XPath expressionmatchoptionaltext/name match mode: "icontains" (default), "contains", "equals", "iequals", "starts_with", "ends_with", "regex"nthoptionalwhen several elements match, pick this one (0-based); omit to require a single matchtimeout_msoptionalmax ms to auto-wait for a match to appear (default ~8000)poll_msoptionalpoll interval while waiting (default ~150)godbrowser_selectChoose an option in a <select> dropdown — by the option's visible text (option_text, e.g. United States, when the value like US is opaque) OR by its exact value. Pass a selector for a specific dropdown, or omit it to use the first / only select. option_text supports match modes (icontains/contains/equals) + nth, and auto-waits for a late-rendered select.7 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchselectoroptionala CSS selector for the <select> (omit to use the first / only select on the page)valueoptionalchoose the option by its exact value (use this OR option_text)option_textoptionalchoose the option by its VISIBLE label text, e.g. "United States"matchoptionaltext match mode for option_text: "icontains" (default), "contains", or "equals"nthoptionalwhen several options match the text, pick this one (0-based); omit to require a single matchtimeout_msoptionalmax ms to auto-wait for a late-rendered select / option (default ~10000)godbrowser_toggle_switch_setSet an on/off toggle switch to a desired state — idempotent (clicks only when it differs; role=switch / aria-checked aware; verify-and-retry). Returns whether it changed. Full universal locator.17 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchstateoptionaldesired state: true = on (default), false = offcheckedoptionalalias for `state`, for symmetry with godbrowser_checkbox_setpierceoptionalalso search inside OPEN shadow roots for this locator (a CLOSED shadow root is unreachable from script by design, and is reported as not-found rather than guessed at)withinoptionala CSS selector for a CONTAINER (usually a form) to search INSIDE — the locator then resolves only within it. Take it from godbrowser_read_page mode:"actions" forms[].selector. Use it whenever a page has more than one form or two similar-looking buttons; omit it for today's whole-page behaviour. A container that is not on the page is reported as within_not_found, never widened back to the whole page.selectoroptionala CSS selector for the elementtextoptionallocate by VISIBLE text (like getByText), e.g. "Subscribe"roleoptionalan ARIA role (like getByRole), pair with name; with text, scopes it to "button"/"link"/"any"nameoptionalthe accessible name to match when role is setlabeloptionala labelled control by its label text, e.g. "Email address"placeholderoptionalan input placeholdertestidoptionala data-testid / data-test-id valuexpathoptionalan XPath expressionmatchoptionaltext/name match mode: "icontains" (default), "contains", "equals", "iequals", "starts_with", "ends_with", "regex"nthoptionalwhen several elements match, pick this one (0-based); omit to require a single matchtimeout_msoptionalmax ms to auto-wait for a match to appear (default ~8000)poll_msoptionalpoll interval while waiting (default ~150)godbrowser_typeType text into a field with real trusted key input — locate it by ANY of: CSS selector, role+name, label, placeholder, testid, or xpath (auto-waits). Set human for a realistic per-key typing cadence (key-hold dwell + variable inter-key delays + word-boundary pauses) instead of one bulk insert — tune with wpm (~65) + jitter (0..1, ~0.35). Optional per_char + submit to press Enter. Deep-piercing locator (T-1023): target a field across nested cross-origin iframes (OOPIFs) and open OR closed shadow roots in one flat selector via the >>> frame-descent combinator (or frame_path[] + selector, or shadow-only pierce:true) — trusted-focusing the field (typing works for shadow-pierce + same-process frames; char delivery into a cross-process OOPIF is a v1 follow-up). First-party / operator-only.20 parameters · 2 required
session_idrequiredthe session_id from godbrowser_launchselectoroptionala CSS selector for the input/textarea (or use a locator below). Deep-piercing: use " >>> " between iframe steps to reach a field inside nested cross-origin iframes and open/closed shadow rootspierceoptionalpierce open AND closed shadow roots when resolving the selector in the current frame (no frame descent)frame_pathoptionalstructured deep descent: an ordered list of iframe CSS selectors to cross before matching the field selector (equivalent to the inline " >>> " form)textrequiredthe text to enterroleoptionalan ARIA role for the field (pair with name), e.g. "textbox"nameoptionalthe accessible name when role is setlabeloptionalthe field's label text, e.g. "Email address"placeholderoptionalthe field's placeholder, e.g. "Search"nthoptionalwhen several fields match, pick this one (0-based); omit to require a single matchtestidoptionala data-testid valuexpathoptionalan XPath expressionwithinoptionala CSS selector for a CONTAINER (usually a form) to search INSIDE — the field locator then resolves only within it, so "the email field" means THIS form's email field. Take it from godbrowser_read_page mode:"actions" forms[].selector. Use it on any page carrying more than one form; omit for today's whole-page behaviour.matchoptionallocator match mode: "icontains" (default), "contains", "equals", "iequals", "starts_with", "ends_with", "regex"humanoptionaltype with realistic human keystroke timing (per-key dwell + variable inter-key delays + word-boundary pauses) — a natural cadence — instead of one bulk insertwpmoptionalapproximate typing speed in words per minute when human is set — the rate ACTUALLY TYPED, key-hold dwell included (default 85 ≈ 82 wpm measured, 1.5x faster than the previous build). Raising it further has little headroom: a ~120ms human key-hold dwell is ~83% of the per-character cost and is deliberately not shortened, because a sub-human dwell is itself a detection tell. For genuinely faster input use human:false (an openly non-human bulk insert)jitteroptionaltiming-variance factor when human is set, 0..1 (default ~0.35)per_charoptionalemit fixed-interval per-character key events (a simpler alternative to human; default: a single trusted insert)clearoptionalempty the field before typing (trusted keys, fires input). Use it whenever a field may already hold something — a pre-filled country prefix, a remembered value, or your own earlier attempt — because typing APPENDS and the result looks correct in every log. DEFAULTS TO TRUE — pass clear:false only when you genuinely mean to append.submitoptionalpress Enter after typinggodbrowser_upload_fileUpload a local file into a file-input (session_id + paths[]) — avatar / photo changes, KYC / document uploads, listing images, any Choose file control. The only way to do it: the browser blocks scripted value-set on a file input, so the node sets it natively and fires change. Target the field with selector_or_hint — a CSS selector, its label, or the drop-zone / upload container (pierces shadow DOM + same-origin iframes), or a short hint (field name / nearby label text) — or omit it when the page has one file input; paths[] takes one or many files (must exist on the node running the session). First-party / operator-only in v1.3 parameters · 2 required
session_idrequiredthe session_id from godbrowser_launchpathsrequirednode-local absolute path(s) of the file(s) to upload; one path, or several for a "multiple" file inputselector_or_hintoptionalhow to find the file field: a CSS selector (the <input type=file>, its <label>, or the drop-zone/upload container), or a short hint (field name / nearby label text). Omit to use the only file input on the page.godbrowser_assert_attributeAssert an element's named attribute matches expected, auto-waiting — clean ok:false (no throw). match default equals. Full universal locator.17 parameters · 2 required
session_idrequiredthe session_id from godbrowser_launchexpectedrequiredthe value the attribute should have (per match)matchoptionaltext/name match mode: "icontains" (default), "contains", "equals", "iequals", "starts_with", "ends_with", "regex"pierceoptionalalso search inside OPEN shadow roots for this locator (a CLOSED shadow root is unreachable from script by design, and is reported as not-found rather than guessed at)withinoptionala CSS selector for a CONTAINER (usually a form) to search INSIDE — the locator then resolves only within it. Take it from godbrowser_read_page mode:"actions" forms[].selector. Use it whenever a page has more than one form or two similar-looking buttons; omit it for today's whole-page behaviour. A container that is not on the page is reported as within_not_found, never widened back to the whole page.selectoroptionala CSS selector for the elementtextoptionallocate by VISIBLE text (like getByText), e.g. "Subscribe"roleoptionalan ARIA role (like getByRole), pair with name; with text, scopes it to "button"/"link"/"any"nameoptionalthe accessible name to match when role is setlabeloptionala labelled control by its label text, e.g. "Email address"placeholderoptionalan input placeholdertestidoptionala data-testid / data-test-id valuexpathoptionalan XPath expressionnthoptionalwhen several elements match, pick this one (0-based); omit to require a single matchtimeout_msoptionalmax ms to auto-wait for a match to appear (default ~8000)poll_msoptionalpoll interval while waiting (default ~150)attributeoptionalthe attribute to check, e.g. "href", "aria-expanded", "data-state". ⚠️ NOT "name" — on this surface `name` is the accessible name that pairs with `role`. (A bare `name` with no `role` is still read as the attribute, for callers written before this parameter existed.)godbrowser_assert_element_absentCheck an element is gone from the DOM (a spinner, modal, or toast disappearing), auto-waiting for it to leave — clean ok:false if still present (no throw). Full universal locator.15 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchpierceoptionalalso search inside OPEN shadow roots for this locator (a CLOSED shadow root is unreachable from script by design, and is reported as not-found rather than guessed at)withinoptionala CSS selector for a CONTAINER (usually a form) to search INSIDE — the locator then resolves only within it. Take it from godbrowser_read_page mode:"actions" forms[].selector. Use it whenever a page has more than one form or two similar-looking buttons; omit it for today's whole-page behaviour. A container that is not on the page is reported as within_not_found, never widened back to the whole page.selectoroptionala CSS selector for the elementtextoptionallocate by VISIBLE text (like getByText), e.g. "Subscribe"roleoptionalan ARIA role (like getByRole), pair with name; with text, scopes it to "button"/"link"/"any"nameoptionalthe accessible name to match when role is setlabeloptionala labelled control by its label text, e.g. "Email address"placeholderoptionalan input placeholdertestidoptionala data-testid / data-test-id valuexpathoptionalan XPath expressionmatchoptionaltext/name match mode: "icontains" (default), "contains", "equals", "iequals", "starts_with", "ends_with", "regex"nthoptionalwhen several elements match, pick this one (0-based); omit to require a single matchtimeout_msoptionalmax ms to auto-wait for a match to appear (default ~8000)poll_msoptionalpoll interval while waiting (default ~150)godbrowser_assert_element_checkedAssert a checkbox / radio / switch is checked, auto-waiting; checked:false asserts UNCHECKED — clean ok:false (no throw). Full universal locator.16 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchcheckedoptionaldesired state: true = checked (default), false = assert uncheckedpierceoptionalalso search inside OPEN shadow roots for this locator (a CLOSED shadow root is unreachable from script by design, and is reported as not-found rather than guessed at)withinoptionala CSS selector for a CONTAINER (usually a form) to search INSIDE — the locator then resolves only within it. Take it from godbrowser_read_page mode:"actions" forms[].selector. Use it whenever a page has more than one form or two similar-looking buttons; omit it for today's whole-page behaviour. A container that is not on the page is reported as within_not_found, never widened back to the whole page.selectoroptionala CSS selector for the elementtextoptionallocate by VISIBLE text (like getByText), e.g. "Subscribe"roleoptionalan ARIA role (like getByRole), pair with name; with text, scopes it to "button"/"link"/"any"nameoptionalthe accessible name to match when role is setlabeloptionala labelled control by its label text, e.g. "Email address"placeholderoptionalan input placeholdertestidoptionala data-testid / data-test-id valuexpathoptionalan XPath expressionmatchoptionaltext/name match mode: "icontains" (default), "contains", "equals", "iequals", "starts_with", "ends_with", "regex"nthoptionalwhen several elements match, pick this one (0-based); omit to require a single matchtimeout_msoptionalmax ms to auto-wait for a match to appear (default ~8000)poll_msoptionalpoll interval while waiting (default ~150)godbrowser_assert_element_countCheck the matched-element count meets expected, auto-waiting — clean ok:false if it never matches (no throw). comparator: equals (default) / gte / lte / gt / lt. Full universal locator.17 parameters · 2 required
session_idrequiredthe session_id from godbrowser_launchexpectedrequiredthe element count to check forcomparatoroptionalhow to compare the actual count to expected: "equals" (default), "gte", "lte", "gt", "lt"pierceoptionalalso search inside OPEN shadow roots for this locator (a CLOSED shadow root is unreachable from script by design, and is reported as not-found rather than guessed at)withinoptionala CSS selector for a CONTAINER (usually a form) to search INSIDE — the locator then resolves only within it. Take it from godbrowser_read_page mode:"actions" forms[].selector. Use it whenever a page has more than one form or two similar-looking buttons; omit it for today's whole-page behaviour. A container that is not on the page is reported as within_not_found, never widened back to the whole page.selectoroptionala CSS selector for the elementtextoptionallocate by VISIBLE text (like getByText), e.g. "Subscribe"roleoptionalan ARIA role (like getByRole), pair with name; with text, scopes it to "button"/"link"/"any"nameoptionalthe accessible name to match when role is setlabeloptionala labelled control by its label text, e.g. "Email address"placeholderoptionalan input placeholdertestidoptionala data-testid / data-test-id valuexpathoptionalan XPath expressionmatchoptionaltext/name match mode: "icontains" (default), "contains", "equals", "iequals", "starts_with", "ends_with", "regex"nthoptionalwhen several elements match, pick this one (0-based); omit to require a single matchtimeout_msoptionalmax ms to auto-wait for a match to appear (default ~8000)poll_msoptionalpoll interval while waiting (default ~150)godbrowser_assert_element_enabledAssert an element is enabled, auto-waiting; enabled:false asserts DISABLED — clean ok:false (no throw). Full universal locator.16 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchenabledoptionaldesired state: true = enabled (default), false = assert disabledpierceoptionalalso search inside OPEN shadow roots for this locator (a CLOSED shadow root is unreachable from script by design, and is reported as not-found rather than guessed at)withinoptionala CSS selector for a CONTAINER (usually a form) to search INSIDE — the locator then resolves only within it. Take it from godbrowser_read_page mode:"actions" forms[].selector. Use it whenever a page has more than one form or two similar-looking buttons; omit it for today's whole-page behaviour. A container that is not on the page is reported as within_not_found, never widened back to the whole page.selectoroptionala CSS selector for the elementtextoptionallocate by VISIBLE text (like getByText), e.g. "Subscribe"roleoptionalan ARIA role (like getByRole), pair with name; with text, scopes it to "button"/"link"/"any"nameoptionalthe accessible name to match when role is setlabeloptionala labelled control by its label text, e.g. "Email address"placeholderoptionalan input placeholdertestidoptionala data-testid / data-test-id valuexpathoptionalan XPath expressionmatchoptionaltext/name match mode: "icontains" (default), "contains", "equals", "iequals", "starts_with", "ends_with", "regex"nthoptionalwhen several elements match, pick this one (0-based); omit to require a single matchtimeout_msoptionalmax ms to auto-wait for a match to appear (default ~8000)poll_msoptionalpoll interval while waiting (default ~150)godbrowser_assert_element_existsCheck an element exists in the DOM (visible or not), auto-waiting — clean ok:false if it never appears (no throw). Full universal locator.15 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchpierceoptionalalso search inside OPEN shadow roots for this locator (a CLOSED shadow root is unreachable from script by design, and is reported as not-found rather than guessed at)withinoptionala CSS selector for a CONTAINER (usually a form) to search INSIDE — the locator then resolves only within it. Take it from godbrowser_read_page mode:"actions" forms[].selector. Use it whenever a page has more than one form or two similar-looking buttons; omit it for today's whole-page behaviour. A container that is not on the page is reported as within_not_found, never widened back to the whole page.selectoroptionala CSS selector for the elementtextoptionallocate by VISIBLE text (like getByText), e.g. "Subscribe"roleoptionalan ARIA role (like getByRole), pair with name; with text, scopes it to "button"/"link"/"any"nameoptionalthe accessible name to match when role is setlabeloptionala labelled control by its label text, e.g. "Email address"placeholderoptionalan input placeholdertestidoptionala data-testid / data-test-id valuexpathoptionalan XPath expressionmatchoptionaltext/name match mode: "icontains" (default), "contains", "equals", "iequals", "starts_with", "ends_with", "regex"nthoptionalwhen several elements match, pick this one (0-based); omit to require a single matchtimeout_msoptionalmax ms to auto-wait for a match to appear (default ~8000)poll_msoptionalpoll interval while waiting (default ~150)godbrowser_assert_element_textCheck an element's visible text matches expected, auto-waiting — clean ok:false with the observed text on mismatch (no throw). match: icontains (default) / contains / equals / iequals / starts_with / ends_with / regex. Full universal locator.17 parameters · 2 required
session_idrequiredthe session_id from godbrowser_launchexpectedrequiredthe text the element should haveexpected_matchoptionalhow to compare against `expected`: icontains (default) | contains | equals | iequals | starts_with | ends_with | regex. Separate from the locator's `match`.pierceoptionalalso search inside OPEN shadow roots for this locator (a CLOSED shadow root is unreachable from script by design, and is reported as not-found rather than guessed at)withinoptionala CSS selector for a CONTAINER (usually a form) to search INSIDE — the locator then resolves only within it. Take it from godbrowser_read_page mode:"actions" forms[].selector. Use it whenever a page has more than one form or two similar-looking buttons; omit it for today's whole-page behaviour. A container that is not on the page is reported as within_not_found, never widened back to the whole page.selectoroptionala CSS selector for the elementtextoptionallocate by VISIBLE text (like getByText), e.g. "Subscribe"roleoptionalan ARIA role (like getByRole), pair with name; with text, scopes it to "button"/"link"/"any"nameoptionalthe accessible name to match when role is setlabeloptionala labelled control by its label text, e.g. "Email address"placeholderoptionalan input placeholdertestidoptionala data-testid / data-test-id valuexpathoptionalan XPath expressionmatchoptionaltext/name match mode: "icontains" (default), "contains", "equals", "iequals", "starts_with", "ends_with", "regex"nthoptionalwhen several elements match, pick this one (0-based); omit to require a single matchtimeout_msoptionalmax ms to auto-wait for a match to appear (default ~8000)poll_msoptionalpoll interval while waiting (default ~150)godbrowser_assert_element_valueCheck a form field's current value (input / textarea / select) matches expected, auto-waiting to confirm a field was filled — clean ok:false on mismatch (no throw). Full universal locator.16 parameters · 2 required
session_idrequiredthe session_id from godbrowser_launchexpectedrequiredthe value the field should holdpierceoptionalalso search inside OPEN shadow roots for this locator (a CLOSED shadow root is unreachable from script by design, and is reported as not-found rather than guessed at)withinoptionala CSS selector for a CONTAINER (usually a form) to search INSIDE — the locator then resolves only within it. Take it from godbrowser_read_page mode:"actions" forms[].selector. Use it whenever a page has more than one form or two similar-looking buttons; omit it for today's whole-page behaviour. A container that is not on the page is reported as within_not_found, never widened back to the whole page.selectoroptionala CSS selector for the elementtextoptionallocate by VISIBLE text (like getByText), e.g. "Subscribe"roleoptionalan ARIA role (like getByRole), pair with name; with text, scopes it to "button"/"link"/"any"nameoptionalthe accessible name to match when role is setlabeloptionala labelled control by its label text, e.g. "Email address"placeholderoptionalan input placeholdertestidoptionala data-testid / data-test-id valuexpathoptionalan XPath expressionmatchoptionaltext/name match mode: "icontains" (default), "contains", "equals", "iequals", "starts_with", "ends_with", "regex"nthoptionalwhen several elements match, pick this one (0-based); omit to require a single matchtimeout_msoptionalmax ms to auto-wait for a match to appear (default ~8000)poll_msoptionalpoll interval while waiting (default ~150)godbrowser_assert_element_visibleCheck an element is present and visible, auto-waiting up to timeout_ms — a failed assert returns a clean ok:false, never an error (branch on ok). Full universal locator.15 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchpierceoptionalalso search inside OPEN shadow roots for this locator (a CLOSED shadow root is unreachable from script by design, and is reported as not-found rather than guessed at)withinoptionala CSS selector for a CONTAINER (usually a form) to search INSIDE — the locator then resolves only within it. Take it from godbrowser_read_page mode:"actions" forms[].selector. Use it whenever a page has more than one form or two similar-looking buttons; omit it for today's whole-page behaviour. A container that is not on the page is reported as within_not_found, never widened back to the whole page.selectoroptionala CSS selector for the elementtextoptionallocate by VISIBLE text (like getByText), e.g. "Subscribe"roleoptionalan ARIA role (like getByRole), pair with name; with text, scopes it to "button"/"link"/"any"nameoptionalthe accessible name to match when role is setlabeloptionala labelled control by its label text, e.g. "Email address"placeholderoptionalan input placeholdertestidoptionala data-testid / data-test-id valuexpathoptionalan XPath expressionmatchoptionaltext/name match mode: "icontains" (default), "contains", "equals", "iequals", "starts_with", "ends_with", "regex"nthoptionalwhen several elements match, pick this one (0-based); omit to require a single matchtimeout_msoptionalmax ms to auto-wait for a match to appear (default ~8000)poll_msoptionalpoll interval while waiting (default ~150)godbrowser_assert_page_contains_textCheck the page's visible text contains a string (confirm the right page or a success banner), auto-waiting — scans the main document + open shadow roots + same-origin iframes; clean ok:false (no throw). match: icontains (default) / contains / equals / regex.5 parameters · 2 required
session_idrequiredthe session_id from godbrowser_launchtextrequiredthe text expected to be visible on the pagematchoptionalmatch mode: "icontains" (default), "contains", "equals", "regex"timeout_msoptionalmax ms to auto-wait for the text to appear (default ~10000)poll_msoptionalpoll interval while waiting (default ~150)godbrowser_assert_titleAssert document.title matches expected, polling post-nav — clean ok:false (no throw). match: icontains (default) / contains / equals / iequals / starts_with / ends_with / regex.5 parameters · 2 required
session_idrequiredthe session_id from godbrowser_launchexpectedrequiredthe title (or fragment, per match) the page should havematchoptionalmatch mode: "icontains" (default), "contains", "equals", "iequals", "starts_with", "ends_with", "regex"timeout_msoptionalmax ms to auto-wait for the title to match (default ~10000)poll_msoptionalpoll interval while waiting (default ~150)godbrowser_assert_urlCheck the top URL matches expected, polling after a navigation settles — clean ok:false with the observed URL (no throw). match: equals (default) / contains / prefix / regex.5 parameters · 2 required
session_idrequiredthe session_id from godbrowser_launchexpectedrequiredthe URL (or URL fragment, per match) the page should be atmatchoptionalmatch mode: "equals" (default), "contains", "prefix", "regex"timeout_msoptionalmax ms to auto-wait for the URL to match (default ~10000)poll_msoptionalpoll interval while waiting (default ~150)godbrowser_capture_networkInspect the HTTP requests + responses your live session made (url, method, status, headers, body, content_type, timing) to find the API/data endpoint behind a page and build a faster direct request. Filter by host, path_contains, method, or resource_type (xhr / fetch / document). Drive the session first, then call this to read the captured XHR / fetch / GraphQL traffic. Read-only, by value + size-capped; infrastructure credentials never included.6 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchhostoptionalonly requests whose host contains this string, e.g. "999.md" or "api."path_containsoptionalonly requests whose path+query contains this string, e.g. "graphql" or "/search"methodoptionalonly this HTTP method, e.g. "POST"resource_typeoptionalonly this resource type: xhr | fetch | document (the data-bearing requests)limitoptionalmax entries to return (most recent; default ~100)godbrowser_count_elementsCount elements matching a locator (0 = none; never throws) — list length, results-appeared, or rows rendered. Returns count + visible. Full universal locator.15 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchpierceoptionalalso search inside OPEN shadow roots for this locator (a CLOSED shadow root is unreachable from script by design, and is reported as not-found rather than guessed at)withinoptionala CSS selector for a CONTAINER (usually a form) to search INSIDE — the locator then resolves only within it. Take it from godbrowser_read_page mode:"actions" forms[].selector. Use it whenever a page has more than one form or two similar-looking buttons; omit it for today's whole-page behaviour. A container that is not on the page is reported as within_not_found, never widened back to the whole page.selectoroptionala CSS selector for the elementtextoptionallocate by VISIBLE text (like getByText), e.g. "Subscribe"roleoptionalan ARIA role (like getByRole), pair with name; with text, scopes it to "button"/"link"/"any"nameoptionalthe accessible name to match when role is setlabeloptionala labelled control by its label text, e.g. "Email address"placeholderoptionalan input placeholdertestidoptionala data-testid / data-test-id valuexpathoptionalan XPath expressionmatchoptionaltext/name match mode: "icontains" (default), "contains", "equals", "iequals", "starts_with", "ends_with", "regex"nthoptionalwhen several elements match, pick this one (0-based); omit to require a single matchtimeout_msoptionalmax ms to auto-wait for a match to appear (default ~8000)poll_msoptionalpoll interval while waiting (default ~150)godbrowser_extractExtract structured data by CSS selector (first match or all), returned by value, size-capped.5 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchselectoroptionala CSS selector for the element(s) to extract (the fast, exact path — required unless you pass schema)alloptionaltrue = extract every match (an array); false = the first matchfieldsoptionaloptional {name: sub-selector} map to pull named fields per matched element (CSS path)schemaoptionaldescribe the fields you want in plain language (e.g. "title, price, year" or "{title, price, year}"); when set, the fields are parsed from the page content into structured JSON — no CSS selector neededgodbrowser_findFind an element by a natural-language description (e.g. the search box, the Sign up button, the email field) and get back a stable ref you pass straight to click / type / fill / select as their selector — no CSS knowledge needed, just describe the element. Returns found / ref / role / name; robust to markup changes.3 parameters · 2 required
session_idrequiredthe session_id from godbrowser_launchdescriptionrequireda natural-language description of the element, e.g. "the email field" or "the Accept cookies button"withinoptionala CSS selector for a CONTAINER (usually a form) — the page outline the search reasons over is narrowed to it first, so a description like "the submit button" cannot resolve to another form's. Take it from godbrowser_read_page mode:"actions" forms[].selector.godbrowser_get_attributeRead a named attribute (href, value, aria-checked, data-*), auto-waiting for a visible match — value is null if the attribute is absent, found:false if no element matches (no throw). Full universal locator.16 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchpierceoptionalalso search inside OPEN shadow roots for this locator (a CLOSED shadow root is unreachable from script by design, and is reported as not-found rather than guessed at)withinoptionala CSS selector for a CONTAINER (usually a form) to search INSIDE — the locator then resolves only within it. Take it from godbrowser_read_page mode:"actions" forms[].selector. Use it whenever a page has more than one form or two similar-looking buttons; omit it for today's whole-page behaviour. A container that is not on the page is reported as within_not_found, never widened back to the whole page.selectoroptionala CSS selector for the elementtextoptionallocate by VISIBLE text (like getByText), e.g. "Subscribe"roleoptionalan ARIA role (like getByRole), pair with name; with text, scopes it to "button"/"link"/"any"nameoptionalthe accessible name to match when role is setlabeloptionala labelled control by its label text, e.g. "Email address"placeholderoptionalan input placeholdertestidoptionala data-testid / data-test-id valuexpathoptionalan XPath expressionmatchoptionaltext/name match mode: "icontains" (default), "contains", "equals", "iequals", "starts_with", "ends_with", "regex"nthoptionalwhen several elements match, pick this one (0-based); omit to require a single matchtimeout_msoptionalmax ms to auto-wait for a match to appear (default ~8000)poll_msoptionalpoll interval while waiting (default ~150)attributeoptionalthe attribute to read, e.g. "href", "value", "aria-checked", "data-id". ⚠️ NOT "name" — on this surface `name` is the accessible name that pairs with `role`. (A bare `name` with no `role` is still read as the attribute, for callers written before this parameter existed.)godbrowser_get_current_urlRead the current page's top URL. Returns the URL.1 parameter · 1 required
session_idrequiredthe session_id from godbrowser_launchgodbrowser_get_element_textRead an element's trimmed visible text (innerText), auto-waiting — found:false if no match (no throw). Full universal locator.15 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchpierceoptionalalso search inside OPEN shadow roots for this locator (a CLOSED shadow root is unreachable from script by design, and is reported as not-found rather than guessed at)withinoptionala CSS selector for a CONTAINER (usually a form) to search INSIDE — the locator then resolves only within it. Take it from godbrowser_read_page mode:"actions" forms[].selector. Use it whenever a page has more than one form or two similar-looking buttons; omit it for today's whole-page behaviour. A container that is not on the page is reported as within_not_found, never widened back to the whole page.selectoroptionala CSS selector for the elementtextoptionallocate by VISIBLE text (like getByText), e.g. "Subscribe"roleoptionalan ARIA role (like getByRole), pair with name; with text, scopes it to "button"/"link"/"any"nameoptionalthe accessible name to match when role is setlabeloptionala labelled control by its label text, e.g. "Email address"placeholderoptionalan input placeholdertestidoptionala data-testid / data-test-id valuexpathoptionalan XPath expressionmatchoptionaltext/name match mode: "icontains" (default), "contains", "equals", "iequals", "starts_with", "ends_with", "regex"nthoptionalwhen several elements match, pick this one (0-based); omit to require a single matchtimeout_msoptionalmax ms to auto-wait for a match to appear (default ~8000)poll_msoptionalpoll interval while waiting (default ~150)godbrowser_get_htmlRead an element's HTML markup (outerHTML default, innerHTML with inner), auto-waiting; size-capped — found:false if no match (no throw). Full universal locator.16 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchinneroptionalreturn innerHTML instead of the default outerHTMLpierceoptionalalso search inside OPEN shadow roots for this locator (a CLOSED shadow root is unreachable from script by design, and is reported as not-found rather than guessed at)withinoptionala CSS selector for a CONTAINER (usually a form) to search INSIDE — the locator then resolves only within it. Take it from godbrowser_read_page mode:"actions" forms[].selector. Use it whenever a page has more than one form or two similar-looking buttons; omit it for today's whole-page behaviour. A container that is not on the page is reported as within_not_found, never widened back to the whole page.selectoroptionala CSS selector for the elementtextoptionallocate by VISIBLE text (like getByText), e.g. "Subscribe"roleoptionalan ARIA role (like getByRole), pair with name; with text, scopes it to "button"/"link"/"any"nameoptionalthe accessible name to match when role is setlabeloptionala labelled control by its label text, e.g. "Email address"placeholderoptionalan input placeholdertestidoptionala data-testid / data-test-id valuexpathoptionalan XPath expressionmatchoptionaltext/name match mode: "icontains" (default), "contains", "equals", "iequals", "starts_with", "ends_with", "regex"nthoptionalwhen several elements match, pick this one (0-based); omit to require a single matchtimeout_msoptionalmax ms to auto-wait for a match to appear (default ~8000)poll_msoptionalpoll interval while waiting (default ~150)godbrowser_get_input_valueRead a form field's current value (input / textarea / select), auto-waiting — found:false if no match (no throw). Full universal locator.15 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchpierceoptionalalso search inside OPEN shadow roots for this locator (a CLOSED shadow root is unreachable from script by design, and is reported as not-found rather than guessed at)withinoptionala CSS selector for a CONTAINER (usually a form) to search INSIDE — the locator then resolves only within it. Take it from godbrowser_read_page mode:"actions" forms[].selector. Use it whenever a page has more than one form or two similar-looking buttons; omit it for today's whole-page behaviour. A container that is not on the page is reported as within_not_found, never widened back to the whole page.selectoroptionala CSS selector for the elementtextoptionallocate by VISIBLE text (like getByText), e.g. "Subscribe"roleoptionalan ARIA role (like getByRole), pair with name; with text, scopes it to "button"/"link"/"any"nameoptionalthe accessible name to match when role is setlabeloptionala labelled control by its label text, e.g. "Email address"placeholderoptionalan input placeholdertestidoptionala data-testid / data-test-id valuexpathoptionalan XPath expressionmatchoptionaltext/name match mode: "icontains" (default), "contains", "equals", "iequals", "starts_with", "ends_with", "regex"nthoptionalwhen several elements match, pick this one (0-based); omit to require a single matchtimeout_msoptionalmax ms to auto-wait for a match to appear (default ~8000)poll_msoptionalpoll interval while waiting (default ~150)godbrowser_get_page_titleRead the current page's title (document.title). Returns the title.1 parameter · 1 required
session_idrequiredthe session_id from godbrowser_launchgodbrowser_inspect_windowHarvest the site-injected JavaScript globals a page stashes on window and return them as ranked JSON — often a faster, requests-less path than DOM scraping. Diffs the page's window globals against a clean same-origin baseline to surface only site-injected state — __NEXT_DATA__ (Next.js), __NUXT__ (Nuxt), __APOLLO_STATE__ (Apollo), __INITIAL_STATE__/__PRELOADED_STATE__ (Redux SSR), dataLayer (GTM), Shopify, wpApiSettings (WordPress), custom app state — classifies each and returns per global {name,type,constructor,keys?,length?,bytes,preview} ranked by usefulness (notable[] = the most useful). Getter- + circular-safe, depth/size-capped. A fixed, safe reader — content by value, never runs code you supply (like read_page).5 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchinclude_previewoptionalinclude a depth+size-capped value preview per global (default true)max_bytesoptionalper-global preview byte budget (default ~50KB, clamped to 128KB)name_filteroptionala JS regex to keep only globals whose name matches, e.g. "^__" or "STATE|DATA"include_functionsoptionalinclude function-valued globals (noted+skipped by default)godbrowser_is_checkedRead whether a checkbox / radio / switch is checked (native input + role=checkbox / radio / switch + aria-checked), auto-waiting — found:false if no match (no throw). Full universal locator.15 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchpierceoptionalalso search inside OPEN shadow roots for this locator (a CLOSED shadow root is unreachable from script by design, and is reported as not-found rather than guessed at)withinoptionala CSS selector for a CONTAINER (usually a form) to search INSIDE — the locator then resolves only within it. Take it from godbrowser_read_page mode:"actions" forms[].selector. Use it whenever a page has more than one form or two similar-looking buttons; omit it for today's whole-page behaviour. A container that is not on the page is reported as within_not_found, never widened back to the whole page.selectoroptionala CSS selector for the elementtextoptionallocate by VISIBLE text (like getByText), e.g. "Subscribe"roleoptionalan ARIA role (like getByRole), pair with name; with text, scopes it to "button"/"link"/"any"nameoptionalthe accessible name to match when role is setlabeloptionala labelled control by its label text, e.g. "Email address"placeholderoptionalan input placeholdertestidoptionala data-testid / data-test-id valuexpathoptionalan XPath expressionmatchoptionaltext/name match mode: "icontains" (default), "contains", "equals", "iequals", "starts_with", "ends_with", "regex"nthoptionalwhen several elements match, pick this one (0-based); omit to require a single matchtimeout_msoptionalmax ms to auto-wait for a match to appear (default ~8000)poll_msoptionalpoll interval while waiting (default ~150)godbrowser_is_enabledRead whether an element is enabled (not disabled / [disabled] / aria-disabled), auto-waiting — found:false if no match (no throw). Full universal locator.15 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchpierceoptionalalso search inside OPEN shadow roots for this locator (a CLOSED shadow root is unreachable from script by design, and is reported as not-found rather than guessed at)withinoptionala CSS selector for a CONTAINER (usually a form) to search INSIDE — the locator then resolves only within it. Take it from godbrowser_read_page mode:"actions" forms[].selector. Use it whenever a page has more than one form or two similar-looking buttons; omit it for today's whole-page behaviour. A container that is not on the page is reported as within_not_found, never widened back to the whole page.selectoroptionala CSS selector for the elementtextoptionallocate by VISIBLE text (like getByText), e.g. "Subscribe"roleoptionalan ARIA role (like getByRole), pair with name; with text, scopes it to "button"/"link"/"any"nameoptionalthe accessible name to match when role is setlabeloptionala labelled control by its label text, e.g. "Email address"placeholderoptionalan input placeholdertestidoptionala data-testid / data-test-id valuexpathoptionalan XPath expressionmatchoptionaltext/name match mode: "icontains" (default), "contains", "equals", "iequals", "starts_with", "ends_with", "regex"nthoptionalwhen several elements match, pick this one (0-based); omit to require a single matchtimeout_msoptionalmax ms to auto-wait for a match to appear (default ~8000)poll_msoptionalpoll interval while waiting (default ~150)godbrowser_protectionsReport the privacy and anti-fingerprint protections GodBrowser detects as active on the current page (the detected vendors, the shield count, and the protection categories present) so you can verify which engaged. A read-only summary returned by value; runs no page logic you supply. First-party / operator-only in v1.1 parameter · 1 required
session_idrequiredthe session_id from godbrowser_launchgodbrowser_read_pageRead the page as a structured outline — the accessibility tree, visible text, forms and links. Your primary way to see the page.4 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchmodeoptional"decide" — USE THIS WHEN DRIVING A PAGE. Returns only what a next-step decision needs: page.class (login|signup|otp|consent|search|error|form|content) with a confidence and the reason, blockers[] (consent overlay, captcha) which you clear FIRST because both present as your real action failing, primary_form with its fields and submit, and next[] — up to 12 ranked things to do, page furniture last. `counts` states exactly what was suppressed and from which region, so a short list is never confused with an empty page. Same single page read as "actions", reduced further. "actions" — every actionable element (up to 250) plus links and forms, when you need the whole surface rather than the next move. "a11y" role/name tree, "text", "both"max_charsoptionalcap on returned text length (default ~20000)withinoptionala CSS selector for a CONTAINER to read INSTEAD of the whole page — pass one of the forms[].selector values from an earlier actions read to see just that form's fields and controls. Cuts the payload on a page with many forms and removes the ambiguity that makes a later click land on the wrong one. If nothing matches the selector, you get within_not_found — the whole page is NEVER silently read as a fallback.godbrowser_scrape_templatesDrop-in scraping for common site shapes — no schema to author. action:"list" returns a curated catalog of scrape templates (product-listing, job-board, classifieds, forum, article, search-results), each a plain-language field spec; action:"apply" with a template_id + url opens the URL under a coherent persona and returns the extracted structured rows inline (rides the AI-native extractor, the same DATA-not-code path as extract schema-mode).7 parameters · 1 required
actionrequired"list" to get the template catalog, or "apply" to run a template against a URLtemplate_idoptionalfor apply: which template to run, e.g. "product-listing" (an id from action:"list")urloptionalfor apply: the page URL to scrape (http/https)osoptionalpersona OS for apply: windows | macos | linuxbrowseroptionalpersona browser for apply: chrome | edge | firefox | safariseedoptionala stable seed string -> a stable device identity for applycountoptionalreserved: how many shards to fan this template across the fleet (the path-b `template-scrape` builtin, live on the next node roll); the current DRIVE path runs a single sessiongodbrowser_screenshotCapture a PNG of the page — viewport, full page, or a single element — as an image you can view.5 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchfull_pageoptionalcapture the full scrollable page (default: the current viewport)selectoroptionalcapture only the element matching this CSS selectorout_pathoptionalALSO write the PNG here, on the machine running this MCP server, and return the absolute path. "~" is expanded and a relative path resolves against the server's working directory; missing parent directories are created. Combine with "selector" to land ONE element on disk. The answer carries `path` and `bytes_written` — a write that fails is reported as an error rather than dropped, because a capture the caller believes is on disk and is not is worse than no capture.return_imageoptionalalso inline the image in the answer when out_path is set. Default FALSE with out_path (the file IS the deliverable, and a base64 PNG in the answer is the cost this parameter exists to avoid) and always true without it.godbrowser_save_recipeWhile driving, save the exact steps you just performed as a reusable recipe. A recipe is data, not code — an ordered list of recorded steps (navigate/click/type/select/press/scroll/wait/extract/screenshot) with their recorded arguments. Page-script evaluation steps are never recorded, and a recipe containing one is rejected before replay.4 parameters · 2 required
session_idrequiredthe session_id from godbrowser_launch (its recorded actions become the recipe)namerequireda name for the saved reciperecipe_idoptionalappend a new version to this existing recipe instead of creating a new oneliteral_stepsoptionalstep indices (from godbrowser_record) whose value should be stored VERBATIM instead of generalised to a placeholder — for a value that really is meant to repeat, like a search term that happened to look like a username. A password/OTP value was never read and cannot be made literal; asking is refused and reported, never silently ignored.godbrowser_evalRun first-party JavaScript in your own live session and return its value. First-party / operator-only.2 parameters · 2 required
session_idrequiredthe session_id from godbrowser_launchexpressionrequireda JavaScript expression to evaluate in the page; its value (or an awaited promise) is returned by valuegodbrowser_loginSign a banked account into its site, optionally persisting the session. First-party / operator-only.6 parameters · 1 required
account_refrequiredthe banked account reference to log in — normally its email address, as saved with godbrowser_account_savehome_urloptionalthe signed-in landing page to confirm on (defaults to the account's site home). ⚠️ Its HOST is also the account lookup key, so passing a subdomain the accounts row does not carry makes the lookup miss — usually better omitted.domainoptionalthe site to log in to, e.g. "oxylabs.io" — REQUIRED when one email has accounts on several sites, since the email alone cannot say which. Prefer this over home_url for disambiguation: it is matched against the accounts row directly rather than being derived from a URL host.headedoptionalrun with a visible window if the site needs on-page interaction (default headless)sign_inoptionalfinish the login with the stored password when the restored session alone does not sign in (default TRUE). It asks the SITE rather than guessing: it opens the login page, and if the site redirects away instead of showing a password field, the restore already worked and nothing is typed. Waits for a pending Cloudflare Turnstile / reCAPTCHA token before submitting. Pass false to restore only and leave the password untouched.window_spreadoptionalspread this window so parallel logins do not stack on top of each other. OFF by default. Pass it when you are restoring several accounts HEADED and want to watch them all — without it every restored window lands at the same place and the ones underneath look like they never started. Geometry is derived from the profile seed, so a given account returns to the same spot on every visit.godbrowser_registerCreate + bank a new account on a target site under a coherent persona. First-party / operator-only.9 parameters · 1 required
targetrequiredthe site to register on (a domain or sign-up URL)emailoptionaluse THIS inbox for the account (must be one of your own inboxes — see godbrowser_inbox). Omit to let one be picked and soft-locked for you.persona_classoptional"desktop" (default) or "android"headedoptionalshow the browser window (default true when running locally, so you can watch the sign-up happen)persistoptionalbank the resulting logged-in session so the account can be restored later (default on)fast_typingoptionalfill each field in ONE bulk write with no per-key timing. ⭐ DEFAULT TRUE — standing operator directive (2026-09-13, restated 2026-09-16): FAST IS THE DEFAULT EVERYWHERE, and slow is opt-in. Pass false ONLY as a remedy for an observed symptom: a site that used to reach submit and now refuses. It is not a general best practice and must not be chosen pre-emptively "because realism matters" — the operator has weighed that trade and made it.resumeoptionalcontinue an account that was already started on this site instead of creating a new one. Its banked session is restored under the same persona, so the browser picks up where it left off (often at "verify your email"). Passing an `email` implies this when that account already exists.typing_wpmoptionalhow fast fields are typed, in words per minute (default 110 — a fast human; 65 is average, 40 the floor, 160 the ceiling). Faster is quicker but less human-looking, since the per-key cadence is part of the fingerprint.identity_hintsoptionaloptional hints for the generated identity (advisory)godbrowser_solve_captchaReport the outcome of the session's built-in captcha-service integration for the current page — armed SERVER-SIDE on every fleet session (no enable step, no provider key on this API): a detected challenge is routed to the configured provider automatically, and this reports the OUTCOME only (cleared? provider? kind? elapsed) — never a token or key. Optionally waits a few seconds for the outcome to settle.5 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchwait_msoptionalpoll up to this many ms for the outcome to settle (max ~120000)typeoptionaloptional hint of the challenge kind (advisory)probeoptionalALSO check the live DOM for a captcha widget the native detector did not log — use it when a widget is visibly on screen but the answer says none / cf_detect_no_challenge (the native detector stops looking ~10 s after page load, so an overlay opened later is never seen). Opt-in: the default answer is a log read with no page footprint. REQUIRED to clear a PerimeterX Press & Hold wall — the probe is what finds and holds it.solveoptionaldefault true. false = with probe:true, CLASSIFY a PerimeterX Press & Hold wall but do NOT hold it (observe the wall without interacting).godbrowser_cancelCancel a running job — queued shards stop instantly; an in-flight shard finishes its current task then stops.1 parameter · 1 required
job_idrequiredthe job_id returned by godbrowser_submitgodbrowser_delete_recipeDelete one or more of your saved recipes by id. Scoped to your own account; returns how many were removed.1 parameter · 1 required
recipe_idsrequiredthe recipe ids to delete (from godbrowser_list_recipes)godbrowser_list_recipesList your saved recipes — id, name, current version, status and creation time. Read-only and scoped to your own account.godbrowser_nodesList your node fleet — each node's OS, status, capabilities and hardware class.godbrowser_resultsFetch a job's scraped rows, paginated + tenant-scoped — page through them as they land.3 parameters · 1 required
job_idrequiredthe job_id returned by godbrowser_submitlimitoptionalrows per page (default 200, max 1000)offsetoptionalcursor offset for the next page (0-based)godbrowser_run_recipeReplay a saved recipe deterministically across your fleet — the recorded steps exactly, under a coherent per-seed persona, with no AI. Returns a job_id you poll like a submit.12 parameters · 1 required
recipe_idrequiredthe saved recipe id to replay (from godbrowser_list_recipes / godbrowser_save_recipe)osoptionalpersona OS -- windows | mac | linux | android | ios. (Aliases the parser also accepts: win, macos, osx, iphone, ipad.) An UNRECOGNISED token is logged and IGNORED, leaving a seed-derived OS, so spell it exactly.browseroptionalpersona browser -- chrome | chromium | edge | firefox | safari | brave | opera | vivaldi | samsung | yandex | duckduckgo. ⛔ PAIR IT COHERENTLY WITH os: safari exists only on mac/ios, samsung only on android, edge not on android. Call godbrowser_personas for the coherent combinations and why.localeoptionalpersona locale, e.g. "en-US", "de-DE" -- sets --bot-config-locale so language headers, Intl and the UA agreeseedoptionala stable seed string -> a stable device identitycountoptionalhow many replay shards to fan across the fleet from this one call (default 1, max 50); each shard runs a distinct coherent per-seed device (T-0904 native fan-out)nameoptionala label for this jobidentityoptional"fresh" (default) picks a NEW inbox + password for each run, so replaying a sign-up creates a NEW account rather than re-typing the recorded one; "reuse" replays literally against an account you name (for a LOGIN recipe, where a second account would be the bug); "none" runs a recipe that needs no identity at all.accountoptionalwith identity:"reuse", the account email whose stored credentials this run replayssession_idoptionallocal only: replay into an ALREADY-OPEN session instead of launching one (useful to watch it happen in a window you can see)headedoptionallocal only: show the browser window while replaying (default true)dry_runoptionalresolve the recipe and report the exact step list that WOULD run, without driving anythinggodbrowser_statusPoll a job — overall state + per-task status/attempts + a result-row count.1 parameter · 1 required
job_idrequiredthe job_id returned by godbrowser_submitgodbrowser_submitRun a workflow across your cross-OS node fleet under a matching-OS persona; returns a job_id to poll. Pick WHAT runs two ways: a built-in workflow via code_ref (call godbrowser_workflows for the list), OR your OWN target — pass url + a fields CSS-selector map ({name:'css-selector'}; a value may also be {selector,attr,all}, and a 'name[]' key collects an array) plus optional item_selector (the repeating list/table container ⇒ one row per match) to run the vetted custom-scrape builtin (deterministic CSS extract, no code upload) — so you can scrape any page at scale, not just the demo code_refs. Pass count (1..50, default 1) to fan N shards from this ONE submit — each shard a distinct coherent per-seed device (shard 0 = your seed, shard i = ${seed}#${i}, reproducible) placed across matching-OS nodes under a single job_id.10 parameters
nameoptionala label for this jobcode_refoptionalbuilt-in workflow: flagship-scrape-quotes | books-catalog | books-detail (default flagship-scrape-quotes). Omit and pass url+fields to run YOUR OWN target (custom-scrape).urloptionalrun YOUR OWN target: the page URL to scrape. Provide with `fields` to run the custom-scrape builtin across the fleet (no code upload).fieldsoptionalthe extraction schema for a custom url: a { name: "css-selector" } map (a value may also be { selector, attr, all } — attr: "text"|"href"|"src"|"html"|"value"; all:true / a "name[]" key collects an array). Deterministic CSS, no AI.item_selectoroptionaloptional, for a custom url: a CSS selector for the repeating container (list/table row). Present -> one result row per matched container; absent -> a single page-level row.osoptionalpersona OS -- windows | mac | linux | android | ios. (Aliases the parser also accepts: win, macos, osx, iphone, ipad.) An UNRECOGNISED token is logged and IGNORED, leaving a seed-derived OS, so spell it exactly.browseroptionalpersona browser -- chrome | chromium | edge | firefox | safari | brave | opera | vivaldi | samsung | yandex | duckduckgo. ⛔ PAIR IT COHERENTLY WITH os: safari exists only on mac/ios, samsung only on android, edge not on android. Call godbrowser_personas for the coherent combinations and why.localeoptionalpersona locale, e.g. "en-US", "de-DE" -- sets --bot-config-locale so language headers, Intl and the UA agreeseedoptionala stable seed string → a stable device identitycountoptionalhow many shards to FAN across the fleet from this one submit (default 1, max 50). Each shard runs a DISTINCT coherent per-seed device: shard 0 = your seed, shard i = a deterministic per-shard seed — one job_id fans N nodes.godbrowser_account_saveRecord an account you just created so you can log into it later: the site, the email, the password, and the persona seed its session was banked under.18 parameters · 2 required
domainrequiredthe site the account is on, e.g. "theoldreader.com"emailrequiredthe account email (normally one of your inboxes)passwordoptionalthe password used. Omit when you are only updating an existing account (a status change, say) — a blank password is never written over a stored one. Never echoed back by any read path.usernameoptionalthe username, if the site uses onepersona_seedoptionalthe seed the browser session was banked under (from godbrowser_launch) — this is what lets the session be restored laterstatusoptional"registered" (default), "verify_pending" if it still needs an emailed/SMS code, or "logged_in"verification_typeoptionalhow the site verified it: none | email_link | email_otp | phone_otp | unknown (default)proxy_provideroptionalthe egress vendor this account was registered through: busyip | nstproxy | iproyal | myprivateproxy | 2captcha | oxylabs | brightdata | smartproxy. This is the QUERYABLE answer to "which accounts came from provider X?" — distinct from `egress`, which is a free-text label that often names a network type ("mobile-us") rather than a vendor.phone_provideroptionalthe phone/SMS vendor whose number verified this account: busysms | textverified | custom (a number you supplied by hand). Omit when no phone was used — NULL means "no phone, or unknown", and guessing one writes a fabricated provenance.phoneoptionalthe number that verified this account, E.164 e.g. "+37367261179". Pair it with phone_provider — the number without the vendor cannot answer "whose number was this?".phone_verifiedoptionalwhether that number actually completed verification (as opposed to merely being typed into the form)notesoptionaloperator-readable provenance for this row — what proxy/exit, what captcha, what went wrong. Rendered in the portal Register Accounts table.persona_osoptionalthe device OS the browser presented at registration: windows | macos | linux | ios | android. A restore MUST relaunch on this device — the session store refuses to hand a banked session to a caller presenting a different one. Take it from godbrowser_launch's persona, not from memory.persona_browseroptionalthe browser engine presented at registration: chrome | edge | firefox | safari | samsung. Same device identity as persona_os; both are compared by the device check.persona_localeoptionalthe locale presented at registration, e.g. "en-US". A restored session whose locale differs from the one its cookies were minted under is a quieter form of the same incoherence as a wrong OS.egress_countryoptionalISO-2 country of the exit this account was registered through, e.g. "AU". ⛔ IT IS CORROBORATED, NOT TRUSTED: the server holds what the launch's egress assertion MEASURED for this persona_seed, and that value wins. A value that contradicts the measurement is REJECTED (the answer says so and names both); a value with no measurement behind it is NOT WRITTEN AT ALL, because a fabricated origin on an accounts row outlives the session and cannot be told apart from a real one afterwards (T-1605/T-1661). Pass persona_seed (or session_id) so the measurement can be found.session_idoptionalthe launch session this account was created in. Optional — persona_seed usually finds the same measurement — but it is the most direct key to the egress measurement used to corroborate egress_country.egress_classoptionalthe exit's network class: residential | mobile | datacenter | isp. NULL = unknown; do not guess one from the provider name.godbrowser_click_indicatorShow where this browser's clicks are landing: a small circle appears at each click and fades, so you can watch a run and see the landing point instead of inferring it from how the page reacted.2 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launch or godbrowser_registerenabledoptionaltrue = mark every click from now on; false = stop marking. Omit to read the current state without changing it.godbrowser_dismiss_dialogClose a welcome / onboarding / tour dialog that is covering the page — the kind a site shows right after sign-up.2 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchdry_runoptionalreport what it WOULD click without clickinggodbrowser_fill_credentialsType a saved account's email and password into a login form WITHOUT the password ever passing through you.6 parameters · 3 required
session_idrequiredthe session_id from godbrowser_launch or godbrowser_loginaccountrequiredthe account to log in as — its email address, as saved with godbrowser_account_savepassword_refrequiredthe password field, as its ref/selector from godbrowser_read_pageemail_refoptionalthe email/username field, if the form has one on this pagedomainoptionalthe site this login is for, e.g. "theoldreader.com" — needed only when the same email has accounts on several sites; otherwise taken from the page you are onsubmitoptionalpress Enter after the password (many login forms submit this way); default false — click the button yourselfgodbrowser_inboxInspect your email inboxes — the mailboxes the register flow catches OTP / verification mail in.21 parameters
actionoptional"status" (default) = your inboxes + liveness summary; "verify" = re-probe them live against the mail service and write the result back (a mailbox that comes back "could-not-check" keeps its stored flag — an unanswered probe is never written down as a failure); "pick" = choose the best inbox to receive the next verification mail; "code" = wait for and read the verification CODE (or confirm LINK) that a site just emailed to one of your inboxesemailoptionalnarrow to one inbox address. REQUIRED for action:"code" — the inbox the site was told to mail.provideroptionalnarrow to one provider, e.g. "gmx.com"usable_onlyoptionalonly inboxes that are active and not locked by a recent register runlimitoptionalmax inboxes to return IN ONE PAGE (status, default 50, max 500) or to probe (verify, default 25, max 200). ⛔ THIS IS A PAGE SIZE, NOT THE POOL — read `page.total_matched` for how many matched in all, and `page.next_offset` to get the rest. Asking for a bigger limit is not how you see more than 500; `offset` is.offsetoptional⭐ PAGE FORWARD. Skip this many matching inboxes before the page begins (default 0). Until 2026-09-24 this parameter did not exist and `status` was hard-capped at the first 500 mailboxes alphabetically — a register lane exhausted them and stopped while working mailboxes it could not address by name sat at row 501+. Walk the pool with `page.next_offset` until `page.has_more` is false.email_containsoptionalsubstring match on the inbox address, case-insensitive (e.g. "chloe", "@gmx.de"). The `email` parameter is an EXACT match and only ever helped a caller that already knew the address; this is how you find one you do not.name_containsoptionalalias for `email_contains` (substring match on the inbox address). Declared so it FILTERS rather than being silently dropped.queryoptionalalias for `email_contains` (substring match on the inbox address). Declared so it FILTERS rather than being silently dropped.receive_provenoptional⭐ SERVER-SIDE FILTER ON THE RECEIVE PROOF — the one that decides whether a pick is worth making. true = only mailboxes that received mail within the last 7 days (measured 2026-09-24: 161 of 5,957 active). false = only those with a recorded receive OLDER than that. "unknown" = only those with no receive ever recorded (127 of 5,957). Omit for no filter. ⛔ THREE-STATE ON PURPOSE: "unknown" is NOT folded into false — "we never wrote it down" and "we wrote it down and it is stale" are different facts. ⚠️ proven is a STRONG HINT, NOT A GUARANTEE: a box can go silent for ONE site while healthy for others. Filtering CLIENT-SIDE cannot substitute for this — with 161 proven in 5,957, the useful rows are mostly outside any single page you can fetch.freshoptionalfor action:"pick" — verify the chosen inbox live before returning it, so you are not handed a stale flagrequire_provenoptionalfor action:"pick" — refuse rather than return an inbox that has NOT received mail in the last 7 days. Measured 2026-09-16: ~75% of the pool has not, and the stored "connected" flag is true for 93% of those, so it cannot tell them apart. Without this you get the best-ranked candidate and a receive_proven field to judge it by; with it you get a fast, explicit refusal instead of a ten-minute wait on a mailbox that catches nothing. It never refuses merely because the proof could not be READ — that returns receive_proof_unavailable, a different fact.siteoptionalfor action:"pick" — THE SITE YOU ARE ABOUT TO REGISTER ON (e.g. "busyproxy.net"). ⛔ PASS IT. An inbox is spent only ON THE SITE it registered on, so with a site named the picker applies the PER-SITE rule; with no site it falls back CLOSED to "used anywhere = retired for ever" and can refuse every inbox you have. Measured 2026-09-16: a pick saw 6 register-ready inboxes and refused all 6 with no_inbox:pool_exhausted, because this surface had no parameter with which to name the site. ⭐ T-1709: with a site named, the answer is ALWAYS confirmed by the register picker (the only thing that can see every owner's accounts on that site), so it can never be an inbox already registered there — the ranked candidates are confirmed by name, best first. ⚠️ Like register, that soft-locks the RETURNED inbox for 3 minutes; omit site for a read-only ranked list.confirm_with_pickeroptionalfor action:"pick" — do not rank a list, ask the REGISTER PICKER itself. What comes back is an inbox godbrowser_register cannot then refuse, and a refusal is the one register would have given, naming the rule that refused. ⚠️ It MUTATES: the picker soft-locks the inbox it allocates for 3 minutes, so use it or lose it. Default false (a read-only recommendation that could still be refused for a rule this list cannot see — the answer says which rule).since_msoptionalfor action:"code" — epoch-ms of the submit that triggered this mail. Mail that arrived BEFORE it is rejected and the wait continues, so a previous attempt's code can never be handed back as this one. ⭐ PREFER session_id: you have no clock, and an anchor at the CALL time refuses the code that already arrived (measured). Without either, mail from the last 3 minutes is accepted. The answer always says which anchor was used (`anchor_source`).session_idoptionalfor action:"code" — ⭐ the session that submitted the form. The anchor is then derived from THAT session's own last submit (click / Enter / fill_form submit, minus 2 minutes so a click after the submit cannot overtake the mail), bounded by its last navigation — so this attempt's code is accepted however long you took to ask, and a previous page's code is not. Locally, with exactly one live session and no session_id, that session is used.timeout_msoptionalfor action:"code" — how long to wait for the mail in ONE call (default 25000, and 25000 is also the CEILING: a larger value is accepted and silently capped, not honoured). ⛔ ASKING FOR LONGER GETS YOU LESS MAIL, NOT MORE. The read runs in a hosted runtime that cancels the worker partway through a long wait, and the cancellation is not an answer — the call simply never returns, so a 120s request yields nothing where a 25s one would have returned the code. Measured on one inbox minutes apart: 60s cancelled every time, 20s answered immediately, and the mail had ALREADY ARRIVED and was sitting unread. If a short call comes back empty, CALL AGAIN with the same since_ms; mail arriving between calls is still found, so repeated short waits cover the same wall-clock without the cancellation. An empty answer whose `wait_clamped` is set carries `retry: true` and is NOT a verdict that the mailbox is empty.linkoptionalfor action:"code" — return the confirmation LINK instead of a code, for a site that mails a magic link rather than digits. ⛔ READ `read_verdict`, NOT just `link`: "found" means one url scored as a confident verification CTA; "link-uncertain" means the mail WAS read and links WERE found but none looks like a verification target — `link` is then null on purpose and you pick from `link_candidates` (always returned, best-first, each with its score, its category and the reasons it was ranked where it was: support / unsubscribe / legal / social / app_store / view_in_browser / homepage are demoted by name). A support-footer url handed back as the CTA is what this distinction exists to prevent. ⚠️ Every url returned here is HTML-entity-decoded before you see it (T-1697 — a real activation link arrived as `…?token&#x3D;eyJ…` and 404s until un-escaped); when the url was changed the answer carries `link_was_escaped:true` and the untouched `link_raw` beside it.code_lenoptionalfor action:"code" — the exact code length the page is asking for (e.g. 6 boxed inputs). A parse of a different length is rejected rather than typed in — including one from the AI fallback. Note the code reader also rejects a WRONG-CONTEXT parse: digits inside a url, a tracking id, a postcode or an order reference are not an OTP, and a message that never mentions a code does not yield one.subjectoptionalfor action:"code" — only consider mail whose subject contains thisfromoptionalfor action:"code" — only consider mail from this sender address or domaingodbrowser_next_stepLook at the current page and say WHAT STEP OF A SIGN-UP OR LOGIN IT IS and what to do next.4 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launch or godbrowser_registergoaloptionalwhat you are trying to achieve, e.g. "register an account" (default) or "log in"emailoptionalthe account email in play — lets the answer tell you WHICH inbox to read a code fromnoteoptionalanything you already know that the page does not show, e.g. "the code was already submitted once and rejected"godbrowser_phoneYour BusySMS phone numbers, for catching an SMS verification code.14 parameters
actionoptional"status" (default) = is BusySMS linked and can anything receive; "numbers" = one row per number with can_receive + reason; "pick" = choose a number for a site and start a verification; "wait_code" = wait for the code to arrive; "manual_code" = record a code you read off your own phonedeviceoptionalpin a specific number instead of letting one be chosen — the "device" handle or the 4-digit "tail" from action:"numbers". On "pick" it selects that number; on "wait_code" it watches that number. Use it when you know which phone the code will land on.targetoptionalfor "pick" — the site the number is for, e.g. "simplenote" or a domain. Used to avoid a number already burned on that site.verification_idoptionalfor "wait_code" — the id returned by "pick"brand_hintoptionalfor "wait_code" — the brand name as it appears in the message BODY, e.g. "Simplenote". More reliable than the sender, which is usually a numeric shortcode or a shared aggregator.timeout_msoptionalfor "wait_code" — how long to wait for the SMS (default 180000, max 300000)since_msoptionalfor "wait_code" — ignore codes older than this epoch-ms. Defaults to 2 minutes ago so a code from an EARLIER attempt is not returned as this one.custom_numberoptionalfor "pick" — use YOUR OWN number instead of a linked BusySMS one, e.g. "+37360000000". GodBrowser fills it into the form but cannot read the SMS, so you enter the code yourself and hand it back with action:"manual_code". Use this when BusySMS is not linked, or when a site needs a specific number.allow_reuseoptionalfor "pick" — this is a LOGIN to an existing account, so reuse the number even though it has already been used on this site. Registration deliberately refuses a reused number; signing back in requires one.forceoptionalfor "pick" with a pinned device — use that number even though BusySMS reports it as unable to receive right now. Only for a phone you can actually see; the answer states what BusySMS said so a real outage is still visible.codeoptionalfor "manual_code" — the verification code you read off your own phoneallow_paid_fallbackoptionalfor "pick" — if BusySMS cannot supply a number, rent one from the paid provider instead. Default FALSE: a tool call never spends money unless you ask it to.countryoptionalfor "pick" — ISO-2 country the number MUST be in, e.g. "US". A site's phone field validates the country BEFORE any SMS is sent, so a number from elsewhere fails at the field and reads as "the site never texted us". Our BusySMS SIMs are MD (+373); asking for US therefore needs allow_paid_fallback:true, and the refusal says so by name rather than reporting an empty SIM pool. Omit when the site accepts any country.preferoptionalfor "pick" — "busysms" (default: use your own linked SIMs, free) or "textverified" (go straight to the paid rental pool, skipping BusySMS). "textverified" IMPLIES allow_paid_fallback and always costs money; use it only when you know your own numbers cannot serve the site.godbrowser_recipe_from_recordingTurn a screencast recording into a replayable recipe: the video and the flow come from the SAME drive, so you record once and get both.3 parameters · 2 required
session_idrequiredthe session that was driven AND recordednamerequireda name for the saved reciperecording_idoptionalthe screencast recording to correlate with (default: the session's most recent)godbrowser_recordShow the steps recorded so far on this session — the flow that godbrowser_save_recipe would store.2 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchactionoptional"status" (default) shows the recorded steps; "clear" discards them and starts recording this session overgodbrowser_register_agenticRegister an account on any site by OBSERVING each step instead of following a fixed script: it looks at the page, works out what step it is, does it, and looks again — through sign-up forms, email codes, SMS codes, consent, region and plan choosers — until the account exists or it is genuinely stuck17 parameters · 1 required
targetrequiredthe site to register on (a domain or a sign-up URL)resumeoptionalCONTINUE a half-finished registration on this site instead of starting a new one. Finds the existing account (status registered / verify_pending / logged_in), restores its banked session under the same persona, and enters the loop ON WHATEVER PAGE THAT BROWSER IS ALREADY ON — the classifier works out the step, so a run interrupted at the email-code screen picks up at the email-code screen and one sitting at the sign-in page signs in. Use it after ANY interruption: a crash, a rate limit, a network drop, or a step someone completed by hand. ⛔ Without it, re-running registers a SECOND account on the same site, burns another inbox and strands the first one half-made. Pair with `email` when several accounts exist for the site. If no matching account is found this REFUSES rather than quietly registering a new one.allow_off_domainoptionalcontinue when the flow lands on a different registrable domain than the one you asked for. Default false: the usual cause is a repurposed or parked domain, and continuing then registers an account on a site you did not ask for.emailoptionaluse THIS inbox (must be one of yours); omit to have one picked and locked for youmax_stepsoptionalhow many steps to attempt before stopping (default 12)headedoptionalshow the browser window (default true, so you can watch)dry_runoptionalclassify each step and report what it WOULD do, without typing or clicking anythingtyping_wpmoptionalPer-key pace for the SLOW path only (default 110; 40 floor, 160 ceiling). ⛔ PASSING THIS DOES NOT MAKE TYPING FASTER — it has no effect at all unless fast_typing:false, and on that path a HIGHER number is still far slower than the default. If you are not deliberately on the cadence-realism path, omit it.typing_delay_msoptionalMilliseconds between keystrokes on the DEFAULT path (0-500, default 1). The default path types PER KEY with real keyDown/keyUp, because a bulk insert fires `input` and nothing else — no keydown, no keyup, and no `change` — so a site whose validation binds to key events reads the field as untouched however correct its value is (GitHub's username-availability check is one). 1ms costs ~15ms for a 15-character field. Raise it only for a site you have evidence is timing keystrokes; for human-like dwell + jitter use fast_typing:false with typing_wpm instead, which is a different thing and ~75ms per character.fast_typingoptionalFill each field in ONE bulk write. DEFAULT TRUE — leave it alone and typing is instant. ⛔ SETTING THIS FALSE MAKES EVERY FIELD TAKE SECONDS INSTEAD OF MILLISECONDS: it types key-by-key at typing_wpm, so a 25-character email costs ~3 seconds of keystrokes and a signup form several times that. It is a REMEDY for ONE named symptom — a site that PREVIOUSLY reached submit now refuses, AND you have already ruled out the persona and the exit. It is not a realism upgrade and must not be set pre-emptively: on 2026-09-16 a caller passed fast_typing:false on a fresh target, then reported the browser as slow. If you are reading this and nothing has regressed, you want the default.proxy_provideroptionalegress provider for the whole registration, e.g. "busyip", "iproyal", "mpp". Omit to use the account pool's default. "busyip" composes its targeting per launch, so pair it with proxy_country.proxy_countryoptionalISO-2 country for the exit, e.g. "uz", "us". An exit that states NO country is excluded rather than assumed to match.proxy_typeoptionalBusyIP only — exit network class: "mobile" | "residential" | "any". Pair a mobile exit with a mobile persona or the pair is a contradiction a detector can read.proxy_modeoptionalBusyIP only — "sticky" PINS ONE EXIT DEVICE for the whole registration. ⭐ Strongly recommended for any register/login flow: "rotate" (the historical default) draws a NEW DEVICE PER REQUEST, so a signup arrives at the origin from dozens of different IPs across several ASNs, which breaks server-side sessions and is the shape anti-bot is built to flag. A pinned session is probed for liveness before the browser launches, and re-pinned onto a fresh device if the drawn one is offline.proxy_sessionoptionalBusyIP only — explicit session id to pin to (1-32 alphanumerics, NO dashes). Implies sticky. Omit and pass proxy_mode:"sticky" to derive one from the run seed.recordoptionalrecord this registration for replay (default TRUE). The recording is written to disk on this machine and labelled with the target site; the answer carries its `recording_id`, which godbrowser_screencast action:"play" turns into a local play URL. ⛔ No live watch URL is created or returned — that is a credential, and a recording is not. Pass false to opt out; you cannot opt IN later, because the capability is granted when the browser starts.directoptional⚠️ REGISTER WITH NO PROXY AT ALL — the whole run egresses from THIS MACHINE'S OWN PUBLIC IP and the site sees the host address. It overrides the account pool, which a register with no proxy argument would otherwise still use. Use it as a DIAGNOSTIC CONTROL — "is this 403 / this security checkpoint about the exit rather than about us?" — and as the way to reach a site that refuses every exit you have. Off by default, never chosen for you, and reported back in the answer as `egress`. ⛔ Contradicts proxy_provider/proxy_country/proxy_type; passing both is refused rather than silently resolved one way.godbrowser_screencastWatch a live GodBrowser session in your browser, and record it for replay.7 parameters
session_idoptionalthe session_id from godbrowser_launch. Required for status/start/stop/record/stop_record; omit for list (lists every recording) and for play/delete addressed by recording_id.actionoptionalstatus (default) = what is actually happening now; start = begin the live stream and return watch_url; stop = end the stream AND close any open recording; record = start (if needed) and begin saving frames to disk; stop_record = close the recording, keep streaming; list = stored recordings, newest first; play = a LOCAL URL for a stored recording (only works on this machine); delete = remove one; share = mint a PUBLIC link anyone can open, no account needed — use this to send a recording to someone; unshare = revoke that link.fpsoptionalframes per second, 1-15 (default 4). Frames beyond this are dropped as they arrive, never buffered -- a live view that is thirty seconds behind is worthless.qualityoptionalJPEG quality 1-100 (default 60)max_widthoptionallongest edge in CSS px (default 1280). The browser scales the frame; we never re-encode.labeloptionalfor action:"record" -- a human name for this recording, e.g. "otp attempt 3"recording_idoptionalfor action:"play" / "delete" -- the id from action:"list" (rec_...)godbrowser_swipeSwipe with a REAL touch gesture (up/down/left/right), on the whole page or on one element.6 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchdirectionoptionalup | down | left | right (default up — the direction your FINGER moves, so "up" scrolls the page down, as on a phone)selectoroptionaloptional: anchor the gesture on this element (a specific carousel), instead of the viewport centredistanceoptionalpixels to travel (default ~60% of the smaller viewport side)duration_msoptionalhow long the gesture takes (default 300). Velocity matters: momentum and fling handlers read the movement profile, not just the endpoints.stepsoptionalintermediate touchMove points (default 12) — a single jump produces no velocity at allgodbrowser_typingChange how fast the register/login flow types, on a browser that is already running — no relaunch.4 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launch or godbrowser_registerwpmoptionalwords per minute for per-key typing: 40 (slow) to 160 (ceiling). 65 is an average human, 110 a fast one. Omit to leave unchanged.jitteroptionalhow much the per-key timing varies, 0..1 (default ~0.35). Lower is more machine-like — 0 is a metronome and an obvious tell.humanoptionalfalse = fill each field instantly in one bulk write (no inter-key timing) — this is the DEFAULT posture per standing operator directive. true = per-key typing, which is slower and is a remedy for a site that demonstrably refuses the bulk write, not a routine setting.godbrowser_accept_termsTick the "I agree to the Terms of Service / Privacy Policy" consent boxes on a sign-up form. ⛔ IT ACCEPTS ALL OF THEM: a form often carries several separate REQUIRED consents (terms, privacy, acceptable-use, billing) and leaving one unticked keeps the submit button inert with no error shown, which looks like a broken button. Returns a per-box result plus `accepted`, which is true only if none were left unchecked. It REFUSES optional marketing/newsletter opt-ins and lists them under `skipped_optional` — it never subscribes you to anything. Handles the common case where the real <input> is hidden behind a styled wrapper (MUI/Radix/label-for), which plain checkbox_set cannot click, and it VERIFIES each box actually ended up checked rather than trusting the click.2 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchinclude_optionaloptionalalso tick optional marketing/newsletter opt-ins (default FALSE — they are refused and reported, never silently accepted)godbrowser_busymateRead the network traffic your GodBrowser sessions captured as a paired Busymate device — the request/response record that OUTLIVES the browser session, unlike godbrowser_capture_network which only sees one live session's in-memory ring. Use it to answer "what did this browser actually send/receive" after the fact, across launches. Actions: "devices" lists the Busymate devices this account owns (uuid, name, when it was last seen); "requests" lists captured requests for ONE device, newest first, with url, host, path, method, status, content-type, size, duration and the device/egress country; "request" returns ONE captured entry in full, including request and response headers and the response body. Read-only — it never pairs, renames or deletes anything.
SCOPE IS THE CREDENTIAL: the account is resolved from the vault on every call and the answer always names the identity it read, so you can see whose traffic you were served. A device (uuid or name) is REQUIRED for "requests" — an unfiltered scan over a real account's history times out server-side rather than returning a short answer, so there is deliberately no unscoped list. Bodies and headers are omitted by default and returned only when you ask for them, because a captured response body can contain the site's own session cookies and tokens — treat anything returned that way as a secret.15 parameters · 1 required
actionrequireddevices = list this account's Busymate devices · hosts = which hosts a device captured and how many each (call this FIRST to see what the noise is) · requests = captured requests for ONE device · request = one captured entry in fulldeviceoptionalREQUIRED for "hosts" and "requests": the device uuid, or its exact name (e.g. "gb-myjob"). Get it from action:"devices".entry_idoptionalREQUIRED for "request": the entry id from action:"requests"hostoptionalonly entries whose host contains this, e.g. "api." or "nike.com"path_containsoptionalonly entries whose path contains this, e.g. "/graphql" or "login"sinceoptionalISO date/datetime — only entries at or after it, e.g. "2026-09-10" or "2026-09-10T15:00:00Z"limitoptionalmax entries (default 25, cap 200)include_bodiesoptionalon "requests": also return request/response headers and the response body for each entry. OFF by default — a captured body can carry the site's own cookies and tokens.methodoptionalonly this HTTP method, e.g. "POST" — the fastest way to cut beacon/asset GET noisestatusoptionalonly this exact response status, e.g. 403status_classoptional"4xx"/"5xx" to find what the site REFUSED · "any" = only entries that got a response at all · "none" = only entries with NO paired response (status 0). On a real capture a third of entries are "none" — preflights and beacons — so this is usually what you want to exclude.content_typeoptionalonly entries whose content-type contains this, e.g. "json" (the single best filter for finding the API behind a page)data_onlyoptionalshorthand for "the API traffic, not the page furniture": keeps entries that are either JSON-typed or a POST. Use it when you want the endpoints, not the images/scripts/beacons.exclude_hostsoptionaldrop entries whose host contains any of these, e.g. ["doubleclick","hotjar"]. Combines with exclude_noise.exclude_noiseoptionaldrop the common ad/analytics/tracker mesh (google, doubleclick, bing, snapchat, pinterest, amazon-adsystem, reddit, facebook, tiktok, criteo, hotjar, segment, sentry, newrelic, datadog, cloudflare insights, …). OFF by default. When ON the answer REPORTS how many entries it removed and the response says so — a filter that hides rows silently is how a capture comes to look empty.godbrowser_fill_formFill a whole form in ONE call: an ordered list of fields, each located the same way godbrowser_type locates one (CSS "selector"; "role"+"name"; "label"; "placeholder"; "testid"; "xpath"; plus "within" to scope it to one form), each with the "text" to enter — and optionally a "submit" control to click once every field has been verified. Use it for any multi-field form: signup, login, checkout, address, profile. It replaces N separate calls with one, which is the whole point — the browser was never the slow part. ⛔ EVERY FIELD IS READ BACK: `filled` per field is what the page actually holds, not the fact that keys were sent, so a field that silently did not take is reported instead of passing as success (it retries such a field once by itself first, and says so). ⛔ It STOPS at the first field that does not verify and does NOT click submit — a half-filled form that gets submitted comes back as the SITE rejecting your data, which sends you to debug the wrong system; pass continue_on_error:true to get every field's verdict in one shot instead. Typing rhythm is taken from whatever this session is currently set to (see godbrowser_typing) unless you pass "human" explicitly, so a per-site cadence choice is not silently overridden by a batch. ⚠️ That is DIFFERENT from godbrowser_type, whose "human" defaults OFF regardless of the session — and it costs real time: measured on one 18-character field, 1.9s at the bulk cadence versus 14.0s at 65 wpm per-key (both including the read-back retry). Fast is the DEFAULT posture per standing operator directive, so you do not need to ask for it; pass human:true only as a remedy for a site that demonstrably refuses a bulk write. The answer always reports which cadence was applied. Values are treated as credentials: only lengths and verdicts come back, never the text.9 parameters · 2 required
session_idrequiredthe session_id from godbrowser_launchfieldsrequiredthe fields to fill, IN ORDER. Each carries its locator and the text to enter.submitoptionaloptional: the control to click once EVERY field has verified. Skipped automatically — with a reason — if any field did not.continue_on_erroroptionalkeep going after a field that does not verify, so one call returns every field's verdict instead of stopping at the first problem. It still never clicks submit over an unverified form. Default false (stop at the first failure).humanoptionalper-key human cadence for every field. OMIT IT to inherit whatever this session is currently set to (godbrowser_typing) — that is the point: a batch verb should not override a per-site cadence decision.wpmoptionaltyping speed when human cadence is in effect (default: the session's current setting)jitteroptionaltiming variance 0..1 when human cadence is in effect (default: the session's current setting)clearoptionalcall-level default for per-field `clear` (default true)timeout_msoptionalcall-level default for how long to auto-wait for each field to appear (default ~8000)godbrowser_fill_otpEnter a one-time code (OTP / 2FA / email or SMS verification) in ONE call. Point it at the field, or at the FIRST box of a boxed code — it works out the rest itself. ⛔ It DETECTS THE SHAPE from the DOM: one input that holds the whole code, or N single-character boxes (some sites render one input that merely looks like boxes, and some name an email field "sms", so neither the id nor the appearance is trusted). It tries the cheapest thing first — write the whole code into the first box, which most box components distribute themselves — then falls back to one insert per box, then to real keystrokes riding the widget's own auto-advance. ⛔ It READS EVERY BOX BACK and reports what actually landed: `filled` is that measurement, never the fact that keys were sent, so a component that swallows or reorders a character is reported instead of passing as success (a five-of-six code is indistinguishable from a WRONG code at the submit button). It also reports `self_submitted` when the form submits itself on the last character, so you do not click a button that is already gone or conclude nothing happened. `human` (per-key cadence) exists but DEFAULTS OFF here — for a code read off a screen it is both slower and less realistic than a burst. The code is treated as a credential: only a verdict and LENGTHS are ever returned or logged.18 parameters · 2 required
session_idrequiredthe session_id from godbrowser_launchcoderequiredthe one-time code to enter. Treated as a credential — never returned, never logged, never written into a recipeselectoroptionala CSS selector for the field, or for the FIRST box of a boxed code (or use a locator below). A selector that matches the whole box group is fine — the first match is usedroleoptionalan ARIA role for the field (pair with name)nameoptionalthe accessible name when role is setlabeloptionalthe field's label text, e.g. "Verification code"placeholderoptionalthe field's placeholdertestidoptionala data-testid value, e.g. "otp-box-0"xpathoptionalan XPath expressionmatchoptionallocator match mode: "icontains" (default), "contains", "equals", "iequals", "starts_with", "ends_with", "regex"nthoptionalwhen the locator matches several elements, which one is the FIRST box (0-based, default 0)strategyoptionalforce one entry path instead of the fallback chain: "bulk" (whole code into the first box) | "per-box" (one insert per box) | "keys" (trusted keystrokes, auto-advance) | "auto" (default — try them in that order until the read-back verifies)humanoptionaltype with per-key human cadence. DEFAULTS OFF for this verb: a code copied off a screen is entered in a burst, so cadence here is both slower AND less realistic than the default. Set it only when a site is measuring keystroke dynamics on the code field itselfwpmoptionalapproximate typing speed when human is set — the rate ACTUALLY TYPED, key-hold dwell included (default 85 ≈ 82 wpm measured)jitteroptionaltiming-variance factor when human is set, 0..1 (default ~0.35)submitoptionalpress Enter after the code verifies. Skipped automatically if the code did not land, or if the form already submitted itselfsubmit_wait_msoptionalhow long to watch for a self-submit after the last character (default 600)timeout_msoptionalmax ms to wait for the field to appear (default ~10000)godbrowser_find_loginFind a site's LOG-IN page. Give it a domain and it returns the URL of the page that actually carries a login form — conventional paths, then the site's own "Log in" link, then app/auth/accounts subdomains. ⛔ Same validation as find_signup and the same trap in reverse: a candidate counts only if it serves a PASSWORD FIELD and the final url after redirects is not a REGISTRATION page. Use it before restoring a saved session or filling stored credentials, so the flow types into a login form rather than a sign-up form for an account that already exists. `how` says which strategy found it; `tried` explains every rejection when nothing is found.1 parameter · 1 required
targetrequiredthe site — a bare domain like "todoist.com"godbrowser_find_signupFind a site's SIGN-UP page. Give it a domain and it returns the URL of the page that actually carries a registration form — trying conventional paths, then following the site's own "Sign up" link, then app/auth/accounts subdomains (the form is often on one the marketing site never links). ⛔ IT VALIDATES, IT DOES NOT GUESS: a candidate counts only if it serves a PASSWORD FIELD and the FINAL url after redirects is not a login page — a /signup that redirects to /login looks like success otherwise, and "Sign up" and "Sign in" differ by two characters. `how` says which strategy found it. NOT FOUND IS NOT "no such page": an entry point rendered by JavaScript is invisible to HTML probing, so `tried` lists every candidate and the reason each was rejected, and the right next move is to drive the site in a browser.1 parameter · 1 required
targetrequiredthe site — a bare domain like "umami.is" is the point; a full URL is returned as-is if it already carries a formgodbrowser_handle_dialogAnswer a NATIVE browser dialog — the OS-drawn alert / confirm / prompt / "leave site?" box that JavaScript opens. These freeze the whole page: while one is open nothing else on the session responds, and every other verb fails fast telling you so. A plain alert is accepted automatically and its text is reported to you, since it has one button and accepting commits nothing. A confirm, a prompt, or a leave-site box is left open for you, because saying yes to one can be destructive — pass accept:true or accept:false to answer it, and prompt_text to fill a prompt. This is NOT for in-page pop-ups built out of HTML (a cookie banner, a welcome modal, a lightbox) — those are DOM elements; use godbrowser_dismiss_dialog or godbrowser_click for them.3 parameters · 2 required
session_idrequiredthe session_id from godbrowser_launchacceptrequiredtrue = press OK/Leave, false = press Cancel/Stay. REQUIRED and has no default: accepting a confirm can be destructive, so this verb will not choose for you.prompt_textoptionalthe text to type into a prompt() box before accepting. Ignored for alert/confirm/beforeunload.godbrowser_password_resetReset a saved account's password end to end: fill the site's "forgot password" form with the account email, submit it, take the reset LINK out of your own inbox, open it, and set a new password — then it is saved back onto the account so a later login uses it. Point it at a session already on the reset page, or pass reset_url and it will navigate there. ⛔ MOST SITES ONLY MAIL A RESET TO A **VERIFIED** ADDRESS: an account whose email was never confirmed gets NO mail and NO error, and this reports that as its own outcome (`stage:"reset_mail"`) rather than as a broken form — check whether the address was ever confirmed before calling it a defect. ⚠️ The final submit is reported as SUBMITTED, not as accepted: a reset page that re-renders is a server answer, so verify by signing in. 6 parameters · 2 required
session_idrequiredthe session_id from godbrowser_launch — the browser that will drive the resetaccountrequiredthe account email to reset. It must be one of YOUR inboxes, because the reset link is read out of it.domainoptionalthe site the account is on, e.g. "github.com" — used to look the account row up when saving the new password. Taken from the page when omitted.reset_urloptionalnavigate here first, e.g. "https://github.com/password_reset". Omit if the session is already on the reset form.new_passwordoptionalthe password to set. Omit and one is generated (20 chars, mixed) — it is written to the account row either way, and never returned here.wait_msoptionalhow long to wait for the reset mail in one call (default 25000, which is also the ceiling — a longer wait gets CANCELLED by the mail runtime and returns nothing, so repeated short waits beat one long one).godbrowser_price_matrixHarvest a vendor's REAL price matrix out of its logged-in order builder — the numbers that only exist once an order is configured, not the "from $X" on the marketing card. It reads the available options off the page itself (term pills, quantity tiles, the free-text quantity box and its min/max, plan tabs, proxy-type radios), then walks the combinations, setting each one with trusted input and reading the summary panel back once it has demonstrably settled. Returns one row per cell — {product, term, quantity, unit_price, discount_pct, total, currency, location, addons, read_at, source_url} — plus a coverage report and an explicit list of what it could NOT enumerate. ⛔ IT NEVER COMMITS: "Continue", "Buy Now", "Complete order", "Checkout", "Add funds" and friends are on a hard denylist, and a page that turns out to be a checkout is abandoned rather than configured. Bounded by max_cells with a stated traversal order, because the full cross-product explodes.9 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launch or godbrowser_login — a session already signed in to the vendor dashboardproductoptionalwhere the builder is: a full URL to navigate to, or the visible name of a nav link to click ("Mobile", "ISP"). Omit to harvest whatever configurator is on the CURRENT page.enter_builderoptionalafter landing, click a non-committing entry control ("Set up my proxy", "Create a new order", "Configure") if the page has one (default true). A commit-shaped control is never clicked, so a product whose only entry is "Buy Now" reports entry:"refused_commit" and you must open the builder yourself.dimensionsoptionalwhich dimensions to WALK, outermost first (default ["proxy_type","plan","term","quantity"]). Everything discovered but not listed is enumerated and reported under not_traversed, held at the page default. "quantity" covers both the preset tiles and the free-text box.quantitiesoptionalextra quantities to probe through the FREE-TEXT box, on top of the preset tiles. This is where the steep tiers live — a 1000-proxy or 10000-GB cell exists nowhere else. Values outside the box's own min/max are skipped and reported.max_cellsoptionalhard ceiling on cells visited (default 60). The traversal is outermost-first, so a truncated run still yields COMPLETE quantity ladders for the dimensions it did reach, rather than a ragged slice of all of them.settle_timeout_msoptionalhow long a single cell may take to settle before it is recorded as unsettled and skipped (default 6000)poll_msoptionalsettle poll interval (default 120)dry_runoptionaldiscover and report the dimensions, the traversal plan and the cell count WITHOUT setting anything or reading a price. Run this first on a new vendor.godbrowser_probe_exitDraw proxy exits until one can actually reach a page, then hand back that live session to drive. Launches, walks the entry path, and PROVES the real page rendered by finding expect_selector — POLLING for it, because an anti-bot INTERSTITIAL (DataDome rt:'i') clears itself in 25-40s and a page read before that shows a challenge that is not a refusal. Returns the session_id of the CLEAN session, left open for you, plus a per-attempt log classifying each exit as clean / pending (still resolving when the budget ran out) / challenged (a hard refusal) / transport (a dead tunnel, which says nothing about reputation). ⚠️ This verb previously read once after ~800ms and its own docstring asserted "1 exit in 6 was usable" — that was its own latency, retracted 2026-09-17 after two controls showed a recorded-failure exit passing on re-test and the persona making no difference on a fixed verified IP. Do not reintroduce a short window.15 parameters · 2 required
urlrequiredthe page that must actually render, e.g. "https://github.com/signup". With entry_url set this is only used to report where it landed.expect_selectorrequiredREQUIRED. A CSS selector present on the REAL page and absent from any challenge/error page — e.g. "#password" for a signup form. This is the positive proof; without it a blank page would count as clean.entry_urloptionalload this FIRST and click through, instead of hitting `url` directly — e.g. "https://github.com/" so the site sees a front-door arrival rather than a cold hit on the protected path.entry_clickoptionalvisible TEXT of the control to click on entry_url, e.g. "Sign up for GitHub". Required if entry_url is set.entry_click_nthoptionalwhen entry_click matches several visible controls, which one (0-based). Measured: github.com renders "Sign up for GitHub" TWICE, and without this the click refuses as ambiguous — correctly, but on every single attempt.entry_click_withinoptionalCSS selector of a container to resolve entry_click INSIDE, e.g. the hero form. Cleaner than nth when the page has a stable wrapper, because it survives a re-order that nth does not.max_attemptsoptionalhow many exits to draw before giving up (default 8). At the measured ~1-in-6 rate, 8 gives a good chance without burning the pool.proxy_provideroptionale.g. "busyip", "nstproxy". Omit to let the account decide.proxy_countryoptionalISO-2, e.g. "UZ".proxy_typeoptionalbusyip only: "mobile" | "residential" | "any".osoptionalpersona OS (default "android" pairs with a mobile exit; use a desktop OS with a residential/datacenter one).browseroptionalpersona browser, default "chrome".headedoptionalshow the window (default true, so you can watch it draw).settle_msoptionalquiet period the DOM must reach before the check, default 800.clear_wait_msoptionalhow long to POLL for expect_selector before giving up, default 60000. ⛔ Do not shorten below ~45000: a DataDome rt:'i' interstitial self-clears in 25-40s, and a budget shorter than that records the challenge instead of the page — the defect this verb shipped with. A timeout here is reported as `pending`, never as a refusal.godbrowser_relogin_checkRe-log-in saved accounts to prove they STILL WORK, several at a time, each in its own isolated browser. For every account it opens a session, signs in (by restoring the banked session or by typing the stored credential — the password never passes through you), answers a device-verification OTP from your own inbox if the site asks for one, and checks a signed-in marker actually rendered. Returns a per-account verdict — signed_in / device_otp_failed / bad_credentials / challenged / transport — so a dead account is distinguishable from a dead proxy. Use it after a batch of registrations, and before relying on any banked account. 16 parameters · 4 required
accountsrequiredthe account emails to check, e.g. ["a@gmx.com","b@gmx.com"]. Each is looked up in your account store; the password is fetched server-side and never returned.domainrequiredthe site these accounts are on, e.g. "github.com".login_urlrequiredthe sign-in page, e.g. "https://github.com/login". This is NOT a signup path, so the front-door rule does not apply to it.signed_in_selectorrequiredREQUIRED. A CSS selector present ONLY when signed in, e.g. a nav avatar. The positive proof — a URL alone is not one, because a failed login can redirect anywhere.email_refoptionalthe email/username field on the login form (default "#login_field").password_refoptionalthe password field (default "#password").submit_textoptionalvisible text of the submit control (default "Sign in").otp_selectoroptionalthe device-verification code field, if the site challenges a new device (default "#otp").concurrencyoptionalhow many accounts to check at once, default 5. Each gets its own browser, so this is real parallelism — keep it modest or the proxy pool starves.proxy_provideroptionalegress provider for the check sessions, e.g. "busyip".proxy_countryoptionalISO-2 country for the check sessions.proxy_typeoptionalbusyip only: "mobile" | "residential" | "any". Pair it with the persona the accounts were made under.osoptionalpersona OS for the check sessions (default "android").browseroptionalpersona browser (default "chrome").headedoptionalshow the windows (default false here — a batch of 5 visible browsers is not useful).otp_wait_msoptionalhow long to wait for a device-verification mail, default 25000 (also the per-call ceiling).godbrowser_replay_requestRe-issue ONE request the page itself makes — from INSIDE the page — and hand back the response. Use it after godbrowser_capture_network shows you the endpoint behind a feed, a search, or an infinite scroll: instead of scrolling forty times, call that endpoint directly and vary its parameters (offset/page/cursor). Running in the page is the point — the request carries the site's own cookies, Origin and Referer, reuses the live connection, and picks up any header the page's scripts add, which a request made outside the browser does not. Returns {status, headers, body} with the body size-capped. ⛔ WRITES ARE REFUSED BY DEFAULT: a replayed GET is a read, but a replayed POST/PUT/PATCH/DELETE PERFORMS THE ACTION AGAIN — a second form submit, a second order — so anything outside GET/HEAD needs allow_write:true. When it fails you get `failure_layer` naming WHICH layer refused (cors_policy · browser_blocked · proxy_transport · network_transport · canceled · unclassified), because a bare fetch rejection and `net::ERR_FAILED` cannot tell a CORS verdict apart from a dead proxy tunnel.9 parameters · 2 required
session_idrequiredthe session_id from godbrowser_launchurlrequiredthe absolute http(s) URL to re-issue — normally one you just saw in godbrowser_capture_network, with its query parameters edited (a different offset/page/cursor)methodoptionalHTTP method (default GET). Anything other than GET/HEAD is refused unless allow_write is set.headersoptionalextra request headers to add, e.g. an x-api-key or accept the page sends. The page's own cookies/Origin/Referer are already applied — do not hand-copy them.bodyoptionalrequest body, for a write method only (ignored on GET/HEAD)credentialsoptional"include" (default — send the site's cookies), "same-origin", or "omit"max_bytesoptionalcap on the returned body (default 200000, max 2000000); the answer says whether it was truncatedtimeout_msoptionalabort the request after this long (default 20000)allow_writeoptionalpermit a non-GET/HEAD method. ⛔ This re-performs the action — only set it when repeating the write is what you actually want.godbrowser_site_mapIndex an AUTHENTICATED website into a structured map of its pages, sections, controls and editable fields — what a support assistant needs to answer "where do I change X?". Takes a session that is ALREADY SIGNED IN (it never logs in itself) and walks it breadth-first, following ONLY same-origin <a href> links that pass a structural safety allowlist. ⛔ STRICTLY READ-ONLY: no form is submitted, no setting saved, no toggle flipped — not even revertibly. Every button, submit and icon-only control is RECORDED with effect:"unverified" and never clicked. Before it starts it derives a language-agnostic signed-in marker from the page itself and proves that marker is ABSENT to an anonymous visitor; a page whose marker fails is dropped rather than published, and a confirmed logout HALTS the crawl instead of re-authenticating. The output is depersonalised (no page prose is ever captured, identifiers are templated, digits/dates/amounts are redacted by shape) and carries a mandatory "Not reached" section. action:"crawl" writes the JSON and stores it against your account; action:"list" shows every site you have a current map for with its age and counts; action:"get" reads one back (pass out_path to land the JSON on disk — a full map is several hundred KB and the answer stays a summary); action:"render" turns that JSON into Markdown as a SEPARATE stage, so a format change never re-crawls and a get→render is two calls with no reshaping; action:"diff" merges two or more crawls to decide which sections are universal and which are conditional. A stored map older than 90 days is REFUSED by the server rather than served; you are told the age and told allow_stale:true exists, and asking for that risk is yours. Run dry_run:true first on any new site. ⚠️ The credential this reaches storage with is NOT uniform across the stack — measured: a gbk_ account key is accepted by the storage function and refused by the hosted cortex master — so the answer reports which endpoint replied rather than implying one key works everywhere.20 parameters
actionoptional"crawl" (default — drives the browser and writes the JSON), "get" (read back a map this account has already stored for a site), "list" (every site this account has a current map for, with ages), "render" (JSON -> Markdown, no browser), or "diff" (merge >=2 crawl JSONs and upgrade visibility)siteoptionalfor "get": which site's stored map to read, e.g. "cloud.webscraper.io". A scheme, a path, a port and a leading "www." are all stripped server-side, so a full URL works too.allow_staleoptionalfor "get": serve a map older than the 90-day refusal band anyway. DEFAULT FALSE and never chosen for you — the server REFUSES an expired map with map_expired and returns no content, because a confidently wrong navigation answer is worse than "I do not have that information". You are told the age and told this flag exists; asking for the risk is yours, in the request, where it is auditable.session_idoptionalREQUIRED for "crawl": a session that is ALREADY SIGNED IN to the site. This verb does not log in, register, or restore an account — that is the caller's job (see the gb-price-intel skill for the ladder), and it is why this tool stays available to non-admin callers.out_pathoptionalwhere to write the crawl JSON on the machine running this server. Optional: the JSON is also returned to the persistence seam. "~" is expanded; missing parents are created.start_urloptionalwhere to begin. Default: wherever the session currently is. Its host becomes authenticated_host and the crawl NEVER leaves it.path_prefixoptionalrestrict the crawl to same-host links whose PATH starts with this, e.g. "/settings". Use it on a MIXED public/private site, where the app lives under one prefix and the marketing site shares the host. ⛔ MEASURED on huggingface.co: without it the crawl walked out of /settings and either dropped 41 of 46 nodes as auth-unverified, or HALTED on /pricing as a "confirmed logout" — a public page inside an authenticated site is indistinguishable from a logged-out one, and the logout trap is right to stop. This keeps the crawl away from such pages rather than weakening the trap. Omit for a site where everything behind the login is private.account_identitiesoptional⛔ THE ACCOUNT HOLDER'S NAME, EMAIL AND ANY OTHER STRING THAT IDENTIFIES THEM. Every occurrence is replaced WHOLESALE with {account_name} before anything is written. This is the one depersonalisation class that is exact and guaranteed — every other layer is a shape heuristic, and on the first live crawl a shape heuristic ate the holder's first name and left the surname standing in 28 published labels. Omit it and the crawl still runs, but the map is stamped `identities_declared:false` and the rendered document says so in its body.account_labeloptionalwhat kind of account this is, e.g. "free tier, owner role". It becomes the map's scope banner. ⚠️ Nothing validates it: a crawl labelled "free tier" from a grandfathered account with Pro features produces a map that is wrong in the one direction nobody checks.max_depthoptionalBFS depth cap (default 4, ceiling 6)max_pagesoptionalhard page cap (default 200, ceiling 500)throttle_msoptionalpause between captures (default 2500). Polite crawling: pair it with a launch that has block_trackers on, which is the default and drops ~61% of requests.expandoptional"none" (default — anchors only), "disclosure" (also open a collapsed aria-expanded="false" disclosure in nav/aside/header: it changes no server state), or "tabs" (also switch a role="tab", relaxed BY ROLE exactly as price_matrix relaxes its commit list for tabs — a tab switches a view and cannot place an order). Nothing beyond these two is permitted.auth_markeroptionalskip the tier-1 AI bootstrap and use this exact page text as the signed-in marker (for a re-crawl of a site you have already mapped). The mandatory anonymous negative control still runs against it.dry_runoptionalREQUIRED FIRST RUN ON A NEW SITE. Reads the landing page, classifies EVERY control against the safety allowlist, reports what would be followed and what refused — and clicks nothing, follows nothing. This is what proves the allowlist resolves anything at all before a live crawl runs; on a JS-routed SPA it will come back near-empty, which is the correct and loud failure.headedoptional⚠️ THIS AFFECTS ONLY THE ANONYMOUS CONTROL SESSION, not the crawl. The crawl runs on the session_id you hand in and inherits whatever THAT was launched with — there is no drive verb that reads a live session's headedness back, so this verb cannot mirror it and will not pretend to. true = show the window for the few seconds the control spends proving the signed-in marker is ABSENT to a stranger, which is the most informative moment of the run and the one nobody can currently see. Default FALSE: a tool never opens a window on someone's desktop unless asked.screenshotsoptional"none" (default) or "debug". Screenshots are the one artifact the depersonalisation stage cannot touch and a leak inside one is invisible to review, so "debug" writes them to a local directory explicitly OUTSIDE the publishable map and they are never persisted.in_pathoptionalfor "render": the crawl JSON to renderin_pathsoptionalfor "diff": two or more crawl JSON pathsout_json_pathoptionalfor "render": ALSO write the SANITISED crawl JSON here. Use it when a render reports sanitised_labels > 0 — that means the STORED json is contaminated and the row must be replaced from this file, because the artifact a support assistant reads is the JSON, not the Markdown.godbrowser_solve_recaptchaSolve a reCAPTCHA v2 OR an hCaptcha on the CURRENT page and deliver the token to the form. Use it when a signup/login button stays disabled with every field filled — that is usually a token gate, and the widget is often in an iframe that godbrowser_read_page cannot see. It searches the top document AND every SAME-ORIGIN child frame (T-1758: ebay.com puts its hCaptcha inside a same-origin `#captchaFrame`, and a top-document-only probe answered "no captcha on this page" about a challenge that was on screen), finds the sitekey (data-sitekey / data-hcaptcha-sitekey, or the k=/sitekey= param of the vendor's own iframe when the site exposes it nowhere), routes to the right provider task for the vendor it found, then injects the token into BOTH g-recaptcha-response and h-captcha-response AND fires the site's callback. The answer names the vendor in `kind` and the frame in `frame_path`. ⚠️ A `sitekey_not_found` reports THE EXTENT OF THE SEARCH, not a verdict about the page: it counts the frames searched and the cross-origin frames it could not read — confirm with a screenshot before concluding there is no challenge. ⛔ READ `delivered`, NOT JUST `ok`: a token obtained and dropped on the floor is the exact failure this exists to prevent, so `delivered` says whether a response field, a data-callback or a grecaptcha client callback actually received it — false means treat the challenge as unsolved. ⚠️ The provider solves from ITS OWN address, so the token is minted at a different IP than the one submitting; most v2 deployments accept that, a strict one will not, and that rejection looks like a site error rather than a solver bug.3 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchprovideroptional"2captcha" (default) or "anticaptcha"timeout_msoptionalgive up after this long (default 180000). A v2 solve typically takes 20-60s.godbrowser_solve_visualSolve an IMAGE captcha challenge — the kind where you must click tiles or a point in a picture, which a token cannot clear. Works across hCaptcha and reCAPTCHA: call it with just the session and it FINDS the challenge on screen by itself, has a human worker solve the picture, clicks the answer with real input, submits, and RETRIES up to 3 times (asking the widget for a fresh image when a worker declines or an answer is rejected) — a multi-page challenge is followed to the end. Use it when godbrowser_solve_captcha has not cleared a challenge that is visibly still on screen. ⚠️ `token_present` means the CAPTCHA WIDGET accepted the solve, not that the site accepted your form — read the page afterwards.10 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchselectoroptionalOPTIONAL. CSS selector of the element holding the challenge (e.g. the captcha iframe). Omit it and the challenge is found automatically — pass it only for a captcha the auto-detect does not know, or to target one of several on a page.regionoptionalOPTIONAL explicit challenge area in VIEWPORT css pixels, when no single element wraps it (read the coordinates off godbrowser_screenshot)instructionoptionalwhat the challenge asks, copied from the page verbatim, e.g. "Click the object that is different from its column". Usually unnecessary — the instruction is inside the captured image and the worker reads it there.modeoptional"coordinates" (default) = the answer is point(s) to click in the picture; works for both tiled grids and single composite images. "grid" = the captured area is EXACTLY a tile grid and the answer is which tiles — only correct when your selector/region wraps the tiles alone, and pair it with rows/columns.rowsoptionalgrid mode: number of rows (default 3)columnsoptionalgrid mode: number of columns (default 3)attemptsoptionalhow many solve attempts before giving up, 1..3 (default 3). Each attempt is billable, which is why 3 is also the hard ceiling.applyoptionalfalse = solve and return the points WITHOUT clicking, to inspect the answer first (default true)timeout_soptionalhow long to wait for the worker on one attempt, 10..300s (default 180)godbrowser_wait_for_dom_stableWait until the page stops changing — the fix for reading a page mid-render and getting a skeleton, a spinner, or a bare chat widget. It watches for DOM mutations and returns once none have happened for quiet_ms. Use it after a navigation, a click that triggers a client-side route change, or any "the page looked empty" read, BEFORE godbrowser_read_page. Returns { ok, settled, waited_ms, mutations_seen }; settled:false on timeout is a NORMAL return, not an error — take it as "this page never stops animating" (a carousel, a live ticker, a polling widget) and read it anyway rather than waiting again. Scope it with "within" to ignore a permanently busy region elsewhere on the page. It does not wait for network, and a settled DOM is not proof the data you want has arrived — assert for the specific element when you know it.5 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchquiet_msoptionalhow long the DOM must go unchanged before it counts as settled (default ~500). Raise it on a page that renders in bursts; lower it when you only need the first paint to land.timeout_msoptionalgive up waiting after this long and return settled:false (default ~10000). Not an error — a page with a carousel or a polling widget never settles, and waiting longer will not change that.withinoptionala CSS selector for a container to watch INSTEAD of the whole document — use it when one region (a chat widget, an ad slot, a live counter) keeps mutating and the part you care about has long since settledpoll_msoptionalhow often to check the quiet interval (default ~100)godbrowser_why_not_clickableExplain why a click on this element would fail — the question godbrowser_is_enabled cannot answer. is_enabled only checks disabled/aria-disabled, so it happily reports enabled:true about a button sitting under a cookie banner. This reports, for the element your locator resolves: its box, whether its centre is inside the viewport and the scrollY at the time; the computed pointer-events / visibility / opacity / display; whether an ancestor is a disabled <fieldset> or carries [inert]; whether the node is detached; and — the field this exists for — what document.elementFromPoint returns at the element's centre, plus the parent chain from that intercepting element back up to your target, so an overlay is distinguishable from the element's own decorative wrapper. Returns a one-line "verdict" naming the FIRST reason it would fail, and ok:true when it genuinely would click. Reach for it after a click reports success and nothing happened, after a click_missed_target, or BEFORE a click on a page you do not trust. It is a read: it clicks nothing, scrolls nothing, and runs no code of yours.15 parameters · 1 required
session_idrequiredthe session_id from godbrowser_launchpierceoptionalalso search inside OPEN shadow roots for this locator (a CLOSED shadow root is unreachable from script by design, and is reported as not-found rather than guessed at)withinoptionala CSS selector for a CONTAINER (usually a form) to search INSIDE — the locator then resolves only within it. Take it from godbrowser_read_page mode:"actions" forms[].selector. Use it whenever a page has more than one form or two similar-looking buttons; omit it for today's whole-page behaviour. A container that is not on the page is reported as within_not_found, never widened back to the whole page.selectoroptionala CSS selector for the elementtextoptionallocate by VISIBLE text (like getByText), e.g. "Subscribe"roleoptionalan ARIA role (like getByRole), pair with name; with text, scopes it to "button"/"link"/"any"nameoptionalthe accessible name to match when role is setlabeloptionala labelled control by its label text, e.g. "Email address"placeholderoptionalan input placeholdertestidoptionala data-testid / data-test-id valuexpathoptionalan XPath expressionmatchoptionaltext/name match mode: "icontains" (default), "contains", "equals", "iequals", "starts_with", "ends_with", "regex"nthoptionalwhen several elements match, pick this one (0-based); omit to require a single matchtimeout_msoptionalmax ms to auto-wait for a match to appear (default ~8000)poll_msoptionalpoll interval while waiting (default ~150)Access tiers. The reading surface — navigate, read_page, extract (including extractSchema), click, type, the asserts, tabs and frames — is available on every tier. Interactive live sessions are their own tier, and it is off by default. When it is not enabled for your account, godbrowser_launch, godbrowser_scrape_templates, godbrowser_session, godbrowser_set_persona answers external_tier_not_enabled — the batch surface (godbrowser_submit, godbrowser_run_recipe, godbrowser_status, godbrowser_results) stays available to you. A few DRIVE verbs stay first-party/operator-only in v1 — godbrowser_eval, godbrowser_protections, godbrowser_recipe_from_recording, godbrowser_save_recipe, godbrowser_wait_for_function answer first_party_only. godbrowser_login, godbrowser_register are operator-only in v1 and answer operator_only_v1. Each of these is a clean, named error rather than a silent failure, so a client can tell "not enabled for you" apart from "that call went wrong".
Saved logins, and what a restore actually restores. When the machine running GodBrowser is signed in to an account, godbrowser_launch now persists by default — the session banks its logins into a stable default profile, so the same session can be brought back from any other computer. Pass persist:false for a throwaway run that leaves nothing in your account. A godbrowser_session restore then reproduces the whole identity rather than just the cookies: the device it was banked on (OS/browser/persona), its locale, and the egress country it was created from — it tries the same exit, then any exit in that country, then falls back to the local machine and says so, in egress_continuity. That matters because a returning session whose device or country changed is a stronger signal than a fresh login would be. Do not pass os or browser to a restore unless you deliberately intend to override the banked device — the response reports persona_restored, persona_banked and egress_continuity so you can check what you actually got.
Choosing your egress. godbrowser_proxy reports what you have — providers, the exit country of each, sticky vs rotating and how often, and which lines are pool sources rather than direct exits — and parses any proxy string you paste, in any provider format. It never returns a password. Then launch through it with proxy (an explicit string) or proxy_provider / proxy_country (pick out of your configured pool). An exit whose provider string states no country is excluded rather than assumed to match, so you never silently egress from somewhere else, and the launch reports the exit it actually chose instead of a bare success.
Launching from a link. The same launch options travel in a gb://open?… URL, so a portal button or a runbook can open GodBrowser on the right saved session, device, locale and egress country. It is argv-only by design — a page cannot trigger one without the operating system's own open-in prompt — and it refuses a proxy credential or a non-http(s) landing page outright. godbrowser_link builds one for you (and does the percent-encoding in code, which is the part that goes wrong by hand). The keys, the encoding rule and the full refusal contract are on the parameter reference. Registration and parsing are verified; end-to-end delivery from a real click is still being confirmed per platform, so treat the scheme itself as arriving in an upcoming build.
Recipes — record, then replay. Drive a flow once, save it with godbrowser_save_recipe, then replay it deterministically at scale with godbrowser_run_recipe (no AI in the replay path). A recipe is data, not code — an ordered list of recorded steps (navigate/click/type/select/press/scroll/wait/extract/screenshot) with their recorded arguments; page-script evaluation steps are never recorded into a recipe, and a recipe containing one is rejected before replay begins. Recipes are scoped to your account: you list, replay and delete only your own. recipe-replay is also a named built-in code_ref alongside flagship-scrape-quotes, books-catalog, books-detail and custom-scrape — it is the deterministic replay walker that godbrowser_run_recipe submits for you.
From your AI client, a full run is three calls — submit, poll, pull:
godbrowser_submit({ code_ref: "flagship-scrape-quotes", os: "windows", seed: "run-1", count: 10 }) → { job_id, task_ids }
godbrowser_status({ job_id }) → status: succeeded, result_count: 300
godbrowser_results({ job_id }) → rows (10 coherent per-seed shards, one job)Run your OWN target at scale — not bounded to the demo code_refs: pass url + a fields CSS-selector map (and optional item_selector for a repeating list/table) to godbrowser_submit, and it fans the vetted custom-scrape builtin (deterministic CSS extract, no code upload) across the fleet:
godbrowser_submit({ url: "https://example.com/products", item_selector: ".product",
fields: { title: ".name", price: ".price", "tags[]": ".tag" }, count: 3 })
→ runs the custom-scrape builtin on your own URL, fanned 3 waysPlaybook — record → analyze → optimize
When a browser-driven automation is slow or brittle, reduce it to a direct requests-only path:
- Run a session with a BusyMate capture device (
--bm-device-name=<label>+--bm-auth-file=<account busymate_auth>). - Perform the action — navigate / filter / submit.
- If the
busymate-netMCP is connected,summarize_device_traffic(<device>)theninspect_requests(host, path_contains, method=POST)the captured traffic. - Identify the data endpoint — the XHR / GraphQL / REST op returning the records.
- Reconstruct a direct requests-only call → instant data.
Worked example: investigating 999.md this way surfaced POST /graphql (op SearchAds); replaying it directly returned the full ~88,793-car dataset. The native capture_network verb (roadmap) will make this in-browser.
Why MCP
Full cluster control
Create, run, and pull workflows across every node you've enrolled — without leaving your AI client.
Auth is your GodBrowser account
One-click Authorize with GodBrowser in your browser — approve the consent screen once and a per-device token is minted; no key to paste, no client to configure, and every grant is revocable per device.
Built for scale
Queue a million pages and fire-and-forget — the cluster shards the run across your nodes and drives it autonomously.
Results stream incrementally
Watch rows arrive as the run progresses with godbrowser_results paging — not just a dump at the end.
Auth & connection
Add the URL, then authorize in your browser: your MCP client discovers the authorization server, registers itself, and opens the GodBrowser consent screen. Approve it once and a per-device token is minted under your account — no key to paste, no client config.
The same authorization works across every machine and client; each is a separately-revocable grant. Revoke any device from the dashboard's API Keys.
Open the dashboard →Read the docs →