# Ecommerce Product Data Extraction API - Price, Stock, GTIN (`nabeelbaghoor/ecommerce-product-extraction-api`) Actor

Extract ecommerce product data from any product, category or search page URL: name, price, regular price, currency, availability, SKU, MPN, GTIN, brand, rating, images and breadcrumbs, plus every product on a listing page and category navigation links. Uses your own Zyte API key.

- **URL**: https://apify.com/nabeelbaghoor/ecommerce-product-extraction-api.md
- **Developed by:** [Nabeel Hassan](https://apify.com/nabeelbaghoor) (community)
- **Categories:** E-commerce, Developer tools, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $12.00 / 1,000 product page record returneds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Ecommerce Product Data Extraction API - Price, Stock, GTIN

Turn a list of product, category or search page URLs from any online store into clean ecommerce rows: price, stock, identifiers, brand and ratings, without writing a parser per site.

### What it extracts

- **Product details** from a single product page: name, price, regular (pre-discount) price, currency and currency symbol, availability (InStock or OutOfStock), SKU, MPN, GTIN codes (GTIN-8, GTIN-13, GTIN-14, ISBN, UPC), brand, average rating, best rating and review count, main image and all images, breadcrumbs, description, color, size, material, style, the number of variants, canonical URL and the provider's probability that the page really is a product page.
- **Product list** from a category or search results page: every product shown, with its product page URL, name, price, regular price, currency and main image, plus the category name.
- **Product navigation** from a category page: every product link and subcategory link with its link text, and the next page link, which the actor can follow for as many pages as you allow.
- The full provider record for every row under `record`, so nothing the extraction returned is lost.

The extraction is AI-powered and works on stores it has never seen, so the same run can mix URLs from different retailers.

### Input

- **What to extract**: product details, product list or product navigation. One per run.
- **Page URLs**: one absolute URL per line. The prefilled example is a public practice bookstore, so pressing Start with a key reads one real product.
- **Extraction source**: automatic, raw HTTP response (faster and cheaper at the provider) or rendered browser page (better on JavaScript-heavy stores).
- **Country to fetch from**: an optional two-letter country code such as US, GB or DE, for stores that change price, currency or stock by country.
- **IP type**: automatic, datacenter or residential.
- **Product model version**: pin a dated product extraction model so results stay comparable.
- **Minimum product probability**: pages scored below it become an uncharged note instead of a product. The provider recommends 0.5.
- **Pages to follow per URL**: for product navigation, how many next pages to follow.
- **Maximum results** and **Requests per minute**: bounds on the run.
- **Zyte API key**: your own key. See the FAQ.

### Example output

```json
{
  "extractionType": "product",
  "extractionLabel": "Product details",
  "requestedUrl": "https://books.toscrape.com/catalogue/a-light-in-the-attic_1000/index.html",
  "pageUrl": "https://books.toscrape.com/catalogue/a-light-in-the-attic_1000/index.html",
  "websiteStatus": 200,
  "found": true,
  "recordKind": "product",
  "name": "A Light in the Attic",
  "price": "51.77",
  "regularPrice": null,
  "currency": "GBP",
  "currencyRaw": "£",
  "availability": "InStock",
  "sku": null,
  "gtin": null,
  "brand": null,
  "ratingValue": null,
  "bestRating": null,
  "reviewCount": null,
  "mainImage": "https://books.toscrape.com/media/cache/.../cover.jpg",
  "breadcrumbs": "Home > Books",
  "productUrl": "https://books.toscrape.com/catalogue/a-light-in-the-attic_1000/index.html",
  "probability": 0.99,
  "retrievedAt": "2026-09-25T09:14:52.118Z",
  "record": { "...": "every field the provider returned, unchanged" },
  "note": null
}
```

The first four values match the provider's own documented example for this page; the rest are illustrative. Every field name is one the provider's product schema defines.

### FAQ

#### What is an ecommerce product data extraction API used for?

Price monitoring, competitor price tracking, MAP compliance checks, catalog enrichment, product matching by GTIN or MPN, stock and availability alerts, and building product feeds from stores that offer no feed. A retailer checks rival prices across a list of product URLs every morning. A brand checks resellers for price and stock. A marketplace fills missing brand, GTIN and image fields in its own catalog.

#### Which websites does it work on?

Any public ecommerce website Zyte API can fetch, including stores it has never seen, because the extraction is AI-powered rather than built on per-site rules. Pages behind a login are not supported, and the provider refuses a small number of domains outright; those come back as a note on the row rather than a failed run.

#### What is the difference between product details, product list and product navigation?

Product details reads one product in depth from its own page. Product list reads every product visible on a category or search results page, with fewer fields each, which is the cheapest way to get prices for a whole category. Product navigation reads links rather than products: product page URLs, subcategory URLs and the next page, which is what you feed back in as product details URLs to crawl a whole store.

#### What happens when a URL is not a product page or fails to download?

It becomes its own row with `found: false` and a note explaining why: the page scored below your probability threshold, the website blocked the download even after retries, the domain is unreachable, or the provider does not allow that domain. Those rows are never charged here, and the provider does not charge for failed downloads either.

#### Do I need an API key?

Yes. This actor is bring-your-own-key: it calls Zyte API with your own Zyte API key and never ships one of its own. Copy the key from the API access page of your Zyte account and paste it into the input, or set it once as the DATA\_API\_KEY environment secret. Zyte bills your account for each successful request at its own rates, separately from this actor's per-result price. A missing, wrong or suspended key ends the run cleanly with a message saying which it was.

#### Can it click, log in or submit forms on the website?

No. The actor only sends the URL, the extraction type and the few documented options above. Browser actions, custom HTTP methods, request bodies, cookies and sessions are never sent, so a run reads pages and cannot act on them.

#### How is it priced?

Pay per result. A product details row costs the most because it is a complete product record. A product list row and a navigation link cost less because one page returns many of them. Rows for URLs that produced nothing are free.

#### How fast does it run?

The actor paces itself at 60 requests per minute by default. Zyte API standard plans allow far more per key, but each website also has its own limit at the provider, and rate limited calls are retried after a generous random pause rather than dropped, as the provider recommends.

### Keyword map

ecommerce product data API, product data extraction, product scraper API, price scraper, price monitoring API, competitor price tracking, product price extraction, stock availability checker, GTIN lookup from product page, SKU and MPN extraction, product catalog scraping, category page scraper, product list extraction, product URL crawler, AI product extraction, Zyte API product extraction, retail price intelligence, MAP monitoring, product feed builder.

# Actor input Schema

## `extractionType` (type: `string`):

One extraction type per run. Product details reads one product from each product page URL. Product list reads every product shown on a category or search results page, with its price and image. Product navigation reads the product links, subcategory links and next page link of a category page, for building a crawl.

## `urls` (type: `array`):

One page URL per line, absolute and starting with https://. The host must be a domain name, not an IP address. Use product page URLs for product details, and category or search result page URLs for product list and product navigation.

## `extractFrom` (type: `string`):

Where Zyte API reads the page from. Automatic lets the provider choose, which is currently a rendered browser page for this kind of extraction. Raw HTTP response is usually faster and cheaper at the provider. Rendered browser page usually gives better results on JavaScript-heavy stores.

## `geolocation` (type: `string`):

Optional two-letter ISO 3166-1 country code, such as US, GB or DE, for the country the page should be requested from. Stores often show a different price, currency or stock level by country. Leave blank to let the provider choose.

## `ipType` (type: `string`):

Whether the provider fetches from a datacenter or a residential IP address. Leave on automatic unless you have a reason: the provider picks the type that avoids bans on each website.

## `productModel` (type: `string`):

Pin the provider's product extraction model to a dated version, so results stay comparable while a newer model rolls out. Product details only; ignored for the other types.

## `minProbability` (type: `number`):

Product details only. The provider scores how likely each page is to be a single product page, from 0 to 1, and recommends 0.5 as the threshold. Pages scored below this become an uncharged row saying so instead of a product.

## `maxPagesPerUrl` (type: `integer`):

Product navigation only. Follow the next page link the provider finds, up to this many pages per starting URL. 1 reads only the page you gave.

## `maxResults` (type: `integer`):

Stop after this many rows. A single listing or category page can return dozens of rows, so this is what bounds a run over many URLs.

## `requestsPerMinute` (type: `integer`):

Pacing ceiling for calls to Zyte API. Standard plans allow far more, but websites also have their own limits at the provider, and rate limited calls are retried with a pause rather than dropped.

## `apiKey` (type: `string`):

Your own Zyte API key, from the API access page of your Zyte account. This actor is bring-your-own-key and never ships a key of its own. Leave blank to use the DATA\_API\_KEY environment secret instead.

## `baseUrl` (type: `string`):

Override the host the actor calls. Only useful for testing against a different environment.

## Actor input object example

```json
{
  "extractionType": "product",
  "urls": [
    "https://books.toscrape.com/catalogue/a-light-in-the-attic_1000/index.html"
  ],
  "extractFrom": "auto",
  "ipType": "auto",
  "productModel": "auto",
  "minProbability": 0.5,
  "maxPagesPerUrl": 1,
  "maxResults": 100,
  "requestsPerMinute": 60
}
```

# Actor output Schema

## `records` (type: `string`):

One row per product or link, alongside the URL that produced it.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "urls": [
        "https://books.toscrape.com/catalogue/a-light-in-the-attic_1000/index.html"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("nabeelbaghoor/ecommerce-product-extraction-api").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "urls": ["https://books.toscrape.com/catalogue/a-light-in-the-attic_1000/index.html"] }

# Run the Actor and wait for it to finish
run = client.actor("nabeelbaghoor/ecommerce-product-extraction-api").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "urls": [
    "https://books.toscrape.com/catalogue/a-light-in-the-attic_1000/index.html"
  ]
}' |
apify call nabeelbaghoor/ecommerce-product-extraction-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nabeelbaghoor/ecommerce-product-extraction-api"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/rrmd4ifRdnp1Fbm6b/builds/joKz2ySyF2TLC0E7C/openapi.json
