> ## Documentation Index
> Fetch the complete documentation index at: https://docs.beta.b3os.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Search the web

Searches the web for `query` and returns up to `limit` results in the provider's order, each with its URL, title and description. The node sends the query to its search provider (the Brave Search API) with the node's key and nothing that identifies your organization; the result sites are not contacted unless you ask for their pages. With `scrape`, every result is also scraped with those options, through the same egress guard and politeness as a scrape, and its document is in the result's `scrape`; a result whose scrape fails has `error` instead, and the search still answers 200 with a `scrape_failed` warning. One answer holds at most 64 MiB of pages; a result past that has `error` `search_answer_too_large` and is not billed. A search's results get no custom `headers`, `profile`, `actions` or `json` format: scrape the URLs you trust with those.
Bills one `vision.page` per search that returns at least one result, plus one `vision.page` per scraped result (as a scrape bills). A search with no results bills nothing. Each search counts against `vision.search.monthly` (searches per UTC calendar month) and `vision.search.rpm`; it answers 429 `quota_exceeded` or `rate_limited` when they are used up. A node without a search key answers 503 `search_unavailable`. 

` POST /v1/vision/search `

Search the web

Searches the web for `query` and returns up to `limit` results in the provider's order, each with its URL,
title and description. The node sends the query to its search provider (the Brave Search API) with the
node's key and nothing that identifies your organization; the result sites are not contacted unless you ask
for their pages. With `scrape`, every result is also scraped with those options, through the same egress
guard and politeness as a scrape, and its document is in the result's `scrape`; a result whose scrape fails
has `error` instead, and the search still answers 200 with a `scrape_failed` warning. One answer holds at
most 64 MiB of pages; a result past that has `error` `search_answer_too_large` and is not billed. A search's
results get no custom `headers`, `profile`, `actions` or `json` format: scrape the URLs you trust with those.

Bills one `vision.page` per search that returns at least one result, plus one `vision.page` per scraped
result (as a scrape bills). A search with no results bills nothing. Each search counts against
`vision.search.monthly` (searches per UTC calendar month) and `vision.search.rpm`; it answers 429
`quota_exceeded` or `rate_limited` when they are used up. A node without a search key answers 503
`search_unavailable`.


## Servers

- ` https://beta-api.b3os.org ` — API (API keys and CLI tokens)

- ` https://beta.b3os.org ` — Dashboard (session cookie and CSRF header; same paths)

## Authentication

The operation accepts these alternatives. Schemes within one alternative are required together.

### Alternative 1

- ` apiKey `: ` http `

  - HTTP scheme: ` bearer ` (b3os_sk_ API key or b3os_pat_ token)

  - `Authorization: Bearer <credential>`. Two credential kinds are accepted:

- **API keys** `b3os_sk_<32 base32>_<crc32>`, created in the dashboard or with `POST /v1/keys`. A key belongs to
  one project, has scopes, an optional spend cap and expiry, and is shown only once.
- **CLI tokens** `b3os_pat_<32 base32>_<crc32>`, issued by the device login (`b3os login`). They act for one
  user in the organization and project chosen at approval.

Keys are stored as SHA-256 hashes. The edge exchanges them for a 60-second node token before forwarding
a request to a node, so nodes never see your key.


## Request body (required)

Content type: ` application/json `

