Product Data Extractor API — Price, Title, Images & Stock avatar

Product Data Extractor API — Price, Title, Images & Stock

Pricing

$0.50 / 1,000 products

Go to Apify Store
Product Data Extractor API — Price, Title, Images & Stock

Product Data Extractor API — Price, Title, Images & Stock

Name, brand, price, currency, stock, rating, images, SKU/GTIN and variants from a product page's schema.org JSON-LD, microdata or Open Graph tags. One JSON record per URL. Product Data Extractor API.

Pricing

$0.50 / 1,000 products

Rating

0.0

(0)

Developer

yestrue

yestrue

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Share

Give it product page URLs from any shop and get one clean JSON record per page: name, brand, price (with a from–to range when the page lists several offers), currency, availability, SKU, GTIN/EAN/ISBN, MPN, rating and review count, images, description, category, color, material, variants, seller and condition. The data comes from the page's own structured data — schema.org JSON-LD (Product, ProductGroup, Offer, AggregateOffer), schema.org microdata and Open Graph product tags — which is what Google Shopping and social previews read too, so it works on most Shopify, WooCommerce, Magento, BigCommerce, PrestaShop and custom stores without a scraper per shop. No browser, no guessing: a page without product markup is reported as such, for free.

Try it in 1 minute:

  1. Press Start — the prefilled input reads one Allbirds product page.
  2. Seconds later the Output tab shows the record: name, brand, price and currency, stock status, SKU, rating and review count, images, description and the size variants with their own stock status.
  3. Paste your own product URLs (one per line), download JSON, CSV or Excel, or switch Include raw JSON-LD on to get the page's whole Product object.

Price: $0.50 per 1,000 products (one page = one record). Pages without product markup, missing pages, pages blocked by robots.txt or a bot check, and invalid URLs are free.

Use it to:

  • Monitor competitor prices and stock on a schedule across many shops with one Actor, instead of one scraper per site.
  • Enrich a list of product links from a spreadsheet, CRM or affiliate feed with structured product data (price, GTIN, images, rating).
  • Feed an AI agent or RAG pipeline with clean product facts from any URL a user pastes.
  • Check that your own catalogue pages expose correct schema.org data (price, availability, GTIN) the way Google Shopping sees it.
  • Build price-comparison, deal-alert or catalogue-sync tools on top of a stable record shape.

