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

# POST /api/openclaw/scrape — extract page data

> Extract structured data from any public web page using OpenClaw. Returns title, headings, links, and full text. Costs 10 credits per call.

The `/api/openclaw/scrape` endpoint fetches a public web page and returns structured data: the page title, meta description, headings, links, and readable text content. Scripts, styles, navigation, and footer elements are stripped before the text is extracted. The endpoint costs **10 credits** per successful call — credits are refunded automatically if the fetch fails.

## Request

**Method:** `POST`\
**URL:** `https://onyxiq.in/api/openclaw/scrape`\
**Authentication:** Required (session cookie). Returns `401` if missing.\
**Content-Type:** `application/json`

### Body parameters

<ParamField body="url" type="string" required>
  The public HTTP or HTTPS URL of the page to scrape. Must be a fully-qualified URL with a valid `http:` or `https:` scheme. Relative paths and other protocols are rejected.
</ParamField>

## Response

### 200 — success

<Note>
  Credits are only deducted when the endpoint returns a `200` response. If the fetch fails for any reason, the 10 credits are refunded to your account automatically.
</Note>

<ResponseField name="ok" type="boolean" required>
  Always `true` on a successful response.
</ResponseField>

<ResponseField name="data" type="object" required>
  The scraped page data.

  <Expandable title="properties" defaultOpen>
    <ResponseField name="url" type="string">
      The normalized URL that was scraped.
    </ResponseField>

    <ResponseField name="title" type="string">
      The page `<title>` element text, trimmed to 300 characters.
    </ResponseField>

    <ResponseField name="description" type="string">
      The `<meta name="description">` content, trimmed to 500 characters. Empty string if absent.
    </ResponseField>

    <ResponseField name="h1" type="string">
      Text of the first `<h1>` element, trimmed to 300 characters. Empty string if absent.
    </ResponseField>

    <ResponseField name="headings" type="object[]">
      Up to 20 `<h2>` and `<h3>` headings found on the page (in document order).

      <Expandable title="heading object properties">
        <ResponseField name="tag" type="string">
          The heading tag in lowercase: `"h2"` or `"h3"`.
        </ResponseField>

        <ResponseField name="text" type="string">
          The heading text, trimmed to 300 characters.
        </ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="links" type="object[]">
      Up to 30 anchor links found on the page, with relative hrefs resolved against the target URL.

      <Expandable title="link object properties">
        <ResponseField name="text" type="string">
          The visible link text (or the resolved href if the link has no text), trimmed to 180 characters.
        </ResponseField>

        <ResponseField name="href" type="string">
          The resolved absolute URL of the link.
        </ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="text" type="string">
      The full readable text content of the page body after removing scripts, styles, nav, header, and footer elements. Trimmed to 3,000 characters.
    </ResponseField>

    <ResponseField name="scrapedAt" type="string">
      ISO 8601 timestamp of when the scrape completed (e.g. `"2026-05-18T10:00:00.000Z"`).
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="creditsUsed" type="number" required>
  Number of credits deducted for this request. Always `10`.
</ResponseField>

<ResponseField name="remainingBalance" type="number" required>
  Your credit balance after the deduction.
</ResponseField>

### Error responses

| Status | `error` message                                                     | Cause                                                                                       |
| ------ | ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
| `400`  | `"Enter a valid HTTP or HTTPS URL."`                                | The `url` field is missing, not a string, or uses an unsupported protocol.                  |
| `400`  | `"Invalid JSON"`                                                    | The request body is not valid JSON.                                                         |
| `401`  | `"Authentication required"`                                         | No valid session cookie was found. [Sign in](https://onyxiq.in/login) first.                |
| `402`  | `"Insufficient credits. 10 credits required, N available."`         | Your balance is below 10. [Top up](https://onyxiq.in/credits) your account.                 |
| `502`  | `"OpenClaw could not fetch that page. Your credits were refunded."` | The target server was unreachable or returned an error. Credits are automatically refunded. |

## Examples

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://onyxiq.in/api/openclaw/scrape \
    -H "Content-Type: application/json" \
    -H "Cookie: sb-[ref]-auth-token=[token]" \
    -d '{"url":"https://example.com"}'
  ```

  ```javascript JavaScript (fetch) theme={null}
  const response = await fetch("https://onyxiq.in/api/openclaw/scrape", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      // In the browser, credentials: "include" sends the cookie automatically.
      // From Node.js, copy and paste your cookie value here:
      // "Cookie": "sb-[ref]-auth-token=[token]",
    },
    credentials: "include", // browser only
    body: JSON.stringify({ url: "https://example.com" }),
  });

  const result = await response.json();

  if (!response.ok) {
    console.error("Error:", result.error);
  } else {
    console.log("Title:", result.data.title);
    console.log("Credits remaining:", result.remainingBalance);
  }
  ```
</CodeGroup>

### Example success response

```json theme={null}
{
  "ok": true,
  "data": {
    "url": "https://example.com",
    "title": "Example Domain",
    "description": "",
    "h1": "Example Domain",
    "headings": [],
    "links": [
      {
        "text": "More information...",
        "href": "https://www.iana.org/domains/reserved"
      }
    ],
    "text": "Example Domain This domain is for use in illustrative examples in documents. You may use this domain in literature without prior coordination or asking for permission.",
    "scrapedAt": "2026-05-18T10:00:00.000Z"
  },
  "creditsUsed": 10,
  "remainingBalance": 90
}
```