- ` value `: type ` object `

  - Required fields: ` query `

  - ` query `: type ` string ` — What to search for, at most 50 words. Operators the provider supports pass through: `site:`, quotes, `-word`.

    - minLength: ` 1 `

    - maxLength: ` 400 `

  - ` limit `: type ` integer ` — Most results to return.

    - default: ` 5 `

    - minimum: ` 1 `

    - maximum: ` 20 `

  - ` country `: type ` string ` — Two-letter country code to rank results for, like `us` or `de`. Default the provider's. A code the provider does not cover answers `400 invalid_request` on this field.

    - pattern: ` "^[A-Za-z]{2}$" `

  - ` lang `: type ` string ` — Language of the results, like `en`, `de` or `pt-br`.

    - pattern: ` "^[a-z]{2}(-[a-z]{2,4})?$" `

  - ` freshness `: type ` string ` — Only results the provider found within this past period.

    - enum: ` ["day","week","month","year"] `

  - ` safe_search `: type ` string ` — Filter adult content.

    - enum: ` ["off","moderate","strict"] `

    - default: ` "moderate" `

  - ` timeout_ms `: type ` integer ` — Time for the whole search, the results' scrapes included. A scrape it cuts short is that result's `scrape_timeout` error.

    - default: ` 30000 `

    - minimum: ` 1000 `

    - maximum: ` 60000 `

  - ` scrape `: type ` unknown ` — Scrape every result with these options. `headers`, `profile`, `actions` and the `json` format are refused (`400 invalid_request`): results are pages a third party's index chose.

    - ` allOf constraint 1 `: type ` object ` — Scrape options applied to every page.

      - ` formats `: type ` array `

        - default: ` ["markdown"] `

        - ` array item `: type ` string ` — `markdown` main content (or the whole page with `only_main_content: false`); `html` cleaned HTML; `raw_html` the HTML as received; `text` plain text; `links` absolute links; `metadata` title, description and Open Graph fields (always included, listed for compatibility); `screenshot` an image of the page (needs a browser); `json` structured data from `json.schema` (needs the node's model). 

          - enum: ` ["markdown","html","raw_html","text","links","metadata","screenshot","json"] `

      - ` only_main_content `: type ` boolean ` — Drop headers, navigation, footers and sidebars.

        - default: ` true `

      - ` include_tags `: type ` array ` — CSS selectors to keep; everything else is dropped.

        - ` array item `: type ` string `

          - maxLength: ` 200 `

      - ` exclude_tags `: type ` array ` — CSS selectors to drop.

        - ` array item `: type ` string `

          - maxLength: ` 200 `

      - ` engine `: type ` string ` — Which tier may serve the page. `auto` (default): cache, then HTTP fetch, then a browser when the fetch may not be enough. `fetch`: never start a browser. `browser`: always render in Chrome (needed for `actions`, `screenshot` and profiles; implied by them). With `auto`, a browser runs when the page needs JavaScript, when the fetch came back thin or mostly script, and when the fetch failed in a way a browser may not. 

        - enum: ` ["auto","fetch","browser"] `

      - ` browser `: type ` unknown ` — Which browser renders the page when the browser tier runs (`engine: browser`, or an `auto` scrape that renders); not allowed with `engine: fetch`. The scrape pool runs `headless-shell`. `chrome` renders in a browser of its own, which counts toward `vision.sessions.concurrent` while it runs, as a scrape with a `profile` does.

        - default: ` "headless-shell" `

        - ` allOf constraint 1 `: type ` string ` — Which browser renders the page: `chrome` (full Chrome in its new headless mode) or `headless-shell` (chrome-headless-shell, which starts faster and uses less memory but has no `window.chrome` and no plugins). Both run the same launch profile: a current Chrome user agent without `HeadlessChrome`, `navigator.webdriver` false, and the time zone and locale of the node's egress location unless the request sets them. Sessions and pages in a browser of their own have WebGL on SwiftShader; pages in the shared scrape pool, whose browsers serve several organizations at once, have no WebGL. 

          - enum: ` ["chrome","headless-shell"] `

      - ` wait_for_ms `: type ` integer ` — Extra wait after the page is ready, before capture.

        - default: ` 0 `

        - minimum: ` 0 `

        - maximum: ` 30000 `

      - ` timeout_ms `: type ` integer `

        - default: ` 30000 `

        - minimum: ` 1000 `

        - maximum: ` 60000 `

      - ` max_age_ms `: type ` integer ` — Accept a cached copy up to this old (default 2 days). `0` always fetches.

        - default: ` 172800000 `

        - minimum: ` 0 `

      - ` cache_only `: type ` boolean ` — Answer from the page cache only, with no outbound request at all (with `respect_robots`, only a robots.txt this node already holds is checked): a cached copy (within `max_age_ms` when it is given) or `404 scrape_no_cached_data`, which is not billed. Cannot be combined with `headers`, `profile`, `actions` or a screenshot, which never use the cache. The share of pages the cache serves is the `b3os_vision_cache_served_ratio` metric.

        - default: ` false `

      - ` store_in_cache `: type ` boolean ` — Store the result in the cache. Requests with headers, a profile or actions are never shared across organizations.

        - default: ` true `

      - ` respect_robots `: type ` boolean ` — Check the site's robots.txt (RFC 9309, product token `B3OSBot`) and Content Signals before fetching: a URL they disallow (or `ai-input=no`) answers `403 robots_disallowed`, which is not billed. Off by default: vision does not consult robots.txt unless asked. In a crawl's `scrape` options it means the same as the crawl's own `respect_robots`.

        - default: ` false `

      - ` headers `: type ` object ` — Extra request headers, sent only to the target URL's origin (scheme, host and port): in a browser to the page and its same-origin subresources and fetches, never to the other hosts the page loads from, and on both tiers never along a redirect to another origin. A header you set replaces the browser's header of the same name (one value is sent, yours). A request with custom headers bypasses the cache. In a browser, a `Cookie` header becomes cookies for the page's host (path `/`), so it reaches the origin as on an HTTP fetch.

      - ` profile `: type ` string ` — A profile ID or name to load cookies and storage from. Implies `engine: browser`. The page renders in a browser of its own (never one shared with other organizations), which counts toward `vision.sessions.concurrent` while it runs: a single scrape answers 429 when no slot is free, a batch or crawl page waits for one. Not served (503 `product_unavailable`) on a node whose Chrome runs without its own sandbox.

      - ` actions `: type ` array ` — Browser actions to run before capture. Implies `engine: browser`.

        - ` array item `: type ` unknown ` — One browser action; `kind` selects it. The kinds and their fields match render timeline actions (`navigate`, `click`, `hover`, `type`, `key`, `scroll`, `select`, `wait`) plus `evaluate`, `screenshot`, `markdown` and `snapshot`, which only `act` and scrape `actions` offer, as is `settle` on `navigate`, `click`, `type`, `key` and `select`. 

          - ` oneOf alternative 1 `: type ` object `

            - Title: Navigate

            - Required fields: ` kind `, ` url `

            - ` kind `: type ` string `

              - enum: ` ["navigate"] `

            - ` url `: type ` string `; format ` uri `

              - maxLength: ` 4096 `

            - ` wait_until `: type ` string `

              - enum: ` ["load","domcontentloaded","networkidle"] `

              - default: ` "load" `

            - ` timeout_ms `: type ` integer `

              - default: ` 10000 `

              - minimum: ` 100 `

              - maximum: ` 60000 `

            - ` settle `: type ` unknown ` — After the action's input, wait until the page settles, and report how long that took (`settled_ms`, from the browser's acknowledgement of the input) and how it ended (`settled_by`). The page is settled when the document is at least interactive (loaded, when the input led to a new document), no document load and no `fetch` or XHR to the page's own site (sent since the action began) is in flight, and no DOM mutation and no such request has started or ended for `quiet_ms`. Third-party requests, images, scripts and streams do not hold it. Reaching `timeout_ms` is not an error: the action succeeds with `settled_by: deadline`. `true` takes the defaults. A click that changes nothing settles in about `quiet_ms`. The observer runs in an isolated world, so the page's scripts never see it.

              - Title: Settle

              - example: ` true `

              - ` oneOf alternative 1 `: type ` boolean `

                - Title: Defaults

              - ` oneOf alternative 2 `: type ` object `

                - Title: Options

                - ` quiet_ms `: type ` integer `

                  - default: ` 50 `

                  - minimum: ` 10 `

                  - maximum: ` 2000 `

                - ` timeout_ms `: type ` integer ` — The longest the settle waits (within the batch's own time).

                  - default: ` 5000 `

                  - minimum: ` 100 `

                  - maximum: ` 60000 `

          - ` oneOf alternative 2 `: type ` object ` — Click the target with trusted mouse events at its centre. Before pressing, vision checks that the target (or an element inside it, or one of its labels) is what the page draws at that point. A band fixed or sticky to the window that covers it gets one scroll to clear the target; any cover still there after half a second fails the click with `target_covered`, naming the cover, and no event is sent. A visually hidden checkbox or radio is clicked through its label.

            - Title: Click

            - Required fields: ` kind `, ` target `

            - ` kind `: type ` string `

              - enum: ` ["click"] `

            - ` target `: type ` unknown ` — The element an action works on: a `Target` (found by selector, text or role when the step runs), or a `ref` from a `snapshot` step, which names the element that snapshot listed and nothing else.

              - ` oneOf alternative 1 `: type ` unknown `

                - Title: Target

                - ` allOf constraint 1 `: type ` object ` — How an action finds its element (the same rules as render timelines): candidates match `selector` (CSS), `text` (visible text, case-insensitive substring unless `exact`) or `role` plus accessible `name`, limited to `within`; the best-scored candidate wins, or the `nth` match when set. An element that stays outside the viewport after scrolling it into view fails with `target_not_found`. 

                  - example: ` {"role":"button","name":"Continue"} `

                  - ` selector `: type ` string `

                    - minLength: ` 1 `

                    - maxLength: ` 1024 `

                  - ` text `: type ` string `

                    - minLength: ` 1 `

                    - maxLength: ` 500 `

                  - ` exact `: type ` boolean `

                    - default: ` false `

                  - ` role `: type ` string `

                    - pattern: ` "^[a-z]{2,32}$" `

                  - ` name `: type ` string `

                    - maxLength: ` 500 `

                  - ` within `: type ` string ` — CSS selector of the scope.

                    - maxLength: ` 1024 `

                  - ` nth `: type ` integer `

                    - minimum: ` 0 `

                    - maximum: ` 1000 `

                  - ` anyOf alternative 1 `: type ` unknown `

                    - Required fields: ` selector `

                  - ` anyOf alternative 2 `: type ` unknown `

                    - Required fields: ` text `

                  - ` anyOf alternative 3 `: type ` unknown `

                    - Required fields: ` role `

              - ` oneOf alternative 2 `: type ` object ` — A ref from a `snapshot` step's outline (`<snapshot id>:e<n>`). It is bound to that element of that document: once the element is removed, or the page has navigated, or the ref comes from another page, the step fails with `stale_ref`, and vision never looks for a look-alike by text or role. A ref is used as it is, alone.

                - Title: Snapshot ref

                - Required fields: ` ref `

                - ` ref `: type ` string `

                  - example: ` "3f9a2c10:e12" `

                  - pattern: ` "^[0-9a-f]{8}:e[1-9][0-9]{0,5}$" `

            - ` button `: type ` string `

              - enum: ` ["left","right","middle"] `

              - default: ` "left" `

            - ` count `: type ` integer `

              - default: ` 1 `

              - minimum: ` 1 `

              - maximum: ` 3 `

            - ` modifiers `: type ` array ` — Modifier keys held during the action.

              - ` array item `: type ` string `

                - enum: ` ["Alt","Control","Meta","Shift"] `

            - ` timeout_ms `: type ` integer ` — How long to wait for the target to appear.

              - default: ` 10000 `

              - minimum: ` 100 `

              - maximum: ` 60000 `

            - ` settle `: type ` unknown ` — After the action's input, wait until the page settles, and report how long that took (`settled_ms`, from the browser's acknowledgement of the input) and how it ended (`settled_by`). The page is settled when the document is at least interactive (loaded, when the input led to a new document), no document load and no `fetch` or XHR to the page's own site (sent since the action began) is in flight, and no DOM mutation and no such request has started or ended for `quiet_ms`. Third-party requests, images, scripts and streams do not hold it. Reaching `timeout_ms` is not an error: the action succeeds with `settled_by: deadline`. `true` takes the defaults. A click that changes nothing settles in about `quiet_ms`. The observer runs in an isolated world, so the page's scripts never see it.

              - Title: Settle

              - example: ` true `

              - ` oneOf alternative 1 `: type ` boolean `

                - Title: Defaults

              - ` oneOf alternative 2 `: type ` object `

                - Title: Options

                - ` quiet_ms `: type ` integer `

                  - default: ` 50 `

                  - minimum: ` 10 `

                  - maximum: ` 2000 `

                - ` timeout_ms `: type ` integer ` — The longest the settle waits (within the batch's own time).

                  - default: ` 5000 `

                  - minimum: ` 100 `

                  - maximum: ` 60000 `

          - ` oneOf alternative 3 `: type ` object `

            - Title: Hover

            - Required fields: ` kind `, ` target `

            - ` kind `: type ` string `

              - enum: ` ["hover"] `

            - ` target `: type ` unknown ` — The element an action works on: a `Target` (found by selector, text or role when the step runs), or a `ref` from a `snapshot` step, which names the element that snapshot listed and nothing else.

              - ` oneOf alternative 1 `: type ` unknown `

                - Title: Target

                - ` allOf constraint 1 `: type ` object ` — How an action finds its element (the same rules as render timelines): candidates match `selector` (CSS), `text` (visible text, case-insensitive substring unless `exact`) or `role` plus accessible `name`, limited to `within`; the best-scored candidate wins, or the `nth` match when set. An element that stays outside the viewport after scrolling it into view fails with `target_not_found`. 

                  - example: ` {"role":"button","name":"Continue"} `

                  - ` selector `: type ` string `

                    - minLength: ` 1 `

                    - maxLength: ` 1024 `

                  - ` text `: type ` string `

                    - minLength: ` 1 `

                    - maxLength: ` 500 `

                  - ` exact `: type ` boolean `

                    - default: ` false `

                  - ` role `: type ` string `

                    - pattern: ` "^[a-z]{2,32}$" `

                  - ` name `: type ` string `

                    - maxLength: ` 500 `

                  - ` within `: type ` string ` — CSS selector of the scope.

                    - maxLength: ` 1024 `

                  - ` nth `: type ` integer `

                    - minimum: ` 0 `

                    - maximum: ` 1000 `

                  - ` anyOf alternative 1 `: type ` unknown `

                    - Required fields: ` selector `

                  - ` anyOf alternative 2 `: type ` unknown `

                    - Required fields: ` text `

                  - ` anyOf alternative 3 `: type ` unknown `

                    - Required fields: ` role `

              - ` oneOf alternative 2 `: type ` object ` — A ref from a `snapshot` step's outline (`<snapshot id>:e<n>`). It is bound to that element of that document: once the element is removed, or the page has navigated, or the ref comes from another page, the step fails with `stale_ref`, and vision never looks for a look-alike by text or role. A ref is used as it is, alone.

                - Title: Snapshot ref

                - Required fields: ` ref `

                - ` ref `: type ` string `

                  - example: ` "3f9a2c10:e12" `

                  - pattern: ` "^[0-9a-f]{8}:e[1-9][0-9]{0,5}$" `

            - ` timeout_ms `: type ` integer `

              - default: ` 10000 `

              - minimum: ` 100 `

              - maximum: ` 60000 `

          - ` oneOf alternative 4 `: type ` object ` — Types `text` into `target` (focused first) or, without a target, into the element that has focus. The target must lead to one field that takes text: an input whose type is not checkbox, radio, button, submit, reset, image, file, color, range or hidden, a textarea, or an editable element; a label, which stands for its control (its `for` target or the field inside it, so `{"text": "Email"}` types into the Email field); or any other element that holds exactly one such field. Anything else fails the step (`act_step_failed`) and nothing is typed. The detail says what to do instead: a `select` step for a select element, a `click` for a checkbox, radio or button, an `evaluate` step for a color or range input; a file or hidden input takes no typed text; an element holding several fields needs a target that names one.

            - Title: Type

            - Required fields: ` kind `, ` text `

            - ` kind `: type ` string `

              - enum: ` ["type"] `

            - ` target `: type ` unknown ` — The element an action works on: a `Target` (found by selector, text or role when the step runs), or a `ref` from a `snapshot` step, which names the element that snapshot listed and nothing else.

              - ` oneOf alternative 1 `: type ` unknown `

                - Title: Target

                - ` allOf constraint 1 `: type ` object ` — How an action finds its element (the same rules as render timelines): candidates match `selector` (CSS), `text` (visible text, case-insensitive substring unless `exact`) or `role` plus accessible `name`, limited to `within`; the best-scored candidate wins, or the `nth` match when set. An element that stays outside the viewport after scrolling it into view fails with `target_not_found`. 

                  - example: ` {"role":"button","name":"Continue"} `

                  - ` selector `: type ` string `

                    - minLength: ` 1 `

                    - maxLength: ` 1024 `

                  - ` text `: type ` string `

                    - minLength: ` 1 `

                    - maxLength: ` 500 `

                  - ` exact `: type ` boolean `

                    - default: ` false `

                  - ` role `: type ` string `

                    - pattern: ` "^[a-z]{2,32}$" `

                  - ` name `: type ` string `

                    - maxLength: ` 500 `

                  - ` within `: type ` string ` — CSS selector of the scope.

                    - maxLength: ` 1024 `

                  - ` nth `: type ` integer `

                    - minimum: ` 0 `

                    - maximum: ` 1000 `

                  - ` anyOf alternative 1 `: type ` unknown `

                    - Required fields: ` selector `

                  - ` anyOf alternative 2 `: type ` unknown `

                    - Required fields: ` text `

                  - ` anyOf alternative 3 `: type ` unknown `

                    - Required fields: ` role `

              - ` oneOf alternative 2 `: type ` object ` — A ref from a `snapshot` step's outline (`<snapshot id>:e<n>`). It is bound to that element of that document: once the element is removed, or the page has navigated, or the ref comes from another page, the step fails with `stale_ref`, and vision never looks for a look-alike by text or role. A ref is used as it is, alone.

                - Title: Snapshot ref

                - Required fields: ` ref `

                - ` ref `: type ` string `

                  - example: ` "3f9a2c10:e12" `

                  - pattern: ` "^[0-9a-f]{8}:e[1-9][0-9]{0,5}$" `

            - ` text `: type ` string `

              - maxLength: ` 10000 `

            - ` clear `: type ` boolean ` — Clear the field before typing.

              - default: ` false `

            - ` interval_ms `: type ` integer ` — Delay between characters.

              - default: ` 0 `

              - minimum: ` 0 `

              - maximum: ` 1000 `

            - ` timeout_ms `: type ` integer `

              - default: ` 10000 `

              - minimum: ` 100 `

              - maximum: ` 60000 `

            - ` settle `: type ` unknown ` — After the action's input, wait until the page settles, and report how long that took (`settled_ms`, from the browser's acknowledgement of the input) and how it ended (`settled_by`). The page is settled when the document is at least interactive (loaded, when the input led to a new document), no document load and no `fetch` or XHR to the page's own site (sent since the action began) is in flight, and no DOM mutation and no such request has started or ended for `quiet_ms`. Third-party requests, images, scripts and streams do not hold it. Reaching `timeout_ms` is not an error: the action succeeds with `settled_by: deadline`. `true` takes the defaults. A click that changes nothing settles in about `quiet_ms`. The observer runs in an isolated world, so the page's scripts never see it.

              - Title: Settle

              - example: ` true `

              - ` oneOf alternative 1 `: type ` boolean `

                - Title: Defaults

              - ` oneOf alternative 2 `: type ` object `

                - Title: Options

                - ` quiet_ms `: type ` integer `

                  - default: ` 50 `

                  - minimum: ` 10 `

                  - maximum: ` 2000 `

                - ` timeout_ms `: type ` integer ` — The longest the settle waits (within the batch's own time).

                  - default: ` 5000 `

                  - minimum: ` 100 `

                  - maximum: ` 60000 `

          - ` oneOf alternative 5 `: type ` object `

            - Title: Key

            - Required fields: ` kind `, ` key `

            - ` kind `: type ` string `

              - enum: ` ["key"] `

            - ` key `: type ` string ` — `KeyboardEvent.key`, such as `Enter`, `Tab` or `a`.

              - minLength: ` 1 `

              - maxLength: ` 32 `

            - ` modifiers `: type ` array ` — Modifier keys held during the action.

              - ` array item `: type ` string `

                - enum: ` ["Alt","Control","Meta","Shift"] `

            - ` settle `: type ` unknown ` — After the action's input, wait until the page settles, and report how long that took (`settled_ms`, from the browser's acknowledgement of the input) and how it ended (`settled_by`). The page is settled when the document is at least interactive (loaded, when the input led to a new document), no document load and no `fetch` or XHR to the page's own site (sent since the action began) is in flight, and no DOM mutation and no such request has started or ended for `quiet_ms`. Third-party requests, images, scripts and streams do not hold it. Reaching `timeout_ms` is not an error: the action succeeds with `settled_by: deadline`. `true` takes the defaults. A click that changes nothing settles in about `quiet_ms`. The observer runs in an isolated world, so the page's scripts never see it.

              - Title: Settle

              - example: ` true `

              - ` oneOf alternative 1 `: type ` boolean `

                - Title: Defaults

              - ` oneOf alternative 2 `: type ` object `

                - Title: Options

                - ` quiet_ms `: type ` integer `

                  - default: ` 50 `

                  - minimum: ` 10 `

                  - maximum: ` 2000 `

                - ` timeout_ms `: type ` integer ` — The longest the settle waits (within the batch's own time).

                  - default: ` 5000 `

                  - minimum: ` 100 `

                  - maximum: ` 60000 `

          - ` oneOf alternative 6 `: type ` object ` — Scroll to an offset (`to`), by a delta (`by`), or until `target` is in view.

            - Title: Scroll

            - Required fields: ` kind `

            - ` kind `: type ` string `

              - enum: ` ["scroll"] `

            - ` target `: type ` unknown ` — The element an action works on: a `Target` (found by selector, text or role when the step runs), or a `ref` from a `snapshot` step, which names the element that snapshot listed and nothing else.

              - ` oneOf alternative 1 `: type ` unknown `

                - Title: Target

                - ` allOf constraint 1 `: type ` object ` — How an action finds its element (the same rules as render timelines): candidates match `selector` (CSS), `text` (visible text, case-insensitive substring unless `exact`) or `role` plus accessible `name`, limited to `within`; the best-scored candidate wins, or the `nth` match when set. An element that stays outside the viewport after scrolling it into view fails with `target_not_found`. 

                  - example: ` {"role":"button","name":"Continue"} `

                  - ` selector `: type ` string `

                    - minLength: ` 1 `

                    - maxLength: ` 1024 `

                  - ` text `: type ` string `

                    - minLength: ` 1 `

                    - maxLength: ` 500 `

                  - ` exact `: type ` boolean `

                    - default: ` false `

                  - ` role `: type ` string `

                    - pattern: ` "^[a-z]{2,32}$" `

                  - ` name `: type ` string `

                    - maxLength: ` 500 `

                  - ` within `: type ` string ` — CSS selector of the scope.

                    - maxLength: ` 1024 `

                  - ` nth `: type ` integer `

                    - minimum: ` 0 `

                    - maximum: ` 1000 `

                  - ` anyOf alternative 1 `: type ` unknown `

                    - Required fields: ` selector `

                  - ` anyOf alternative 2 `: type ` unknown `

                    - Required fields: ` text `

                  - ` anyOf alternative 3 `: type ` unknown `

                    - Required fields: ` role `

              - ` oneOf alternative 2 `: type ` object ` — A ref from a `snapshot` step's outline (`<snapshot id>:e<n>`). It is bound to that element of that document: once the element is removed, or the page has navigated, or the ref comes from another page, the step fails with `stale_ref`, and vision never looks for a look-alike by text or role. A ref is used as it is, alone.

                - Title: Snapshot ref

                - Required fields: ` ref `

                - ` ref `: type ` string `

                  - example: ` "3f9a2c10:e12" `

                  - pattern: ` "^[0-9a-f]{8}:e[1-9][0-9]{0,5}$" `

            - ` to `: type ` object ` — A position in CSS pixels.

              - Required fields: ` x `, ` y `

              - ` x `: type ` number `

              - ` y `: type ` number `

            - ` by `: type ` object ` — A position in CSS pixels.

              - Required fields: ` x `, ` y `

              - ` x `: type ` number `

              - ` y `: type ` number `

          - ` oneOf alternative 7 `: type ` object `

            - Title: Select

            - Required fields: ` kind `, ` target `, ` value `

            - ` kind `: type ` string `

              - enum: ` ["select"] `

            - ` target `: type ` unknown ` — The element an action works on: a `Target` (found by selector, text or role when the step runs), or a `ref` from a `snapshot` step, which names the element that snapshot listed and nothing else.

              - ` oneOf alternative 1 `: type ` unknown `

                - Title: Target

                - ` allOf constraint 1 `: type ` object ` — How an action finds its element (the same rules as render timelines): candidates match `selector` (CSS), `text` (visible text, case-insensitive substring unless `exact`) or `role` plus accessible `name`, limited to `within`; the best-scored candidate wins, or the `nth` match when set. An element that stays outside the viewport after scrolling it into view fails with `target_not_found`. 

                  - example: ` {"role":"button","name":"Continue"} `

                  - ` selector `: type ` string `

                    - minLength: ` 1 `

                    - maxLength: ` 1024 `

                  - ` text `: type ` string `

                    - minLength: ` 1 `

                    - maxLength: ` 500 `

                  - ` exact `: type ` boolean `

                    - default: ` false `

                  - ` role `: type ` string `

                    - pattern: ` "^[a-z]{2,32}$" `

                  - ` name `: type ` string `

                    - maxLength: ` 500 `

                  - ` within `: type ` string ` — CSS selector of the scope.

                    - maxLength: ` 1024 `

                  - ` nth `: type ` integer `

                    - minimum: ` 0 `

                    - maximum: ` 1000 `

                  - ` anyOf alternative 1 `: type ` unknown `

                    - Required fields: ` selector `

                  - ` anyOf alternative 2 `: type ` unknown `

                    - Required fields: ` text `

                  - ` anyOf alternative 3 `: type ` unknown `

                    - Required fields: ` role `

              - ` oneOf alternative 2 `: type ` object ` — A ref from a `snapshot` step's outline (`<snapshot id>:e<n>`). It is bound to that element of that document: once the element is removed, or the page has navigated, or the ref comes from another page, the step fails with `stale_ref`, and vision never looks for a look-alike by text or role. A ref is used as it is, alone.

                - Title: Snapshot ref

                - Required fields: ` ref `

                - ` ref `: type ` string `

                  - example: ` "3f9a2c10:e12" `

                  - pattern: ` "^[0-9a-f]{8}:e[1-9][0-9]{0,5}$" `

            - ` value `: type ` string ` — The option value to select.

              - maxLength: ` 1000 `

            - ` settle `: type ` unknown ` — After the action's input, wait until the page settles, and report how long that took (`settled_ms`, from the browser's acknowledgement of the input) and how it ended (`settled_by`). The page is settled when the document is at least interactive (loaded, when the input led to a new document), no document load and no `fetch` or XHR to the page's own site (sent since the action began) is in flight, and no DOM mutation and no such request has started or ended for `quiet_ms`. Third-party requests, images, scripts and streams do not hold it. Reaching `timeout_ms` is not an error: the action succeeds with `settled_by: deadline`. `true` takes the defaults. A click that changes nothing settles in about `quiet_ms`. The observer runs in an isolated world, so the page's scripts never see it.

              - Title: Settle

              - example: ` true `

              - ` oneOf alternative 1 `: type ` boolean `

                - Title: Defaults

              - ` oneOf alternative 2 `: type ` object `

                - Title: Options

                - ` quiet_ms `: type ` integer `

                  - default: ` 50 `

                  - minimum: ` 10 `

                  - maximum: ` 2000 `

                - ` timeout_ms `: type ` integer ` — The longest the settle waits (within the batch's own time).

                  - default: ` 5000 `

                  - minimum: ` 100 `

                  - maximum: ` 60000 `

          - ` oneOf alternative 8 `: type ` object ` — Wait a fixed time (`ms`) or until a condition holds (`for`). `network_idle` holds once the document has loaded and no request has been in flight, sent or ended for 500 ms, counted from the start of the wait; requests count from the moment they are sent (long polls older than 30 seconds are ignored).

            - Title: Wait

            - Required fields: ` kind `

            - ` kind `: type ` string `

              - enum: ` ["wait"] `

            - ` ms `: type ` integer `

              - minimum: ` 1 `

              - maximum: ` 30000 `

            - ` for `: type ` object ` — Exactly one condition to wait for (the same as a timeline `wait` action's `for`).

              - ` selector `: type ` string ` — An element matching this CSS selector is visible.

                - maxLength: ` 1024 `

              - ` text `: type ` string ` — This text is visible.

                - maxLength: ` 500 `

              - ` url `: type ` string ` — The page URL contains this substring.

                - maxLength: ` 4096 `

              - ` network_idle `: type ` boolean ` — The network has been quiet.

                - enum: ` [true] `

            - ` timeout_ms `: type ` integer `

              - default: ` 10000 `

              - minimum: ` 100 `

              - maximum: ` 60000 `

          - ` oneOf alternative 9 `: type ` object `

            - Title: Evaluate

            - Required fields: ` kind `, ` expression `

            - ` kind `: type ` string `

              - enum: ` ["evaluate"] `

            - ` expression `: type ` string ` — JavaScript evaluated in the page; a returned promise is awaited and the JSON-serializable result is returned.

              - maxLength: ` 100000 `

          - ` oneOf alternative 10 `: type ` object `

            - Title: Screenshot

            - Required fields: ` kind `

            - ` kind `: type ` string `

              - enum: ` ["screenshot"] `

            - ` target `: type ` unknown ` — The element an action works on: a `Target` (found by selector, text or role when the step runs), or a `ref` from a `snapshot` step, which names the element that snapshot listed and nothing else.

              - ` oneOf alternative 1 `: type ` unknown `

                - Title: Target

                - ` allOf constraint 1 `: type ` object ` — How an action finds its element (the same rules as render timelines): candidates match `selector` (CSS), `text` (visible text, case-insensitive substring unless `exact`) or `role` plus accessible `name`, limited to `within`; the best-scored candidate wins, or the `nth` match when set. An element that stays outside the viewport after scrolling it into view fails with `target_not_found`. 

                  - example: ` {"role":"button","name":"Continue"} `

                  - ` selector `: type ` string `

                    - minLength: ` 1 `

                    - maxLength: ` 1024 `

                  - ` text `: type ` string `

                    - minLength: ` 1 `

                    - maxLength: ` 500 `

                  - ` exact `: type ` boolean `

                    - default: ` false `

                  - ` role `: type ` string `

                    - pattern: ` "^[a-z]{2,32}$" `

                  - ` name `: type ` string `

                    - maxLength: ` 500 `

                  - ` within `: type ` string ` — CSS selector of the scope.

                    - maxLength: ` 1024 `

                  - ` nth `: type ` integer `

                    - minimum: ` 0 `

                    - maximum: ` 1000 `

                  - ` anyOf alternative 1 `: type ` unknown `

                    - Required fields: ` selector `

                  - ` anyOf alternative 2 `: type ` unknown `

                    - Required fields: ` text `

                  - ` anyOf alternative 3 `: type ` unknown `

                    - Required fields: ` role `

              - ` oneOf alternative 2 `: type ` object ` — A ref from a `snapshot` step's outline (`<snapshot id>:e<n>`). It is bound to that element of that document: once the element is removed, or the page has navigated, or the ref comes from another page, the step fails with `stale_ref`, and vision never looks for a look-alike by text or role. A ref is used as it is, alone.

                - Title: Snapshot ref

                - Required fields: ` ref `

                - ` ref `: type ` string `

                  - example: ` "3f9a2c10:e12" `

                  - pattern: ` "^[0-9a-f]{8}:e[1-9][0-9]{0,5}$" `

            - ` full_page `: type ` boolean `

              - default: ` false `

            - ` format `: type ` string `

              - enum: ` ["jpeg","png","webp"] `

              - default: ` "jpeg" `

            - ` quality `: type ` integer `

              - default: ` 80 `

              - minimum: ` 1 `

              - maximum: ` 100 `

          - ` oneOf alternative 11 `: type ` object `

            - Title: Markdown

            - Required fields: ` kind `

            - ` kind `: type ` string `

              - enum: ` ["markdown"] `

            - ` only_main_content `: type ` boolean `

              - default: ` true `

          - ` oneOf alternative 12 `: type ` object ` — An outline of the page for choosing what to act on: one element per line, indented by container, in Playwright's aria-snapshot shape (`- button "Sign in" [ref=3f9a2c10:e4]`). Controls and headings carry a `ref`; a later step targets one with `target: {ref}`, in this batch or a later `act` on the same page. `skeleton` lists landmarks, headings and controls, cuts names at 80 characters and counts the controls of one role past the eighth in a container (`- link (42 more)`) instead of listing them; `full` also lists text blocks and images, and every control. The outline stops at `max_tokens` (tokens counted as characters / 4): the step is still `ok`, with `truncated: true` and `complete: false`. Frames are listed, not entered.

            - Title: Snapshot

            - Required fields: ` kind `

            - ` kind `: type ` string `

              - enum: ` ["snapshot"] `

            - ` mode `: type ` string `

              - enum: ` ["skeleton","full"] `

              - default: ` "skeleton" `

            - ` root `: type ` string ` — CSS selector of the element to outline (the body by default).

              - minLength: ` 1 `

              - maxLength: ` 1024 `

            - ` max_tokens `: type ` integer `

              - default: ` 4000 `

              - minimum: ` 100 `

              - maximum: ` 32000 `

      - ` locale `: type ` string ` — BCP 47 locale for `Accept-Language` and the browser. Defaults to the locale of the node's egress location (`en-US` on every node today).

        - default: ` "en-US" `

      - ` timezone `: type ` string ` — IANA time zone for the browser, such as `Europe/Berlin`. Defaults to the time zone of the node's egress location (`America/Los_Angeles` on every node today).

      - ` mobile `: type ` boolean ` — Emulate a phone (viewport, user agent, touch).

        - default: ` false `

      - ` viewport `: type ` object ` — Browser viewport in CSS pixels.

        - Required fields: ` width `, ` height `

        - ` width `: type ` integer `

          - minimum: ` 320 `

          - maximum: ` 3840 `

        - ` height `: type ` integer `

          - minimum: ` 240 `

          - maximum: ` 2160 `

      - ` block_ads `: type ` boolean ` — Block ads, trackers and cookie banners.

        - default: ` true `

      - ` block_resources `: type ` array ` — Resource types the browser does not download. Defaults to images, media and fonts unless a screenshot is requested.

        - ` array item `: type ` string `

          - enum: ` ["image","media","font","stylesheet"] `

      - ` screenshot `: type ` object ` — Options for the `screenshot` format.

        - ` full_page `: type ` boolean `

          - default: ` false `

        - ` format `: type ` string `

          - enum: ` ["jpeg","png","webp"] `

          - default: ` "jpeg" `

        - ` quality `: type ` integer ` — JPEG and WebP quality.

          - default: ` 80 `

          - minimum: ` 1 `

          - maximum: ` 100 `

      - ` json `: type ` object ` — Options for the `json` format. The node's model fills `schema` from the page.

        - ` schema `: type ` object ` — A JSON Schema the result must match.

        - ` prompt `: type ` string ` — Guidance for the model.

          - maxLength: ` 10000 `

      - ` walls `: type ` string ` — What a wall (`page_state` `blocked` or `captcha`) costs. `free`: no `vision.page`, and the result carries no page content, only `page_state`, `status_code`, `final_url` and `content_withheld: true`. `bill`: the wall bills like any page and its content is returned. A scrape with `actions` bills either way.

        - enum: ` ["free","bill"] `

        - default: ` "free" `

Example:

```json
{
  "query": "rust async runtime",
  "limit": 2,
  "scrape": {
    "formats": [
      "markdown"
    ]
  }
}
```

## Responses

### ` 200 ` — The results.

Content type: ` application/json `

- ` value `: type ` object `

  - Required fields: ` object `, ` query `, ` results `, ` timing `

  - ` object `: type ` string `

    - enum: ` ["search"] `

  - ` query `: type ` string `

  - ` results `: type ` array `

    - ` array item `: type ` object `

      - Required fields: ` position `, ` url `, ` title `

      - ` position `: type ` integer ` — Rank in the provider's order, from 1.

        - minimum: ` 1 `

      - ` url `: type ` string `; format ` uri `

      - ` title `: type ` string `

      - ` description `: type ` string `

      - ` scrape `: type ` object `

        - Required fields: ` object `, ` url `, ` final_url `, ` status_code `, ` tier `, ` cache `, ` warnings `, ` timing `

        - ` object `: type ` string `

          - enum: ` ["scrape"] `

        - ` url `: type ` string `; format ` uri ` — The requested URL.

        - ` final_url `: type ` string `; format ` uri ` — The URL of the page the answer was read from: the URL after redirects or, for a page the browser rendered, the page the browser read. When a script moved the browser to another host or path after the load, or changed the address to another path with `history.pushState` or `replaceState`, it is that address. A change of query or fragment alone after the load leaves it at the URL after redirects.

        - ` status_code `: type ` integer ` — The HTTP status the site returned. A 404 page is still a successful scrape. For a page the browser rendered, it is the status the browser got when it loaded the page, so after a script moved the browser to another page (see `final_url`) it can be the status of the page before the move.

        - ` content_type `: type ` string `

        - ` tier `: type ` string ` — What served the page.

          - enum: ` ["cache","fetch","browser"] `

        - ` cache `: type ` object `

          - Required fields: ` state `, ` age_s `

          - ` state `: type ` string ` — `hit` served from cache; `miss` fetched and stored; `bypass` fetched and not shared (custom headers, profile, actions).

            - enum: ` ["hit","miss","bypass"] `

          - ` age_s `: type ` integer ` — Age of the served copy in seconds.

            - minimum: ` 0 `

        - ` markdown `: type ` string `

        - ` html `: type ` string `

        - ` raw_html `: type ` string `

        - ` text `: type ` string `

        - ` links `: type ` array `

          - ` array item `: type ` string `

        - ` screenshot `: type ` object `

          - Required fields: ` format `, ` width `, ` height `, ` data_base64 `

          - ` format `: type ` string `

            - enum: ` ["jpeg","png","webp"] `

          - ` width `: type ` integer `

          - ` height `: type ` integer `

          - ` data_base64 `: type ` string `; format ` byte `

        - ` json `: type ` unknown ` — Data matching `json.schema`, when the `json` format was requested.

        - ` metadata `: type ` object ` — Metadata read from the page.

          - ` title `: type ` string `

          - ` description `: type ` string `

          - ` language `: type ` string `

          - ` canonical_url `: type ` string `; format ` uri `

          - ` favicon `: type ` string `; format ` uri `

          - ` og `: type ` object ` — Open Graph properties, keyed without the `og:` prefix.

          - ` published_time `: type ` string `

          - ` modified_time `: type ` string `

          - ` robots `: type ` string ` — The page's robots meta tag.

        - ` actions `: type ` array ` — Results of `actions`, in order.

          - ` array item `: type ` object `

            - Required fields: ` kind `, ` status `, ` duration_ms `, ` delivery `, ` retry `

            - ` kind `: type ` string `

              - enum: ` ["navigate","click","hover","type","key","scroll","select","wait","evaluate","screenshot","markdown","snapshot"] `

            - ` status `: type ` string `

              - enum: ` ["ok","failed","skipped"] `

            - ` duration_ms `: type ` number `

            - ` url `: type ` string ` — `navigate`: the URL after redirects.

            - ` status_code `: type ` integer ` — `navigate`: the HTTP status.

            - ` value `: type ` unknown ` — `evaluate`: the JSON result.

            - ` screenshot `: type ` object `

              - Required fields: ` format `, ` width `, ` height `, ` data_base64 `

              - ` format `: type ` string `

                - enum: ` ["jpeg","png","webp"] `

              - ` width `: type ` integer `

              - ` height `: type ` integer `

              - ` data_base64 `: type ` string `; format ` byte `

            - ` markdown `: type ` string ` — `markdown`: the page as Markdown.

            - ` snapshot `: type ` object `

              - Required fields: ` id `, ` mode `, ` text `, ` refs `, ` nodes `, ` tokens `, ` complete `, ` truncated `

              - ` id `: type ` string ` — The snapshot's id, the first part of its refs.

                - pattern: ` "^[0-9a-f]{8}$" `

              - ` mode `: type ` string `

                - enum: ` ["skeleton","full"] `

              - ` text `: type ` string ` — The outline, one element per line; controls and headings end in `[ref=<id>:e<n>]`.

              - ` refs `: type ` integer ` — How many refs the outline holds.

              - ` nodes `: type ` integer ` — How many elements the outline lists.

              - ` tokens `: type ` integer ` — The outline's size in tokens, counted as characters / 4.

              - ` complete `: type ` boolean ` — Every element of the mode's kinds is listed (none counted instead, nothing cut by the budget).

              - ` truncated `: type ` boolean ` — The budget (`max_tokens`) cut the outline.

            - ` error `: type ` object ` — An RFC 9457 problem. `code` is stable and listed in the errors catalog; `type` links to its entry. `detail` is human-readable and may change. Extension members appear only for the codes that document them; ignore members you do not recognize. 

              - Required fields: ` type `, ` title `, ` status `, ` code `, ` detail `

              - ` type `: type ` string `; format ` uri ` — `https://docs.beta.b3os.org/errors#<code>`.

                - example: ` "https://docs.beta.b3os.org/errors#invalid_request" `

              - ` title `: type ` string ` — Short summary of the problem type.

              - ` status `: type ` integer ` — The HTTP status code, repeated for convenience.

                - minimum: ` 400 `

                - maximum: ` 599 `

              - ` code `: type ` string ` — Stable machine-readable error code from the errors catalog.

                - pattern: ` "^[a-z][a-z0-9_]*$" `

              - ` detail `: type ` string ` — Explanation of this occurrence. Never contains secrets.

              - ` instance `: type ` string ` — The request ID (`req_…`) of the request that failed. Include it when you contact support.

                - example: ` "req_01m5t4yg394wegr3j4y01qb363" `

              - ` errors `: type ` array ` — Validation problems, one per field (`invalid_request` and the other codes that list `errors`).

                - ` array item `: type ` object ` — One validation problem.

                  - Required fields: ` pointer `, ` detail `

                  - ` pointer `: type ` string ` — Where the problem is: a JSON pointer into the request body (`/url`, `/steps/0/uses`), or `#query/<name>`, `#path/<name>` or `#header/<name>` for parameters. 

                    - example: ` "/url" `

                  - ` detail `: type ` string ` — What is wrong there.

                    - example: ` "must be an absolute http or https URL" `

              - ` reason `: type ` string ` — Finer-grained cause for codes that document one (`unauthorized`, `forbidden`, `egress_denied`, `upstream_unreachable`, …).

              - ` required_scope `: type ` string ` — The scope that was missing (`forbidden` with `reason: scope`).

              - ` retry_after_s `: type ` integer ` — Same value as the `Retry-After` header, for clients that only read the body.

                - minimum: ` 0 `

              - ` limit `: type ` object ` — The limit an error refers to. IDs and current values are listed by `GET /v1/limits`.

                - Required fields: ` id `, ` limit `, ` unit `

                - ` id `: type ` string ` — Limit ID, such as `vision.scrape.rpm` or `sandboxes.concurrent`.

                  - example: ` "vision.scrape.rpm" `

                - ` limit `: type ` number ` — The limit's value.

                - ` unit `: type ` string ` — What the limit counts, such as `requests`, `sandboxes`, `vcpu` or `MiB`.

                - ` window_s `: type ` integer ` — Window length in seconds for rate limits and quotas.

                - ` current `: type ` number ` — Current usage against the limit, when known.

              - ` current_status `: type ` string ` — The object's current status, for state conflicts such as `sandbox_not_running`.

              - ` upstream_status `: type ` integer ` — The HTTP status the upstream returned (`upstream_error`, `action_output_invalid`).

              - ` step `: type ` string ` — The failed step, as a step ID (routines), an index (`act`) or a path such as `beats/2/do/0` (render).

              - ` pack_error `: type ` object ` — The error a pack's error mapping chose (`upstream_error` from pack actions).

                - Required fields: ` code `, ` message `, ` retryable `

                - ` code `: type ` string `

                - ` message `: type ` string `

                - ` retryable `: type ` boolean `

            - ` dialogs `: type ` array ` — JavaScript dialogs the page opened while the action ran, in order. Left out when there were none.

              - ` array item `: type ` object `

                - Required fields: ` type `, ` message `, ` action `

                - ` type `: type ` string `

                  - enum: ` ["alert","confirm","prompt","beforeunload"] `

                - ` message `: type ` string ` — The dialog's text (cut at 1,000 characters).

                  - maxLength: ` 1000 `

                - ` action `: type ` string `

                  - enum: ` ["accepted","dismissed"] `

            - ` delivery `: type ` string ` — Whether the action's input reached the page, on every result, failed and skipped ones included. `delivered_verified`: sent, and the page's answer was seen (a `navigate` whose document loaded). `delivered_unverified`: sent and acknowledged by the browser (a click, typed text, a key, a select, an `evaluate`); what the page did with it is not checked. `delivery_uncertain`: part of it may have reached the page (a `navigate` that timed out, `type` with `interval_ms` cut off). `not_delivered`: nothing was sent: the target was missing, covered (`target_covered`) or stale (`stale_ref`), a field or option check refused, the step was skipped, or the action sends no input (`wait`, `screenshot`, `markdown`, `snapshot`). `unknown`: the browser stopped answering, or the batch ran out of time, after the input was sent. 

              - enum: ` ["delivered_verified","delivered_unverified","delivery_uncertain","not_delivered","unknown"] `

              - example: ` "delivered_unverified" `

            - ` retry `: type ` string ` — Whether sending the action again is safe. `safe`: nothing was sent, or the action does the same thing twice (`navigate`, `hover`, `scroll`, the read actions). `unsafe`: its input landed and a second send repeats it (a second click, the text typed twice). `unknown`: whether its input landed cannot be told (`delivery` `unknown`, or an `evaluate` that threw part way). 

              - enum: ` ["safe","unsafe","unknown"] `

              - example: ` "safe" `

            - ` settled_ms `: type ` number ` — With `settle`: milliseconds from the browser's acknowledgement of the input until the page settled (or the settle's deadline). Left out without `settle`.

            - ` settled_by `: type ` string ` — With `settle`: `quiet` (the page went quiet), `navigation` (the input led to a new document, which loaded and went quiet; a `navigate` always ends this way) or `deadline` (`timeout_ms` came first; the action still succeeded).

              - enum: ` ["quiet","navigation","deadline"] `

            - ` warnings `: type ` array ` — What changed this action's answer, each starting with its code as a scrape's `warnings` do: a `screenshot` cut at the 16,384 px screenshot limit (`screenshot_truncated:` with the page's or the element's real size), a `markdown` read that returned the whole page because main content was under a quarter of it, or one that a markup limit or the extraction deadline shortened. Left out when there is nothing to say.

              - ` array item `: type ` string `

        - ` page_state `: type ` object ` — What kind of page the scrape returned (the page your `actions` left, when there are any), from heuristics on the HTML, the status and the amount of text (no model call): `ok` (the page), `blocked` (a bot-management interstitial or refusal), `captcha` (a challenge for a person), `cookie_wall` (consent before content), `login` (a sign-in form instead of content), `error` (an error status, or a 200 whose title says the page is missing) or `loading` (an unfinished shell). `blocked` and `captcha` are walls, and when the signals are unclear the state is `ok`, since a wall's content is withheld. A wall has little text (under about 2,500 bytes of visible text, counted outside the head whether or not the document has a `<body>` tag, and under 2,000 bytes of Markdown of the default main content, whatever `include_tags`, `exclude_tags` or `only_main_content` ask for) and either a 403 or 429 status or an interstitial signal: a challenge or refusal title (whole words, such as "Just a moment" or "Access denied"), a resource only a vendor's challenge loads (such as Cloudflare's `/cdn-cgi/challenge-platform/.../orchestrate/` or DataDome's `captcha-delivery.com`), an element only a vendor's challenge or block page has (Cloudflare's `cf-error-details` only with a 403 or 429 status or its "you have been blocked" headline: its 5xx origin-error pages, 520 to 526, use the same template and are `error`), or a CAPTCHA widget (`g-recaptcha`, `h-captcha`, `cf-turnstile`, or a rendered Turnstile widget's frame) on a page without a form field to fill in. Scripts that sites load on every page are not signals (reCAPTCHA v3, Cloudflare's JavaScript detections, PerimeterX, Kasada or Imperva loaders), so a small page that carries one is `ok`; vendor names count only in markup (classes, ids, resource URLs, inline scripts, comments), never in visible text; and a body that is not HTML (JSON, text) is judged by its status alone. Without an error status a wall is also small, at most 16 KiB of markup: a thin page with more keeps its content in scripts (a single-page app's inline state) and is not a wall. A marker or refusal word that the requested or final URL also carries (percent-decoded, in any case, a slug's words included) does not count: a page that echoes its own address, such as a search page with the query in its title or a tag page titled after its slug, is not refusing it. The markup judged is the document as served or, in a browser, the whole DOM with its scripts when the page shows fewer than 6,000 characters of text (counted in the DOM itself, the same whatever `formats` asks for); a page that shows more is judged by that text, and no rule that reads markup applies to it. So `formats` does not change the state, and neither does which copy of a page the cache holds for the same tier; a `cache_only` scrape with `engine: "auto"` reads whichever tier's copy is cached, and the fetch tier and the browser can judge the same page differently. A page whose content is visible text is not a wall, whatever its status or markers: with a consent banner or a CAPTCHA widget it is `ok`, answered with 403 or 429 it is `error`. A thin page that keeps its content in scripts and is answered with 403 or 429 is a wall, so its content is withheld unless `walls: "bill"`. Your own `actions` can make a wall (an `evaluate` step that empties the page), and the state then says so. A wall is free (no `vision.page`, not counted against the allowance; Firecrawl's `creditsUsed` is 0) and its content withheld (`content_withheld`), unless the request sets `walls: "bill"` or runs `actions`, which bill like any page. The other states are billed: they are the site's answer.

          - Required fields: ` state `

          - ` state `: type ` string `

            - enum: ` ["ok","blocked","captcha","cookie_wall","login","error","loading"] `

          - ` signal `: type ` string ` — What decided it, such as `cloudflare_challenge`, `recaptcha`, `onetrust`, `password_form`, `status`, `title` or `empty_spa_root`.

        - ` content_withheld `: type ` boolean ` — Present (`true`) when the page is a wall and the scrape was free (`walls: free`): the result then has no `markdown`, `html`, `raw_html`, `text`, `links`, `metadata`, `screenshot`, `json`, `actions` or `content_type`, only the state, `status_code` and `final_url`.

        - ` warnings `: type ` array ` — Non-fatal problems, such as a format that could not be produced.

          - ` array item `: type ` string `

        - ` timing `: type ` object ` — Server-side phase durations in milliseconds with microsecond resolution: the same phases as the `Server-Timing` header, keyed `<phase>_ms`. `total_ms` is always present. Phase names are product-specific and documented per operation. Example values in this reference are illustrative, not measurements. 

          - example: ` {"claim_ms":1.1,"navigate_ms":31,"extract_ms":4.2,"total_ms":36.6} `

          - Required fields: ` total_ms `

          - ` total_ms `: type ` number `

            - minimum: ` 0 `

      - ` error `: type ` object ` — An RFC 9457 problem. `code` is stable and listed in the errors catalog; `type` links to its entry. `detail` is human-readable and may change. Extension members appear only for the codes that document them; ignore members you do not recognize. 

        - Required fields: ` type `, ` title `, ` status `, ` code `, ` detail `

        - ` type `: type ` string `; format ` uri ` — `https://docs.beta.b3os.org/errors#<code>`.

          - example: ` "https://docs.beta.b3os.org/errors#invalid_request" `

        - ` title `: type ` string ` — Short summary of the problem type.

        - ` status `: type ` integer ` — The HTTP status code, repeated for convenience.

          - minimum: ` 400 `

          - maximum: ` 599 `

        - ` code `: type ` string ` — Stable machine-readable error code from the errors catalog.

          - pattern: ` "^[a-z][a-z0-9_]*$" `

        - ` detail `: type ` string ` — Explanation of this occurrence. Never contains secrets.

        - ` instance `: type ` string ` — The request ID (`req_…`) of the request that failed. Include it when you contact support.

          - example: ` "req_01m5t4yg394wegr3j4y01qb363" `

        - ` errors `: type ` array ` — Validation problems, one per field (`invalid_request` and the other codes that list `errors`).

          - ` array item `: type ` object ` — One validation problem.

            - Required fields: ` pointer `, ` detail `

            - ` pointer `: type ` string ` — Where the problem is: a JSON pointer into the request body (`/url`, `/steps/0/uses`), or `#query/<name>`, `#path/<name>` or `#header/<name>` for parameters. 

              - example: ` "/url" `

            - ` detail `: type ` string ` — What is wrong there.

              - example: ` "must be an absolute http or https URL" `

        - ` reason `: type ` string ` — Finer-grained cause for codes that document one (`unauthorized`, `forbidden`, `egress_denied`, `upstream_unreachable`, …).

        - ` required_scope `: type ` string ` — The scope that was missing (`forbidden` with `reason: scope`).

        - ` retry_after_s `: type ` integer ` — Same value as the `Retry-After` header, for clients that only read the body.

          - minimum: ` 0 `

        - ` limit `: type ` object ` — The limit an error refers to. IDs and current values are listed by `GET /v1/limits`.

          - Required fields: ` id `, ` limit `, ` unit `

          - ` id `: type ` string ` — Limit ID, such as `vision.scrape.rpm` or `sandboxes.concurrent`.

            - example: ` "vision.scrape.rpm" `

          - ` limit `: type ` number ` — The limit's value.

          - ` unit `: type ` string ` — What the limit counts, such as `requests`, `sandboxes`, `vcpu` or `MiB`.

          - ` window_s `: type ` integer ` — Window length in seconds for rate limits and quotas.

          - ` current `: type ` number ` — Current usage against the limit, when known.

        - ` current_status `: type ` string ` — The object's current status, for state conflicts such as `sandbox_not_running`.

        - ` upstream_status `: type ` integer ` — The HTTP status the upstream returned (`upstream_error`, `action_output_invalid`).

        - ` step `: type ` string ` — The failed step, as a step ID (routines), an index (`act`) or a path such as `beats/2/do/0` (render).

        - ` pack_error `: type ` object ` — The error a pack's error mapping chose (`upstream_error` from pack actions).

          - Required fields: ` code `, ` message `, ` retryable `

          - ` code `: type ` string `

          - ` message `: type ` string `

          - ` retryable `: type ` boolean `

  - ` warnings `: type ` array ` — `scrape_failed: <n> of <m> results could not be scraped; each has its error`, and `empty_page: <n> of <m> results came back with no text in their Markdown; each has its warning`.

    - ` array item `: type ` string `

  - ` timing `: type ` unknown ` — `search_ms` and `total_ms`, and `scrape_ms` when the request has `scrape` and the search found results.

    - ` allOf constraint 1 `: type ` object ` — Server-side phase durations in milliseconds with microsecond resolution: the same phases as the `Server-Timing` header, keyed `<phase>_ms`. `total_ms` is always present. Phase names are product-specific and documented per operation. Example values in this reference are illustrative, not measurements. 

      - example: ` {"claim_ms":1.1,"navigate_ms":31,"extract_ms":4.2,"total_ms":36.6} `

      - Required fields: ` total_ms `

      - ` total_ms `: type ` number `

        - minimum: ` 0 `

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Example:

