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

# Fetch

> Fetch any page and get data in the formats you choose

Fetch loads a URL in a cloud browser and returns the outputs you specify—markdown, HTML, links, screenshots, structured JSON, or a branding profile. It's the core building block for web scraping with Hyperbrowser.

<Info>
  For the full API schema, see the [Fetch API Reference](/api-reference/fetch-a-web-page).
</Info>

***

## Quick Start

<Steps>
  <Step title="Install the SDK">
    <CodeGroup>
      ```bash npm theme={null}
      npm install @hyperbrowser/sdk
      ```

      ```bash yarn theme={null}
      yarn add @hyperbrowser/sdk
      ```

      ```bash pip theme={null}
      pip install hyperbrowser
      ```

      ```bash uv theme={null}
      uv add hyperbrowser
      ```
    </CodeGroup>
  </Step>

  <Step title="Fetch a page">
    <CodeGroup>
      ```typescript Node theme={null}
      import { Hyperbrowser } from "@hyperbrowser/sdk";
      import { config } from "dotenv";

      config();

      const client = new Hyperbrowser({
        apiKey: process.env.HYPERBROWSER_API_KEY,
      });

      const result = await client.web.fetch({
        url: "https://example.com",
      });

      console.log(result);
      ```

      ```python Python theme={null}
      import os
      from dotenv import load_dotenv
      from hyperbrowser import Hyperbrowser
      from hyperbrowser.models import FetchParams

      load_dotenv()

      client = Hyperbrowser(api_key=os.getenv("HYPERBROWSER_API_KEY"))

      result = client.web.fetch(
          FetchParams(url="https://example.com")
      )

      print(result)
      ```

      ```bash cURL theme={null}
      curl -X POST https://api.hyperbrowser.ai/api/web/fetch \
        -H 'Content-Type: application/json' \
        -H 'x-api-key: <YOUR_API_KEY>' \
        -d '{
          "url": "https://example.com",
          "outputs": {
            "formats": ["markdown", "links"]
          }
        }'
      ```
    </CodeGroup>
  </Step>
</Steps>

***

## Response

The response includes a `jobId`, overall `status`, and the outputs under `data`:

```json theme={null}
{
  "jobId": "962372c4-a140-400b-8c26-4ffe21d9fb9c",
  "status": "completed",
  "data": {
    "metadata": {
      "title": "Example Domain",
      "sourceURL": "https://example.com"
    },
    "markdown": "# Example Domain\n\nThis domain is for use in illustrative examples...",
    "links": [
      "https://www.iana.org/domains/example"
    ]
  }
}
```

***

## Outputs

Use `outputs.formats` to specify what data you want returned.

| Output       | Description                                                          |
| ------------ | -------------------------------------------------------------------- |
| `markdown`   | Page content converted to Markdown                                   |
| `html`       | Raw HTML of the page                                                 |
| `links`      | All links found on the page                                          |
| `screenshot` | Screenshot image (configure with options)                            |
| `json`       | Structured data extracted using a JSON Schema, a prompt, or both     |
| `branding`   | Visual brand profile—colors, fonts, logo, button styles, personality |

<Info>
  `outputs.formats` cannot contain duplicate output types (e.g. two screenshots).
</Info>

<CodeGroup>
  ```typescript Node theme={null}
  import { Hyperbrowser } from "@hyperbrowser/sdk";
  import { config } from "dotenv";

  config();

  const client = new Hyperbrowser({
    apiKey: process.env.HYPERBROWSER_API_KEY,
  });

  const result = await client.web.fetch({
    url: "https://example.com",
    outputs: {
      formats: ["markdown", "links"],
    },
  });

  console.log(result.data.markdown);
  console.log(result.data.links);
  ```

  ```python Python theme={null}
  import os
  from dotenv import load_dotenv
  from hyperbrowser import Hyperbrowser
  from hyperbrowser.models import FetchParams, FetchOutputOptions

  load_dotenv()

  client = Hyperbrowser(api_key=os.getenv("HYPERBROWSER_API_KEY"))

  result = client.web.fetch(
      FetchParams(
          url="https://example.com",
          outputs=FetchOutputOptions(
              formats=["markdown", "links"]
          ),
      )
  )

  print(result.data.markdown)
  print(result.data.links)
  ```

  ```bash cURL theme={null}
  curl -X POST https://api.hyperbrowser.ai/api/web/fetch \
    -H 'Content-Type: application/json' \
    -H 'x-api-key: <YOUR_API_KEY>' \
    -d '{
      "url": "https://example.com",
      "outputs": {
        "formats": ["markdown", "links"]
      }
    }'
  ```
