Shopify Scraper: Stock, Images & Product Updates avatar

Shopify Scraper: Stock, Images & Product Updates

Pricing

from $4.99 / 1,000 results

Go to Apify Store
Shopify Scraper: Stock, Images & Product Updates

Shopify Scraper: Stock, Images & Product Updates

Shopify Scraper extracts stock levels, product images, prices, variants, SKUs, availability, and product updates from Shopify stores. Monitor inventory and catalogue changes, track competitors, and collect ecommerce data for analysis and automation.

Pricing

from $4.99 / 1,000 results

Rating

0.0

(0)

Developer

API Empire

API Empire

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Share

Shopify Scraper — Extract Products, Stock & Catalog Health as JSON

Shopify Scraper: Stock, Images & Product Updates pulls structured product data — title, brand, variants, pricing, media, and stock status — from any public Shopify store, collection, or product page, and computes a per-store catalog-health summary (out-of-stock rate, missing-image rate, single-variant-only rate, and product-age freshness cohorts) from that same data at no extra request cost. Every response returns typed, normalized JSON — no HTML, no selectors, no parsing. Point it at one storefront or fifty and get individual product rows plus one roll-up row per store, ready to load into a spreadsheet, a database, or an AI agent pipeline.


What is Shopify Scraper: Stock, Images & Product Updates?

Shopify Scraper: Stock, Images & Product Updates is an Apify Actor that scrapes any public Shopify storefront — a store homepage, a collection page, or a single product URL — and returns two things in the same dataset: a full product row for every item found, and one catalog-health summary row per store computed from the products already scanned. No Shopify account, app installation, or API token is required — it reads the same public JSON endpoints (/products.json, /collections/<handle>/products.json) that a browser loads, on stores that expose them publicly. A store that is password-protected is reported as inaccessible rather than silently returning zero results.

  • Scrape full product data — title, brand, tags, categories, variants, pricing, media, and options
  • Get real per-variant stock status (isInStock), not a guessed default
  • Get per-store catalog-health rollups — stock, image, and variant-depth completeness, plus freshness cohorts
  • Attach lightweight related-product references per product, on request
  • Export as JSON, CSV, Excel, or connect via the Apify API

What data does Shopify Scraper: Stock, Images & Product Updates collect?

The Actor returns product rows, per-variant stock and pricing data, and a per-store catalog-health summary — all from the same scan, no separate runs required.

Data TypeKey FieldsJSON Field Names
Productstitle, brand, description, tags, categories, mediatitle, brand, description, tags, categories, medias
Variants & stockprice, SKU, options, in-stock statusvariants[].price.current, variants[].sku, variants[].price.stockStatus, isInStock
Store catalog-health summaryout-of-stock %, missing-image %, single-variant-only %, freshness cohortsoutOfStockPct, noImagesPct, singleVariantOnlyPct, ageCohorts
Related product references (optional)id, handle, title, URLrelatedProductRefs[].id, relatedProductRefs[].handle, relatedProductRefs[].url

Need more Shopify data?

If you need supplier or merchant-level details instead of product catalogs, the API-Empire account also publishes Shopify-Merchant-Scraper, Shopify-Products-Scraper, and Shopify-Store-Scraper, each targeting a different slice of the same platform.


How does Shopify Scraper: Stock, Images & Product Updates differ from the official Shopify API?

Shopify's own Storefront and Admin APIs require an access token generated by the store's own owner and scoped to that one store — there is no official way for a third party to pull catalog data from a store they don't own or control (verified on shopify.dev/docs/api/usage/authentication, checked 2026-08-15). Shopify Scraper: Stock, Images & Product Updates instead reads the same public JSON that a browser already loads on any public storefront, so it works across stores you have no relationship with.