```json
{
  "object": "search",
  "query": "rust async runtime",
  "results": [
    {
      "position": 1,
      "url": "https://tokio.rs/",
      "title": "Tokio - An asynchronous Rust runtime",
      "description": "Tokio is an asynchronous runtime for the Rust programming language.",
      "scrape": {
        "object": "scrape",
        "url": "https://tokio.rs/",
        "final_url": "https://tokio.rs/",
        "status_code": 200,
        "tier": "fetch",
        "cache": {
          "state": "miss",
          "age_s": 0
        },
        "markdown": "# Tokio\n\nBuild reliable network applications without compromising speed.\n",
        "warnings": [],
        "timing": {
          "fetch_ms": 88.4,
          "extract_ms": 2.1,
          "total_ms": 91
        }
      }
    },
    {
      "position": 2,
      "url": "https://docs.rs/tokio/latest/tokio/",
      "title": "tokio - Rust",
      "description": "A runtime for writing reliable network applications without compromising speed.",
      "scrape": {
        "object": "scrape",
        "url": "https://docs.rs/tokio/latest/tokio/",
        "final_url": "https://docs.rs/tokio/latest/tokio/",
        "status_code": 200,
        "tier": "fetch",
        "cache": {
          "state": "miss",
          "age_s": 0
        },
        "markdown": "# Crate tokio\n\nA runtime for writing reliable network applications without compromising speed.\n",
        "warnings": [],
        "timing": {
          "fetch_ms": 96.2,
          "extract_ms": 3,
          "total_ms": 99.7
        }
      }
    }
  ],
  "timing": {
    "search_ms": 412.6,
    "scrape_ms": 101.3,
    "total_ms": 515.2
  }
}
```