</CodeGroup>

<Accordion title="Screenshot with options">
  <CodeGroup>
    ```typescript Node theme={null}
    import { Hyperbrowser } from "@hyperbrowser/sdk";
    import { config } from "dotenv";

    config();

    const client = new Hyperbrowser({
      apiKey: process.env.HYPERBROWSER_API_KEY,
    });

    const result = await client.web.fetch({
      url: "https://hackernews.com",
      outputs: {
        formats: [
          "markdown",
          {
            type: "screenshot",
            fullPage: true,
            format: "png",
          },
        ],
      },
    });

    console.log(result.data.screenshot);
    ```

    ```python Python theme={null}
    import os
    from dotenv import load_dotenv
    from hyperbrowser import Hyperbrowser
    from hyperbrowser.models import FetchParams, FetchOutputOptions, FetchOutputScreenshot

    load_dotenv()

    client = Hyperbrowser(api_key=os.getenv("HYPERBROWSER_API_KEY"))

    result = client.web.fetch(
        FetchParams(
            url="https://hackernews.com",
            outputs=FetchOutputOptions(
                formats=[
                    "markdown",
                    FetchOutputScreenshot(
                        type="screenshot",
                        full_page=True,
                        format="png",
                    ),
                ]
            ),
        )
    )

    print(result.data.screenshot)
    ```

    ```bash cURL theme={null}
    curl -X POST https://api.hyperbrowser.ai/api/web/fetch \
      -H 'Content-Type: application/json' \
      -H 'x-api-key: <YOUR_API_KEY>' \
      -d '{
        "url": "https://hackernews.com",
        "outputs": {
          "formats": [
            "markdown",
            {
              "type": "screenshot",
              "fullPage": true,
              "format": "png"
            }
          ]
        }
      }'
    ```
  </CodeGroup>
</Accordion>

