Shopify Store Leads — Catalog Size, Apps, Contacts
Pricing
from $4.50 / 1,000 qualified stores
Shopify Store Leads — Catalog Size, Apps, Contacts
Find and qualify Shopify stores, or enrich domains you own. Each lead returns catalog size, price band, theme, installed apps, published policies, new products a month, emails, phones and socials. Filter by country, category, keyword, size, ships-to, price or apps. You pay only for rows you keep.
Pricing
from $4.50 / 1,000 qualified stores
Rating
0.0
(0)
Developer
Richard Feng
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
3 hours ago
Last modified
Categories
Share
Shopify store leads you can qualify before you reach out. Every row is one store: its business emails, phone numbers, social profiles and address — and how big it is, what it runs, and whether it is still selling. Find stores by what they sell, where they are and what they have installed, or paste the domains you already have. You pay only for stores that match your filters.
Why choose this Actor?
Know a store before you pitch it. Most Shopify lead lists tell you a store exists and hand you an email address. This one also returns the product count, the price band, the product types and vendors, the theme and the installed apps, how many new products the store publishes a month and how many days since its last. A 6,500-product catalog and a 13-product boutique look the same in a list of emails; here they don't.
Contacts in the same row. Business emails, phone numbers and social profiles from the
store's page on the Shop app, its storefront and its own contact page — plus its business
address and its Shop app rating. Every address the store publishes — info@, hey@,
kundenservice@ alike — except the ones nobody reads, like no-reply@.
Filter on what your pitch depends on. Country, product category, keyword, catalog size, average price, the countries a store ships to, stock, recent publishing, the apps a store runs — or has not installed yet — the social networks it links, and whether it publishes an email or a phone number. A keyword or a category is searched on the Shop app, Shopify's marketplace, so you find stores by what they actually sell.
Pay only for stores that match. A store your filters reject is never returned and never charged, and a store reached twice in one run is charged once. $5.00 per 1,000 stores on the Free plan, down to $4.50 on Business.
🚀 Quick start
- Click Try for free. The input opens prefilled with a few well-known stores: start it as it is, and within a minute you have rows to look at.
- To profile stores you already know, paste their domains into Store URLs — one per
line;
gorjana.comandhttps://gorjana.comboth work. - To find new stores instead, leave Store URLs empty and set a Keyword or a Product category, then any filters — Countries, Minimum products, Published a product within (days), the apps a store should or should not run.
- Set Maximum stores. It caps how many rows the run returns, and so the most it can charge you.
- Click Start, then download the results from the Storage tab as JSON, CSV, Excel or XML — or pull them from the API.
Start small, check the rows look how you expect, then raise Maximum stores.
💡 What people use it for
Sell to stores that run an app you integrate with. Stores running Klaviyo or Okendo that link an Instagram account, in the US and the UK:
{ "hasApps": ["klaviyo", "okendo"], "hasSocials": ["instagram"], "countries": ["US", "GB"], "maxItems": 200 }
Find stores that don't show a competitor's app yet. Stores on Klaviyo with no reviews app on their storefront:
{ "hasApps": ["klaviyo"], "excludeApps": ["judge-me", "loox", "okendo", "stamped", "yotpo"], "countries": ["US"], "maxItems": 200 }
Build a list of active stores in a niche. US jewellery stores with a real catalog that published a product in the last 90 days:
{ "countries": ["US"], "category": "jewelry", "minProducts": 50, "activeWithinDays": 90, "maxItems": 500 }
Find stores by what they sell, each with its Shop app rating and business address:
{ "query": "coffee", "countries": ["US"], "maxItems": 100 }
Qualify mid-market stores that ship to you, are trading, and can be contacted:
{ "shipsToCountries": ["US"], "minAvgPrice": 5000, "maxAvgPrice": 30000, "inStockOnly": true, "requireEmail": true, "maxItems": 200 }
Profile stores you already know:
{ "storeUrls": ["gorjana.com", "allbirds.com"], "maxItems": 10 }
📋 Input
Everything is optional. With a query or a category, the stores come from the Shop app's
search for it, and from nowhere else. With neither, the Actor discovers stores from its
built-in list of 6,542 verified stores, then from Common Crawl. Either way it looks each
store it keeps up on the Shop app.
| Field | Type | Default | What it does |
|---|---|---|---|
storeUrls | array | — | Domains to profile. Set this and discovery is skipped entirely. |
query | string | — | Find stores selling this: searched on the Shop app, which is then the only source of stores. With useShopApp off, or on your own storeUrls, it is matched against store name, description and domain instead. |
category | string | — | Product category. With no query, searched on the Shop app, which is then the only source of stores; otherwise matched against the store's own product types. |
countries | array | — | Two-letter country codes, e.g. ["US","GB"]. |
minProducts | integer | — | Skip stores with fewer products than this. |
maxProducts | integer | — | Skip stores with more products than this. |
activeWithinDays | integer | — | Only stores that published a product this recently. |
excludeKeywords | array | — | Drop stores matching any of these words. |
shipsToCountries | array | — | Only stores shipping to at least one of these countries. |
minAvgPrice | integer | — | Minimum average product price, in minor units — 5000 is 50.00. |
maxAvgPrice | integer | — | Maximum average product price, in minor units. |
inStockOnly | boolean | false | Only stores with something actually in stock. |
hasApps | array | — | Only stores running these apps, by handle — klaviyo, judge-me, okendo. |
appMatchMode | string | any | Whether hasApps means any of them or all of them. |
excludeApps | array | — | Drop stores running any of these apps — find stores that have not installed a competitor yet. |
hasSocials | array | — | Only stores linking at least one of these networks — instagram, tiktok, facebook. |
requireEmail | boolean | false | Only stores that publish a business email address. |
requirePhone | boolean | false | Only stores that publish a phone number. |
maxItems | integer | 100 | Maximum stores to return. The hard cap on what the run can charge. To cap spend in currency instead, set Maximum total charge in the run options — the platform enforces it. |
includeCatalog | boolean | true | Product/collection counts, price band, types, vendors. |
includeContacts | boolean | true | Business emails, phones and social profiles, and the business address. The ones on the store's Shop app page come first; the storefront fills in the rest. |
includeTechStack | boolean | true | Theme, installed apps, accepted card brands. |
useShopApp | boolean | true | Use the Shop app. With a query, or a category when there is no query, its product search is where the stores come from. Every store that passes your filters is then found on the Shop app — by that search, or by its own name — for its rating and, with includeContacts, its business address and the contacts it lists there. Set false to read only the stores' own storefronts, found through the seed and Common Crawl. |
useSeed | boolean | true | Examine the built-in list of verified stores before Common Crawl, when there is no query or category for the Shop app to search. |
ccIndex | string | — | Pin a specific Common Crawl index. Leave empty for the newest. |
proxy | object | Apify Proxy | Leave this on — see the FAQ. |
📤 Output
One row per store, 40 fields in seven groups:
| Group | Fields |
|---|---|
| Identity and location | url, domain, myshopifyDomain, name, description, country, province, city, currency, languages, shipsToCountries |
| Catalog | productCount, collectionCount, priceMin, priceMax, priceAvg, pricedFrom, productTypes, vendors, sizeBand |
| Activity | newestProductUTC, oldestProductUTC, daysSinceLastProduct, isActive, productsPerMonth |
| Tech stack | theme, apps, policies, announcementBarText, cardBrands, offersShopPayInstallments |
| Contacts | emails, phones, socials |
| From the Shop app | rating — average, ratingCount, reviewCount — and address |
| Provenance | discoveredVia, scrapedUTC |
Real output, trimmed for length:
{"url": "https://www.gorjana.com/","domain": "www.gorjana.com","myshopifyDomain": "gorjana.myshopify.com","name": "gorjana","description": "Complete your look with jewelry designed to layer...","country": "US","province": "California","city": "Laguna Beach","address": ["3275 Laguna Canyon Rd Ste R1", "Laguna Beach, California 92651", "United States"],"currency": "USD","languages": ["en"],"shipsToCountries": ["AC", "AD", "AE", "..."],"catalog": {"productCount": 983,"collectionCount": 575,"priceMin": 3000,"priceMax": 599000,"priceAvg": 17884,"pricedFrom": 250,"productTypes": ["Anklets", "Bracelets", "Charms", "Earrings", "Gift Cards", "Hand Chains", "Necklaces", "Rings"],"vendors": ["Bespoke", "Fine", "Layering Set", "..."],"sizeBand": "medium"},"activity": {"newestProductUTC": 1790111736,"oldestProductUTC": 1767325861,"daysSinceLastProduct": 1,"isActive": true,"productsPerMonth": 28.9},"theme": { "name": "[RELEASE] 5.2.0", "id": 166571606147, "version": "" },"apps": [{ "handle": "klaviyo", "name": "Klaviyo" }, { "handle": "okendo", "name": "Okendo" }],"policies": [],"announcementBarText": null,"cardBrands": ["visa", "master", "american_express", "discover"],"offersShopPayInstallments": true,"contacts": {"emails": ["customercare@gorjana.com"],"phones": ["8668290030"],"socials": {"x": "https://twitter.com/gorjana_brand","facebook": "https://www.facebook.com/gorjanabrand","instagram": "https://www.instagram.com/gorjana","youtube": "https://www.youtube.com/@gorjanabrand","tiktok": "https://www.tiktok.com/@gorjana","pinterest": "https://www.pinterest.com/gorjanabrand"}},"rating": { "average": 4.81, "ratingCount": 18510, "reviewCount": 4610 },"discoveredVia": "input","scrapedUTC": 1790214009}
Two conventions worth knowing: prices are integers in minor units, so 17884 means
$178.84, and timestamps are epoch seconds.
productsPerMonth is what separates a store publishing 30 products a month from one that
published its last 30 over four years — isActive calls both of them active.
policies is empty for this store because gorjana links its policies as ordinary pages
rather than at Shopify's canonical /policies/… URLs, which is worth knowing before you
filter on it. Across a sample of ordinary stores about eight in ten use the canonical form
and return a list like ["refund-policy", "shipping-policy", "terms-of-service"] — but
large direct-to-consumer brands mostly do not: of nine well-known ones checked, one
published canonical policy URLs. Read an empty list as "not published at the canonical
URL", never as "this store has no refund policy".
announcementBarText is the storefront's announcement bar, verbatim and in whatever
language the merchant wrote it in — "FREE SHIPPING FOR ORDERS OVER £70",
"DESCUENTO DEL 10% PARA COMPRAS SUPERIORES A 80€",
"Final Sale. No Returns or Exchanges."rating is the store's rating on the Shop app, built by Shop from its own reviews and
approved review apps, so no storefront carries it. address is the business address a
store gives the Shop app, one entry per line as the Shop app formats it: street, then town,
region and postcode, then country. It is not split into parts, because the layout is the
country's. The Actor finds every store it keeps on the Shop app: a store the Shop app's
search found arrives with its rating, and any other — like gorjana here, named in
storeUrls — is looked up there by its own name and matched on its Shopify id. gorjana's
Shop app page also gave the phone number and the Pinterest profile above: its homepage
prints the number without linking it and does not link Pinterest at all, so the storefront
alone gave neither. Of 30 coffee stores found through the Shop app's search on 2026-09-23,
all 30 carried a rating, 25 an address, 24 an email and 23 a phone.
💰 Pricing
Pay per store returned, with no monthly fee. The price per store falls with your Apify plan:
| Apify plan | Per 1,000 stores | Per store |
|---|---|---|
| Free | $5.00 | $0.0050 |
| Starter | $4.80 | $0.0048 |
| Scale | $4.60 | $0.0046 |
| Business and above | $4.50 | $0.0045 |
- A store your filters reject is never charged — it is never returned. You pay for the rows you keep.
- A store reached twice in one run is charged once.
- Two ways to cap a run: Maximum stores caps the rows and so the charge, and Maximum total charge in the run options caps it in dollars — the platform enforces it.
- Each run also carries a start fee of $0.00005.
⚠️ What this Actor does not do
Stated up front so you can judge fit before paying.
- The price band is a sample, not a census. Computed from up to 250 products;
catalog.pricedFromtells you how many were used. Product and collection counts are exact — the store reports those itself. - App detection sees the public storefront only. A purely back-office app with no asset on the page is invisible. A detected app is real; an undetected one is not proof of absence.
- Contacts are what the store publishes, as it publishes them. Every email address on
its storefront, its Shop app page or its contact page is kept — a named person's too, when
the store lists one — except
no-reply@addresses and the placeholders themes and apps ship with. No job titles or LinkedIn profiles: nothing the store did not publish itself. - A keyword run finds what the Shop app's search finds, and nothing more. With a
queryorcategory, the stores come from that search alone, custom domains included; a store the Shop app does not list, or does not show for that word, is not found — you can still profile it directly viastoreUrls. Without either, discovery walks the built-in list and Common Crawl, which finds stores through their.myshopify.comaddress: roughly half have a custom domain configured, and a store only ever crawled at its custom domain may not be discoverable. ratingandaddresscome from the Shop app. A store its search found carries them; any other is looked up by its own name and matched on its Shopify id. A store the Shop app does not list under that name hasrating: nullandaddress: []— as, sometimes, does one whose products do not ship to where the request comes from, which the Shop app's search leaves out. So does every store withuseShopAppoff.- Shop app requests are made one at a time, each from its own IP. A stored store costs
one when the Shop app's search found it, two otherwise — a lookup, then its page when
includeContactsis on — and the Actor spaces them half a second apart. Stores rejected by your filters never cost one. A refused request is sent again from another IP. If the Shop app still stops answering a store's requests, the run carries on and the rest of its stores come back without the Shop app's data; if it stops answering the search itself, a keyword run ends with the stores it has and says why. policiescounts Shopify's canonical policy pages only. A store that hand-builds a/pages/refund-policyinstead is reported as having none. Empty means "not published at the canonical URL", not "this store has no refund policy".announcementBarTextis the bar's text, not a parsed promotion. There is no free-shipping threshold, discount percentage or promo-code field, and that is measured, not an omission: the copy is written in the store's own language, so an English pattern would report every non-English store as running no promotion — and a percent-off pattern run over a storefront matches product prices, not promotions. You get the sentence; read it yourself. How much of a rotating bar you get depends on the theme. Where each slide sits in its own element you get one message; where the theme puts them all in one element you get them all, joined —tentree.comreturns, which is four promotions at once. Where a theme splits one message across nested elements you get the innermost piece. Null means the store has no bar, or fills it in after the page renders."FREE SHIPPING ON ORDERS OVER $100 FREE SHIPPING ENDS MONDAY. CODE: FREESHIP DEEPEST DISCOUNTS: 30-50% OFF SHOP NOW EVERY ITEM PLANTS 10 TREES"productsPerMonthis measured over the sampled window. For a store with more products than the sample it is the recent rate; for a smaller store it is the lifetime average. It isnullwhen the sample is too thin to support a rate.- The price filters compare each store in its own currency.
minAvgPriceis matched against the store's own prices, so a run spanning several currencies is comparing numbers, not value. Pair them withcountrieswhen that matters. - Stores that don't answer are skipped, not guessed at — and cost you nothing.
🧰 Works well with
| Actor | Use it for |
|---|---|
| Shopify Scraper | Products and collections from a store this Actor found. The natural next step: qualify the store here, then pull its catalog there. |
| Schema Markup Scraper & SEO Auditor | Audit the structured data and SEO of any store in your list. |
| Anytime Mailbox Scraper | Business locations and CMRA records — another lead source to enrich the same list. |
| Indeed Jobs Scraper | Hiring signals on the companies you qualify. |
| WooCommerce Scraper | Catalogs for the WooCommerce stores in your list. |
All of them: apify.com/autofacts
❓ FAQ
Do I need to configure the proxy? No — leave it on the default. Shopify limits requests per IP address, so the Actor rotates through Apify Proxy automatically, and sends a refused request again from another address. Turning the proxy off makes every store share one address and get refused together.
How fresh is the data?
Every run reads each store live — its storefront, its catalog and its Shop app page — at
the time of the run. Nothing is served from a cache, and scrapedUTC records when each row
was read.
Is scraping these stores legal?
Everything returned is published openly for anyone to read — no login, no paywall — by the
store on its own storefront, or by the merchant on its Shop app page. Contacts are the
addresses the store chose to publish, which can include a named person's where the store
lists one. The Shop app
is Shopify's consumer marketplace, and its terms restrict automated access; the Actor reads
it by default, and useShopApp: false keeps a run to the stores' own storefronts. You are
responsible for how you use the output, including under GDPR, CAN-SPAM and local marketing
rules.
How many stores can I get?
As many as maxItems allows and your filters leave. With a query or category, that is
also as many as the Shop app's search has for the word — up to about 10,000 candidates a
run; the run says so when the search runs out first. The Actor stops as soon as it has
stored what you asked for.
Can I get results automatically? Yes. Schedule the Actor, or call it from the Apify API, or connect it to Make, Zapier, Slack, Google Sheets and the other Apify integrations. Results can also be pushed to a webhook when a run finishes.
Why are some fields empty?
Not every store publishes everything. A store with no public email returns an empty
contacts.emails rather than a guess. Empty means "not published", not "not checked".
Can you add a field or a filter? Yes — open an issue on the Actor and describe what you need.
🤖 Use with AI agents
This Actor is callable as a tool by any MCP-capable agent — Claude, Cursor, VS Code — or by your own code, with no wrapper and nothing extra to deploy.
Connect over MCP
https://mcp.apify.com?tools=autofacts/shopify-store-leads
In a client that reads an mcpServers configuration block:
{"mcpServers": {"apify": {"url": "https://mcp.apify.com?tools=autofacts/shopify-store-leads","headers": { "Authorization": "Bearer YOUR_APIFY_TOKEN" }}}}
The agent reads this Actor's parameters and their descriptions straight from the input schema, and the hosted server infers the result field types from the dataset schema — so a model knows what to send and what comes back before it ever calls anything.
Or call the API directly
curl -X POST "https://api.apify.com/v2/acts/autofacts~shopify-store-leads/run-sync-get-dataset-items?token=$APIFY_TOKEN" \-H 'Content-Type: application/json' \-d '{"storeUrls": ["gorjana.com", "tentree.com", "ayvii.com"]}'
The response body is the dataset records described above.