### ` 400 ` — The request failed validation (`invalid_request`, `invalid_url`).

Content type: ` application/problem+json `

- ` value `: type ` object ` — An RFC 9457 problem. `code` is stable and listed in the errors catalog; `type` links to its entry. `detail` is human-readable and may change. Extension members appear only for the codes that document them; ignore members you do not recognize. 

  - Required fields: ` type `, ` title `, ` status `, ` code `, ` detail `

  - ` type `: type ` string `; format ` uri ` — `https://docs.beta.b3os.org/errors#<code>`.

    - example: ` "https://docs.beta.b3os.org/errors#invalid_request" `

  - ` title `: type ` string ` — Short summary of the problem type.

  - ` status `: type ` integer ` — The HTTP status code, repeated for convenience.

    - minimum: ` 400 `

    - maximum: ` 599 `

  - ` code `: type ` string ` — Stable machine-readable error code from the errors catalog.

    - pattern: ` "^[a-z][a-z0-9_]*$" `

  - ` detail `: type ` string ` — Explanation of this occurrence. Never contains secrets.

  - ` instance `: type ` string ` — The request ID (`req_…`) of the request that failed. Include it when you contact support.

    - example: ` "req_01m5t4yg394wegr3j4y01qb363" `

  - ` errors `: type ` array ` — Validation problems, one per field (`invalid_request` and the other codes that list `errors`).

    - ` array item `: type ` object ` — One validation problem.

      - Required fields: ` pointer `, ` detail `

      - ` pointer `: type ` string ` — Where the problem is: a JSON pointer into the request body (`/url`, `/steps/0/uses`), or `#query/<name>`, `#path/<name>` or `#header/<name>` for parameters. 

        - example: ` "/url" `

      - ` detail `: type ` string ` — What is wrong there.

        - example: ` "must be an absolute http or https URL" `

  - ` reason `: type ` string ` — Finer-grained cause for codes that document one (`unauthorized`, `forbidden`, `egress_denied`, `upstream_unreachable`, …).

  - ` required_scope `: type ` string ` — The scope that was missing (`forbidden` with `reason: scope`).

  - ` retry_after_s `: type ` integer ` — Same value as the `Retry-After` header, for clients that only read the body.

    - minimum: ` 0 `

  - ` limit `: type ` object ` — The limit an error refers to. IDs and current values are listed by `GET /v1/limits`.

    - Required fields: ` id `, ` limit `, ` unit `

    - ` id `: type ` string ` — Limit ID, such as `vision.scrape.rpm` or `sandboxes.concurrent`.

      - example: ` "vision.scrape.rpm" `

    - ` limit `: type ` number ` — The limit's value.

    - ` unit `: type ` string ` — What the limit counts, such as `requests`, `sandboxes`, `vcpu` or `MiB`.

    - ` window_s `: type ` integer ` — Window length in seconds for rate limits and quotas.

    - ` current `: type ` number ` — Current usage against the limit, when known.

  - ` current_status `: type ` string ` — The object's current status, for state conflicts such as `sandbox_not_running`.

  - ` upstream_status `: type ` integer ` — The HTTP status the upstream returned (`upstream_error`, `action_output_invalid`).

  - ` step `: type ` string ` — The failed step, as a step ID (routines), an index (`act`) or a path such as `beats/2/do/0` (render).

  - ` pack_error `: type ` object ` — The error a pack's error mapping chose (`upstream_error` from pack actions).

    - Required fields: ` code `, ` message `, ` retryable `

    - ` code `: type ` string `

    - ` message `: type ` string `

    - ` retryable `: type ` boolean `

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Example:

