E-commerce Platform Detector: Identify & Extract Any Store avatar

E-commerce Platform Detector: Identify & Extract Any Store

Pricing

from $0.74 / 1,000 record scrapeds

Go to Apify Store
E-commerce Platform Detector: Identify & Extract Any Store

E-commerce Platform Detector: Identify & Extract Any Store

Point it at any online store and it identifies the platform (Shopify, WooCommerce, BigCommerce, Squarespace or Magento) then extracts the catalogue using that platform's public API.

Pricing

from $0.74 / 1,000 record scrapeds

Rating

0.0

(0)

Developer

Arman Hossain

Arman Hossain

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

0

Monthly active users

21 days ago

Last modified

Share

E-commerce Platform Detector: Point it at any storefront and get the platform, a confidence score and the evidence, then the catalogue pulled through that platform's own API

E-commerce Platform Detector takes a storefront URL, works out which platform it runs on, Shopify, WooCommerce, BigCommerce, Squarespace or Magento, and then pulls the catalogue through that platform's own public endpoint. One input, one output shape, whatever the store is built on.

Every record carries the platform, a confidence score and the exact evidence behind it, so you can audit the detection instead of trusting it.

Agent skill: SKILL.md

https://api.apify.com/v2/key-value-stores/t7YoTxpZEJOWvw4Ug/records/ecommerce-platform-detector.md

How detection works

Two stages, both cheap:

  1. Passive fingerprinting, the store's home page is fetched once and scored against response headers (powered-by: Shopify, server: Squarespace, x-magento-*), Set-Cookie names (_shopify_essential, woocommerce_*, Shopper-Pref), and markup markers (cdn11.bigcommerce.com, /wp-content/plugins/woocommerce, Static.SQUARESPACE_CONTEXT, /static/version*/frontend/).
  2. Active confirmation, the candidate platform's catalogue endpoint is probed directly. A hit both proves the platform and proves the catalogue is reachable, which is why probes outweigh any single passive marker.

Stage 2 matters more than it sounds. A headless storefront can serve markup with zero platform markers in it, bulk.com renders a custom front end whose HTML mentions Magento nowhere, and is still identified with confidence 70 because /graphql and /rest/V1/directory/currency both answer.

Scores are additive and capped at 100. Below 30 the store is reported as platform: "unknown" with whatever evidence was found, never as an error.

What you get

Output fieldMeaning
store, storeUrlHostname and canonical origin after redirects
detectedPlatformshopify, woocommerce, bigcommerce, squarespace, magento or unknown
confidence0-100. Anything at 30 or above named a platform
detectionSignalsThe individual markers that produced the score, each tagged header:, cookie:, html: or probe:
extractionMethodWhich route the products came from, see the table below
productId, sku, handlePlatform-native identifiers
title, vendor, productTypeProduct name, brand and category, where the platform exposes them
price, compareAtPrice, currencyLowest current price, the struck-through price if on sale, and the ISO currency code
availableWhether any variant is purchasable
variantCountNumber of variants
imagesUp to 10 image URLs
urlDirect link to the product page
scrapedAtRun timestamp

