Shopify Store Scraper — Markets, Currencies & Catalogs
Pricing
from $0.01 / 1,000 results
Shopify Store Scraper — Markets, Currencies & Catalogs
Shopify Store Scraper extracts store data across markets, currencies, and product catalogs, including product titles, prices, variants, inventory, collections, and store details. Ideal for competitor research, pricing analysis, catalog monitoring, and e-commerce insights.
Pricing
from $0.01 / 1,000 results
Rating
0.0
(0)
Developer
SimpleAPI
Maintained by CommunityActor stats
0
Bookmarked
6
Total users
1
Monthly active users
3 days ago
Last modified
Categories
Share
Shopify Store Scraper — Markets, Currencies & Catalogs
Give this Shopify store scraper a storefront URL and it returns every market that store actually sells in, the real currency each market is served in, and how the catalogue and prices shift from one market to the next. Each run produces a store row (baseCurrency, marketCount, currencyCount, distinctCurrencies, isInternationalised) plus one market row per country (marketCode, currency, priceMedian, anchorPrice, catalogueCoveragePct). Ecommerce analysts, cross-border service vendors, and DTC competitive researchers use it to see how a brand really prices and stocks itself abroad — not what its country selector claims.
🧭 What is Shopify Store Scraper — Markets, Currencies & Catalogs?
It is an Apify Actor that profiles one or more public Shopify storefronts and answers three questions a standard store profile does not: which markets the store actually sells in, what currency each of those markets is really served in, and how the catalogue and price level differ market to market. Output is a flat, typed JSON dataset — no Shopify account, API key, or store login is required, since every field comes from the same public storefront endpoints (meta.json, products.json, collections.json, cart.js) that any visitor's browser already loads.
- 🗺️ Market discovery from three independent public signals — published regional (hreflang) alternates, localized storefront sections, and the store's shipping destination list — unioned and de-duplicated, or narrowed to one source with
discoverMarkets. - 💱 Real, pinned currency per market — each market is asked directly what it charges, not inferred from a flag icon or the store's declared currency.
- 📦 Localized catalogue size and price level per market, with coverage against the home market (
catalogueCoveragePct,priceMedian,priceMin,priceMax). - 🧷 One identical product priced across every market (
anchorPrice), for a like-for-like comparison instead of comparing medians of catalogues that are not the same. - 🎯 Country targeting that bypasses discovery — name exact ISO country codes in
probeCountriesand get exactly those markets, whether or not the store publishes them. - ⬇️ Standard Apify dataset export — JSON, CSV, Excel, XML or HTML table, plus a separate mirrored dataset of market-only rows when
emitMarketRowsis on.
📦 What data can I extract with Shopify Store Scraper — Markets, Currencies & Catalogs?
Every run returns three kinds of rows — a store row, one market row per probed market, and (only when a storefront can't be profiled) a status row — each carrying every field below.
Store row (type: "store", isChild: false) — one per storefront
| Field | Example value | Use case |
|---|---|---|
type | "store" | Filter store-level rows out of the mixed dataset |
isChild | false | Same filter, boolean form |
store_domain | "rothys.com" | Primary key joining a store row to its market rows |
store_url | "https://rothys.com" | The normalized storefront address that was profiled |
shop_name | "rothys.myshopify.com" | Store's real myshopify.com handle |
myshopifyDomain | "rothys.myshopify.com" | Same handle under its canonical field name |
shopId | 12345678 | Shopify's internal numeric shop ID |
storeName | "Rothy's" | Store's published display name |
country | "US" | Store's home country |
currency | "USD" | Store's home currency |
baseCurrency | "USD" | Store's declared home currency (same value as currency) |
moneyFormat | "${{amount}}" | How the store formats prices on its own pages |
locale | "en" | Storefront's declared content language |
storefrontStatus | "open" | open / limited_data / closed_to_public / not_shopify / unreachable / temporarily_unavailable |
excludedFromCoverage | false | true when this row should be dropped from coverage math |
theme_name | "Impulse" | Storefront theme label |
themeSchemaName | "impulse" | Theme's internal schema name |
theme_id | 123456789 | Numeric theme ID |
theme_version | "9.2.1" | Theme version string |
apps_installed | ["Klaviyo", "Shop Pay", "Yotpo"] | Apps the storefront itself evidences |
apps_by_source | {"theme_app_extension": [...], "app_proxy": [...], "storefront_signal": [...]} | Same list, broken out by how it was detected |
apps_count | 14 | Count of apps_installed |
total_products | 664 | Home-catalogue product count |
publishedProductsCount | 664 | Store's own published-count figure, for cross-check |
catalogueTruncated | false | true if a catalogue page failed mid-walk |
productPagesWalked | 3 | Pages read to build total_products |
total_variants | 2114 | Variant count across all products |
collections | ["Flats", "Sneakers", "New Arrivals"] | Collection titles |
collections_count | 198 | Collections found (paginated to completion) |
publishedCollectionsCount | 198 | Store's own published-count figure |
collectionPagesWalked | 1 | Pages read for collections |
categories | ["Shoes", "Bags"] | Distinct product_type values |
vendors | ["Rothy's"] | Distinct vendor values |
price_min | 45.0 | Cheapest home-catalogue price |
price_avg | 128.4 | Mean home-catalogue price |
price_max | 268.0 | Most expensive home-catalogue price |
products_on_sale | 42 | Products with a compare_at_price discount |
discount_pct_avg | 18.5 | Mean discount % across on-sale products |
maxDiscountPct | 40.0 | Largest single discount % found |
total_variants_available | 1890 | Variants currently in stock |
inventory_availability_pct | 89.4 | % of variants in stock |
oldest_product_date | "2015-03-02" | Earliest product created_at (date only) |
newest_product_date | "2026-07-30" | Latest product created_at (date only) |
products_with_images | 664 | Products carrying at least one image |
avg_images_per_product | 4.2 | Mean image count per product |
products_with_description | 660 | Products with non-empty body_html |
top_products | [{"title": "...", "url": "...", "price": 160.0}] | Ten newest products, most recent first |
marketCount | 35 | Distinct markets discovered from all sources |
localizedStorefrontCount | 35 | Discovered markets with their own path or domain |
marketsProbed | 8 | Markets actually probed this run |
discoveredMarketCountries | ["AT", "AU", "BR", "..."] | Every country code discovered, probed or not |
marketCountries | ["AT", "BR", "CA", "..."] | Country codes actually probed this run |
marketLocales | ["en-CA", "pt-BR"] | hreflang tags of the probed markets |
marketPaths | ["/en-ca", "/pt-br"] | URL path prefixes of the probed markets |
distinctCurrencies | ["ARS", "AUD", "BRL", "CAD", "CHF", "EUR"] | Currencies found among probed markets |
currencyCount | 6 | Count of distinctCurrencies |
isInternationalised | true | true when >1 currency or an alternate domain exists |
publishedAlternateCount | 40 | hreflang alternate links found on the homepage |
alternateDomains | [] | Separate-domain sibling storefronts detected (e.g. a .co.uk) |
marketDiscoverySources | {"published_alternates": 40, "localized_sections": 12, "shipping_list": 35} | Raw hit count per discovery source |
inputMarketPath | null | Market path supplied directly in the input URL, if any |
shipsToCountries | ["US", "CA", "GB", "..."] | Store's own declared shipping list |
shipsToCountryCount | 224 | Count of shipsToCountries |
declaredCurrency | "USD" | Duplicate of baseCurrency, kept for compatibility |
homeCountry | "US" | Duplicate of country |
unpinnedCurrency | "USD" | Currency returned by an un-pinned cart.js read of the home store |
storefrontQuotesByRequestOrigin | false | true when unpinnedCurrency disagrees with baseCurrency |
marketsWhereOriginChangedTheAnswer | 0 | Count of probed markets where the pinned and unpinned currency disagree |
pricesPinnedToCountry | "US" | Country code used to pin the home-catalogue price sample |
rootCatalogueCount | 492 | Home market's sitemap-counted product total |
catalogueCoverageByMarket | {"AT": 64.23, "BR": 64.23} | catalogueCoveragePct keyed by market code |
priceIndexByMarket | {"AT": {"index": 1.14, "median": 170.0, "currency": "EUR", "sameCurrencyAsBase": false}} | Each market's median price relative to the home market |
priceIndexBaseMarket | "ROOT" | Always "ROOT" — the home catalogue is the index base |
priceIndexFxAdjusted | false | Always false — the index is never currency-converted |
rootPriceMedian | 150.0 | Home market's median sample price |
priceLeaderByCurrency | {"USD": {"cheapestMarket": "US", ...}} | Cheapest/dearest computed separately within each currency group |
cheapestMarket | "FR" | Cheapest market in the headline currency group |
dearestMarket | "AT" | Dearest market in the headline currency group |
marketPriceSpreadPct | 3.03 | % spread between cheapest and dearest in that group |
priceComparisonCurrency | "EUR" | Which currency group the headline comparison was made in |
anchorProductHandle | "womens-casual-clog-revelvet-syrah" | Product handle used for the like-for-like check |
anchorPriceRoot | 160.0 | Anchor product's home-market price |
anchorPriceByMarket | {"CA": {"price": 235.0, "currency": "CAD"}} | Anchor product's price, per market |
anchorMarketsCovered | 7 | Markets where the anchor product was actually found and priced |
scraped_at | "2026-08-08T00:00:00+00:00" | ISO timestamp the row was collected |
scrape_duration_sec | 41.2 | Wall-clock seconds spent profiling this store |
💱 Market row (type: "market", isChild: true) — one per probed market
The decision-driving data attached to every market: its own currency, its own catalogue size, and its own price level, so a market can be judged on what it is actually offered rather than the store's home numbers.
| Field | Example value |
|---|---|
type / isChild | "market" / true |
store_domain, store_url | "rothys.com", "https://rothys.com" |
marketCode | "BR" |
marketPath | "/pt-br" |
marketUrl | "https://rothys.com/pt-br" |
marketLocaleTag | "pt-BR" |
alternateUrl | null |
isAlternateDomain | false |
discoveredVia | ["localized_sections", "published_alternates", "shipping_list"] |
inShipsToList | true |
currency | "BRL" |
currencySource | "localized_storefront" (or "alternate_storefront" / "country_selection") |
storeDeclaredCurrency | "USD" |
currencyMatchesStore / currencyIsBaseCurrency | false / false |
currencyUnpinned | "USD" |
currencyDependsOnRequestOrigin | false |
pricePinnedToCountry | "BR" |
marketProductCount | 316 |
marketProductCountSource | "market_index" |
catalogueCoveragePct | 64.23 |
priceMedian / priceMin / priceMax | 1050.0 / 720.0 / 1890.0 |
priceCurrency | "BRL" |
priceSampleSize | 100 |
priceSampleVariants | 1604 |
anchorProductHandle | "womens-casual-clog-revelvet-syrah" |
anchorPrice | 1050.0 |
anchorPriceMoneyShape | "minor_units_integer" |
scraped_at | "2026-08-08T00:12:41+00:00" |
🎯 Targeting and discovery fields
The fields that drive which markets get probed and how they're segmented: marketCode (ISO country), discoveredVia (which of the three discovery sources found it), inShipsToList, isAlternateDomain/alternateUrl (separate-domain markets), and — on the store row — marketDiscoverySources (per-source hit counts) and discoveredMarketCountries (everything found, whether or not it was probed). These are the fields the input parameters below act on: discoverMarkets picks which sources feed them, probeCountries bypasses them entirely for named codes, and maxMarkets caps how many get probed.
Status row (type: "status") — emitted instead of a store row
| Field | Example value |
|---|---|
type | "status" |
isChild | false |
store_url, store_domain | "https://example-store.com", "example-store.com" |
storefrontStatus | "unreachable" / "temporarily_unavailable" / "not_shopify" / "incomplete" / "no_input" |
statusDetail | "This address does not present as a Shopify storefront." |
excludedFromCoverage | true |
scraped_at | "2026-08-08T00:00:00+00:00" |
🆚 How does this Shopify store scraper differ from the official Shopify API?
Shopify's own Storefront API can return a store's markets, localization and international prices — but every Storefront API access token is scoped to a single store, generated and approved by that store's own owner. You cannot use it to survey which markets and currencies a competitor's or a prospect's store serves, because you don't hold — and cannot get — a token for a store you don't administer. That scoping is documented in Shopify's own developer docs as of 2026-08-15 (shopify.dev — Getting started with the Storefront API; shopify.dev — Building localized experiences with the Storefront API and Shopify Markets).
| Feature | Shopify Storefront API | This Actor |
|---|---|---|
| Credential needed | Access token generated and approved by the store owner | None — works from a public storefront URL |
| Coverage across stores you don't run | One store per token; cannot query a store you don't administer | Any number of public storefronts in one run, via startUrls |
| Market discovery | You must already know a store's markets to query it | Discovers markets from three independent public signals automatically |
| Currency per market | Returns the store's configured market list | Directly probes each market's live currency, pinned per country |
| Cross-market price comparison | You write your own cart/context calls, per market, per store | anchorProductCheck prices one identical product across every probed market in a single run |
| Setup | Register an app, get a token approved by the store | Add a URL and run |
| Output | Raw GraphQL response shape you define | Flat, typed dataset rows, same schema for every store |
Why can't I just query another store's markets with the Storefront API?
Because the token is scoped to one store. Building a competitive or market-research view — "which of these 40 brands sell into Brazil, and in what currency" — would mean getting each of those 40 merchants to hand you their own access token, which they have no reason to do. This Actor sidesteps that entirely: it reads the same public JSON endpoints (meta.json, products.json, cart.js) any visitor's browser already receives when it loads the store, so no token or store relationship is required, for any number of storefronts.
Use the Storefront API when you're building or operating your own store's storefront or headless frontend. Use this Actor when you need market, currency and price data about storefronts you do not run.
🎯 How to use data extracted from Shopify?
Ecommerce and DTC competitive analysts
Feed a list of competitor startUrls, keep fetchLocalizedCatalogue and anchorProductCheck on, and get back each brand's real footprint: currencyCount, distinctCurrencies, marketPriceSpreadPct, and the anchor product's price in every market. This turns "does Brand X sell internationally" from a guess based on a footer flag icon into a table of currencies, coverage percentages and prices you can sort and chart.
Cross-border service providers
3PL, tax, FX and localization vendors run a fixed prospect list through the actor on a schedule, filtering on isInternationalised and currencyCount to separate stores that are already multi-market from ones that are still domestic — the latter being the better outreach target for "help me expand," the former for "help me optimize what I already have."
Market research and intelligence
Run a set of stores in one category and aggregate distinctCurrencies, catalogueCoverageByMarket and priceIndexByMarket across them to map which regions a category is under-served in, or how consistently brands price the same product type abroad versus at home.
AI agents and automated pipelines
Because output is one flat JSON schema per row regardless of the store, an agent can call this Actor as a tool over any storefront URL and read baseCurrency, marketCount and anchorPriceByMarket straight into a pricing or expansion-planning pipeline without per-store parsing logic.
🔼 Input sample
| Parameter | Required | Type | Description | Example value |
|---|---|---|---|---|
startUrls | Yes | array | One or more Shopify storefronts to profile. A bare domain works too. Each storefront produces one store row plus one row per market. | ["https://rothys.com", "https://www.allbirds.com"] |
storefrontUrls | No | array | Optional extra storefronts, merged with startUrls and de-duplicated. | ["https://gymshark.com"] |
discoverMarkets | No | string (enum) | Which signals build the candidate market list: all (default, union of all sources), published_alternates, localized_sections, shipping_list. | "all" |
probeCountries | No | array | Two-letter country codes to probe whether or not the store published them. Listing codes here gets you exactly those markets — maxMarkets never trims a list you typed yourself. | ["US", "CA", "GB", "DE", "BR"] |
maxMarkets | No | integer (min 1, max 60, default 8) | How many discovered markets are probed per store. Localized storefronts are always probed before shipping-only countries. Ignored when probeCountries is set. | 8 |
fetchLocalizedCatalogue | No | boolean (default true) | Reads each market's own catalogue for product count, coverage and price range. Off runs currency-only. | true |
priceSampleSize | No | integer (min 10, max 250, default 100) | Products read per market to compute median/min/max price. Higher is more stable and slower. | 100 |
anchorProductCheck | No | boolean (default true) | Picks one product and prices it in every market for a like-for-like comparison. | true |
emitMarketRows | No | boolean (default true) | Adds a labelled row per market and mirrors those rows into a separate per-run market dataset. Off returns store rows only. | true |
proxyConfiguration | No | object (proxy editor, default {"useApifyProxy": false}) | Optional connection settings — leave as-is unless a specific storefront is slow to respond. | {"useApifyProxy": false} |
{"startUrls": ["https://rothys.com", "https://www.allbirds.com"],"discoverMarkets": "all","maxMarkets": 8,"fetchLocalizedCatalogue": true,"priceSampleSize": 100,"anchorProductCheck": true,"emitMarketRows": true}
Common pitfall: probeCountries codes must be exactly two letters — a three-letter code like "USA" is silently ignored (only 2-character entries are used). And once you list any codes there, maxMarkets stops applying entirely: the cap only ever trims a discovered list, never one you typed by hand, so you always get every country you named, plus nothing else.
🔽 Output sample
Output is typed, normalized JSON with the same schema for every store — no per-brand parsing needed. Every run writes to the Actor's default dataset, which exports to JSON, CSV, Excel, XML or HTML table like any Apify dataset; market rows are also mirrored into a separate per-run market-only dataset when emitMarketRows is on.
{"type": "store","isChild": false,"store_domain": "rothys.com","store_url": "https://rothys.com","shop_name": "rothys.myshopify.com","storefrontStatus": "open","country": "US","baseCurrency": "USD","moneyFormat": "${{amount}}","locale": "en","apps_count": 14,"apps_installed": ["Attentive", "Google Analytics 4", "Klaviyo", "Shop Pay"],"total_products": 664,"publishedProductsCount": 664,"collections_count": 198,"marketCount": 35,"marketsProbed": 8,"distinctCurrencies": ["ARS", "AUD", "BRL", "CAD", "CHF", "EUR"],"currencyCount": 6,"isInternationalised": true,"alternateDomains": [],"rootCatalogueCount": 492,"priceIndexByMarket": {"AT": { "index": 1.1409, "median": 170.0, "currency": "EUR", "sameCurrencyAsBase": false }},"priceIndexFxAdjusted": false,"anchorProductHandle": "womens-casual-clog-revelvet-syrah","anchorPriceRoot": 160.0,"anchorPriceByMarket": { "CA": { "price": 235.0, "currency": "CAD" } },"cheapestMarket": "FR","dearestMarket": "AT","marketPriceSpreadPct": 3.03,"priceComparisonCurrency": "EUR","scraped_at": "2026-08-08T00:00:00+00:00","scrape_duration_sec": 41.2}
{"type": "market","isChild": true,"store_domain": "rothys.com","marketCode": "BR","marketPath": "/pt-br","marketUrl": "https://rothys.com/pt-br","marketLocaleTag": "pt-BR","isAlternateDomain": false,"discoveredVia": ["localized_sections", "published_alternates", "shipping_list"],"inShipsToList": true,"currency": "BRL","currencySource": "localized_storefront","currencyIsBaseCurrency": false,"marketProductCount": 316,"catalogueCoveragePct": 64.23,"priceMedian": 1050.0,"priceCurrency": "BRL","priceSampleSize": 100,"priceSampleVariants": 1604,"anchorProductHandle": "womens-casual-clog-revelvet-syrah","anchorPrice": 1050.0,"anchorPriceMoneyShape": "minor_units_integer","scraped_at": "2026-08-08T00:12:41+00:00"}
⚠️ Only store and market rows are billed. Both are pushed with the row_result charged event. Status rows — unreachable, temporarily_unavailable, not_shopify, incomplete, no_input — are pushed with no charged event at all, so an unreachable storefront costs nothing. Filter them out of any analysis with type != "status" (equivalently, excludedFromCoverage == false).
🎚️ How do you filter and target specific markets?
This is the actual control surface, not a generic filter list — every knob below maps directly to an input parameter.
Discovery source vs named countries. discoverMarkets: "all" unions three public signals and is the most complete option for most stores, since real coverage varies by brand and most publish only one or two of the three. Switch to a single source (published_alternates, localized_sections, or shipping_list) when you already know which signal a given storefront uses and want a faster, narrower run. probeCountries bypasses discovery entirely — name exact ISO codes and get exactly those markets, whether the store published them or not.
Volume control. maxMarkets (1–60, default 8) caps how many discovered markets get probed, with localized storefronts always probed ahead of shipping-only countries. It never trims a probeCountries list — that list is honoured in full, so five codes always means five market rows.
Depth vs speed. fetchLocalizedCatalogue (default on) turns per-market catalogue and price reads on or off; priceSampleSize (10–250, default 100) trades sample stability for run time; anchorProductCheck (default on) adds the one-product, every-market comparison.
{ "startUrls": ["https://rothys.com"], "probeCountries": ["US", "CA", "GB", "DE", "BR"] }
{ "startUrls": ["https://rothys.com"], "maxMarkets": 20, "fetchLocalizedCatalogue": false, "anchorProductCheck": false }
{ "startUrls": ["https://rothys.com"], "discoverMarkets": "localized_sections", "priceSampleSize": 250, "anchorProductCheck": true }
The first pins five specific countries regardless of what the store discloses. The second is a fast, currency-only sweep across up to 20 discovered markets. The third is a slower, deeper price audit restricted to markets with their own localized storefront section.
▶️ Want to try other Shopify scrapers?
| Scraper | What it extracts |
|---|---|
| Shopify Merchant Scraper: Niche & Keyword Store Search | Discovers Shopify stores by niche or keyword |
| Shopify Products Scraper With Variant & SKU Rows | Per-product, per-variant catalogue rows for a given store |
| Shopify Scraper: Sales Channel & Product Templates Data | Sales-channel and theme/template metadata per store |
| Amazon Search Scraper By Country & Currency | Cross-country pricing for Amazon search results |
| Google Play Scraper: Country Pricing & In-App Purchases | Cross-country app pricing and in-app purchase data |
🔌 How to extract Shopify data programmatically
Every run is a standard Apify Actor call: one API call starts it, one call reads back structured JSON — no separate signup or credential beyond your Apify API token.
Python example
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_API_TOKEN>")run = client.actor("your-username/shopify-store-scraper-markets-currencies-catalogs").call(run_input={"startUrls": ["https://rothys.com"],"probeCountries": ["US", "CA", "GB", "DE"],"anchorProductCheck": True,})for row in client.dataset(run["defaultDatasetId"]).iterate_items():if row.get("type") == "market":print(row["marketCode"], row["currency"], row["priceMedian"])
Export to spreadsheets or CRM
Apify's dataset export handles CSV/Excel directly — map store_domain to a "Store" column, baseCurrency/currency to "Currency", marketCount/marketCode to "Markets", and anchorPrice/priceMedian to your pricing columns. Import the CSV into Sheets, Excel, or a CRM's bulk-import flow with no reshaping needed.
⚖️ Is it legal to scrape Shopify storefronts?
Yes. This Actor reads only public storefront data — store profile, market list, currencies, catalogue and price figures — that Shopify serves to any visitor's browser without a login. These are business and product records, not personal data about identifiable individuals, so GDPR and CCPA do not govern them; the relevant frameworks are Shopify's own terms of service, which govern what a third party may do with data read from a merchant's storefront, and database-rights law in jurisdictions where a compiled catalogue is separately protected. Consult legal counsel for commercial applications involving bulk storage of personal data.
❓ Frequently asked questions
What happens if a store has closed or isn't on Shopify anymore?
The run reports a status row instead of guessing. storefrontStatus is closed_to_public for a password-locked store, not_shopify for a non-Shopify address, unreachable/temporarily_unavailable for a store that didn't respond, and incomplete if profiling failed partway through. All of these carry excludedFromCoverage: true so they never quietly drag down a coverage figure.
Can I get catalogue and pricing data along with the market list?
Yes — fetchLocalizedCatalogue (default on) adds marketProductCount, catalogueCoveragePct, priceMedian, priceMin and priceMax per market, and anchorProductCheck (default on) adds anchorPrice for one identical product priced everywhere it's found. Turn both off for a currency-only run.
How accurate is the price and currency data?
The Actor returns each market's price and currency exactly as its storefront answers at request time, pinned to that specific country — never inferred from an unpinned request, which can answer with the wrong currency entirely. Prices move with the merchant's own pricing changes, so re-run periodically if you're tracking price changes over time.
How many markets can I get per run?
Up to maxMarkets (maximum 60, default 8) discovered markets per store, or exactly as many markets as you name in probeCountries — that list is never trimmed. There is no cap on how many storefronts you list in startUrls.
What's the real difference between maxMarkets and probeCountries?
maxMarkets caps a discovered list built from the store's own published signals; probeCountries replaces discovery altogether with countries you name explicitly, and is honoured in full regardless of maxMarkets. Use probeCountries when you need the same fixed set of countries for every store in a comparison run.
Does this scraper work with Claude, ChatGPT, and AI agent frameworks?
It's callable as a standard Apify Actor run by any agent framework or HTTP client via apify_client or a direct REST call — there's no separate MCP server documented for this Actor.
How is this different from a plain Shopify product scraper?
A product scraper returns one row per SKU in a single market. This Actor never emits per-product rows at all — it emits one store summary plus one row per market, with currency, catalogue coverage and one anchor product's price compared across every market in the run. If you need line-item product and variant data for a single store, pair this with SimpleAPI's own Shopify Products Scraper instead.
Can I use this without a Shopify API key or developer account?
Yes. Supply a public storefront URL — a bare domain works — and run it. No Shopify account, API key, access token, or store login of any kind is required.
✅ Conclusion
Shopify Store Scraper — Markets, Currencies & Catalogs turns "does this brand sell internationally" from a guess into a dataset: which markets a store actually serves, what currency each one is really quoted in, and how catalogue size and price level shift market to market, down to one identical product priced everywhere it's carried. It's built for ecommerce analysts, cross-border service vendors, and market researchers who need that comparison across any number of public Shopify storefronts without a token or login for any of them. Add a storefront URL and run it on the Apify platform to get your first store and market rows in one pass.