```json
{
  "type": "https://docs.beta.b3os.org/errors#invalid_request",
  "title": "Invalid request",
  "status": 400,
  "code": "invalid_request",
  "detail": "1 field failed validation",
  "instance": "req_01m5t4yg394wegr3j4y01qb363",
  "errors": [
    {
      "pointer": "/url",
      "detail": "must be an absolute http or https URL"
    }
  ]
}
```

### ` 401 ` — Missing, malformed, expired or revoked credentials (`unauthorized`).

Content type: ` application/problem+json `

- ` value `: type ` object ` — An RFC 9457 problem. `code` is stable and listed in the errors catalog; `type` links to its entry. `detail` is human-readable and may change. Extension members appear only for the codes that document them; ignore members you do not recognize. 

  - Required fields: ` type `, ` title `, ` status `, ` code `, ` detail `

  - ` type `: type ` string `; format ` uri ` — `https://docs.beta.b3os.org/errors#<code>`.

    - example: ` "https://docs.beta.b3os.org/errors#invalid_request" `

  - ` title `: type ` string ` — Short summary of the problem type.

  - ` status `: type ` integer ` — The HTTP status code, repeated for convenience.

    - minimum: ` 400 `

    - maximum: ` 599 `

  - ` code `: type ` string ` — Stable machine-readable error code from the errors catalog.

    - pattern: ` "^[a-z][a-z0-9_]*$" `

  - ` detail `: type ` string ` — Explanation of this occurrence. Never contains secrets.

  - ` instance `: type ` string ` — The request ID (`req_…`) of the request that failed. Include it when you contact support.

    - example: ` "req_01m5t4yg394wegr3j4y01qb363" `

  - ` errors `: type ` array ` — Validation problems, one per field (`invalid_request` and the other codes that list `errors`).

    - ` array item `: type ` object ` — One validation problem.

      - Required fields: ` pointer `, ` detail `

      - ` pointer `: type ` string ` — Where the problem is: a JSON pointer into the request body (`/url`, `/steps/0/uses`), or `#query/<name>`, `#path/<name>` or `#header/<name>` for parameters. 

        - example: ` "/url" `

      - ` detail `: type ` string ` — What is wrong there.

        - example: ` "must be an absolute http or https URL" `

  - ` reason `: type ` string ` — Finer-grained cause for codes that document one (`unauthorized`, `forbidden`, `egress_denied`, `upstream_unreachable`, …).

  - ` required_scope `: type ` string ` — The scope that was missing (`forbidden` with `reason: scope`).

  - ` retry_after_s `: type ` integer ` — Same value as the `Retry-After` header, for clients that only read the body.

    - minimum: ` 0 `

  - ` limit `: type ` object ` — The limit an error refers to. IDs and current values are listed by `GET /v1/limits`.

    - Required fields: ` id `, ` limit `, ` unit `

    - ` id `: type ` string ` — Limit ID, such as `vision.scrape.rpm` or `sandboxes.concurrent`.

      - example: ` "vision.scrape.rpm" `

    - ` limit `: type ` number ` — The limit's value.

    - ` unit `: type ` string ` — What the limit counts, such as `requests`, `sandboxes`, `vcpu` or `MiB`.

    - ` window_s `: type ` integer ` — Window length in seconds for rate limits and quotas.

    - ` current `: type ` number ` — Current usage against the limit, when known.

  - ` current_status `: type ` string ` — The object's current status, for state conflicts such as `sandbox_not_running`.

  - ` upstream_status `: type ` integer ` — The HTTP status the upstream returned (`upstream_error`, `action_output_invalid`).

  - ` step `: type ` string ` — The failed step, as a step ID (routines), an index (`act`) or a path such as `beats/2/do/0` (render).

  - ` pack_error `: type ` object ` — The error a pack's error mapping chose (`upstream_error` from pack actions).

    - Required fields: ` code `, ` message `, ` retryable `

    - ` code `: type ` string `

    - ` message `: type ` string `

    - ` retryable `: type ` boolean `

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Example:

