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

# Scrape URL

> Scrape any public URL and get cleaned markdown, HTML, links, or structured JSON

Scrape a public URL and receive cleaned output in one or more formats: markdown, HTML, raw HTML, links, a summary, a screenshot, or LLM-extracted JSON.

Runs synchronously by default. Set `mode` to `async` to get a `scrape_id` back immediately and poll [Scrape Status](/rest-api-reference/web-scrape-status) for the result.

## Request Body

<ParamField body="url" type="string" required>
  The URL to scrape. Must be a valid, publicly accessible URL.
</ParamField>

<ParamField body="mode" type="string" default="sync">
  `sync` waits for the result; `async` returns `202` with a `scrape_id` to poll.
</ParamField>

<ParamField body="timeout" type="number">
  Max time in milliseconds to wait for a sync result. Between `1000` and
  `600000`.
</ParamField>

<ParamField body="output" type="object">
  Output options. - `formats` (string\[], default `["markdown"]`) — any of
  `html`, `raw_html`, `markdown`, `links`, `summary`, `screenshot`, `json` -
  `screenshot` (`viewport` | `full_page`) — screenshot capture mode - `json`
  (object) — `prompt` and/or `json_schema` for structured extraction
</ParamField>

<ParamField body="breakdown" type="boolean" default="false">
  When `true`, JSON extraction also returns the selector recipe used
  (`data.json_recipe`).
</ParamField>

<ParamField body="proxy" type="object">
  Proxy options: `location` (country code, default `US`) and `sticky_session`.
</ParamField>

<ParamField body="request" type="object">
  Request options: `locale`, `device` (`desktop` | `mobile`), `cookies`,
  `headers`, `only_main_content` (default `true`), `block_ads` (default `true`),
  `skip_tls_verification` (default `true`).
</ParamField>

<ParamField body="js_render" type="object">
  JavaScript rendering: `enabled` (default `true`), `wait_until` (`load` | `domcontentloaded` | `networkidle`), `viewport` (`{ width, height }`).
</ParamField>

<ParamField body="webhook" type="object">
  Delivery webhook for async jobs: `url`, optional `headers`, `events` (default
  `["started", "completed", "failed"]`).
</ParamField>

## Response

<ResponseField name="scrape_id" type="string">
  Unique ID for this scrape job.
</ResponseField>

<ResponseField name="status" type="string">
  `pending`, `completed`, or `failed`.
</ResponseField>

<ResponseField name="data" type="object">
  Present when completed. Contains the requested formats — `markdown`, `html`,
  `raw_html`, `links`, `summary`, `json`, `screenshot` (key for [Get
  Screenshot](/rest-api-reference/web-screenshot)) — plus page `metadata`.
</ResponseField>

<RequestExample>
  ```bash sync theme={null}
  curl -X POST https://scrape.st/web/scrape \
    -H "x-api-key: YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "url": "https://example.com",
      "output": { "formats": ["markdown", "links"] }
    }'
  ```

  ```bash async theme={null}
  curl -X POST https://scrape.st/web/scrape \
    -H "x-api-key: YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "url": "https://example.com",
      "mode": "async"
    }'
  ```
</RequestExample>

<ResponseExample>
  ```json sync theme={null}
  {
    "scrape_id": "scr_01HZX...",
    "version": "1.0.0",
    "status": "completed",
    "url": "https://example.com",
    "data": {
      "markdown": "# Example Domain\n\nThis domain is for use in illustrative examples...",
      "links": ["https://www.iana.org/domains/example"],
      "metadata": {
        "title": "Example Domain",
        "status_code": 200,
        "final_url": "https://example.com/"
      }
    },
    "started_at": "2026-06-12T10:00:00.000Z",
    "ended_at": "2026-06-12T10:00:04.200Z"
  }
  ```

  ```json async (202) theme={null}
  {
    "scrape_id": "scr_01HZX...",
    "version": "1.0.0",
    "status": "pending"
  }
  ```
</ResponseExample>
