Skip to main content
Extract turns a web page into structured JSON in a single request. Add extract=auto to your Fetch 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.
Extract works on any prepared domain, with any active Zenrows API key and no extra setup. You can prepare a new domain yourself.

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 a domain’s pages, 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. That tailoring is per domain, so a domain has to be prepared before Extract can serve it. You can prepare one yourself: see Domain coverage.

Basic usage

Enable Extract by adding the extract=auto parameter to your Zenrows request:
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.

Parameters

Extract adds two parameters to a Fetch request. Every other Fetch parameter keeps working alongside them.

Response

A request with extract=auto returns Content-Type: application/json with two fields:
JSON
  • parsed contains the structured data extracted from the page.
  • html contains the raw HTML of the scraped page. It’s included 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, and the response shape around parsed may evolve, so build your data pipeline around parsed and treat html as a validation aid rather than a permanent contract.
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.

Selecting the fields you need

parsed carries every field Extract found on the page. Add extract_fields with a comma-separated list to get back only the ones your pipeline reads:
Response
How the list is read:
  • A bare name selects a whole group. extract_fields=products returns every product with all of its fields.
  • A dot path selects inside a group, element by element. products.name returns the name of every product in the list, not only the first one.
  • Spaces after commas are ignored. products.name, products.price selects the same fields as products.name,products.price.
  • Only parsed is filtered. The html field always comes back in full.
  • Filtering never adds a field. Naming something the page doesn’t provide doesn’t produce an empty field, it just isn’t there.
It works the same way in every extraction mode, so a standard request can be narrowed with the canonical field names: extract=standard&extract_fields=listings.title,listings.price.
Field names come from each website, so they differ from site to site in the default mode. Send one request without extract_fields first, read the names in parsed, then pin the ones you want.

When none of the requested fields exist

A name that matches nothing is ignored as long as at least one other name in the list does match, so a typo costs you that field quietly. When no name matches, the request fails with 400 (REQS004) rather than returning an empty object, and the message lists the fields the page does offer:
Response

Extraction modes

The value of extract also picks which extraction resolves for the page: Stay on auto unless you’re merging pages from several websites into one table, which is the job standard exists for. The trade is richness for uniformity: a native extraction returns everything a given site exposes, and a standard one returns the agreed set.
The mode is an API-level parameter. The playground in your dashboard runs the default extraction and lists standard as coming soon, so pick a mode from a direct API request or from an SDK, which passes the parameter straight through.
The difference is visible on two real-estate search pages from different websites. In the default mode, each site names things its own way, one calling floor area construction_area_m2 and the other area_sqm, one splitting the price into price and price_currency, the other into price_amount and price_currency. In standard, both return the same field names:
Response
standard currently covers real estate only, both search results and listing pages. A page in any other vertical is rejected with 400 (REQS004), so use auto or native everywhere else.
Any value other than the three above is rejected before the page is even fetched, with 400 (REQS004) and the message Invalid value "..." for 'extract' parameter. Supported values: auto, native, standard.

Domain coverage

Extract works on a domain once that domain has been prepared: Zenrows learns the shapes of its pages and checks that extraction returns the right data. A prepared domain then works for every Zenrows API key, so coverage is per domain and never per account, and there is no allowlist to manage on your side. The exception is a site Extract is not enabled for: its REQS007 title says Extract is not enabled for the requested domain, and preparing it does not help. Use css_extractor there, or contact support to have the site enabled. Many domains are prepared already, and the set grows as people ask for the sites they need.

Checking whether a domain is ready

GET /v1/extract/domains returns everything Extract serves right now:
cURL
Response
An integration can check this before sending a request instead of handling an error after one. See the endpoint reference for the full response.

Asking for a domain

If the domain you need isn’t there, ask for it. This request sends three product pages from the same site:
cURL
Preparation takes a few minutes and costs no credits. Poll GET /v1/extract/prepared-domains/{domain} about every 30 seconds until status is ready, then send your extract=auto request as normal. The domain is the host: a leading www. is dropped, and any other subdomain is prepared on its own.