```json
{
  "type": "https://docs.beta.b3os.org/errors#unauthorized",
  "title": "Unauthorized",
  "status": 401,
  "code": "unauthorized",
  "detail": "API key checksum does not match; check that the whole key was copied",
  "instance": "req_01m5t4yg394wegr3j4y01qb363",
  "reason": "malformed"
}
```

### ` 402 ` — The organization has no credits left, or the key reached its spend cap.

Content type: ` application/problem+json `

- ` value `: type ` object ` — An RFC 9457 problem. `code` is stable and listed in the errors catalog; `type` links to its entry. `detail` is human-readable and may change. Extension members appear only for the codes that document them; ignore members you do not recognize. 

  - Required fields: ` type `, ` title `, ` status `, ` code `, ` detail `

  - ` type `: type ` string `; format ` uri ` — `https://docs.beta.b3os.org/errors#<code>`.

    - example: ` "https://docs.beta.b3os.org/errors#invalid_request" `

  - ` title `: type ` string ` — Short summary of the problem type.

  - ` status `: type ` integer ` — The HTTP status code, repeated for convenience.

    - minimum: ` 400 `

    - maximum: ` 599 `

  - ` code `: type ` string ` — Stable machine-readable error code from the errors catalog.

    - pattern: ` "^[a-z][a-z0-9_]*$" `

  - ` detail `: type ` string ` — Explanation of this occurrence. Never contains secrets.

  - ` instance `: type ` string ` — The request ID (`req_…`) of the request that failed. Include it when you contact support.

    - example: ` "req_01m5t4yg394wegr3j4y01qb363" `

  - ` errors `: type ` array ` — Validation problems, one per field (`invalid_request` and the other codes that list `errors`).

    - ` array item `: type ` object ` — One validation problem.

      - Required fields: ` pointer `, ` detail `

      - ` pointer `: type ` string ` — Where the problem is: a JSON pointer into the request body (`/url`, `/steps/0/uses`), or `#query/<name>`, `#path/<name>` or `#header/<name>` for parameters. 

        - example: ` "/url" `

      - ` detail `: type ` string ` — What is wrong there.

        - example: ` "must be an absolute http or https URL" `

  - ` reason `: type ` string ` — Finer-grained cause for codes that document one (`unauthorized`, `forbidden`, `egress_denied`, `upstream_unreachable`, …).

  - ` required_scope `: type ` string ` — The scope that was missing (`forbidden` with `reason: scope`).

  - ` retry_after_s `: type ` integer ` — Same value as the `Retry-After` header, for clients that only read the body.

    - minimum: ` 0 `

  - ` limit `: type ` object ` — The limit an error refers to. IDs and current values are listed by `GET /v1/limits`.

    - Required fields: ` id `, ` limit `, ` unit `

    - ` id `: type ` string ` — Limit ID, such as `vision.scrape.rpm` or `sandboxes.concurrent`.

      - example: ` "vision.scrape.rpm" `

    - ` limit `: type ` number ` — The limit's value.

    - ` unit `: type ` string ` — What the limit counts, such as `requests`, `sandboxes`, `vcpu` or `MiB`.

    - ` window_s `: type ` integer ` — Window length in seconds for rate limits and quotas.

    - ` current `: type ` number ` — Current usage against the limit, when known.

  - ` current_status `: type ` string ` — The object's current status, for state conflicts such as `sandbox_not_running`.

  - ` upstream_status `: type ` integer ` — The HTTP status the upstream returned (`upstream_error`, `action_output_invalid`).

  - ` step `: type ` string ` — The failed step, as a step ID (routines), an index (`act`) or a path such as `beats/2/do/0` (render).

  - ` pack_error `: type ` object ` — The error a pack's error mapping chose (`upstream_error` from pack actions).

    - Required fields: ` code `, ` message `, ` retryable `

    - ` code `: type ` string `

    - ` message `: type ` string `

    - ` retryable `: type ` boolean `

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Example:

```json
{
  "type": "https://docs.beta.b3os.org/errors#credits_exhausted",
  "title": "Credits exhausted",
  "status": 402,
  "code": "credits_exhausted",
  "detail": "Organization org_01m5t5hthd29mm5wpza5ndd6mm has no credits left",
  "instance": "req_01m5t4yg394wegr3j4y01qb363"
}
```

### ` 403 ` — Authenticated but not allowed (`forbidden`, `egress_denied`).

Content type: ` application/problem+json `

- ` value `: type ` object ` — An RFC 9457 problem. `code` is stable and listed in the errors catalog; `type` links to its entry. `detail` is human-readable and may change. Extension members appear only for the codes that document them; ignore members you do not recognize. 

  - Required fields: ` type `, ` title `, ` status `, ` code `, ` detail `

  - ` type `: type ` string `; format ` uri ` — `https://docs.beta.b3os.org/errors#<code>`.

    - example: ` "https://docs.beta.b3os.org/errors#invalid_request" `

  - ` title `: type ` string ` — Short summary of the problem type.

  - ` status `: type ` integer ` — The HTTP status code, repeated for convenience.

    - minimum: ` 400 `

    - maximum: ` 599 `

  - ` code `: type ` string ` — Stable machine-readable error code from the errors catalog.

    - pattern: ` "^[a-z][a-z0-9_]*$" `

  - ` detail `: type ` string ` — Explanation of this occurrence. Never contains secrets.

  - ` instance `: type ` string ` — The request ID (`req_…`) of the request that failed. Include it when you contact support.

    - example: ` "req_01m5t4yg394wegr3j4y01qb363" `

  - ` errors `: type ` array ` — Validation problems, one per field (`invalid_request` and the other codes that list `errors`).

    - ` array item `: type ` object ` — One validation problem.

      - Required fields: ` pointer `, ` detail `

      - ` pointer `: type ` string ` — Where the problem is: a JSON pointer into the request body (`/url`, `/steps/0/uses`), or `#query/<name>`, `#path/<name>` or `#header/<name>` for parameters. 

        - example: ` "/url" `

      - ` detail `: type ` string ` — What is wrong there.

        - example: ` "must be an absolute http or https URL" `

  - ` reason `: type ` string ` — Finer-grained cause for codes that document one (`unauthorized`, `forbidden`, `egress_denied`, `upstream_unreachable`, …).

  - ` required_scope `: type ` string ` — The scope that was missing (`forbidden` with `reason: scope`).

  - ` retry_after_s `: type ` integer ` — Same value as the `Retry-After` header, for clients that only read the body.

    - minimum: ` 0 `

  - ` limit `: type ` object ` — The limit an error refers to. IDs and current values are listed by `GET /v1/limits`.

    - Required fields: ` id `, ` limit `, ` unit `

    - ` id `: type ` string ` — Limit ID, such as `vision.scrape.rpm` or `sandboxes.concurrent`.

      - example: ` "vision.scrape.rpm" `

    - ` limit `: type ` number ` — The limit's value.

    - ` unit `: type ` string ` — What the limit counts, such as `requests`, `sandboxes`, `vcpu` or `MiB`.

    - ` window_s `: type ` integer ` — Window length in seconds for rate limits and quotas.

    - ` current `: type ` number ` — Current usage against the limit, when known.

  - ` current_status `: type ` string ` — The object's current status, for state conflicts such as `sandbox_not_running`.

  - ` upstream_status `: type ` integer ` — The HTTP status the upstream returned (`upstream_error`, `action_output_invalid`).

  - ` step `: type ` string ` — The failed step, as a step ID (routines), an index (`act`) or a path such as `beats/2/do/0` (render).

  - ` pack_error `: type ` object ` — The error a pack's error mapping chose (`upstream_error` from pack actions).

    - Required fields: ` code `, ` message `, ` retryable `

    - ` code `: type ` string `

    - ` message `: type ` string `

    - ` retryable `: type ` boolean `

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Example:

