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

# Scrape

> Extract content from any public URL as Markdown, structured JSON, or raw HTML.

# Scrape

`POST /scrape` runs a synchronous scrape on a URL and returns content in the
requested formats. Messora's native anti-bot engine handles protections
automatically.

## Endpoint

```
POST /scrape
```

## Authentication

`X-API-Key` header required. See [Authentication](/en/authentication).

## Parameters

<ParamField body="url" type="string" required>
  Public URL to scrape. Internal URLs (RFC1918, loopback, cloud metadata) are rejected by the SSRF guard.
</ParamField>

<ParamField body="formats" type="string[]" default="[&#x22;markdown&#x22;]">
  Desired output formats. Accepted values: `markdown`, `json`, `raw`.
</ParamField>

<ParamField body="json_schema" type="object">
  JSON schema for structured extraction. **Required** when `formats` includes `json`.
</ParamField>

<ParamField body="json_prompt" type="string">
  Context prompt to guide structured extraction (used with `json_schema`).
</ParamField>

<ParamField body="render_js" type="boolean" default="false">
  If `true`, render JavaScript before extraction (headless browser).
</ParamField>

<ParamField body="only_main_content" type="boolean" default="false">
  If `true`, extract only the main page content, removing navigation, footers, and sidebars.
</ParamField>

<ParamField body="timeout" type="integer" default="60">
  Maximum wait time in seconds (1–180).
</ParamField>

<ParamField body="wait_for" type="integer">
  Extra wait in milliseconds after load (useful with `render_js`).
</ParamField>

<ParamField body="tags" type="string[]">
  Attribution tags for usage records (up to 10 tags).
</ParamField>

## Cost

| Format                         | Credits                |
| ------------------------------ | ---------------------- |
| `markdown` or `raw`            | 1 credit per page      |
| `json` (structured extraction) | 10 credits per request |

<Note>
  Failures (`blocked_antibot`, `timeout`, `extraction_failed`) do **not** consume credits.
</Note>

## Example

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.messora.dev/scrape \
    -H "Content-Type: application/json" \
    -H "X-API-Key: YOUR_API_KEY" \
    -d '{
      "url": "https://example.com",
      "formats": ["markdown"],
      "only_main_content": true
    }'
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      "https://api.messora.dev/scrape",
      headers={
          "Content-Type": "application/json",
          "X-API-Key": "YOUR_API_KEY",
      },
      json={
          "url": "https://example.com",
          "formats": ["markdown"],
          "only_main_content": True,
      },
  )

  data = response.json()
  print(data["markdown"])
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch("https://api.messora.dev/scrape", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-API-Key": "YOUR_API_KEY",
    },
    body: JSON.stringify({
      url: "https://example.com",
      formats: ["markdown"],
      only_main_content: true,
    }),
  });

  const data = await response.json();
  console.log(data.markdown);
  ```
</CodeGroup>

## Successful response

```json theme={null}
{
  "success": true,
  "scrape_status": "success",
  "markdown": "# Example Domain\n\nThis domain is for use in illustrative examples...",
  "credits_used": 1,
  "remaining_credits": 99
}
```

## Structured extraction (JSON)

To extract structured data, include `json` in `formats` and provide a `json_schema`:

```bash theme={null}
curl -X POST https://api.messora.dev/scrape \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{
    "url": "https://example.com/product",
    "formats": ["json"],
    "json_schema": {
      "type": "object",
      "properties": {
        "title": {"type": "string"},
        "price": {"type": "number"},
        "available": {"type": "boolean"}
      },
      "required": ["title", "price"]
    }
  }'
```

<Warning>
  Structured extraction costs **10 credits** per request (regardless of outcome).
</Warning>

## Response status

| `scrape_status`     | Meaning                        | Credits charged |
| ------------------- | ------------------------------ | --------------- |
| `success`           | Content extracted successfully | Yes             |
| `blocked_antibot`   | Target blocked the extraction  | No              |
| `timeout`           | Time limit exceeded            | No              |
| `extraction_failed` | Content extraction failed      | No              |

## Errors

| HTTP Status | Description                                                                          |
| ----------- | ------------------------------------------------------------------------------------ |
| `401`       | Missing `X-API-Key`                                                                  |
| `403`       | Invalid or revoked API key                                                           |
| `422`       | Internal URL (SSRF), invalid parameters, or missing `json_schema` with `json` format |
| `429`       | Rate limit exceeded (10 req/min)                                                     |