How it works

  1. URLs are normalised (scheme added, fragments dropped) and deduplicated; one record per page.
  2. Unless you turn it off, the site's robots.txt is read once per domain and a page it disallows for generic crawlers gets a free ROBOTS_DISALLOWED record.
  3. The page is fetched over plain HTTP with a desktop Chrome (or mobile Safari) identity — directly first, through the Apify proxy only to retry after a network or server error (or from the first request when you switch that on). A shop's rate limit (HTTP 429) is waited out and retried on the same route. Nothing else is requested: no scripts run, no product API is called.
  4. The product is read from the page in this order of trust, later sources only filling gaps: JSON-LD Product / ProductGroup (also inside @graph, arrays and a WebPage's mainEntity; Offer, AggregateOffer, offer arrays, priceSpecification, hasVariant variants) → microdata (itemtype schema.org/Product with itemprop name, price, priceCurrency, availability, sku, brand, image, ratingValue, reviewCount …, or a page-level <meta itemprop="price">) → Open Graph / Twitter tags (og:title, og:image, product:price:amount, product:price:currency, product:availability, product:brand, product:retailer_item_id, product:condition, twitter:label1 "Price"). The source field says which one(s) the record came from.
  5. Prices are parsed in both conventions ("1,299.00" and "1.299,00"), currency symbols become ISO codes when unambiguous (priceCurrency always wins), availability URLs become plain words (InStock, OutOfStock, PreOrder, BackOrder, Discontinued, LimitedAvailability, SoldOut, OnlineOnly, InStoreOnly), image URLs are made absolute and deduplicated, and the description becomes plain text with phone numbers and e-mail addresses removed.
  6. A page with no product markup at all — or markup that names neither a product nor a price — gets a free NO_STRUCTURED_DATA record; a price is never guessed from the page text.

Input

FieldWhat it does
urlsProduct pages to read, one URL per line.
includeDescriptionPlain-text description, up to 5,000 characters (default on).
includeRawJsonLdAdd the page's schema.org Product object as found, in rawJsonLd (default off).
respectRobotsSkip pages the site's robots.txt disallows (default on).
userAgentdesktop (Chrome on Windows, default) or mobile (Safari on iPhone).
maxConcurrencyPages read in parallel (default 5, up to 20).
proxyFromFirstRequestSend every request through the proxy from the start (default off) — for shops that answer datacenter IPs with HTTP 429.
proxyConfigurationUsed only to retry after a network or server error unless the switch above is on; the first try is direct. A bot-check page is never retried on another IP.

Output

One record per URL:

FieldWhat it is
input, urlThe URL as given, and the final URL after redirects
name, brand, sku, gtin, mpnIdentity: name, brand, the shop's code, GTIN-14/13/12/8/EAN/UPC/ISBN, manufacturer part number
price, priceMin, priceMax, currencyPrice as a number (the lowest when several offers are listed), the range when there is one, ISO 4217 currency
availability, availabilityRawNormalised stock status and the value as the page wrote it
rating, reviewCount, bestRatingAverage rating, number of reviews/ratings, the scale's maximum when given
images[], imageAbsolute image URLs (deduplicated, up to 20) and the first one
description, category, color, material, sizeWhat the page states, as plain text
variants[]{ name, sku, price, currency, availability, url } from a ProductGroup's variants or several offers, up to 50
seller, conditionSeller (business) name; New, Used, Refurbished or Damaged
source, siteName, httpStatusjson-ld, microdata, opengraph or mixed; og:site_name; the HTTP status
rawJsonLdThe schema.org Product object as found (with Include raw JSON-LD on), else null
status, error, scrapedAtOK / NO_STRUCTURED_DATA / NOT_FOUND / ROBOTS_DISALLOWED / INVALID_INPUT / FAILED, the reason, and when

Example

{
"input": "https://shop.acme.example/p/trail-runner-x1",
"url": "https://shop.acme.example/p/trail-runner-x1",
"name": "Trail Runner X1",
"brand": "Acme",
"price": 129.9,
"priceMin": null,
"priceMax": null,
"currency": "EUR",
"availability": "InStock",
"availabilityRaw": "http://schema.org/InStock",
"sku": "X1-BLK-42",
"gtin": "4006381333931",
"mpn": "ACM-X1-2026",
"rating": 4.6,
"reviewCount": 128,
"bestRating": 5,
"images": [
"https://cdn.acme.example/img/x1-front.jpg",
"https://shop.acme.example/img/x1-side.jpg",
"https://cdn.acme.example/img/x1-top.jpg"
],
"image": "https://cdn.acme.example/img/x1-front.jpg",
"description": "Light trail shoe with a Vibram sole.",
"category": "Shoes > Trail running",
"color": "Black",
"material": "Recycled polyester",
"size": "42",
"variants": [
{ "name": "Trail Runner X1 - 42", "sku": "X1-BLK-42", "price": 129.9, "currency": "EUR", "availability": "InStock", "url": "https://shop.acme.example/p/trail-runner-x1?size=42" },
{ "name": "Trail Runner X1 - 43", "sku": "X1-BLK-43", "price": 129.9, "currency": "EUR", "availability": "OutOfStock", "url": "https://shop.acme.example/p/trail-runner-x1?size=43" }
],
"seller": "Acme Outdoor GmbH",
"condition": "New",
"source": "json-ld",
"siteName": "Acme Outdoor Shop",
"rawJsonLd": null,
"httpStatus": 200,
"status": "OK",
"error": null,
"scrapedAt": "2026-10-19T12:00:00.000Z"
}

FAQ

Is this an official API? No, it's an unofficial API built on public pages — it reads the schema.org and Open Graph markup that shops publish on their own product pages for search engines and social networks. There is no shop API behind it and no account is needed.

Why did a page come back as NO_STRUCTURED_DATA? The page has no JSON-LD Product, no microdata Product and no Open Graph product tags in its HTML — or it fills them in with JavaScript after loading, which this version does not run. The Actor never guesses a price from the page text. Open the page source and search for application/ld+json or product:price:amount to see what the shop exposes.

Does it work on Amazon, Walmart or other big marketplaces? Usually not: they answer automated requests with a bot-check page, which is reported as a free FAILED record ("bot check") and never retried on another IP. The Actor is built for the long tail of brand and retailer stores. Some Shopify stores throttle datacenter IPs with HTTP 429 "Too many requests"; the run waits and retries, and if that keeps failing, switch Use the proxy from the first request on with a residential proxy group. Wherever a site offers an official product API, use that.

Which price is price when the page lists several? The lowest offer, with priceMin/priceMax giving the range and variants[] the individual offers. A single offer has priceMin/priceMax null. currency comes from priceCurrency when stated, else from an unambiguous symbol (€, £, $, ¥, zł, Kč …); "kr" alone is left null because it could be SEK, NOK or DKK.

How are JavaScript-only shops handled? They are not, in this version: only what the server sends is read. A browser-rendering option is planned; until then, such pages are free NO_STRUCTURED_DATA records.

Like it? A short review on the Store page helps other people find this Actor. Something missing or broken? Tell us on the Issues tab — we read every one.