In detectOnly mode each record instead carries platformScores (every platform's score, not just the winner), httpStatus and finalUrl.

A RUN_SUMMARY record in the key-value store holds a per-store breakdown, a platform histogram, the filters used and any store that failed.

Extraction routes

PlatformMethodEndpoint
Shopifyshopify-products-json/products.json?limit=250&page=N, currency from /meta.json
WooCommercewoocommerce-store-api/wp-json/wc/store/v1/products (falls back to the pre-v1 path)
Squarespacesquarespace-format-jsonStore collections discovered from the sitemap, read via ?format=json
Magentomagento-graphqlPOST /graphql with a paged products(filter: {}) query
BigCommerce, unknown, or any closed APIjsonld-sitemapProduct URLs from robots.txt / sitemap.xml / xmlsitemap.php, then schema.org Product JSON-LD from each page

Extraction degrades. It does not fail. If a store is confidently Shopify but has /products.json switched off, the Actor logs that and falls back to sitemap + JSON-LD rather than returning nothing. BigCommerce has no anonymous catalogue API at all, so it always takes the JSON-LD route, and still returns structured products.

Common use cases

Audit a competitor set on mixed platforms. One input, one output schema, regardless of what each competitor is built on.

{
"storeUrls": [
"https://www.allbirds.com",
"https://barefootbuttons.com",
"https://www.berlinpackaging.com",
"https://www.aaksonline.com"
],
"maxProductsPerStore": 250
}

Qualify e-commerce leads by platform. Detection only, one cheap record per domain, no catalogue.

{
"storeUrls": ["allbirds.com", "gymshark.com", "bulk.com", "aaksonline.com"],
"detectOnly": true
}

Build a universal price monitor. Restrict to the platforms whose APIs give you exact prices, and run it on a schedule.

{
"storeUrls": ["https://www.allbirds.com", "https://barefootbuttons.com"],
"platforms": ["shopify", "woocommerce"],
"maxProductsPerStore": 1000
}

Quick start

One store, first 100 products:

{
"storeUrls": ["https://www.allbirds.com"]
}

Just tell me what it runs on:

{
"storeUrls": ["allbirds.com"],
"detectOnly": true
}

Input

FieldTypeDefaultNotes
storeUrlsarray-Required. Store home pages. Bare domains work; redirects are followed.
detectOnlybooleanfalseEmit one detection record per store and skip extraction.
maxProductsPerStoreinteger100Cap per store. 0 = no limit.
platformsarray[]Restrict extraction to these platforms. Empty = all. Add unknown to keep unidentified stores.

Combinations that make sense together:

  • detectOnly: true + a long storeUrls list: the lead-qualification mode. One record and roughly two to four requests per domain.
  • platforms + a long list: everything is still detected (and reported in RUN_SUMMARY.stores), but only matching stores are extracted. You get the tech-stack census for free while paying for products from just the platforms you care about.
  • A locale sub-path in storeUrls. Pass ikea.com/us/en/ rather than ikea.com. Detection normalises to the origin, but URLs under the sub-path you gave are preferred during sitemap extraction and used when building Magento product links.
  • maxProductsPerStore: 0 on a big Shopify store: expect tens of thousands of products; raise the run timeout to match.

Output example

{
"store": "www.allbirds.com",
"storeUrl": "https://www.allbirds.com",
"detectedPlatform": "shopify",
"confidence": 100,
"detectionSignals": [
"header: powered-by: Shopify response header",
"cookie: _shopify_* session cookie",
"html: cdn.shopify.com asset host",
"probe: /products.json returns a Shopify product array",
"probe: /meta.json exposes a myshopify_domain"
],
"extractionMethod": "shopify-products-json",
"productId": 7292464955472,
"title": "Men's Cruiser - Shadow Blue (Natural White Sole)",
"handle": "mens-cruiser-shadow-blue-natural-white-sole",
"vendor": "Allbirds",
"productType": "Shoes",
"price": 105,
"compareAtPrice": null,
"currency": "USD",
"available": true,
"sku": "A12856M080",
"variantCount": 13,
"images": ["https://cdn.shopify.com/s/files/1/1104/4168/files/All-birds_0010.png?v=1783535519"],
"url": "https://www.allbirds.com/products/mens-cruiser-shadow-blue-natural-white-sole",
"scrapedAt": "2026-08-06T11:49:23.335Z"
}

A detectOnly record:

{
"store": "www.bulk.com",
"storeUrl": "https://www.bulk.com",
"detectedPlatform": "magento",
"confidence": 70,
"detectionSignals": [
"probe: Magento GraphQL products query succeeds at /graphql",
"probe: Magento REST answers at /rest/V1/directory/currency"
],
"platformScores": { "magento": 70 },
"extractionMethod": "magento-graphql",
"httpStatus": 200,
"finalUrl": "https://www.bulk.com/uk/",
"scrapedAt": "2026-08-06T11:52:04.118Z"
}

RUN_SUMMARY looks like this:

{
"storesRequested": 5,
"storesFailed": 0,
"failures": [],
"stores": [
{ "store": "www.allbirds.com", "detectedPlatform": "shopify", "confidence": 100, "detectionSignals": ["."], "extractionMethod": "shopify-products-json", "products": 291 },
{ "store": "barefootbuttons.com", "detectedPlatform": "woocommerce", "confidence": 100, "detectionSignals": ["."], "extractionMethod": "woocommerce-store-api", "products": 61 },
{ "store": "www.berlinpackaging.com", "detectedPlatform": "bigcommerce", "confidence": 100, "detectionSignals": ["."], "extractionMethod": "jsonld-sitemap", "products": 60 }
],
"platformBreakdown": { "shopify": 1, "woocommerce": 1, "bigcommerce": 1 },
"itemsSaved": 412,
"filters": { "detectOnly": false, "maxProductsPerStore": 0, "platforms": [] },
"finishedAt": "2026-08-06T11:53:41.902Z"
}

Limits and behaviour

  • An unknown platform is a result, not an error. Stores below the confidence threshold are reported as platform: "unknown" with their evidence, and still go through sitemap + JSON-LD extraction. In testing, ikea.com, which matches none of the five fingerprints, returned fully structured products this way.
  • Confidence is additive and capped at 100. Two independent probes plus a header marker will hit the cap; a single weak HTML marker will not clear the threshold of 30 on its own.
  • WordPress is not WooCommerce. Generic WordPress markers score low on purpose; the decisive signal is the Store API answering at /wp-json/wc/store/v1/products.
  • Prices are normalised. WooCommerce's Store API returns money in minor units ("195" with currency_minor_unit: 2); this Actor divides it out, so you get 1.95. Squarespace variant prices come from priceMoney, not the frequently-zero product-level field.
  • price is the lowest current variant price, not the price of a specific variant. compareAtPrice is the struck-through original where the platform reports one.
  • Magento product URLs are the Magento-canonical path. For a standard install that is the live URL. Heavily customised or headless storefronts sometimes route products elsewhere, in which case the link points at the canonical path rather than the custom one, the price, SKU and stock status are still exact.
  • JSON-LD extraction is only as good as the store's markup. Products without a schema.org Product block are skipped rather than guessed at, and the Actor reports how many sitemap URLs it scanned in the log and in the failure note.
  • Sitemap crawling is bounded. At most 12 sitemap files and 6 child sitemaps from an index, with product-shaped URLs prioritised.
  • Bare domains are recovered. Plenty of stores serve a valid certificate on www. and a broken chain on the apex, berlinpackaging.com is one. If the host you gave fails outright, the other variant is tried once before the store is written off.
  • One store failing never aborts the run. Detection and extraction failures are recorded in RUN_SUMMARY.failures and the run continues.
  • Transient errors are retried. 429 and 5xx get up to three attempts with linear backoff. A 4xx from a probe is treated as a signal (that platform is absent), not a failure.
  • Public catalogue data only. No authentication, no personal data, no access-control bypass, every endpoint used is one the platform publishes for front-end code to read.

Verified against real stores

Detection and extraction were run against five live storefronts on five different platforms, plus one store matching none of the fingerprints:

StoreDetectedConfidenceRouteResult
allbirds.comshopify100shopify-products-json291 products, powered-by header + _shopify_* cookies + both probes
barefootbuttons.comwoocommerce100woocommerce-store-api61 products, plugin asset path + Store API probe
berlinpackaging.combigcommerce100jsonld-sitemap60/60 requested products, all with price, SKU and images; no anonymous API, so JSON-LD was used
aaksonline.comsquarespace100squarespace-format-json41 products, server: Squarespace + ?format=json probe
bulk.com/uk/magento70magento-graphqlZero HTML markers, headless front end; identified entirely by the /graphql and /rest/V1 probes
ikea.com/us/en/unknown0jsonld-sitemapNo fingerprint matched; products still extracted from schema.org markup, in USD from the /us/en/ catalogue

API example

curl -X POST "https://api.apify.com/v2/acts/arman-bd~ecommerce-platform-detector/run-sync-get-dataset-items?token=YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"storeUrls": ["https://www.allbirds.com", "https://barefootbuttons.com"],
"maxProductsPerStore": 50
}'