<Accordion title="Structured JSON extraction">
  Extract structured data from the page using `prompt`, `schema`, or both:

  * **`prompt` only** — Describe what you want in natural language. A schema is auto-generated from the prompt.
  * **`schema` only** — Provide a JSON Schema (or Zod/Pydantic equivalent) defining the exact output structure.
  * **`prompt` and `schema`** — The schema defines the output structure, while the prompt provides additional guidance for the extraction.

  <Tip>
    For best results, provide both a `schema` and a `prompt`. The schema defines exactly how you want the data formatted, and the prompt provides context to guide the extraction.
  </Tip>

  **Prompt only (schema auto-generated):**

  <CodeGroup>
    ```typescript Node theme={null}
    import { Hyperbrowser } from "@hyperbrowser/sdk";
    import { config } from "dotenv";

    config();

    const client = new Hyperbrowser({
      apiKey: process.env.HYPERBROWSER_API_KEY,
    });

    const result = await client.web.fetch({
      url: "https://example.com",
      outputs: {
        formats: [
          {
            type: "json",
            prompt: "Extract the main heading and a brief description of the page",
          },
        ],
      },
    });
    ```

    ```python Python theme={null}
    import os
    from dotenv import load_dotenv
    from hyperbrowser import Hyperbrowser
    from hyperbrowser.models import FetchParams, FetchOutputOptions, FetchOutputJson

    load_dotenv()

    client = Hyperbrowser(api_key=os.getenv("HYPERBROWSER_API_KEY"))

    result = client.web.fetch(
        FetchParams(
            url="https://example.com",
            outputs=FetchOutputOptions(
                formats=[
                    FetchOutputJson(
                        type="json",
                        prompt="Extract the main heading and a brief description of the page",
                    )
                ]
            ),
        )
    )

    print(result.data.json_)
    ```

    ```bash cURL theme={null}
    curl -X POST https://api.hyperbrowser.ai/api/web/fetch \
      -H 'Content-Type: application/json' \
      -H 'x-api-key: <YOUR_API_KEY>' \
      -d '{
        "url": "https://example.com",
        "outputs": {
          "formats": [
            {
              "type": "json",
              "prompt": "Extract the main heading and a brief description of the page"
            }
          ]
        }
      }'
    ```
  </CodeGroup>

  **Schema only:**

  <CodeGroup>
    ```typescript Node (JSON Schema) theme={null}
    import { Hyperbrowser } from "@hyperbrowser/sdk";
    import { config } from "dotenv";

    config();

    const client = new Hyperbrowser({
      apiKey: process.env.HYPERBROWSER_API_KEY,
    });

    const result = await client.web.fetch({
      url: "https://example.com",
      outputs: {
        formats: [
          {
            type: "json",
            schema: {
              type: "object",
              properties: {
                heading: { type: "string" },
                description: { type: "string" },
              },
              required: ["heading", "description"],
              additionalProperties: false,
            },
          },
        ],
      },
    });
    ```

    ```typescript Node (Zod) theme={null}
    import { Hyperbrowser } from "@hyperbrowser/sdk";
    import { config } from "dotenv";
    import { z } from "zod";

    config();

    const client = new Hyperbrowser({
      apiKey: process.env.HYPERBROWSER_API_KEY,
    });

    const PageSchema = z.object({
      heading: z.string(),
      description: z.string(),
    });

    const result = await client.web.fetch({
      url: "https://example.com",
      outputs: {
        formats: [
          {
            type: "json",
            schema: PageSchema,
          },
        ],
      },
    });
    ```

    ```python Python (JSON Schema) theme={null}
    import os
    from dotenv import load_dotenv
    from hyperbrowser import Hyperbrowser
    from hyperbrowser.models import FetchParams, FetchOutputOptions, FetchOutputJson

    load_dotenv()

    client = Hyperbrowser(api_key=os.getenv("HYPERBROWSER_API_KEY"))

    result = client.web.fetch(
        FetchParams(
            url="https://example.com",
            outputs=FetchOutputOptions(
                formats=[
                    FetchOutputJson(
                        type="json",
                        schema={
                            "type": "object",
                            "properties": {
                                "heading": {"type": "string"},
                                "description": {"type": "string"},
                            },
                            "required": ["heading", "description"],
                            "additionalProperties": False,
                        }
                    )
                ]
            ),
        )
    )

    print(result.data.json_)
    ```

    ```python Python (Pydantic) theme={null}
    import os
    from dotenv import load_dotenv
    from hyperbrowser import Hyperbrowser
    from hyperbrowser.models import FetchParams, FetchOutputOptions, FetchOutputJson
    from pydantic import BaseModel

    load_dotenv()

    client = Hyperbrowser(api_key=os.getenv("HYPERBROWSER_API_KEY"))


    class PageData(BaseModel):
        heading: str
        description: str


    result = client.web.fetch(
        FetchParams(
            url="https://example.com",
            outputs=FetchOutputOptions(
                formats=[FetchOutputJson(
                  type="json",
                  schema=PageData
                )]
            ),
        )
    )

    print(result.data.json_)
    ```
  </CodeGroup>

  **Both prompt and schema (recommended):**

  <CodeGroup>
    ```typescript Node (JSON Schema) theme={null}
    import { Hyperbrowser } from "@hyperbrowser/sdk";
    import { config } from "dotenv";

    config();

    const client = new Hyperbrowser({
      apiKey: process.env.HYPERBROWSER_API_KEY,
    });

    const result = await client.web.fetch({
      url: "https://example.com",
      outputs: {
        formats: [
          {
            type: "json",
            prompt: "Extract the main heading and a brief description of the page",
            schema: {
              type: "object",
              properties: {
                heading: { type: "string" },
                description: { type: "string" },
              },
              required: ["heading", "description"],
              additionalProperties: false,
            },
          },
        ],
      },
    });
    ```

    ```typescript Node (Zod) theme={null}
    import { Hyperbrowser } from "@hyperbrowser/sdk";
    import { config } from "dotenv";
    import { z } from "zod";

    config();

    const client = new Hyperbrowser({
      apiKey: process.env.HYPERBROWSER_API_KEY,
    });

    const PageSchema = z.object({
      heading: z.string(),
      description: z.string(),
    });

    const result = await client.web.fetch({
      url: "https://example.com",
      outputs: {
        formats: [
          {
            type: "json",
            prompt: "Extract the main heading and a brief description of the page",
            schema: PageSchema,
          },
        ],
      },
    });
    ```

    ```python Python (JSON Schema) theme={null}
    import os
    from dotenv import load_dotenv
    from hyperbrowser import Hyperbrowser
    from hyperbrowser.models import FetchParams, FetchOutputOptions, FetchOutputJson

    load_dotenv()

    client = Hyperbrowser(api_key=os.getenv("HYPERBROWSER_API_KEY"))

    result = client.web.fetch(
        FetchParams(
            url="https://example.com",
            outputs=FetchOutputOptions(
                formats=[
                    FetchOutputJson(
                        type="json",
                        prompt="Extract the main heading and a brief description of the page",
                        schema={
                            "type": "object",
                            "properties": {
                                "heading": {"type": "string"},
                                "description": {"type": "string"},
                            },
                            "required": ["heading", "description"],
                            "additionalProperties": False,
                        }
                    )
                ]
            ),
        )
    )

    print(result.data.json_)
    ```

    ```python Python (Pydantic) theme={null}
    import os
    from dotenv import load_dotenv
    from hyperbrowser import Hyperbrowser
    from hyperbrowser.models import FetchParams, FetchOutputOptions, FetchOutputJson
    from pydantic import BaseModel

    load_dotenv()

    client = Hyperbrowser(api_key=os.getenv("HYPERBROWSER_API_KEY"))


    class PageData(BaseModel):
        heading: str
        description: str


    result = client.web.fetch(
        FetchParams(
            url="https://example.com",
            outputs=FetchOutputOptions(
                formats=[
                    FetchOutputJson(
                        type="json",
                        prompt="Extract the main heading and a brief description of the page",
                        schema=PageData,
                    )
                ]
            ),
        )
    )

    print(result.data.json_)
    ```
  </CodeGroup>

  <Info>
    **Node SDK**: You can pass a Zod schema directly to the `schema` field, and it will be automatically converted to JSON Schema.

    **Python SDK**: You can pass a Pydantic model class directly to the `schema` field, and it will be automatically converted to JSON Schema.
  </Info>
