Title: x402 page scrape API
Source: https://nodely.io/docs/x402/scrape/

# x402 page scrape API

This API fetches one web page and returns its content as markdown, HTML or a list of links. It renders the page in a headless browser when the page needs one. It costs **0.011 USDC per page** on Algorand and **0.012 USDC** on Base or Arc, paid with [x402](https://nodely.io/docs/x402/payment).

-   Endpoint: `POST https://x402.api.nodely.io/v1/scrape`. `GET` with query parameters also works; separate list values with commas.
-   One public `http(s)` URL per call.
-   A page that fails, times out or answers with HTTP 4xx/5xx isn’t charged.

<a id="request"></a>

## Request

Field names follow Firecrawl v2. The API accepts both camelCase and snake\_case names.

| Field | Type | Notes |
| --- | --- | --- |
| `url` | string, up to 2048 chars | Required. Must be `http` or `https` with a public DNS name |
| `formats` | array of `markdown`, `html`, `rawHtml`, `links` | Default `["markdown"]` |
| `only_main_content` | boolean, default true | Removes navigation, headers and footers. Alias: `onlyMainContent` |
| `include_tags`, `exclude_tags` | string array, up to 50 | Alias: `includeTags`, `excludeTags` |
| `wait_for` | integer ms, 0–10000 | Wait after the page loads. At most half the timeout. Alias: `waitFor` |
| `mobile` | boolean, default false | Render as a mobile browser |
| `timeout` | integer ms | At most 20 s, limited by the payment’s validity window |

```json
{ "url": "https://example.org/", "formats": ["markdown", "links"] }
```

The API refuses these URLs with `400` before you pay anything:

-   URLs with credentials
-   IP addresses instead of host names
-   private names such as `localhost`, `*.local`, `*.internal`, `*.lan` and single-label hosts

<a id="response"></a>

## Response

```json
{
  "url": "https://example.org/",
  "data": {
    "markdown": "# Example Domain\n\nThis domain is for use in documentation examples.",
    "links": ["https://www.iana.org/domains/example"],
    "metadata": {
      "title": "Example Domain",
      "sourceURL": "https://example.org/",
      "url": "https://example.org/",
      "statusCode": 200,
      "contentType": "text/html"
    }
  },
  "warnings": [],
  "request_id": "…",
  "response_time": 1.7
}
```

`data` follows Firecrawl v2’s scrape data format. The `PAYMENT-RESPONSE` header confirms the payment; on Algorand it holds the payment’s transaction id.

<a id="limits-and-charging"></a>

## Limits and charging

-   The scrape must finish while the payment is still valid. The deadline is whatever time the payment’s validity window has left, up to 20 s.
-   On Algorand, if the window has less than 3 s left, the API refuses the request with `402 invalid_exact_avm_validity_window` and fetches nothing.
-   The API charges only when it delivers the page and the page answered with a status below 400.
-   A failed scrape (`502 scrape_failed`) or a timeout (`504 scrape_timeout`) isn’t charged. You can retry it with the same payment a limited number of times.

<a id="examples"></a>

## Examples

Show the 402 offer without paying:

```bash
curl -si -X POST https://x402.api.nodely.io/v1/scrape \
  -H 'Content-Type: application/json' \
  -d '{"url":"https://example.org/"}'
```

Paid request with the Node.js client from [Pricing & payment](https://nodely.io/docs/x402/payment#client-example-nodejs):

```js
const res = await paidFetch("https://x402.api.nodely.io/v1/scrape", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ url: "https://example.org/", formats: ["markdown"] }),
});
const { data } = await res.json();
console.log(data.markdown);
```

The full schema is in the [live API reference](https://x402.api.nodely.io/docs/).
