---
source_url: "https://docs.zyte.com/zyte-api/usage/extract/index.html"
title: Zyte API automatic extraction - Zyte documentation
mirrored_at: 2026-08-12T01:03:34.281Z
host: docs.zyte.com
cited_in_42a: true
mirror_canonical: "https://index.42a.ai/docs.zyte.com/zyte-api/usage/extract/index.html"
---

> **Original source:** https://docs.zyte.com/zyte-api/usage/extract/index.html

**Automatic extraction** gets you structured data from web data.

Automatic extraction supports [AI-powered extraction](#ai-extraction) of e-commerce, article and job posting data from any website, as well as **non-AI extraction** of search engine results.

You can use [Zyte API requests](https://docs.zyte.com/zyte-api/usage/reference.html#zapi-reference) to get structured data from webpages.

## Structured data types[¶](#structured-data-types "Link to this heading")

In a [Zyte API request](https://docs.zyte.com/zyte-api/usage/reference.html#zapi-reference), enable any of the following fields to get matching structured data:

Note

You can only enable 1 of these fields per Zyte API request.

E-commerce

Articles

Job postings

Generic

Example

C#

using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

HttpClientHandler handler \= new HttpClientHandler()
{
    AutomaticDecompression \= DecompressionMethods.All
};
HttpClient client \= new HttpClient(handler);

var apiKey \= "YOUR\_ZYTE\_API\_KEY";
var bytes \= Encoding.GetEncoding("ISO-8859-1").GetBytes(apiKey + ":");
var auth \= System.Convert.ToBase64String(bytes);
client.DefaultRequestHeaders.Add("Authorization", "Basic " + auth);

client.DefaultRequestHeaders.Add("Accept-Encoding", "br, gzip, deflate");

var input \= new Dictionary<string, object\>(){
    {"url", "https://books.toscrape.com/catalogue/a-light-in-the-attic\_1000/index.html"},
    {"product", true}
};
var inputJson \= JsonSerializer.Serialize(input);
var content \= new StringContent(inputJson, Encoding.UTF8, "application/json");

HttpResponseMessage response \= await client.PostAsync("https://api.zyte.com/v1/extract", content);
var body \= await response.Content.ReadAsByteArrayAsync();

var data \= JsonDocument.Parse(body);
var product \= data.RootElement.GetProperty("product").ToString();

Console.WriteLine(product);

CLI client

input.jsonl[¶](#id1 "Link to this code")

{"url": "https://books.toscrape.com/catalogue/a-light-in-the-attic\_1000/index.html", "product": true}

zyte-api input.jsonl \\
    | jq \--raw-output .product

curl

input.json[¶](#id2 "Link to this code")

{
    "url": "https://books.toscrape.com/catalogue/a-light-in-the-attic\_1000/index.html",
    "product": true
}

curl \\
    \--user YOUR\_ZYTE\_API\_KEY: \\
    \--header 'Content-Type: application/json' \\
    \--data @input.json \\
    \--compressed \\
    https://api.zyte.com/v1/extract \\
    | jq \--raw-output .product

Java

import com.google.common.collect.ImmutableMap;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Map;
import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.HttpHeaders;
import org.apache.hc.core5.http.ParseException;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.io.entity.StringEntity;

class Example {
  private static final String API\_KEY \= "YOUR\_ZYTE\_API\_KEY";

  public static void main(final String\[\] args)
      throws InterruptedException, IOException, ParseException {
    Map<String, Object\> parameters \=
        ImmutableMap.of(
            "url",
            "https://books.toscrape.com/catalogue/a-light-in-the-attic\_1000/index.html",
            "product",
            true);
    String requestBody \= new Gson().toJson(parameters);

    HttpPost request \= new HttpPost("https://api.zyte.com/v1/extract");
    request.setHeader(HttpHeaders.CONTENT\_TYPE, ContentType.APPLICATION\_JSON);
    request.setHeader(HttpHeaders.ACCEPT\_ENCODING, "gzip, deflate");
    request.setHeader(HttpHeaders.AUTHORIZATION, buildAuthHeader());
    request.setEntity(new StringEntity(requestBody));

    CloseableHttpClient client \= HttpClients.createDefault();
    client.execute(
        request,
        response \-> {
          HttpEntity entity \= response.getEntity();
          String apiResponse \= EntityUtils.toString(entity, StandardCharsets.UTF\_8);
          JsonObject jsonObject \= JsonParser.parseString(apiResponse).getAsJsonObject();
          JsonObject product \= jsonObject.get("product").getAsJsonObject();
          Gson gson \= new GsonBuilder().setPrettyPrinting().create();
          System.out.println(gson.toJson(product));
          return null;
        });
  }

  private static String buildAuthHeader() {
    String auth \= API\_KEY + ":";
    String encodedAuth \= Base64.getEncoder().encodeToString(auth.getBytes());
    return "Basic " + encodedAuth;
  }
}

JS

const axios \= require('axios')

axios.post(
  'https://api.zyte.com/v1/extract',
  {
    url: 'https://books.toscrape.com/catalogue/a-light-in-the-attic\_1000/index.html',
    product: true
  },
  {
    auth: { username: 'YOUR\_ZYTE\_API\_KEY' }
  }
).then((response) \=> {
  const product \= response.data.product
  console.log(product)
})

PHP

<?php

$client \= new GuzzleHttp\\Client();
$response \= $client\->request('POST', 'https://api.zyte.com/v1/extract', \[
    'auth' \=> \['YOUR\_ZYTE\_API\_KEY', ''\],
    'headers' \=> \['Accept-Encoding' \=> 'gzip'\],
    'json' \=> \[
        'url' \=> 'https://books.toscrape.com/catalogue/a-light-in-the-attic\_1000/index.html',
        'product' \=> true,
    \],
\]);
$data \= json\_decode($response\->getBody());
$product \= json\_encode($data\->product);
echo $product.PHP\_EOL;

Python

import requests

api\_response \= requests.post(
    "https://api.zyte.com/v1/extract",
    auth\=("YOUR\_ZYTE\_API\_KEY", ""),
    json\={
        "url": (
            "https://books.toscrape.com/catalogue"
            "/a-light-in-the-attic\_1000/index.html"
        ),
        "product": True,
    },
)
product \= api\_response.json()\["product"\]
print(product)

Python client

import asyncio
import json

from zyte\_api import AsyncZyteAPI

async def main():
    client \= AsyncZyteAPI()
    api\_response \= await client.get(
        {
            "url": (
                "https://books.toscrape.com/catalogue"
                "/a-light-in-the-attic\_1000/index.html"
            ),
            "product": True,
        }
    )
    product \= api\_response\["product"\]
    print(json.dumps(product, indent\=2, ensure\_ascii\=False))

asyncio.run(main())

Scrapy

from scrapy import Request, Spider

class BooksToScrapeComSpider(Spider):
    name \= "books\_toscrape\_com"

    async def start(self):
        yield Request(
            (
                "https://books.toscrape.com/catalogue"
                "/a-light-in-the-attic\_1000/index.html"
            ),
            meta\={
                "zyte\_api\_automap": {
                    "product": True,
                },
            },
        )

    def parse(self, response):
        product \= response.raw\_api\_response\["product"\]
        print(product)

Output (first 5 lines):

{
  "name": "A Light in the Attic",
  "price": "51.77",
  "currency": "GBP",
  "currencyRaw": "£",

## AI-powered extraction[¶](#ai-powered-extraction "Link to this heading")

Automatic extraction uses AI-powered extraction for the following structured data types: [product](https://docs.zyte.com/zyte-api/usage/reference.html#operation/extract/request/product), [productList](https://docs.zyte.com/zyte-api/usage/reference.html#operation/extract/request/productList), [productNavigation](https://docs.zyte.com/zyte-api/usage/reference.html#operation/extract/request/productNavigation), [article](https://docs.zyte.com/zyte-api/usage/reference.html#operation/extract/request/article), [articleList](https://docs.zyte.com/zyte-api/usage/reference.html#operation/extract/request/articleList), [articleNavigation](https://docs.zyte.com/zyte-api/usage/reference.html#operation/extract/request/articleNavigation), [forumThread](https://docs.zyte.com/zyte-api/usage/reference.html#operation/extract/request/forumThread), [jobPosting](https://docs.zyte.com/zyte-api/usage/reference.html#operation/extract/request/jobPosting), [jobPostingNavigation](https://docs.zyte.com/zyte-api/usage/reference.html#operation/extract/request/jobPostingNavigation), [pageContent](https://docs.zyte.com/zyte-api/usage/reference.html#operation/extract/request/pageContent).

AI-powered extraction also supports [LLM-based extraction of custom attributes](https://docs.zyte.com/zyte-api/usage/extract/custom-attributes.html#custom-attributes), as well as: [geolocation](https://docs.zyte.com/zyte-api/usage/features.html#zapi-geolocation), [IP type](https://docs.zyte.com/zyte-api/usage/features.html#zapi-ip-type), [cookies](https://docs.zyte.com/zyte-api/usage/features.html#zapi-cookies), [sessions](https://docs.zyte.com/zyte-api/usage/features.html#zapi-sessions), [redirection](https://docs.zyte.com/zyte-api/usage/http.html#zapi-redirection), [response headers](https://docs.zyte.com/zyte-api/usage/features.html#zapi-headers), and [metadata](https://docs.zyte.com/zyte-api/usage/features.html#zapi-metadata), plus additional features depending on your [extraction source](#zapi-extract-from).

### Extraction source[¶](#extraction-source "Link to this heading")

Use the corresponding `extractFrom` option, e.g. [productOptions.extractFrom](https://docs.zyte.com/zyte-api/usage/reference.html#operation/extract/request/productOptions.extractFrom) when extracting a [product](https://docs.zyte.com/zyte-api/usage/reference.html#operation/extract/request/product), to indicate which sources to use for automatic extraction:

-   `httpResponseBody` extracts from [httpResponseBody](https://docs.zyte.com/zyte-api/usage/reference.html#operation/extract/response/200/httpResponseBody). It is usually faster and cheaper.
    
-   `browserHtmlOnly` extracts from [browserHtml](https://docs.zyte.com/zyte-api/usage/reference.html#operation/extract/response/200/browserHtml). It typically improves quality over `httpResponseBody` on JavaScript-heavy web pages.
    
-   `browserHtml` extracts from both [browserHtml](https://docs.zyte.com/zyte-api/usage/reference.html#operation/extract/response/200/browserHtml) and visual features of the rendered web page. It typically improves quality over `browserHtmlOnly`, but is not as robust in case of rendering issues.
    

If not specified, `browserHtml` is currently used by default for [AI extraction](#ai-extraction), while `httpResponseBody` is used by default for [non-AI extraction](#non-ai-extraction). In the future, the default value may depend on the target website.

Automatic extraction using an HTTP request (`httpResponseBody`) supports HTTP request attributes for [method](https://docs.zyte.com/zyte-api/usage/http.html#zapi-set-method), [body](https://docs.zyte.com/zyte-api/usage/http.html#zapi-set-body), and [headers](https://docs.zyte.com/zyte-api/usage/http.html#zapi-body-request-headers).

Automatic extraction using a browser request (`browserHtmlOnly` or `browserHtml`) supports [browser HTML](https://docs.zyte.com/zyte-api/usage/browser.html#zapi-browser-html), [screenshots](https://docs.zyte.com/zyte-api/usage/browser.html#zapi-screenshot), [some request headers](https://docs.zyte.com/zyte-api/usage/browser.html#zapi-set-browser-headers), [actions](https://docs.zyte.com/zyte-api/usage/browser.html#zapi-actions), [network capture](https://docs.zyte.com/zyte-api/usage/browser.html#zapi-network-capture), and [toggling JavaScript](https://docs.zyte.com/zyte-api/usage/browser.html#zapi-javascript). The [limitations of browser requests](https://docs.zyte.com/zyte-api/usage/browser.html#zapi-browser-limitations) also apply in this case.

### Model pinning[¶](#model-pinning "Link to this heading")

The AI models of AI-powered extraction are retrained regularly, usually a few times per year. While new model versions aim to improve overall accuracy, they may become less accurate for specific fields of specific websites.

For certain data types, we provide an option to pin a specific model version, which allows you to postpone an update to the latest model.

To pin a model, use the corresponding `model` option, e.g. [productOptions.model](https://docs.zyte.com/zyte-api/usage/reference.html#operation/extract/request/productOptions.model) when extracting a [product](https://docs.zyte.com/zyte-api/usage/reference.html#operation/extract/request/product).

Model versions remain available for at least 1 year after their release. For example, a product model version `"2024-02-01"` would remain available at least until the 1st of February 2025.

When we decide to remove a model version, we announce its end-of-life date by email to its users at least 3 months in advance, and we list that date in the table below.

Data type

Model name

Description

product

2024-02-01

product

2024-09-16

Default product model