</Accordion>

<Warning>
  Screenshot cropping rules:

  * `fullPage` and `cropToContent` are mutually exclusive.
  * If both `cropToContentMaxHeight` and `cropToContentMinHeight` are set, max must be ≥ min.
  * Crop dimensions must be between **100** and **8000** pixels.
</Warning>

<Accordion title="Branding profile">
  Extract a structured brand profile for the page: color roles (primary, secondary, accent, background, text), typography, logo + favicon, primary/secondary button styles, personality, and confidence scores. Combines in-browser DOM analysis with an LLM pass over the detected elements.

  <CodeGroup>
    ```typescript Node theme={null}
    import { Hyperbrowser } from "@hyperbrowser/sdk";
    import { config } from "dotenv";

    config();

    async function main() {
      const client = new Hyperbrowser({
        apiKey: process.env.HYPERBROWSER_API_KEY,
      });

      const result = await client.web.fetch({
        url: "https://stripe.com",
        outputs: {
          formats: ["branding"],
        },
      });

      console.log(result.data?.branding?.colors?.primary);
      console.log(result.data?.branding?.images?.logo);
      console.log(result.data?.branding?.personality?.tone);
    }

    main().catch(console.error);
    ```

    ```python Python theme={null}
    import os
    from dotenv import load_dotenv
    from hyperbrowser import Hyperbrowser
    from hyperbrowser.models import FetchParams, FetchOutputOptions

    load_dotenv()

    client = Hyperbrowser(api_key=os.getenv("HYPERBROWSER_API_KEY"))

    result = client.web.fetch(
        FetchParams(
            url="https://stripe.com",
            outputs=FetchOutputOptions(formats=["branding"]),
        )
    )

    branding = result.data.branding if result.data else None
    if branding:
        if branding.colors:
            print(branding.colors.primary)
        if branding.images:
            print(branding.images.logo)
        if branding.personality:
            print(branding.personality.tone)
    ```

    ```bash cURL theme={null}
    curl -X POST https://api.hyperbrowser.ai/api/web/fetch \
      -H 'Content-Type: application/json' \
      -H 'x-api-key: <YOUR_API_KEY>' \
      -d '{
        "url": "https://stripe.com",
        "outputs": {
          "formats": ["branding"]
        }
      }'
    ```
  </CodeGroup>

  The response `data.branding` object includes:

  | Field          | Description                                                          |
  | -------------- | -------------------------------------------------------------------- |
  | `colorScheme`  | `"light"` or `"dark"`                                                |
  | `colors`       | `primary`, `secondary`, `accent`, `background`, `textPrimary`, …     |
  | `fonts`        | Cleaned brand fonts with roles (`heading`, `body`, `monospace`, …)   |
  | `typography`   | `fontFamilies`, `fontStacks`, `fontSizes`                            |
  | `spacing`      | `baseUnit`, `borderRadius`                                           |
  | `components`   | `buttonPrimary`, `buttonSecondary`, `input` — full CSS style objects |
  | `images`       | `logo`, `logoHref`, `logoAlt`, `favicon`, `ogImage`                  |
  | `personality`  | `tone`, `energy`, `targetAudience`                                   |
  | `designSystem` | `framework` (tailwind, bootstrap, …), `componentLibrary`             |
  | `confidence`   | `buttons`, `colors`, `overall` (0–1)                                 |

  <Info>
    Branding works identically in [Crawl](/web/crawl) — each crawled page gets its own `branding` profile.
  </Info>