```json
{
  "type": "https://docs.beta.b3os.org/errors#forbidden",
  "title": "Forbidden",
  "status": 403,
  "code": "forbidden",
  "detail": "This key lacks the scope sandboxes:write",
  "instance": "req_01m5t4yg394wegr3j4y01qb363",
  "reason": "scope",
  "required_scope": "sandboxes:write"
}
```

### ` 413 ` — The request body exceeds this operation's limit.

Content type: ` application/problem+json `

- ` value `: type ` object ` — An RFC 9457 problem. `code` is stable and listed in the errors catalog; `type` links to its entry. `detail` is human-readable and may change. Extension members appear only for the codes that document them; ignore members you do not recognize. 

  - Required fields: ` type `, ` title `, ` status `, ` code `, ` detail `

  - ` type `: type ` string `; format ` uri ` — `https://docs.beta.b3os.org/errors#<code>`.

    - example: ` "https://docs.beta.b3os.org/errors#invalid_request" `

  - ` title `: type ` string ` — Short summary of the problem type.

  - ` status `: type ` integer ` — The HTTP status code, repeated for convenience.

    - minimum: ` 400 `

    - maximum: ` 599 `

  - ` code `: type ` string ` — Stable machine-readable error code from the errors catalog.

    - pattern: ` "^[a-z][a-z0-9_]*$" `

  - ` detail `: type ` string ` — Explanation of this occurrence. Never contains secrets.

  - ` instance `: type ` string ` — The request ID (`req_…`) of the request that failed. Include it when you contact support.

    - example: ` "req_01m5t4yg394wegr3j4y01qb363" `

  - ` errors `: type ` array ` — Validation problems, one per field (`invalid_request` and the other codes that list `errors`).

    - ` array item `: type ` object ` — One validation problem.

      - Required fields: ` pointer `, ` detail `

      - ` pointer `: type ` string ` — Where the problem is: a JSON pointer into the request body (`/url`, `/steps/0/uses`), or `#query/<name>`, `#path/<name>` or `#header/<name>` for parameters. 

        - example: ` "/url" `

      - ` detail `: type ` string ` — What is wrong there.

        - example: ` "must be an absolute http or https URL" `

  - ` reason `: type ` string ` — Finer-grained cause for codes that document one (`unauthorized`, `forbidden`, `egress_denied`, `upstream_unreachable`, …).

  - ` required_scope `: type ` string ` — The scope that was missing (`forbidden` with `reason: scope`).

  - ` retry_after_s `: type ` integer ` — Same value as the `Retry-After` header, for clients that only read the body.

    - minimum: ` 0 `

  - ` limit `: type ` object ` — The limit an error refers to. IDs and current values are listed by `GET /v1/limits`.

    - Required fields: ` id `, ` limit `, ` unit `

    - ` id `: type ` string ` — Limit ID, such as `vision.scrape.rpm` or `sandboxes.concurrent`.

      - example: ` "vision.scrape.rpm" `

    - ` limit `: type ` number ` — The limit's value.

    - ` unit `: type ` string ` — What the limit counts, such as `requests`, `sandboxes`, `vcpu` or `MiB`.

    - ` window_s `: type ` integer ` — Window length in seconds for rate limits and quotas.

    - ` current `: type ` number ` — Current usage against the limit, when known.

  - ` current_status `: type ` string ` — The object's current status, for state conflicts such as `sandbox_not_running`.

  - ` upstream_status `: type ` integer ` — The HTTP status the upstream returned (`upstream_error`, `action_output_invalid`).

  - ` step `: type ` string ` — The failed step, as a step ID (routines), an index (`act`) or a path such as `beats/2/do/0` (render).

  - ` pack_error `: type ` object ` — The error a pack's error mapping chose (`upstream_error` from pack actions).

    - Required fields: ` code `, ` message `, ` retryable `

    - ` code `: type ` string `

    - ` message `: type ` string `

    - ` retryable `: type ` boolean `

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Example:

```json
{
  "type": "https://docs.beta.b3os.org/errors#payload_too_large",
  "title": "Payload too large",
  "status": 413,
  "code": "payload_too_large",
  "detail": "Request body is 1572864 bytes; this operation accepts at most 1048576",
  "instance": "req_01m5t4yg394wegr3j4y01qb363"
}
```

### ` 415 ` — The Content-Type is not accepted by this operation.

Content type: ` application/problem+json `

- ` value `: type ` object ` — An RFC 9457 problem. `code` is stable and listed in the errors catalog; `type` links to its entry. `detail` is human-readable and may change. Extension members appear only for the codes that document them; ignore members you do not recognize. 

  - Required fields: ` type `, ` title `, ` status `, ` code `, ` detail `

  - ` type `: type ` string `; format ` uri ` — `https://docs.beta.b3os.org/errors#<code>`.

    - example: ` "https://docs.beta.b3os.org/errors#invalid_request" `

  - ` title `: type ` string ` — Short summary of the problem type.

  - ` status `: type ` integer ` — The HTTP status code, repeated for convenience.

    - minimum: ` 400 `

    - maximum: ` 599 `

  - ` code `: type ` string ` — Stable machine-readable error code from the errors catalog.

    - pattern: ` "^[a-z][a-z0-9_]*$" `

  - ` detail `: type ` string ` — Explanation of this occurrence. Never contains secrets.

  - ` instance `: type ` string ` — The request ID (`req_…`) of the request that failed. Include it when you contact support.

    - example: ` "req_01m5t4yg394wegr3j4y01qb363" `

  - ` errors `: type ` array ` — Validation problems, one per field (`invalid_request` and the other codes that list `errors`).

    - ` array item `: type ` object ` — One validation problem.

      - Required fields: ` pointer `, ` detail `

      - ` pointer `: type ` string ` — Where the problem is: a JSON pointer into the request body (`/url`, `/steps/0/uses`), or `#query/<name>`, `#path/<name>` or `#header/<name>` for parameters. 

        - example: ` "/url" `

      - ` detail `: type ` string ` — What is wrong there.

        - example: ` "must be an absolute http or https URL" `

  - ` reason `: type ` string ` — Finer-grained cause for codes that document one (`unauthorized`, `forbidden`, `egress_denied`, `upstream_unreachable`, …).

  - ` required_scope `: type ` string ` — The scope that was missing (`forbidden` with `reason: scope`).

  - ` retry_after_s `: type ` integer ` — Same value as the `Retry-After` header, for clients that only read the body.

    - minimum: ` 0 `

  - ` limit `: type ` object ` — The limit an error refers to. IDs and current values are listed by `GET /v1/limits`.

    - Required fields: ` id `, ` limit `, ` unit `

    - ` id `: type ` string ` — Limit ID, such as `vision.scrape.rpm` or `sandboxes.concurrent`.

      - example: ` "vision.scrape.rpm" `

    - ` limit `: type ` number ` — The limit's value.

    - ` unit `: type ` string ` — What the limit counts, such as `requests`, `sandboxes`, `vcpu` or `MiB`.

    - ` window_s `: type ` integer ` — Window length in seconds for rate limits and quotas.

    - ` current `: type ` number ` — Current usage against the limit, when known.

  - ` current_status `: type ` string ` — The object's current status, for state conflicts such as `sandbox_not_running`.

  - ` upstream_status `: type ` integer ` — The HTTP status the upstream returned (`upstream_error`, `action_output_invalid`).

  - ` step `: type ` string ` — The failed step, as a step ID (routines), an index (`act`) or a path such as `beats/2/do/0` (render).

  - ` pack_error `: type ` object ` — The error a pack's error mapping chose (`upstream_error` from pack actions).

    - Required fields: ` code `, ` message `, ` retryable `

    - ` code `: type ` string `

    - ` message `: type ` string `

    - ` retryable `: type ` boolean `

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Example:

```json
{
  "type": "https://docs.beta.b3os.org/errors#unsupported_media_type",
  "title": "Unsupported media type",
  "status": 415,
  "code": "unsupported_media_type",
  "detail": "Expected Content-Type application/json",
  "instance": "req_01m5t4yg394wegr3j4y01qb363"
}
```

### ` 429 ` — A rate, concurrency or quota limit applies (`rate_limited`, `concurrency_limited`, `quota_exceeded`).

Content type: ` application/problem+json `

- ` value `: type ` object ` — An RFC 9457 problem. `code` is stable and listed in the errors catalog; `type` links to its entry. `detail` is human-readable and may change. Extension members appear only for the codes that document them; ignore members you do not recognize. 

  - Required fields: ` type `, ` title `, ` status `, ` code `, ` detail `

  - ` type `: type ` string `; format ` uri ` — `https://docs.beta.b3os.org/errors#<code>`.

    - example: ` "https://docs.beta.b3os.org/errors#invalid_request" `

  - ` title `: type ` string ` — Short summary of the problem type.

  - ` status `: type ` integer ` — The HTTP status code, repeated for convenience.

    - minimum: ` 400 `

    - maximum: ` 599 `

  - ` code `: type ` string ` — Stable machine-readable error code from the errors catalog.

    - pattern: ` "^[a-z][a-z0-9_]*$" `

  - ` detail `: type ` string ` — Explanation of this occurrence. Never contains secrets.

  - ` instance `: type ` string ` — The request ID (`req_…`) of the request that failed. Include it when you contact support.

    - example: ` "req_01m5t4yg394wegr3j4y01qb363" `

  - ` errors `: type ` array ` — Validation problems, one per field (`invalid_request` and the other codes that list `errors`).

    - ` array item `: type ` object ` — One validation problem.

      - Required fields: ` pointer `, ` detail `

      - ` pointer `: type ` string ` — Where the problem is: a JSON pointer into the request body (`/url`, `/steps/0/uses`), or `#query/<name>`, `#path/<name>` or `#header/<name>` for parameters. 

        - example: ` "/url" `

      - ` detail `: type ` string ` — What is wrong there.

        - example: ` "must be an absolute http or https URL" `

  - ` reason `: type ` string ` — Finer-grained cause for codes that document one (`unauthorized`, `forbidden`, `egress_denied`, `upstream_unreachable`, …).

  - ` required_scope `: type ` string ` — The scope that was missing (`forbidden` with `reason: scope`).

  - ` retry_after_s `: type ` integer ` — Same value as the `Retry-After` header, for clients that only read the body.

    - minimum: ` 0 `

  - ` limit `: type ` object ` — The limit an error refers to. IDs and current values are listed by `GET /v1/limits`.

    - Required fields: ` id `, ` limit `, ` unit `

    - ` id `: type ` string ` — Limit ID, such as `vision.scrape.rpm` or `sandboxes.concurrent`.

      - example: ` "vision.scrape.rpm" `

    - ` limit `: type ` number ` — The limit's value.

    - ` unit `: type ` string ` — What the limit counts, such as `requests`, `sandboxes`, `vcpu` or `MiB`.

    - ` window_s `: type ` integer ` — Window length in seconds for rate limits and quotas.

    - ` current `: type ` number ` — Current usage against the limit, when known.

  - ` current_status `: type ` string ` — The object's current status, for state conflicts such as `sandbox_not_running`.

  - ` upstream_status `: type ` integer ` — The HTTP status the upstream returned (`upstream_error`, `action_output_invalid`).

  - ` step `: type ` string ` — The failed step, as a step ID (routines), an index (`act`) or a path such as `beats/2/do/0` (render).

  - ` pack_error `: type ` object ` — The error a pack's error mapping chose (`upstream_error` from pack actions).

    - Required fields: ` code `, ` message `, ` retryable `

    - ` code `: type ` string `

    - ` message `: type ` string `

    - ` retryable `: type ` boolean `

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Response header ` Retry-After ` — Seconds to wait before retrying or polling again.

- ` value `: type ` integer `

  - minimum: ` 0 `

Response header ` RateLimit-Limit ` — Requests allowed in the current window for the limit that applies to this operation.

- ` value `: type ` integer `

Response header ` RateLimit-Remaining ` — Requests left in the current window.

- ` value `: type ` integer `

Response header ` RateLimit-Reset ` — Seconds until the current window resets.

- ` value `: type ` integer `

Response header ` RateLimit-Policy ` — The applied policy as `<limit>;w=<window seconds>;name="<limit id>"` (limit IDs are listed by `GET /v1/limits`).

- ` value `: type ` string `

Example:

```json
{
  "type": "https://docs.beta.b3os.org/errors#rate_limited",
  "title": "Rate limited",
  "status": 429,
  "code": "rate_limited",
  "detail": "60 scrapes per minute allowed; retry in 12 seconds",
  "instance": "req_01m5t4yg394wegr3j4y01qb363",
  "retry_after_s": 12,
  "limit": {
    "id": "vision.scrape.rpm",
    "limit": 60,
    "unit": "requests",
    "window_s": 60,
    "current": 60
  }
}
```