JavaScript example

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('arman-bd/ecommerce-platform-detector').call({
storeUrls: ['allbirds.com', 'barefootbuttons.com', 'bulk.com'],
detectOnly: true,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const s of items) console.log(`${s.store} → ${s.detectedPlatform} (${s.confidence})`);

Defaults: 2 GB memory, 30 min timeout.

FAQ

Do I need a proxy? No. Proxy configuration is not required to run this Actor.

Do I need an account on the source? No, on any of the five platforms.

What happens if a store is unavailable? It is recorded in RUN_SUMMARY.failures and the run continues with the rest. The Actor only throws if no store could be processed at all.

Why did a store come back as unknown? Either it runs on a platform outside the five fingerprinted here (Salesforce Commerce Cloud, Wix, Ecwid, custom builds), or it is a headless front end whose APIs are not at the standard paths. Check platformScores in detectOnly mode to see whether anything scored at all, products may still have been extracted from JSON-LD.

Why does a BigCommerce store use jsonld-sitemap? BigCommerce's storefront GraphQL API requires a bearer token that stores do not publish, so there is no anonymous catalogue endpoint. Sitemap plus schema.org markup is the honest route, and it works.

Can I get variant-level prices? Not as separate records, price is the lowest live variant price and variantCount tells you how many there are. This keeps one row per product across all five platforms.

Why is currency sometimes null? Not every store declares one in a machine-readable place. Shopify reads it from /meta.json, WooCommerce and Squarespace return it per product, and JSON-LD supplies priceCurrency when the store publishes it.

Can I schedule it? Yes, it is designed for scheduled runs. Diff on productId plus price for price monitoring, or on detectedPlatform to catch re-platforming.

Can I integrate it with something else? Yes, Apify API, client libraries, webhooks, scheduled runs, dataset exports (JSON/CSV/Excel) or MCP. Output is structured JSON.