FeatureShopify Storefront/Admin APIShopify Scraper: Stock, Images & Product Updates
Authorization neededAccess token generated by the store's own owner (shopify.dev, checked 2026-08-15)None — reads the store's public product JSON
Works on stores you don't ownNoYes — any public storefront, collection, or product URL
Catalog-health rollupsNot provided — raw product/variant objects onlyComputed automatically per store in the same run
Stock-status sourceavailable field on the authenticated variant objectSame field, read from the store's own public listing page
SetupCreate an app, generate a token, authorize per storePaste store URLs and run

The official API is the right choice when you own the store and need live, first-party integration for checkout, cart, or order data. Shopify Scraper: Stock, Images & Product Updates is the right choice when you need catalog visibility into stores you don't own — competitor benchmarking, supplier vetting, market research — where a token was never available to begin with.


Why do developers and teams scrape Shopify?

For AI engineers and agent builders

Product catalogs are common context for shopping agents, price-comparison tools, and RAG pipelines. Each product row is typed JSON — title, brand, variants[].price.current, isInStock — with no HTML to strip before it goes into an embedding index or an agent's tool response, and the catalogHealthSummary row gives an agent a store-level signal (outOfStockPct, medianProductAgeDays) without it having to aggregate hundreds of product rows itself.

For merchandising and pricing teams

Compare your own catalog's completeness against a competitor's: noImagesPct and singleVariantOnlyPct on the summary row expose gaps in product photography or variant depth at a glance, across as many stores as you list in one run.

For researchers and market analysts

ageCohorts and medianProductAgeDays turn a store's public catalog into a freshness signal — how much of its inventory is new versus stale — useful for tracking a market segment's turnover without needing any store-side access.

For developers building data products

Because the schema is stable and the same run produces both row-level and store-level data, it drops directly into a scheduled pipeline: run on a schedule, load both row types into a warehouse, and build dashboards or alerts on top without maintaining a scraper yourself.


How to scrape Shopify (step by step)

  1. Open Shopify Scraper: Stock, Images & Product Updates on the Apify Store and click Try for free.
  2. Paste one or more store, collection, or product URLs into auditUrls.
  3. Set filterKeyword to narrow by keyword, maxResults to cap products scanned per store, and toggle computeCompletenessProfile / computeFreshnessCohorts for the summary stats you want.
  4. Click Start and let the run finish.
  5. Download results as JSON, CSV, or Excel, or pull them via the Apify API.

What to do when Shopify changes its structure

The Actor is maintained, and the output schema stays stable — field names and types don't change on your end. No specific turnaround time is published for fixes.


⬇️ Input

None of the fields below are required — an empty run simply exits with a warning if no store URL is provided.

ParameterRequiredTypeConstraintsDescription
auditUrlsNoarrayeditor: stringListPaste Shopify store URLs, one per line — homepages, collection pages, or single product pages.
startUrlsNoarrayeditor: stringListLegacy alias of auditUrls, kept for compatibility with the base Shopify Scraper's input format. If both are set, auditUrls is used.
filterKeywordNostringeditor: textfieldOnly include products whose title, tags, or description contain this keyword (case-insensitive). Leave empty to include every product.
queryNostringeditor: textfieldLegacy alias of filterKeyword, kept for compatibility with the base actor's input format. If both are set, filterKeyword is used.
maxResultsNointegerdefault 100, minimum 0Maximum products to scan per store URL. Set to 0 for no limit.
maxRecommendationsPerProductNointegerdefault 0, minimum 0, maximum 20How many related-product references (id, handle, title, URL) to attach to each product row (0–20). Set 0 to disable. This is a lightweight reference list only — no price comparison.
computeCompletenessProfileNobooleandefault trueCompute per-store stock, image, and variant-choice completeness statistics (out-of-stock rate, missing-image rate, single-variant-only rate).
flagNoImageProductsNobooleandefault trueAdd a per-product hasImages flag and count/percentage of image-less products per store.
flagSingleVariantProductsNobooleandefault trueAdd a per-product isSingleVariantOnly flag and count/percentage of products with no real size/color choice per store.
computeFreshnessCohortsNobooleandefault trueCompute per-store catalog age statistics: oldest/newest/median product age, counts of recently-added products, and age-bucket cohorts.
freshWindowDaysNoarraydefault ["30", "60", "90"], editor: select, enum ["30", "60", "90"]Which recency windows to count new products in. Each selected window adds a newProductsLastNDays count to the store summary row.
ageCohortBoundariesNoarrayeditor: stringList, prefill ["30", "90", "365"]Day-count boundaries used to bucket products by age into the ageCohorts summary object, e.g. ["30","90","365"] buckets into 0-30d / 31-90d / 91-365d / 366d+.
proxyConfigurationNoobjecteditor: proxy, prefill {"useApifyProxy": false}Leave empty to start with no proxy. If a store is temporarily unreachable, the actor automatically retries with a different connection.

