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

# Extract

> POST /v1/extract — extract structured data from a page using a JSON schema, CSS selectors, or XPath.

# Extract structured data

`POST /v1/extract` fetches a URL and pulls **structured data** out of it using one of
three extraction methods. It returns typed JSON instead of raw Markdown.

<Info>
  **Authentication:** API key **or** x402 payment.
</Info>

## Endpoint

```
POST https://api.tazpal.com/v1/extract
```

## Request

### Body

| Field       | Type   | Required       | Description                              |
| ----------- | ------ | -------------- | ---------------------------------------- |
| `url`       | string | ✅              | Target URL to extract data from          |
| `schema`    | object | *at least one* | JSON schema describing fields to extract |
| `selectors` | object | *at least one* | CSS selectors to extract                 |
| `xpaths`    | object | *at least one* | XPath 1.0 queries to extract             |
| `options`   | object | no             | Extraction options (see below)           |

Provide **at least one** of `schema`, `selectors`, or `xpaths`. When multiple are
given, priority is `schema` > `selectors` > `xpaths`.

### `options` object

| Field           | Type    | Default | Description                                |
| --------------- | ------- | ------- | ------------------------------------------ |
| `format`        | string  | `json`  | Output format (currently `json`)           |
| `wait_for`      | string  | —       | CSS selector to wait for before extraction |
| `timeout`       | integer | `30000` | Navigation timeout in ms (1000–120000)     |
| `block_media`   | boolean | `true`  | Block image/font/video requests            |
| `wait_strategy` | string  | auto    | `default`, `spa`, `heavy`, `cloudflare`    |
| `javascript`    | string  | —       | Custom JS to execute after page load       |
| `proxy_url`     | string  | —       | Explicit proxy                             |
| `retry`         | boolean | `true`  | Retry on failure                           |
| `bypass_cache`  | boolean | `false` | Skip the response cache                    |

## Response

### Success — `200 OK`

| Field      | Type           | Description                                                |
| ---------- | -------------- | ---------------------------------------------------------- |
| `status`   | integer        | Always `200`                                               |
| `url`      | string         | The extracted URL                                          |
| `data`     | object         | Extracted fields (keys match your schema/selectors/xpaths) |
| `metadata` | object         | Extraction metadata                                        |
| `payment`  | object \| null | x402 settlement result                                     |

**`metadata` shape:**

| Field                | Type    | Description                                  |
| -------------------- | ------- | -------------------------------------------- |
| `extraction_method`  | string  | `schema`, `css_selector`, `xpath`, or `none` |
| `confidence`         | number  | 0.0–1.0 confidence score                     |
| `processing_time_ms` | integer | End-to-end processing time                   |

## Examples

### Schema-based extraction

The schema engine layers multiple signals: JSON-LD (highest confidence), meta tags,
semantic CSS selectors, then a generic attribute/class fallback.

<CodeGroup>
  ```bash theme={null}
  curl -X POST https://api.tazpal.com/v1/extract \
    -H "Authorization: Bearer baas_live_YOUR_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "url": "https://example.com/product/123",
      "schema": {
        "type": "object",
        "properties": {
          "title": {"type": "string"},
          "price": {"type": "number"},
          "description": {"type": "string"},
          "in_stock": {"type": "boolean"}
        }
      }
    }'
  ```

  ```python theme={null}
  import httpx

  resp = httpx.post(
      "https://api.tazpal.com/v1/extract",
      headers={"Authorization": "Bearer baas_live_YOUR_KEY"},
      json={
          "url": "https://example.com/product/123",
          "schema": {
              "type": "object",
              "properties": {
                  "title": {"type": "string"},
                  "price": {"type": "number"},
                  "description": {"type": "string"},
                  "in_stock": {"type": "boolean"},
              },
          },
      },
  )
  print(resp.json())
  ```
</CodeGroup>

```json Response theme={null}
{
  "status": 200,
  "url": "https://example.com/product/123",
  "data": {
    "title": "Acme Widget",
    "price": 19.99,
    "description": "The original Acme widget.",
    "in_stock": true
  },
  "metadata": {
    "extraction_method": "schema",
    "confidence": 0.85,
    "processing_time_ms": 1520
  },
  "payment": null
}
```

### CSS selector extraction

Selectors can be a plain string or an object with `selector`, `attribute`, `type`
(`list`), and nested `fields`:

```python theme={null}
import httpx

resp = httpx.post(
    "https://api.tazpal.com/v1/extract",
    headers={"Authorization": "Bearer baas_live_YOUR_KEY"},
    json={
        "url": "https://example.com/products",
        "selectors": {
            "heading": "h1",
            "product_links": {"selector": "a.product", "attribute": "href", "type": "list"},
        },
    },
)
print(resp.json()["data"])
```

### XPath extraction

```python theme={null}
import httpx

resp = httpx.post(
    "https://api.tazpal.com/v1/extract",
    headers={"Authorization": "Bearer baas_live_YOUR_KEY"},
    json={
        "url": "https://example.com",
        "xpaths": {
            "title": "//h1/text()",
            "links": "//a/@href",
        },
    },
)
print(resp.json()["data"])
```

## Errors

| Status | `detail.error`      | Meaning                                        |
| ------ | ------------------- | ---------------------------------------------- |
| `400`  | `invalid_request`   | No `schema`, `selectors`, or `xpaths` provided |
| `400`  | `connection_failed` | URL unreachable                                |
| `401`  | `unauthorized`      | Missing or invalid credentials                 |
| `429`  | `rate_limited`      | Rate limit exceeded                            |
| `500`  | `extract_failed`    | Extraction engine failure                      |
| `504`  | `timeout`           | Navigation timed out                           |

<Note>
  Fields that can't be extracted are returned as `null` with a lower confidence score,
  rather than failing the whole request.
</Note>