</Accordion>

***

## Output Controls

Control what gets extracted and returned:

| Field                      | Type       | Default  | Description                                                |
| -------------------------- | ---------- | -------- | ---------------------------------------------------------- |
| `outputs.sanitize`         | `string`   | `"none"` | Sanitize mode: `"none"`, `"basic"`, or `"advanced"`        |
| `outputs.includeSelectors` | `string[]` | `[]`     | CSS selectors to include (only matching elements returned) |
| `outputs.excludeSelectors` | `string[]` | `[]`     | CSS selectors to exclude from output                       |
| `outputs.storageState`     | `object`   | —        | Pre-seed localStorage/sessionStorage before fetching       |

<Accordion title="Example with selectors, storageState, navigation, and cache">
  <CodeGroup>
    ```typescript Node theme={null}
    import { Hyperbrowser } from "@hyperbrowser/sdk";
    import { config } from "dotenv";

    config();

    const client = new Hyperbrowser({
      apiKey: process.env.HYPERBROWSER_API_KEY,
    });

    const result = await client.web.fetch({
      url: "https://example.com",
      outputs: {
        formats: ["html"],
        excludeSelectors: ["nav", "footer", "aside"],
        storageState: {
          localStorage: {
            "example:key": "example:value",
          },
        },
      },
      navigation: {
        waitUntil: "load",
        waitFor: 2000,
      },
      cache: {
        maxAgeSeconds: 3600,
      },
    });
    ```

    ```python Python theme={null}
    import os
    from dotenv import load_dotenv
    from hyperbrowser import Hyperbrowser
    from hyperbrowser.models import (
        FetchParams,
        FetchOutputOptions,
        FetchNavigationOptions,
        FetchCacheOptions,
        FetchStorageStateOptions,
    )

    load_dotenv()

    client = Hyperbrowser(api_key=os.getenv("HYPERBROWSER_API_KEY"))

    result = client.web.fetch(
        FetchParams(
            url="https://example.com",
            outputs=FetchOutputOptions(
                formats=["html"],
                exclude_selectors=["nav", "footer", "aside"],
                storage_state=FetchStorageStateOptions(
                    local_storage={"example:key": "example:value"}
                ),
            ),
            navigation=FetchNavigationOptions(
                wait_until="load", wait_for=2000
            ),
            cache=FetchCacheOptions(max_age_seconds=3600),
        )
    )

    print(result)
    ```

    ```bash cURL theme={null}
    curl -X POST https://api.hyperbrowser.ai/api/web/fetch \
      -H 'Content-Type: application/json' \
      -H 'x-api-key: <YOUR_API_KEY>' \
      -d '{
        "url": "https://example.com",
        "outputs": {
          "formats": ["html"],
          "excludeSelectors": ["nav", "footer", "aside"],
          "storageState": {
            "localStorage": {
              "example:key": "example:value"
            }
          }
        },
        "navigation": {
          "waitUntil": "load",
          "waitFor": 2000
        },
        "cache": {
          "maxAgeSeconds": 3600
        }
      }'
    ```
  </CodeGroup>