Example JSON input

{
"auditUrls": [
"https://boat-lifestyle.com",
"https://allbirds.com/collections/mens-shoes"
],
"filterKeyword": "",
"maxResults": 200,
"maxRecommendationsPerProduct": 5,
"computeCompletenessProfile": true,
"flagNoImageProducts": true,
"flagSingleVariantProducts": true,
"computeFreshnessCohorts": true,
"freshWindowDays": ["30", "60", "90"],
"ageCohortBoundaries": ["30", "90", "365"],
"proxyConfiguration": { "useApifyProxy": false }
}

Common pitfall: leaving auditUrls empty and only filling the legacy startUrls field works, but if you set both, auditUrls silently wins — don't fill both with different lists expecting them to merge.


⬆️ Output

Every run pushes two structurally different row types into the same dataset, told apart by type: product rows and one catalogHealthSummary row per store. Results export as JSON, CSV, or Excel directly from the Apify Console, or are readable via the Apify API / apify_client.

Scraped product

{
"type": "product",
"source": {
"id": "7403574100062",
"canonicalUrl": "https://boat-lifestyle.com/products/blue-sneakers",
"retailer": "boat-lifestyle.com",
"language": "en-IN",
"currency": "INR",
"createdUTC": "2021-05-14T10:12:00-04:00",
"updatedUTC": "2026-08-01T09:00:00-04:00",
"publishedUTC": "2021-05-14T10:20:00-04:00"
},
"retailer": "boat-lifestyle.com",
"title": "Blue Sneakers",
"description": "<p>Lightweight everyday sneaker.</p>",
"brand": "boAt",
"categories": ["footwear", "sneakers"],
"tags": ["footwear", "sneakers"],
"variants": [
{
"id": "41234567890",
"title": "Default Title",
"sku": "BLU-SNK-01",
"options": [],
"price": { "current": 249900, "previous": 299900, "stockStatus": "InStock" }
}
],
"medias": [
{
"id": "0",
"type": "Image",
"url": {
"id": 9988776,
"product_id": 7403574100062,
"position": 1,
"created_at": "2021-05-14T10:12:00-04:00",
"updated_at": "2021-05-14T10:12:00-04:00",
"alt": "",
"width": 1200,
"height": 1200,
"src": "https://cdn.shopify.com/s/files/blue-sneakers.jpg",
"variant_ids": []
},
"variantIds": [],
"alt": ""
}
],
"options": [],
"hasImages": true,
"isSingleVariantOnly": true,
"isInStock": true,
"relatedProductRefs": null,
"productAgeDays": 1917,
"scrapedAt": "2026-08-15T00:00:00Z"
}

Store catalog-health summary

