Product catalogue of any WooCommerce store from its public Store API, up to 200 stores a run and 5,000 products each: name, URL, SKU, price, sale price, currency, stock and on-sale flags, rating, categories, tags, brands, attributes, images and description. Robots-aware. Pay per product.
One product delivered. Stores that are not on WooCommerce, closed by robots.txt or without products are never charged.
ACTOR=steadydata~woocommerce-products-catalog URL="https://api.apify.com/v2/acts/$ACTOR/run-sync-get-dataset-items" curl -X POST "$URL?token=$APIFY_TOKEN" \ -H "Content-Type: application/json" \ -d '{"stores": ["barefootbuttons.com", "porterandyork.com"], "maxProductsPerStore": 500, "includeDescription": false}'
import os, requests ACTOR = "steadydata~woocommerce-products-catalog" URL = f"https://api.apify.com/v2/acts/{ACTOR}/run-sync-get-dataset-items" rows = requests.post( URL, params={"token": os.environ["APIFY_TOKEN"]}, json={'stores': ['barefootbuttons.com', 'porterandyork.com'], 'maxProductsPerStore': 500, 'includeDescription': False}, timeout=900, ).json() # every row carries a status; failures are records, not exceptions ok = [r for r in rows if r.get("status") == "ok"] print(len(ok), "rows delivered")
const ACTOR = "steadydata~woocommerce-products-catalog"; const url = `https://api.apify.com/v2/acts/${ACTOR}/run-sync-get-dataset-items` + `?token=${process.env.APIFY_TOKEN}`; const rows = await fetch(url, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({"stores": ["barefootbuttons.com", "porterandyork.com"], "maxProductsPerStore": 500, "includeDescription": false}), }).then((r) => r.json()); // one object per delivered row, same shape every time console.log(rows.filter((r) => r.status === "ok").length, "rows");
Point an MCP client at Apify's hosted server with this dataset in the tools list, or run our own server locally. The field explanations in the table below travel with the schema, so your agent reads them straight from the platform instead of from this page.
https://mcp.apify.com?tools=steadydata/woocommerce-products-catalog # the tool arrives in your agent as steadydata--woocommerce-products-catalog
| Field | Type | Name | What it does |
|---|---|---|---|
storesrequired | array of string | WooCommerce stores | One per row, up to 200: the store domain or any URL on it (barefootbuttons.com, https://porterandyork.com/shop/). |
maxProductsPerStore | integer | Max products per store | Cost ceiling per store, in the store's order. Pages of 100. |
includeDescription | boolean | Include the product description | On: short and full description as plain text. Off keeps rows small. |
onlyInStock | boolean | Only products in stock | On: products that are out of stock are skipped and not charged. |
{
"store": string | null,
"productId": string | null,
"name": string | null,
"slug": string | null,
"url": string | null,
"sku": string | null,
"type": string | null,
"currency": string | null,
"price": number | null,
"regularPrice": number | null,
"salePrice": number | null,
"priceMin": number | null,
"priceMax": number | null,
"onSale": boolean | null,
"inStock": boolean | null,
"stockText": string | null,
"lowStockRemaining": integer | null,
"isPurchasable": boolean | null,
"averageRating": number | null,
"reviewCount": integer | null,
"categories": array | null,
"tags": array | null,
"brands": array | null,
"attributes": array | null,
"variationCount": integer | null,
"imageCount": integer | null,
"imageUrl": string | null,
"images": array | null,
"weight": string | null,
"shortDescription": string | null,
"description": string | null,
"storeProductTotal": integer | null,
"status": string | null,
"input": string | null,
"errorCode": string | null,
"error": string | null
}| Field | Type | When it is filled |
|---|---|---|
store | string, null | |
productId | string, null | |
name | string, null | |
slug | string, null | |
url | string, null | |
sku | string, null | Filled when the shop fills in an article number; it is an optional field in WooCommerce. |
type | string, null | |
currency | string, null | |
price | number, null | |
regularPrice | number, null | |
salePrice | number, null | Filled when the product is on sale; regularPrice always holds the undiscounted price. |
priceMin | number, null | For a product with variations the lowest variation price; for a simple product the same as price. |
priceMax | number, null | For a product with variations the highest variation price; for a simple product the same as price. |
onSale | boolean, null | |
inStock | boolean, null | |
stockText | string, null | The shop's own wording about availability, which differs per shop and per language. |
lowStockRemaining | integer, null | Filled when the shop publishes a low-stock warning with a number, for example 'only 3 left'. |
isPurchasable | boolean, null | |
averageRating | number, null | Filled when the product has been reviewed; empty when reviewCount is 0. |
reviewCount | integer, null | |
categories | array, null | |
tags | array, null | Filled when the shop tags its products; many shops use categories only. |
brands | array, null | Filled when the shop uses a brands plugin; many shops do not. |
attributes | array, null | The product attributes with their values, and whether each one drives the variations. |
variationCount | integer, null | How many variations the product has, for example sizes or colours; 0 for a simple product. |
imageCount | integer, null | |
imageUrl | string, null | The first image; images holds all of them. |
images | array, null | |
weight | string, null | Filled when the shop fills in a weight; it is an optional field in WooCommerce. |
shortDescription | string, null | Filled when includeDescription is on; off by default because it makes rows much larger. |
description | string, null | Filled when includeDescription is on; off by default because it makes rows much larger. |
storeProductTotal | integer, null | How many products the shop has in total, so a run can be compared with the whole catalogue. |
status | string, null | Either 'ok' or 'error'. An error row carries errorCode and error, and leaves the data fields empty; it is never charged. |
input | string, null | The input this row was built from, so a row can always be traced back. |
errorCode | string, null | Filled on an error row only; a delivered row leaves it empty. |
error | string, null | Filled on an error row only; a delivered row leaves it empty. |
Product catalogue of any Shopify store from its public products feed, up to 200 stores a run and 5,000 products each: title, handle, URL, vendor, type, tags, dates, price range, sale and stock flags, every variant with SKU, price and options, images and description. Robots-aware. Pay per product.
$1.00 per 1,000 · Product listedOne report per Shopify store, up to 200 stores per run: catalogue size, price range and average, currency, share in stock, share on sale, product types, brands, newest and oldest product, plus ranked signals such as a stale catalogue or heavy discounting. Pay per delivered report.
$3.50 per 1,000 · Store reportedOne report per WooCommerce store, up to 200 stores per run: the exact product count, price range and average, currency, share in stock, share on sale, categories, brands, average review rating, and ranked signals such as an empty catalogue or heavy discounting. Company data only, no personal data.
$3.50 per 1,000 · Store reportedAlready using this one? Ratings are the first thing other buyers look at, and this dataset has none yet. If it does a job for you, a rating on its Apify page is the one thing that helps. It takes a minute and it is the only thing we ask for.