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

# Extract

> Turn any web page into structured JSON in a single request with ZenRows Extract, a private beta feature that builds a tailored extraction for each website and keeps it working when the site's layout changes.

Extract turns a web page into structured JSON in a single request. Add `extract=auto` to your Universal Scraper API call, and ZenRows identifies the meaningful data on the page and returns it as clean JSON, together with the raw HTML. There are no selectors to write, no schema to define, and no parser to maintain. The extraction adapts automatically when a website changes its layout.

<Note>
  Extract is currently in **private beta** and works on a curated set of domains. Any active ZenRows API key can use it on the enabled domains, with no extra setup needed. To get more domains enabled, contact ZenRows support.
</Note>

## How Extract works

Unlike general-purpose parsing rules that apply the same logic to every website, Extract builds and maintains an extraction that's tailored to each individual site. ZenRows analyzes the pages on an enabled domain, identifies its meaningful data points, and keeps that extraction working as the site evolves, so you get richer and more complete fields than a one-size-fits-all approach can offer.

During the private beta, this tailored extraction is only available for domains the ZenRows team has prepared and enabled. Coverage expands throughout the beta as more domains are onboarded.

## Basic usage

Enable Extract by adding the `extract=auto` parameter to your ZenRows request:

<CodeGroup>
  ```python Python theme={null}
  # pip install requests
  import requests

  url = 'https://www.scrapingcourse.com/ecommerce/'
  apikey = 'YOUR_ZENROWS_API_KEY'
  params = {
      'url': url,
      'apikey': apikey,
      'extract': 'auto',
  }
  response = requests.get('https://api.zenrows.com/v1/', params=params)
  print(response.json())
  ```

  ```javascript Node.js theme={null}
  // npm install axios
  const axios = require('axios');

  const url = 'https://www.scrapingcourse.com/ecommerce/';
  const apikey = 'YOUR_ZENROWS_API_KEY';
  axios({
      url: 'https://api.zenrows.com/v1/',
      method: 'GET',
      params: {
          'url': url,
          'apikey': apikey,
          'extract': 'auto',
      },
  })
      .then(response => console.log(response.data))
      .catch(error => console.log(error));
  ```

  ```java Java theme={null}
  import org.apache.hc.client5.http.fluent.Request;

  public class APIRequest {
      public static void main(final String... args) throws Exception {
          String apiUrl = "https://api.zenrows.com/v1/?apikey=YOUR_ZENROWS_API_KEY&url=https%3A%2F%2Fwww.scrapingcourse.com%2Fecommerce%2F&extract=auto";
          String response = Request.get(apiUrl)
                  .execute().returnContent().asString();

          System.out.println(response);
      }
  }
  ```

  ```php PHP theme={null}
  <?php
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, 'https://api.zenrows.com/v1/?apikey=YOUR_ZENROWS_API_KEY&url=https%3A%2F%2Fwww.scrapingcourse.com%2Fecommerce%2F&extract=auto');
  curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  $response = curl_exec($ch);
  echo $response . PHP_EOL;
  curl_close($ch);
  ?>
  ```

  ```go Go theme={null}
  package main

  import (
      "io"
      "log"
      "net/http"
  )

  func main() {
      client := &http.Client{}
      req, err := http.NewRequest("GET", "https://api.zenrows.com/v1/?apikey=YOUR_ZENROWS_API_KEY&url=https%3A%2F%2Fwww.scrapingcourse.com%2Fecommerce%2F&extract=auto", nil)
      if err != nil {
          log.Fatalln(err)
      }
      resp, err := client.Do(req)
      if err != nil {
          log.Fatalln(err)
      }
      defer resp.Body.Close()

      body, err := io.ReadAll(resp.Body)
      if err != nil {
          log.Fatalln(err)
      }

      log.Println(string(body))
  }
  ```

  ```ruby Ruby theme={null}
  # gem install faraday
  require 'faraday'

  url = URI.parse('https://api.zenrows.com/v1/?apikey=YOUR_ZENROWS_API_KEY&url=https%3A%2F%2Fwww.scrapingcourse.com%2Fecommerce%2F&extract=auto')
  conn = Faraday.new()
  conn.options.timeout = 180
  res = conn.get(url, nil, nil)
  print(res.body)
  ```

  ```bash cURL theme={null}
  curl "https://api.zenrows.com/v1/?apikey=YOUR_ZENROWS_API_KEY&url=https%3A%2F%2Fwww.scrapingcourse.com%2Fecommerce%2F&extract=auto"
  ```
</CodeGroup>

This example extracts structured data from the Scraping Course eCommerce page. Instead of raw HTML alone, you get a JSON response with the meaningful data ZenRows identified on the page, plus the original HTML for reference.

## Response

A request with `extract=auto` returns `Content-Type: application/json` with two fields:

```json JSON theme={null}
{
  "html": "<!DOCTYPE html><html>...</html>",
  "parsed": {
    "products": [
      {
        "name": "Abominable Hoodie",
        "price": "69.00",
        "currency": "USD",
        "image_url": "https://www.scrapingcourse.com/.../mh09-blue_main.jpg",
        "product_url": "https://www.scrapingcourse.com/ecommerce/product/abominable-hoodie/"
      }
    ]
  }
}
```

* **`parsed`** contains the structured data extracted from the page.
* **`html`** contains the raw HTML of the scraped page. It's included during the beta so you can validate the extracted data against the source.

Field names are in plain English and reflect the data each website actually exposes, so different websites can return different fields for similar pages. The set of fields inside `parsed` stays stable across requests for a given website, and new fields may be added over time as extraction improves, so treat unknown fields as additive rather than breaking. The `html` field is included for validation during the beta, and the overall response shape may evolve once the beta ends, so build your data pipeline around `parsed` and treat `html` as a validation aid rather than a permanent contract.