{
"type": "catalogHealthSummary",
"isChild": false,
"retailer": "boat-lifestyle.com",
"storeAccessible": true,
"accessNote": null,
"totalProductsScanned": 200,
"stockStatusKnownCount": 200,
"scrapedAt": "2026-08-15T00:00:00Z",
"outOfStockCount": 130,
"outOfStockPct": 65.0,
"noImagesCount": 0,
"noImagesPct": 0.0,
"singleVariantOnlyCount": 66,
"singleVariantOnlyPct": 33.1,
"oldestProductAgeDays": 2777,
"newestProductAgeDays": 5,
"medianProductAgeDays": 1152,
"newProductsLast30Days": 4,
"newProductsLast60Days": 7,
"newProductsLast90Days": 11,
"ageCohorts": { "0-30d": 4, "31-90d": 7, "91-365d": 22, "366d+": 167 }
}

If computeCompletenessProfile, flagNoImageProducts, flagSingleVariantProducts, or computeFreshnessCohorts is turned off, the corresponding fields on the summary row are pushed as null rather than omitted. When a store is inaccessible or nothing was scanned, every statistic field is null and only storeAccessible, accessNote, totalProductsScanned, and stockStatusKnownCount carry real values.


How does Shopify Scraper: Stock, Images & Product Updates compare to other Shopify scrapers?

FeatureShopify Scraper: Stock, Images & Product UpdatesGeneric alternative
Output formatTyped, normalized JSON with a stable schemaOften raw HTML or an ad hoc structure you parse yourself
Entity coverageProduct, variant, and media rows plus a per-store catalog-health summary row, in one runUsually product rows only — completeness and freshness stats are a script you write separately
Stock-status accuracyReads the store's own listing-page available flag; returns null rather than a guessed default when it can't be determinedCommonly assumes "in stock" when the field is missing
Store accessibility handlingPassword-protected stores are flagged storeAccessible: false with an accessNoteOften returns zero results with no explanation
Anti-bot handlingEscalates automatically from a direct connection to Apify Proxy (datacenter, then residential) on blocks or connection errorsUsually requires you to wire up your own proxy and retry logic

If you're building an AI agent or RAG pipeline, the output-format row is the decision-maker — parsing HTML inside an agent loop is a reliability failure mode, not a feature. The rest of the table is about how much of the completeness/freshness work is already done for you versus left as a follow-up script.


How many results can you scrape with Shopify Scraper: Stock, Images & Product Updates?

There's no hard cap in the input schema — maxResults defaults to 100 per store URL, has a declared minimum of 0, and no declared maximum; setting it to 0 removes the per-store cap entirely and the Actor scans every product it can reach. Pagination is handled automatically: the Actor pages through Shopify's own collection JSON endpoint (/collections/<handle>/products.json), which returns up to 250 products per page, requesting additional pages until it hits maxResults or runs out of pages. maxRecommendationsPerProduct is separately hard-capped at 20 regardless of what value is supplied. No benchmark run time is published — actual duration depends on the store, the number of stores in auditUrls, and whether the connection has to escalate through proxy tiers.


Integrate Shopify Scraper: Stock, Images & Product Updates and automate your workflow

Shopify Scraper: Stock, Images & Product Updates works with any language or tool that can send an HTTP request, and runs natively on Apify: Console runs, scheduled triggers, and webhooks are all available without any extra setup.

REST API integration

from apify_client import ApifyClient
# Replace <APIFY_API_TOKEN> with your token, and <owner> with the account
# this Actor is published under (shown at the top of its Console page).
client = ApifyClient("<APIFY_API_TOKEN>")
run = client.actor("<owner>/shopify-scraper-stock-images-and-product-updates").call(
run_input={
"auditUrls": ["https://boat-lifestyle.com"],
"maxResults": 200,
}
)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
if item["type"] == "product":
print(item["title"], item["isInStock"])

Works in Python, Node.js, Go, Ruby, cURL.

Automation platforms (n8n, Make, LangChain)

Any Apify Actor, including this one, can be triggered from n8n through Apify's official n8n node by selecting this Actor and passing the same input fields shown above. In Make, the Apify app's Run Actor module does the same. In LangChain (or any Python agent framework), the Apify integration's ApifyActorsTool / ApifyWrapper calls this Actor by name and returns dataset items directly to the agent.