</Accordion>

## Browser & Stealth

Configure how the cloud browser runs:

| Field                   | Type      | Default                        | Description                                                                                      |
| ----------------------- | --------- | ------------------------------ | ------------------------------------------------------------------------------------------------ |
| `stealth`               | `string`  | `"auto"`                       | Stealth mode: `"none"`, `"auto"`, or `"ultra"` (recommended: `"auto"` or `"ultra"`)              |
| `browser.profileId`     | `string`  | —                              | Reuse an existing browser profile                                                                |
| `browser.solveCaptchas` | `boolean` | `false`                        | Enable CAPTCHA solving                                                                           |
| `browser.screen`        | `object`  | `{ width: 1280, height: 720 }` | Set viewport dimensions (`width`, `height`)                                                      |
| `browser.location`      | `object`  | —                              | Localize via proxy location (`country`, `state`, `city`). If set, proxy is enabled automatically |

## Navigation Controls

Control page load behavior and timing:

| Field                  | Type     | Default              | Description                                                                         |
| ---------------------- | -------- | -------------------- | ----------------------------------------------------------------------------------- |
| `navigation.waitUntil` | `string` | `"domcontentloaded"` | Load condition: `"load"`, `"domcontentloaded"`, or `"networkidle"`                  |
| `navigation.waitFor`   | `number` | `0`                  | Milliseconds to wait after navigation completes before collecting outputs (0–30000) |
| `navigation.timeoutMs` | `number` | `30000`              | Max time (ms) to wait for navigation (1–60000)                                      |

## Cache Controls

Control caching behavior for fetch results:

| Field                 | Type     | Default | Description                                                                                         |
| --------------------- | -------- | ------- | --------------------------------------------------------------------------------------------------- |
| `cache.maxAgeSeconds` | `number` | —       | Cache control—cached results older than this are treated as stale. Set to `0` to bypass cache reads |

<Info>
  Using cache can improve response times for frequently accessed pages. Set `maxAgeSeconds` based on how fresh you need the data to be.
</Info>

***

## X402 Support

For agentic workflows, Hyperbrowser supports x402 payment for the Fetch API, enabling agents to programmatically pay for browser sessions at request time using USDC, with payment handled inline via HTTP 402 responses. See the [X402 Integration](/integrations/x402) page for details.