<Warning>Extraction is fully automatic, and a field is only returned when it's present on the page. Always run test requests on your target pages and verify all the data you need is extracted before using Extract in production.</Warning>

## Coverage during the private beta

Extract is enabled per domain, not per account. The ZenRows team prepares and enables each domain, and once a domain is enabled, it works for every ZenRows API key, so there's no customer allowlist to manage on your side.

If you send `extract=auto` for a domain that isn't enabled yet, the request fails with a `402` error (`AUTH010`) explaining that the domain isn't part of the beta. To get a domain enabled, contact ZenRows support and the team will onboard it.

<Tip>Coverage expands throughout the beta. If a domain you need isn't enabled yet, reach out to support rather than assuming it will never be available.</Tip>

## Combining with other features

Extract works on the final HTML of the page, so it combines with the scraping features you already use. For JavaScript-heavy websites, add JavaScript Rendering with a short wait so dynamic content finishes loading before extraction. For protected websites, add Premium Proxy:

<CodeGroup>
  ```python Python theme={null}
  # pip install requests
  import requests

  url = 'https://www.scrapingcourse.com/ecommerce/'
  apikey = 'YOUR_ZENROWS_API_KEY'
  params = {
      'url': url,
      'apikey': apikey,
      'extract': 'auto',
      'js_render': 'true',
      'wait': '3000',
      'premium_proxy': 'true',
  }
  response = requests.get('https://api.zenrows.com/v1/', params=params)
  print(response.json())
  ```

  ```bash cURL theme={null}
  curl "https://api.zenrows.com/v1/?apikey=YOUR_ZENROWS_API_KEY&url=https%3A%2F%2Fwww.scrapingcourse.com%2Fecommerce%2F&extract=auto&js_render=true&wait=3000&premium_proxy=true"
  ```
</CodeGroup>

<Note>When `extract=auto` is set, it takes precedence over other output formats. `autoparse`, `css_extractor`, `response_type`, and `outputs` are ignored on that request.</Note>

## Extract vs. Autoparse vs. CSS Extractor

| Method                              | Best for                                               | Pros                                                                           | Cons                                                   |
| ----------------------------------- | ------------------------------------------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------ |
| **Extract** (`extract=auto`)        | Enabled domains where you want the richest data        | Tailored to each website, adapts when the site's layout changes, richer fields | Only available on domains enabled for the private beta |
| **Autoparse** (`autoparse=true`)    | Quick, general-purpose extraction on any website       | Works on any site, no setup, included at no extra cost                         | General-purpose rules, may miss specific fields        |
| **CSS Extractor** (`css_extractor`) | Specific data points, single site, custom requirements | Full control, precise targeting                                                | Requires HTML knowledge, selectors are site-specific   |

## Pricing

Extract is **free during the private beta**. You only pay the standard Universal Scraper API cost of the underlying request, including JavaScript Rendering or Premium Proxy if you use them.

<Tip>
  You can monitor your ZenRows usage in multiple ways to stay informed about your account activity and prevent unexpected overages.

  **Dashboard monitoring**: View real-time usage statistics, remaining requests, success rates, and request history on your [Analytics Page](https://app.zenrows.com/analytics/scraper-api). You can also set up usage alerts in your [notification settings](https://app.zenrows.com/account/notifications) to receive notifications when you approach your limits.

  **Programmatic monitoring**: For automated monitoring in your applications, call the `/v1/subscriptions/self/details` endpoint with your API key in the `X-API-Key` header. This returns real-time usage data that you can integrate into your monitoring systems. [Learn more about the usage endpoint](/universal-scraper-api/features/other#plan-usage).

  **Response header monitoring**: Track your concurrency usage through response headers included with each request:

  * `Concurrency-Limit`: Your maximum concurrent requests
  * `Concurrency-Remaining`: Available concurrent request slots
  * `X-Request-Cost`: Cost of the current request
</Tip>

## Frequently Asked Questions (FAQ)

<AccordionGroup>
  <Accordion title="How is Extract different from Autoparse?">
    Autoparse (`autoparse=true`) applies general-purpose extraction rules that work the same way on every website. Extract (`extract=auto`) builds an extraction tailored to each website, which returns richer, more complete fields and adjusts itself when the website's layout changes. During the beta, Extract works only on enabled domains, while Autoparse remains available on any website.
  </Accordion>

  <Accordion title="What happens on a domain that isn't enabled yet?">
    The request fails with a `402` error (`AUTH010`) stating that the domain isn't enabled for the private beta. Contact ZenRows support to get additional domains onboarded, usually within a short time.
  </Accordion>

  <Accordion title="Will the extracted fields change over time?">
    The response shape for an enabled website stays stable. Your integration keeps receiving the same fields even as ZenRows improves extraction behind the scenes. New fields may be added over time, so treat unknown fields as additive rather than breaking.
  </Accordion>

  <Accordion title="Do I need to sign up separately to use Extract?">
    No. Access is per domain, not per account. Any active ZenRows API key can use `extract=auto` on a domain once that domain is enabled for the beta. There's no separate signup or plan change required.
  </Accordion>

  <Accordion title="Can I rely on the html field long term?">
    Treat `html` as a validation aid rather than a permanent part of the contract. It's included during the beta so you can check the extracted data against the source page. Build your data pipeline around `parsed`, since the surrounding response shape may evolve once the beta ends.
  </Accordion>

  <Accordion title="Can I combine Extract with other ZenRows features?">
    Yes. Extract works alongside JavaScript Rendering, Premium Proxy, and other request options. It takes precedence over other output formats, so `autoparse`, `css_extractor`, `response_type`, and `outputs` are ignored on a request that sets `extract=auto`.
  </Accordion>
</AccordionGroup>