Scraping publicly accessible Shopify product data is generally legal. Shopify Scraper: Stock, Images & Product Updates returns only publicly available product, variant, and store-level data — nothing behind a login or a storefront password, and password-protected stores are explicitly reported as inaccessible rather than bypassed.

This is business and product data, not personal data — product titles, prices, stock levels, and catalog statistics, not names or contact details of individuals — so this falls under a store's terms of service and database-rights considerations rather than GDPR or CCPA. Review the terms of service of any store you scrape at scale, particularly for commercial use, and consult legal counsel for commercial use cases involving bulk data collection.


Frequently asked questions

Does Shopify Scraper: Stock, Images & Product Updates work without a Shopify account?

Yes. No Shopify account, app installation, or API token is required — the Actor reads the same public product JSON a browser loads on any public storefront. If a store is password-protected, the corresponding summary row reports storeAccessible: false with an accessNote of "password_protected" instead of returning fabricated results.

How often is the scraped data updated?

Every run fetches live data directly from the store at run time — there is no caching layer. Re-run the Actor whenever you need current stock, pricing, or catalog-age numbers.

What happens when a product is out of stock, deleted, or a store is unreachable?

An out-of-stock product still returns a full row; isInStock is false and each affected variant's price.stockStatus is "OutOfStock". A deleted or renamed product simply produces no row for that handle. An unreachable or password-protected store still produces a catalogHealthSummary row with storeAccessible: false, accessNote set, and every statistic field null — never a silently empty result with no explanation.

Can I scrape password-protected or private Shopify stores?

No. Only publicly accessible storefronts, collections, and product pages are scraped. A password-protected store is detected and reported, not bypassed.

What does the Actor charge for?

The row_result pay-per-event charge applies to each product row pushed to the dataset. The per-store catalogHealthSummary summary row is pushed without that charged event, so it is not billed — filter a dataset export on type == "product" if you want to see only the billed rows.

Does Shopify Scraper: Stock, Images & Product Updates work for AI agent workflows and LLM pipelines?

Yes. It's callable as an HTTP endpoint by any agent framework via apify_client or a direct API call. Every response is typed JSON — no HTML, no selectors, no parsing step before passing results to an LLM or indexing them into a vector store.

How does it handle Shopify's anti-bot defenses?

The Actor starts with a direct connection (no proxy). On a blocked response (403, 429, 503) or a connection error, it automatically escalates: first to Apify Proxy's datacenter group, then to the residential group, retrying with backoff up to 3 residential attempts before giving up on that request. 429 responses are retried with a short delay before any proxy escalation.

How does Shopify Scraper: Stock, Images & Product Updates compare to other Shopify scrapers?

See the comparison table above — the observable differences are the built-in per-store catalog-health rollup, the honest null stock status when it truly can't be determined, and explicit reporting of inaccessible stores instead of silent empty results.

Does it return data in a format LLMs can use directly?

Yes. Typed, normalized JSON with stable field names — pass it directly into an LLM context window, index it into a vector store, or route it through an agent tool without a parsing step.

Can I use Shopify Scraper: Stock, Images & Product Updates without managing proxies?

Yes. The Actor starts with a direct connection and automatically escalates through Apify Proxy tiers on blocks or errors; you can also supply your own proxyConfiguration if you want to control that behavior.

What happens when Shopify changes its structure or blocks the scraper?

The Actor is maintained, and the output schema stays stable on your end — field names and types don't change even if the underlying scraping logic has to adapt. No specific turnaround time is published for fixes.


💬 Your feedback

Found a bug, or missing a field you need? We want to know. Reach out through the Actor's page on the Apify Store, or open an issue via Apify Console support — reports like this are how the schema stays accurate and the scraper stays maintained.