Drex

Browser runs

A browser run gives an agent a task and a website: it browses in a cloud browser of its own, only on the origins you allow, and returns an answer. nace browser run starts one and waits for it. A run is billed once, when it ends: its Drex Max and LLM tokens and its browser seconds, never more than --max-cost. Reading and listing runs is free; a run cancelled while queued isn't charged, one cancelled while running is charged its browser seconds so far. See Browser runs for prices, the sites runs may not browse, limits and retention.

Run a task

nace browser run "Find the price of the blue ceramic mug" --start-url https://shop.example.com/
nace browser run "Find the cheapest 1 TB SSD" --start-url https://shop.example.com/ \
  --answer-schema '{"type": "object", "properties": {"name": {"type": "string"}, "price": {"type": "number"}}, "required": ["name", "price"]}' \
  --max-cost 0.1 --max-seconds 300
nace browser run "Read the opening hours" --start-url https://example.com/ --no-wait   # prints brun_...

nace browser run TASK takes the task in plain language, 1 to 4000 characters. It starts the run, prints browser run <id> queued on stderr, and waits until the run ends:

  • Stdout gets the answer: the structured answer as JSON when you gave --answer-schema, else the agent's answer_text.
  • Stderr gets browser run <id> <status>, with how it ended in parentheses when that says more (partial (blocked_login)), then the reason, the final url: and the cost: in US dollars.
  • With --json, stdout gets the whole run instead: id, status, answer, answer_text, outcome, final_url, steps, usage, limits and the rest.

It exits 0 when the run succeeded. A run that ended partial, failed, cancelled or timed_out is printed the same way, then error: browser run <id> ended <status> [<outcome>] goes to stderr and it exits 1. A wait that runs out exits 1 with the run id on stdout (the run with --json); the run keeps going, so read it later with nace browser get.

FlagWhat it does
--start-url URLRequired. The page to open first: an http:// or https:// URL on a public host, on the default port.
--allow ORIGINAn origin the browser may load, such as https://shop.example.com (no path). Repeatable, up to 20. It must include the start URL's origin. Without it, the run may load only the start URL's origin.
--answer-schema SCHEMAA JSON Schema for a structured answer, as a JSON object: a file path, @FILE, inline JSON, or -. At most 16 KB, without pattern or patternProperties. An answer that doesn't match fails the run as answer_invalid, charged.
--max-cost USDThe most the run may be charged, in US dollars: at least 0.01 and at most 1 (default 0.04). Anything else exits 2.
--max-seconds NHow long the run may browse, 1 to 1800 seconds (default 600).
--max-llm-calls NHow many planning and reading calls the agent may make, 1 to 100 (default 20).
--metadata KEY=VALUEA string of your own, returned with the run. Repeatable, up to 20.
--idempotency-key KEYThe same key returns the same run instead of starting another; the same key with a different task or flags is refused with 409 idempotency_conflict. Without it, nace sends a new key on each run, so retries inside one run never start a second one.
--no-waitPrint the run id (the queued run with --json) and return at once.
--wait-timeout SECONDSHow long to wait for the run (default 3000), which outlasts any run: Drex times out a run queued for 15 minutes or browsing past --max-seconds.

A --max-seconds or --max-llm-calls outside its range, a --start-url that isn't http:// or https://, a --metadata without =, an --answer-schema that isn't a JSON object, and a negative --wait-timeout exit 2 before anything is sent. Drex refuses a run with 422: origin_blocked for a site runs may not browse, invalid_request for anything else it doesn't take. Past 20 queued or running runs, or past the account's daily spending limit for runs, it answers 429 (rate_limited or daily_spend_limit).

Read a run

nace browser get brun_...
nace browser artifacts brun_...
CommandWhat it prints
browser get RUN_IDThe run as nace browser run prints it, with steps in --json. It exits 0 whatever the run's status, so check it: a run still queued or running prints only its status line.
browser artifacts RUN_IDOne line per artifact the run reported, <kind> step <n> <url>. Each link works until its expires_at. An empty list says no artifacts on stderr. With --json, {"items": [...]}.

A run's task, answer, steps and evidence are erased 48 hours after it ends; the run, its status and its usage stay, with an empty task.

List runs

nace browser list
nace browser list --status running --all

nace browser list prints one line per run, newest first, without its steps: brun_... <status> <cost> <created_at> <task>, the task cut to 60 characters and the cost - until the run ends.

FlagWhat it does
--status {queued,running,succeeded,partial,failed,cancelled,timed_out}Only runs in this status.
--limit NRuns per page, 1 to 50 (default 20). A larger number exits 2.
--cursor CURSORStart at this page: the next_cursor of the page before.
--allEvery run, across every page. Not with --cursor.
--jsonPrint {"items": [...], "next_cursor": ...}.

Without --json, when more pages follow, stderr says more runs: --cursor <next> (or --all). An empty list says no runs on stderr.

Cancel a run

nace browser cancel brun_...

nace browser cancel <run_id> stops a queued or running run and its browser. Stderr says browser run <run_id> cancelled; stdout stays empty, or gets {"id", "object", "status"} with --json. Cancelling a cancelled run succeeds again; any other run that already ended fails with 409 run_finished. A run cancelled while queued isn't charged; one cancelled while running is charged its browser time so far.

On this page