Choosing example URLs

example_urls takes 1 to 5 URLs, and they tell Zenrows exactly which pages to prepare.
  • One works. Extract prepares the page type it points at.
  • We recommend 3 or more of the same page type (e.g. 3 product pages, as in the example above), because Extract compares pages of one type to check the fields it found and fill in fields one page is missing.
  • Several page types can share the 5 (e.g. 3 product pages + 2 search-result pages).
Each account can prepare a set number of new domains per month; the endpoint reference covers how to check what’s left. If you send extract=auto for a domain that isn’t prepared, the request fails with a 403 error (REQS007) whose title says Extract is not prepared for the requested domain, and the message tells you how to prepare it. On a prepared domain, the same error can instead have a title that says Extract did not recognise this page. That means the page may have nothing to extract, such as a home page. Try a product, article or listing page instead, retry once in a few minutes if the page should work, or use css_extractor. Preparing the domain again does not change this error. Neither request is charged, and nothing about your plan or your account changes either outcome. If Extract knows the page type but none of the fields come back filled (with extract_fields, none of the ones you asked for, as long as they exist; names that match nothing are REQS004), the request fails with a 422 error (no_data_extracted) rather than returning 200 with an empty parsed object. That request is not charged, and it doesn’t return the raw HTML.

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:
When extract=auto is set, it takes precedence over other output formats. autoparse, css_extractor, response_type, and outputs are ignored on that request.

Extract vs. Autoparse vs. CSS Extractor

Pricing

Extract is currently free. You only pay the standard Fetch cost of the underlying request, including JavaScript Rendering or Premium Proxy if you use them.
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. You can also set up usage alerts in your notification settings 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.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
  • X-Key-Credits-Remaining: Lowest remaining credits across your API key’s credit caps, sent only for keys with at least one cap

Frequently Asked Questions (FAQ)

Autoparse (autoparse=true) applies general-purpose extraction rules that work the same way on every website, and it is deprecated. 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. Extract needs a domain to be prepared first, which you can request; see Migrate to Extract for the parameter swap.
The request fails with a 403 error (REQS007) whose title says Extract is not prepared for the requested domain, and it isn’t charged. The message tells you how to prepare it: POST /v1/extract/prepared-domains with up to 5 example URLs, then retry once it reports ready, a few minutes later. Nothing about your plan or your account changes the outcome, since preparation is per domain.
Extract never answers 200 with an empty parsed object, and neither outcome is charged or returns the raw HTML. If the domain is prepared but Extract did not recognise this page as one it can extract, the request fails with a 403 error (REQS007) whose title says Extract did not recognise this page. Try a product, article or listing page on the same site, retry once in a few minutes if this page should work, or use css_extractor. Preparing the domain again does not change it. If Extract recognised the page but no field came back filled, the request fails with a 422 error (no_data_extracted); check that the page rendered fully (some sites need js_render=true or premium_proxy=true) and, if you use extract_fields, omit it to see whether other fields have values. Names that match nothing fail earlier, with REQS004.
Yes. Add extract_fields with a comma-separated list, using dot paths for fields inside a group: extract_fields=products.name,products.price. A dot path applies to every element of a list, so that example returns the name and price of every product. Omit the parameter to receive every field the page provides.
extract=auto (the default) and extract=native return the website’s own extraction, so field names follow what that particular site exposes and differ from site to site. extract=standard returns a canonical schema shared by every website in the same vertical, so pages from different websites line up without mapping. standard currently covers real estate only, and modes are available on the API, not yet in the dashboard playground. See Extraction modes.
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.
No. Access is per domain, not per account. Any active Zenrows API key can use extract=auto on a domain once that domain is prepared, and any key can ask for a domain to be prepared. There’s no separate signup or plan change required.
Treat html as a validation aid rather than a permanent part of the contract. It’s included so you can check the extracted data against the source page. Build your data pipeline around parsed, since the surrounding response shape may evolve.
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.