### ` 500 ` — Something failed inside B3OS (`internal`). Retry with backoff.

Content type: ` application/problem+json `

- ` value `: type ` object ` — An RFC 9457 problem. `code` is stable and listed in the errors catalog; `type` links to its entry. `detail` is human-readable and may change. Extension members appear only for the codes that document them; ignore members you do not recognize. 

  - Required fields: ` type `, ` title `, ` status `, ` code `, ` detail `

  - ` type `: type ` string `; format ` uri ` — `https://docs.beta.b3os.org/errors#<code>`.

    - example: ` "https://docs.beta.b3os.org/errors#invalid_request" `

  - ` title `: type ` string ` — Short summary of the problem type.

  - ` status `: type ` integer ` — The HTTP status code, repeated for convenience.

    - minimum: ` 400 `

    - maximum: ` 599 `

  - ` code `: type ` string ` — Stable machine-readable error code from the errors catalog.

    - pattern: ` "^[a-z][a-z0-9_]*$" `

  - ` detail `: type ` string ` — Explanation of this occurrence. Never contains secrets.

  - ` instance `: type ` string ` — The request ID (`req_…`) of the request that failed. Include it when you contact support.

    - example: ` "req_01m5t4yg394wegr3j4y01qb363" `

  - ` errors `: type ` array ` — Validation problems, one per field (`invalid_request` and the other codes that list `errors`).

    - ` array item `: type ` object ` — One validation problem.

      - Required fields: ` pointer `, ` detail `

      - ` pointer `: type ` string ` — Where the problem is: a JSON pointer into the request body (`/url`, `/steps/0/uses`), or `#query/<name>`, `#path/<name>` or `#header/<name>` for parameters. 

        - example: ` "/url" `

      - ` detail `: type ` string ` — What is wrong there.

        - example: ` "must be an absolute http or https URL" `

  - ` reason `: type ` string ` — Finer-grained cause for codes that document one (`unauthorized`, `forbidden`, `egress_denied`, `upstream_unreachable`, …).

  - ` required_scope `: type ` string ` — The scope that was missing (`forbidden` with `reason: scope`).

  - ` retry_after_s `: type ` integer ` — Same value as the `Retry-After` header, for clients that only read the body.

    - minimum: ` 0 `

  - ` limit `: type ` object ` — The limit an error refers to. IDs and current values are listed by `GET /v1/limits`.

    - Required fields: ` id `, ` limit `, ` unit `

    - ` id `: type ` string ` — Limit ID, such as `vision.scrape.rpm` or `sandboxes.concurrent`.

      - example: ` "vision.scrape.rpm" `

    - ` limit `: type ` number ` — The limit's value.

    - ` unit `: type ` string ` — What the limit counts, such as `requests`, `sandboxes`, `vcpu` or `MiB`.

    - ` window_s `: type ` integer ` — Window length in seconds for rate limits and quotas.

    - ` current `: type ` number ` — Current usage against the limit, when known.

  - ` current_status `: type ` string ` — The object's current status, for state conflicts such as `sandbox_not_running`.

  - ` upstream_status `: type ` integer ` — The HTTP status the upstream returned (`upstream_error`, `action_output_invalid`).

  - ` step `: type ` string ` — The failed step, as a step ID (routines), an index (`act`) or a path such as `beats/2/do/0` (render).

  - ` pack_error `: type ` object ` — The error a pack's error mapping chose (`upstream_error` from pack actions).

    - Required fields: ` code `, ` message `, ` retryable `

    - ` code `: type ` string `

    - ` message `: type ` string `

    - ` retryable `: type ` boolean `

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Example:

```json
{
  "type": "https://docs.beta.b3os.org/errors#internal",
  "title": "Internal error",
  "status": 500,
  "code": "internal",
  "detail": "internal error",
  "instance": "req_01m5t4yg394wegr3j4y01qb363"
}
```

### ` 502 ` — The search provider did not answer in time, was busy or failed (`search_failed`).

Content type: ` application/problem+json `

- ` value `: type ` object ` — An RFC 9457 problem. `code` is stable and listed in the errors catalog; `type` links to its entry. `detail` is human-readable and may change. Extension members appear only for the codes that document them; ignore members you do not recognize. 

  - Required fields: ` type `, ` title `, ` status `, ` code `, ` detail `

  - ` type `: type ` string `; format ` uri ` — `https://docs.beta.b3os.org/errors#<code>`.

    - example: ` "https://docs.beta.b3os.org/errors#invalid_request" `

  - ` title `: type ` string ` — Short summary of the problem type.

  - ` status `: type ` integer ` — The HTTP status code, repeated for convenience.

    - minimum: ` 400 `

    - maximum: ` 599 `

  - ` code `: type ` string ` — Stable machine-readable error code from the errors catalog.

    - pattern: ` "^[a-z][a-z0-9_]*$" `

  - ` detail `: type ` string ` — Explanation of this occurrence. Never contains secrets.

  - ` instance `: type ` string ` — The request ID (`req_…`) of the request that failed. Include it when you contact support.

    - example: ` "req_01m5t4yg394wegr3j4y01qb363" `

  - ` errors `: type ` array ` — Validation problems, one per field (`invalid_request` and the other codes that list `errors`).

    - ` array item `: type ` object ` — One validation problem.

      - Required fields: ` pointer `, ` detail `

      - ` pointer `: type ` string ` — Where the problem is: a JSON pointer into the request body (`/url`, `/steps/0/uses`), or `#query/<name>`, `#path/<name>` or `#header/<name>` for parameters. 

        - example: ` "/url" `

      - ` detail `: type ` string ` — What is wrong there.

        - example: ` "must be an absolute http or https URL" `

  - ` reason `: type ` string ` — Finer-grained cause for codes that document one (`unauthorized`, `forbidden`, `egress_denied`, `upstream_unreachable`, …).

  - ` required_scope `: type ` string ` — The scope that was missing (`forbidden` with `reason: scope`).

  - ` retry_after_s `: type ` integer ` — Same value as the `Retry-After` header, for clients that only read the body.

    - minimum: ` 0 `

  - ` limit `: type ` object ` — The limit an error refers to. IDs and current values are listed by `GET /v1/limits`.

    - Required fields: ` id `, ` limit `, ` unit `

    - ` id `: type ` string ` — Limit ID, such as `vision.scrape.rpm` or `sandboxes.concurrent`.

      - example: ` "vision.scrape.rpm" `

    - ` limit `: type ` number ` — The limit's value.

    - ` unit `: type ` string ` — What the limit counts, such as `requests`, `sandboxes`, `vcpu` or `MiB`.

    - ` window_s `: type ` integer ` — Window length in seconds for rate limits and quotas.

    - ` current `: type ` number ` — Current usage against the limit, when known.

  - ` current_status `: type ` string ` — The object's current status, for state conflicts such as `sandbox_not_running`.

  - ` upstream_status `: type ` integer ` — The HTTP status the upstream returned (`upstream_error`, `action_output_invalid`).

  - ` step `: type ` string ` — The failed step, as a step ID (routines), an index (`act`) or a path such as `beats/2/do/0` (render).

  - ` pack_error `: type ` object ` — The error a pack's error mapping chose (`upstream_error` from pack actions).

    - Required fields: ` code `, ` message `, ` retryable `

    - ` code `: type ` string `

    - ` message `: type ` string `

    - ` retryable `: type ` boolean `

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Example:

```json
{
  "type": "https://docs.beta.b3os.org/errors#search_failed",
  "title": "Search failed",
  "status": 502,
  "code": "search_failed",
  "detail": "the search provider did not answer in time",
  "instance": "req_01m5t4yg394wegr3j4y01qb363",
  "retry_after_s": 1
}
```

### ` 503 ` — This node has no search key, or the provider refused it (`search_unavailable`).

Content type: ` application/problem+json `

- ` value `: type ` object ` — An RFC 9457 problem. `code` is stable and listed in the errors catalog; `type` links to its entry. `detail` is human-readable and may change. Extension members appear only for the codes that document them; ignore members you do not recognize. 

  - Required fields: ` type `, ` title `, ` status `, ` code `, ` detail `

  - ` type `: type ` string `; format ` uri ` — `https://docs.beta.b3os.org/errors#<code>`.

    - example: ` "https://docs.beta.b3os.org/errors#invalid_request" `

  - ` title `: type ` string ` — Short summary of the problem type.

  - ` status `: type ` integer ` — The HTTP status code, repeated for convenience.

    - minimum: ` 400 `

    - maximum: ` 599 `

  - ` code `: type ` string ` — Stable machine-readable error code from the errors catalog.

    - pattern: ` "^[a-z][a-z0-9_]*$" `

  - ` detail `: type ` string ` — Explanation of this occurrence. Never contains secrets.

  - ` instance `: type ` string ` — The request ID (`req_…`) of the request that failed. Include it when you contact support.

    - example: ` "req_01m5t4yg394wegr3j4y01qb363" `

  - ` errors `: type ` array ` — Validation problems, one per field (`invalid_request` and the other codes that list `errors`).

    - ` array item `: type ` object ` — One validation problem.

      - Required fields: ` pointer `, ` detail `

      - ` pointer `: type ` string ` — Where the problem is: a JSON pointer into the request body (`/url`, `/steps/0/uses`), or `#query/<name>`, `#path/<name>` or `#header/<name>` for parameters. 

        - example: ` "/url" `

      - ` detail `: type ` string ` — What is wrong there.

        - example: ` "must be an absolute http or https URL" `

  - ` reason `: type ` string ` — Finer-grained cause for codes that document one (`unauthorized`, `forbidden`, `egress_denied`, `upstream_unreachable`, …).

  - ` required_scope `: type ` string ` — The scope that was missing (`forbidden` with `reason: scope`).

  - ` retry_after_s `: type ` integer ` — Same value as the `Retry-After` header, for clients that only read the body.

    - minimum: ` 0 `

  - ` limit `: type ` object ` — The limit an error refers to. IDs and current values are listed by `GET /v1/limits`.

    - Required fields: ` id `, ` limit `, ` unit `

    - ` id `: type ` string ` — Limit ID, such as `vision.scrape.rpm` or `sandboxes.concurrent`.

      - example: ` "vision.scrape.rpm" `

    - ` limit `: type ` number ` — The limit's value.

    - ` unit `: type ` string ` — What the limit counts, such as `requests`, `sandboxes`, `vcpu` or `MiB`.

    - ` window_s `: type ` integer ` — Window length in seconds for rate limits and quotas.

    - ` current `: type ` number ` — Current usage against the limit, when known.

  - ` current_status `: type ` string ` — The object's current status, for state conflicts such as `sandbox_not_running`.

  - ` upstream_status `: type ` integer ` — The HTTP status the upstream returned (`upstream_error`, `action_output_invalid`).

  - ` step `: type ` string ` — The failed step, as a step ID (routines), an index (`act`) or a path such as `beats/2/do/0` (render).

  - ` pack_error `: type ` object ` — The error a pack's error mapping chose (`upstream_error` from pack actions).

    - Required fields: ` code `, ` message `, ` retryable `

    - ` code `: type ` string `

    - ` message `: type ` string `

    - ` retryable `: type ` boolean `

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Example:

```json
{
  "type": "https://docs.beta.b3os.org/errors#search_unavailable",
  "title": "Search unavailable",
  "status": 503,
  "code": "search_unavailable",
  "detail": "this node has no search provider key; scrape known URLs with POST /v1/vision/scrape",
  "instance": "req_01m5t4yg394wegr3j4y01qb363"
}
```

## Request examples

### cURL

```curl
curl -X POST 'https://beta-api.b3os.org/v1/vision/search' \
  -H 'Authorization: Bearer YOUR_API_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
  "query": "rust async runtime",
  "limit": 2,
  "scrape": {
    "formats": [
      "markdown"
    ]
  }
}'
```

### JavaScript

```javascript
const response = await fetch('https://beta-api.b3os.org/v1/vision/search', {
  method: 'POST',
  headers: {
      "Authorization": "Bearer YOUR_API_TOKEN",
      "Content-Type": "application/json"
  },
  body: JSON.stringify({
    "query": "rust async runtime",
    "limit": 2,
    "scrape": {
      "formats": [
        "markdown"
      ]
    }
  })
});

const data = await response.json();
console.log(data);
```

### Python

```python
import requests

headers = {
    'Authorization': 'Bearer YOUR_API_TOKEN'
}

response = requests.post('https://beta-api.b3os.org/v1/vision/search', headers=headers, json={
  "query": "rust async runtime",
  "limit": 2,
  "scrape": {
    "formats": [
      "markdown"
    ]
  }
})
print(response.json())
```