# Shopify Store Leads Scraper — $4/1K · Emails, Phones & Ratings (`apivault_labs/shopify-store-leads-scraper`) Actor

Discover Shopify sellers by keyword/category, origin and product filters. Public contacts with evidence, qualified emails, apps/theme, business addresses and optional catalog. Reuse lead lists to skip delivered domains; labeled rating/coverage scopes.

- **URL**: https://apify.com/apivault_labs/shopify-store-leads-scraper.md
- **Developed by:** [Apivault Labs](https://apify.com/apivault_labs) (community)
- **Categories:** Lead generation, E-commerce
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 store leads

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Shopify Store Leads Scraper — Emails, Phones & Ratings

Find Shopify sellers by product keywords, then collect public business contacts with evidence URLs. This is a separate lead-focused Actor from [Shopify Store Analyzer](https://apify.com/apivault_labs/shopify-store-analyzer).

### Quick start

```json
{"searchTerms":["organic coffee"],"maxStores":3,"enrichWebsite":true,"maxContactPages":2}
```

For known stores, use `{"storeUrls":["https://boody.com.au"],"maxStores":1}` without keywords. API and hosted MCP require your Apify account; public sources need no separate provider key or store login.

### What each lead contains

- Actual seller website/domain and available name; deduplicated by domain within a run.
- Public `emails`, `phones`, `socials` and `contact_evidence` linking each value to its page. These are published contacts, not verified deliverability or consent.
- `ratings` with explicit scope and source. **Catalog ratings describe individual products, not the store.**
- `store_rating` only when matching Store/Organization JSON-LD publishes an aggregate rating. Its scope is `store_self_published`; this is a storefront claim, not an independent merchant score. Otherwise null.
- Up to three matching `sample_products`, discovery page, keyword, merchant-origin filter and website status.

`country` filters keyword discovery through Catalog's merchant-origin country filter; it does not verify a headquarters address. `minProductRating` filters matching product/variant ratings, never seller reputation. These search filters cannot be used with known URLs. Require email and/or phone to exclude candidates lacking those contacts; `maxStoresScanned` applies before filtering; `maxStores` limits delivered leads.

### Coverage and diagnostics

Search uses Shopify's documented [public Catalog MCP](https://shopify.dev/docs/agents/catalog/global-catalog-extension). It follows opaque product cursors, up to `maxPagesPerTerm` (1–20), at 50 products per page. The source caps a search at 1,000 products. This gives a **bounded sample of product sellers**, not all Shopify stores. Repeated runs can overlap unless you enable the delivery history or import a previous Dataset; see the section below.

Website enrichment visits the homepage plus up to four discovered same-domain contact/about/privacy pages. HTTP is the default. Optional Chromium rendering can execute public page JavaScript; it does not log in, solve challenges or reveal private admin data. Known URLs need a reachable page with Shopify evidence; unreachable/unconfirmed URLs go to diagnostics, not charged rows. Catalog sellers remain useful discovery rows if their website is protected; `website_status` and `ERRORS` explain missing enrichment. Contact filters can yield an empty Dataset.

Discovery and enrichment have finite processing budgets. Large requests can stop with partial results before the requested candidate limit; `SUMMARY.discovery.truncated` and errors explain the stop. Use smaller runs for slow websites.

Read run `SUMMARY` and `ERRORS`, even when the run succeeds. Source failures are `DATA_SOURCE_UNAVAILABLE` or `PARTIAL_RESULTS`, not successful empty search. Missing contacts, counts and ratings are unknown, not zero. Use the Dataset JSON/CSV/Excel export; nested evidence and scoped ratings are best preserved in JSON.

### Cost and integrations

**$4 per 1,000 delivered store rows**, plus **$0.00005 per start** (one event per GB, minimum one). **Apify platform usage is paid separately by the user.** Contact filters exclude candidates before Dataset billing; a returned discovery row may have no contact. Start and platform costs can apply to empty runs. No downstream paid Actor is started. Apify Proxy is optional and off by default; enabling it adds user-paid proxy usage. Check the current pricing and start with a small batch and cost cap.

Hosted MCP: `https://mcp.apify.com?tools=apivault_labs/shopify-store-leads-scraper`. Tool: `apivault_labs--shopify-store-leads-scraper`. Send a small `maxStores` and inspect Dataset, `SUMMARY` and `ERRORS` before expanding.

The Actor has its own runtime and does not start or charge the Analyzer. No dedicated n8n or Python package is published for this new Actor; Analyzer clients target a different Actor and must not be used as substitutes. Use the Apify API, hosted MCP or a generic HTTP node with this Actor ID.

### Example inputs

| Goal | Input |
|---|---|
| Niche discovery | `{"searchTerms":["organic coffee"],"maxStores":3}` |
| Leads with emails | `{"searchTerms":["organic coffee"],"maxStores":6,"requireEmail":true}` |
| Enrich known stores | `{"storeUrls":["https://exhalecoffee.com"],"maxContactPages":2}` |
| US-origin sellers | `{"searchTerms":["organic coffee"],"country":"US","maxStores":3}` |
| Rated matching products | `{"searchTerms":["organic coffee"],"minProductRating":4.5,"maxStores":3}` |
| Public phone numbers | `{"storeUrls":["https://www.freshroastedcoffee.com"],"requirePhone":true}` |

Change the sample URLs, keywords and limits to your own research. These are bounded examples, not guaranteed contacts for every store.

### Qualify leads and reuse lists

```json
{"searchTerms":["organic coffee"],"maxStores":5,"maxStoresScanned":20,"requireBestEmail":true,"hasApps":["Klaviyo"],"includeCatalog":true,"maxProductsPerStore":50,"maxConcurrency":2}
```

- `best_email` selects a published own-domain contact first. Known vendor, noreply and privacy mailboxes are not chosen. Personal mailboxes published on the site and brand-domain heuristics remain explicitly labeled. All extracted addresses remain visible with candidate classification; selection is not ownership or deliverability verification.
- `validateEmails:true` optionally checks MX routing through Google public DNS. A null MX or nonexistent domain cannot qualify; unavailable DNS is unknown. No SMTP or message sending occurs.
- `apps` and `app_evidence` expose public signature matches, not a private installed-app list. `hasApps` supports any/all; `excludeApps` requires reachable website coverage. `tech_gaps` means no signature seen in observed pages, not proven absence.
- Theme, declared currency/country, policy links, legal name and structured addresses carry source URLs. Declared market is separate from headquarters and merchant-origin search filters.
- Optional `includeCatalog` paginates public products.json up to your cap. Exact `product_count` appears only on observed source exhaustion; otherwise use `product_count_lower_bound`. Products include variants, images, tags, vendor/type and observed availability/sales. Price statistics name the currency and sample; unknown currency is not USD. `maxProducts` requires complete coverage, `minProducts` can use a proven lower bound.
- `activeWithinDays` uses latest observed publication. `launchedWithinDays` checks the oldest publication in a complete catalog; this is a product-catalog proxy, not a verified store launch. No verified Shopify billing plan or sales volume is inferred.

### Category, location and product filters

Use `categories` with current [Shopify taxonomy IDs](https://github.com/Shopify/product-taxonomy), `countries` for multiple merchant-origin countries, and `shipsTo` for product destination. For category-only discovery use `searchTerms:[]`. `priceMinMinor`/`priceMaxMinor` are currency **minor units** in `currency`;1000 means10USD but1000JPY. Source warnings are preserved. Minimum reviews/rating target the matching variant; both product and variant rating scopes are retained separately.

`onSale`, catalog size/average price, recent publication, vendor and type filters read a bounded storefront catalog. Product filters only prove a match in the observed sample. `requireSocials` uses full social domains. Missing source coverage cannot silently satisfy a maximum, negative-app or date filter. Large jobs can stop partially within the processing budget even if the accepted limit is10000; this is not a10000-store coverage guarantee.

### Skip leads already delivered

```json
{"searchTerms":["organic coffee"],"maxStores":5,"maxStoresScanned":30,"skipPreviouslyScraped":true,"leadListName":"coffee-prospects"}
```

Enable history from your first run. Domains are stored in an account-owned named KV store per list (`shopify-store-leads-history-` plus a stable list hash); only successfully delivered rows are marked. Retain that list store to retain history. Each delivered domain is a separate small record; the full list is not rewritten for every row. Run one job at a time for the same list: there is no transactional concurrency lock. Different `leadListName` values are isolated. A storage error after delivery can leave uncertain history and fails the run; no automatic retry of delivery is made. `SUMMARY.skipped_previously_delivered` reports skipped domains. A list accepts up to100000domains. To import an existing accessible Dataset, pass `previousDatasetId`; failed access or a dataset over100000rows stops the import instead of silently including duplicates.

### Public API examples

[GitHub API guide and standard Python client example](https://github.com/apivault-labs/apivault-labs/tree/main/guides/shopify-store-leads). These target this exact Actor. No dedicated new npm/PyPI package is claimed; existing Analyzer packages target the other product. Price remains$4/1000delivered rows plus start and user-paid platform usage.

### Public browser and alternate discovery

`renderJs:"auto"` can retry failed public HTML reads in Chromium;`"on"` renders the page directly. Set run memory to at least512MiB. Rendering is serialized even when HTTP enrichment is parallel. There is no logged-in session, CAPTCHA solver or challenge bypass. `useApifyProxy:true` opts into Apify Proxy using your platform entitlement; it can add proxy charges. `proxyFallback:true` tries direct requests first; optional proxy country/groups affect the exit route, not the store's origin. Failed proxy access remains a diagnostic, not proof of empty data. `respectRobots:true` optionally checks public robots.txt and skips disallowed paths.

`discoverySource:"common_crawl"` reads a bounded historical myshopify URL-index sample from the public Common Crawl CDX service, then qualifies the CURRENT storefront. Clear keyword/category/location filters: CC is not a keyword search or current merchant directory. Archive timestamps are not launch dates. `ccIndex` pins an archive; `ccStartPage` and `ccMaxPages` bound source paging. Canonical myshopify-to-storefront redirects require observed Shopify evidence and are deduplicated before billing. Common Crawl can rate-limit or deny requests; this is reported explicitly.

Category-only Catalog input uses a literal wildcard query plus the requested taxonomy filter because the source rejects empty global browsing without a specific shop. `category_query_basis` exposes this; it remains a bounded search, not all stores in a category. Source filter warnings are retained. Predefined `region` expands to the explicit origin-country targeting list in `origin_country_filter`, combined by OR with `country` and `countries`.

`includeCollections:true` reads up to250public collections. `collectionHandles` scopes product reading to named collections and never turns subset counts into full-store counts. `includePolicies:true` reads bounded public policy excerpts with source URLs; no legal conclusions are generated. `flatOutput:true` retains nested evidence as JSON strings for CSV columns.

`lead_score` measures observed data completeness on an explicit100-point rubric: qualified email35, phone15, structured address10, social10, sampled catalog10, observed app10, reachable website10. `minLeadScore` can filter on it. This is not calibrated sales potential or expected conversion. History-skipped Catalog domains are skipped before collecting new candidates; search continues within the page/time limits to find unseen sellers.

Supported public signature names for app filters: `Affirm`, `AfterShip`, `Afterpay`, `Algolia`, `Apple Pay`, `Attentive`, `AutoDS`, `Bold Commerce`, `CJ Dropshipping`, `Crazy Egg`, `Drift`, `Dsers`, `Facebook Pixel`, `GemPages`, `Google Ads`, `Google Analytics`, `Google Pay`, `Gorgias`, `Growave`, `Hotjar`, `Intercom`, `Judge.me`, `Junip`, `Klarna`, `Klaviyo`, `Loox`, `LoyaltyLion`, `Lucky Orange`, `Mailchimp`, `Microsoft Clarity`, `Mouseflow`, `Northbeam`, `Oberlo`, `Okendo`, `Omnisend`, `PageFly`, `PayPal`, `Pinterest Tag`, `Postscript`, `Printful`, `Privy`, `PushOwl`, `Re:amaze`, `ReCharge`, `Rebuy`, `Refersion`, `Reviews.io`, `SMSBump`, `Searchanise`, `Sendlane`, `Sezzle`, `ShipBob`, `ShipStation`, `Shogun`, `Shop Pay`, `Smile.io`, `Snapchat Pixel`, `Spocket`, `Stamped.io`, `Tidio`, `TikTok Pixel`, `Triple Whale`, `Yotpo`, `Zendesk`. These are signature detectors, not a guarantee of detection on every storefront.

`includeContacts:false` omits contact fields while retaining requested store/catalog signals. `minPrice`/`maxPrice` filter observed storefront variant prices in major units of the selected currency, including known-URL enrichment. They are separate from source-search `priceMinMinor`/`priceMaxMinor`. Public `/meta.json` is read opportunistically for declared currency and shipping-country fields when exposed; unavailable declarations remain unknown. HTML `<address>` blocks are retained with raw text and explicitly heuristic postal components; they do not establish headquarters.

### Public Storefront settings and larger catalogs

When public business details are enabled, the Actor also tries the documented **tokenless** Storefront API (`/api/2026-10/graphql.json`) for shop identity, declared shipping countries, currency/payment settings and published contact/legal policies. No public/private merchant token is collected or supplied; there are no customer/order/admin queries or mutations. The returned primary domain must match the store. `storefront_api.status` identifies coverage. `published_shipping_countries` is a store declaration, not a checkout or delivery guarantee; `shipsToCountries` can require listed destinations and excludes unknown coverage. This is separate from the matching-product `shipsTo` Catalog filter.

`websiteEnrichmentMode:"missing_email"` skips extra contact pages when the homepage already publishes an email;default`"all"` keeps bounded enrichment. Storefront contact policies can supply additional published contacts with source evidence.

Large observed product details are retained in run-owned KV chunks if a store row would exceed the Dataset record safety cap. The row then exposes `product_details_in_kv:true` and authenticated `product_exports` links; every observed product stays downloadable and only the single store row is billed. A chunk/storage failure precedes Dataset delivery. These are separate from source pagination/completeness limits.

Runs that render JavaScript or sample more than500products per store need at least512MiB. Heavy browser/large-catalog enrichment is serialized;256MiB HTTP runs use at most two store workers. `SUMMARY.effective_concurrency` reports the applied limit.

### Current source limitations

As checked on 20 October 2026, Common Crawl returned HTTP 504 in two release checks; use Catalog discovery or known URLs while its public index is unavailable. The public Shop merchant-profile page was also inaccessible by HTTP/browser/proxy, so independent merchant reputation is not supplied. Product ratings and self-published storefront ratings retain their separate scopes. Default run memory is512MiB for optional browser support; lightweight HTTP jobs can select256MiB.

# Actor input Schema

## `searchTerms` (type: `array`):

Product keywords used to find matching public Shopify sellers. Bounded sample, not a merchant census. Clear this list to use only known URLs.

## `storeUrls` (type: `array`):

Optional public store URLs. Without explicit searchTerms, URLs disable the default keyword search. Country/rating search filters cannot be combined with URLs.

## `country` (type: `string`):

Optional uppercase ISO country code such as US. Keyword search only; source merchant-origin filter, not verified headquarters.

## `maxStores` (type: `integer`):

Output limit after filters. Subject to candidate, source and processing limits; not a promise of this many stores.

## `maxPagesPerTerm` (type: `integer`):

50 products per page; Catalog source cap 1000 products per search. Product coverage is not store coverage.

## `enrichWebsite` (type: `boolean`):

Visit homepage and a bounded number of same-domain contact/about/privacy pages. No login or browser challenge bypass.

## `maxContactPages` (type: `integer`):

Homepage is additional to this limit.

## `requireEmail` (type: `boolean`):

Requires website enrichment. Excluded candidates do not create Dataset rows.

## `requirePhone` (type: `boolean`):

Requires website enrichment. Phone numbers are extracted from public tel links.

## `minProductRating` (type: `number`):

Optional keyword search filter on a matching product/variant rating, not a seller rating. Minimum one source review. Applies through Catalog.

## `maxStoresScanned` (type: `integer`):

New candidate budget before qualification. Catalog skips previously delivered domains while paging. Larger values help restrictive filters; source/time budgets still apply.

## `countries` (type: `array`):

ISO codes, OR matching through source ships_from. Does not establish headquarters. Keyword discovery only.

## `categories` (type: `array`):

Current TaxonomyCategory GIDs, e.g. gid://shopify/TaxonomyCategory/fb. OR matching. Clear searchTerms for category-only search.

## `shipsTo` (type: `string`):

ISO destination country; Catalog product filter, not store headquarters or delivery-date guarantee.

## `currency` (type: `string`):

Price source context and average-price filter currency. Never converts money silently.

## `priceMinMinor` (type: `integer`):

Catalog product price in currency MINOR units:1000=10USD,1000=1000JPY. Keyword discovery only.

## `priceMaxMinor` (type: `integer`):

Catalog product price in currency MINOR units:1000=10USD,1000=1000JPY. Keyword discovery only.

## `minProductReviews` (type: `integer`):

Used together with minProductRating; product/variant evidence is not store reputation.

## `includeTechStack` (type: `boolean`):

Observed HTML signatures with evidence; absence is not proof an app is uninstalled.

## `includeBusinessDetails` (type: `boolean`):

Published JSON-LD/HTML addresses, legal names, declared currency/country, policy links and tokenless Storefront settings. Missing remains unknown. Theme/app detection is a separate option.

## `includeCatalog` (type: `boolean`):

Optional bounded products.json pagination; completeness and count lower bounds are explicit. Product details include variants/images/vendor/type/tags.

## `maxProductsPerStore` (type: `integer`):

1–2500. Reaching the cap is incomplete unless source exhaustion is observed.

## `maxConcurrency` (type: `integer`):

Bounded1–4; results keep discovery order. Higher values can increase platform usage and source rate limits.

## `validateEmails` (type: `boolean`):

Optional Google public DNS-over-HTTPS lookup. Never sends email or probes SMTP. MX is not mailbox deliverability; unavailable lookup stays unknown.

## `requireBestEmail` (type: `boolean`):

Own-domain, public personal mailbox or labeled brand-domain heuristic. Excludes known vendor/noreply/privacy addresses from best_email.

## `hasApps` (type: `array`):

Documented detector names, any/all matching. Requires a positive public signal.

## `excludeApps` (type: `array`):

Exclude observed signatures; protected website is unknown and excluded from this filter, not treated as no apps.

## `requireSocials` (type: `array`):

All requested domains must appear, e.g.instagram.com or linkedin.com.

## `excludeKeywords` (type: `array`):

Case-insensitive match in store name, domain or discovery product sample.

## `vendorFilter` (type: `array`):

Case-insensitive exact vendor names; requires a matching sampled product.

## `productTypeFilter` (type: `array`):

Case-insensitive exact type names; requires a matching sampled product.

## `appMatchMode` (type: `string`):

Match any or all required observed app signatures.

## `minProducts` (type: `integer`):

Min uses observed lower bound; max requires a complete catalog. Unknown coverage cannot satisfy this filter.

## `maxProducts` (type: `integer`):

Min uses observed lower bound; max requires a complete catalog. Unknown coverage cannot satisfy this filter.

## `minAvgPrice` (type: `number`):

Major units of selected currency. Requires observed store currency; sample average, not complete revenue.

## `maxAvgPrice` (type: `number`):

Major units of selected currency. Requires observed store currency; sample average, not complete revenue.

## `activeWithinDays` (type: `integer`):

Observed product timestamps. Oldest publication requires complete catalog and is NOT verified store launch date.

## `launchedWithinDays` (type: `integer`):

Observed product timestamps. Oldest publication requires complete catalog and is NOT verified store launch date.

## `createdSinceDays` (type: `integer`):

Observed product timestamps. Oldest publication requires complete catalog and is NOT verified store launch date.

## `onSale` (type: `boolean`):

Sample variant compare_at_price must exceed price. Enables storefront catalog reading.

## `inStockOnly` (type: `boolean`):

Catalog availability filter in discovery; when storefront catalog is read, at least one matched available product is required.

## `skipPreviouslyScraped` (type: `boolean`):

Persist delivery domains in your account named KV store. Enable from first run; use one run at a time per leadListName. Writes follow successful Dataset delivery.

## `leadListName` (type: `string`):

Named account-scoped history,1–80letters/digits/\_/-. Different lists are isolated. Concurrent runs on the same list are unsupported.

## `previousDatasetId` (type: `string`):

Your accessible Dataset ID, up to100000rows. Uses domain/store_url/websiteUrl; unavailable or oversized import fails instead of silently ignoring dedup.

## `renderJs` (type: `string`):

off=HTTP;auto=browser fallback after failed public HTML read;on=render public HTML.512MiB minimum. Does not log in or solve challenges. Chromium is serialized to bound memory.

## `useApifyProxy` (type: `boolean`):

Opt-in paid proxy using platform proxy credential. Proxy charges are additional user-paid usage. No external proxy password is returned.

## `proxyFallback` (type: `boolean`):

When proxy is enabled, use it only after direct failure. Disable to route source HTTP through configured proxy immediately.

## `proxyCountry` (type: `string`):

Optional ISO country, requires useApifyProxy. Does not replace merchant-origin filters.

## `proxyGroups` (type: `array`):

Optional entitled group names such as RESIDENTIAL. Additional proxy charges and availability apply; no group is enabled by default.

## `respectRobots` (type: `boolean`):

Opt-in: disallowed store paths are skipped; failed robots access is not silently treated as permission.

## `discoverySource` (type: `string`):

catalog=live matching product sellers;common_crawl=bounded historical myshopify URL candidates, verified against current storefronts. CC does not support Catalog keyword/origin/category/price filters.

## `ccIndex` (type: `string`):

Optional CC-MAIN-YYYY-NN. Empty uses the first archive returned by the public collection list. Historical URLs are not current contacts.

## `ccStartPage` (type: `integer`):

CDX index page, not store offset. Pages can overlap; domain/history dedup still applies.

## `ccMaxPages` (type: `integer`):

Bounded1–3 requests, with spacing. Not a bulk crawl export.

## `includePolicies` (type: `boolean`):

Read up to maxPolicyPages discovered same-domain policy pages. Returns source/title/text excerpt, not legal interpretation.

## `maxPolicyPages` (type: `integer`):

Additional bounded public policy reads, only when enabled.

## `includeCollections` (type: `boolean`):

Reads first250public collections; complete flag only if fewer than250. No hidden/private collections.

## `collectionHandles` (type: `array`):

Up to10public collection handles. Product count is then a subset/lower bound, never a full-store count. Enables catalog reading.

## `flatOutput` (type: `boolean`):

Serialize arrays/objects as JSON strings in top-level columns, retaining evidence and scope.

## `region` (type: `string`):

Named targeting presets expanded to explicit ISO countries, not geopolitical completeness or verified headquarters. Combined by OR with country/countries.

## `minLeadScore` (type: `integer`):

Explicit heuristic:qualified email35,phone15,address10,social10,catalog10,app10,reachable website10. Not a conversion prediction or business revenue score.

## `includeContacts` (type: `boolean`):

Return published emails/phones/socials/evidence. Disable for store fingerprint/catalog research; contact filters require this option.

## `minPrice` (type: `number`):

Major units of the selected currency. Matches a sampled storefront variant; enables catalog. Unknown or different currency cannot satisfy this filter. Separate from Catalog search minor-unit price filters.

## `maxPrice` (type: `number`):

Major units of the selected currency. Matches a sampled storefront variant; enables catalog. Unknown or different currency cannot satisfy this filter. Separate from Catalog search minor-unit price filters.

## `shipsToCountries` (type: `array`):

Known-store/enrichment filter:all ISO destinations must appear in the public tokenless Storefront API or metadata declaration. Unknown does not match. Not a checkout/delivery guarantee; separate from Catalog product shipsTo.

## `websiteEnrichmentMode` (type: `string`):

all=read bounded discovered contact pages;missing_email=skip extra contact pages if the homepage already exposes an email. Public business metadata can still be read.

## Actor input object example

```json
{
  "searchTerms": [
    "organic coffee"
  ],
  "country": "",
  "maxStores": 10,
  "maxPagesPerTerm": 3,
  "enrichWebsite": true,
  "maxContactPages": 2,
  "requireEmail": false,
  "requirePhone": false,
  "shipsTo": "",
  "currency": "USD",
  "minProductReviews": 1,
  "includeTechStack": true,
  "includeBusinessDetails": true,
  "includeCatalog": false,
  "maxProductsPerStore": 100,
  "maxConcurrency": 1,
  "validateEmails": false,
  "requireBestEmail": false,
  "appMatchMode": "any",
  "onSale": false,
  "inStockOnly": false,
  "skipPreviouslyScraped": false,
  "leadListName": "default",
  "renderJs": "off",
  "useApifyProxy": false,
  "proxyFallback": true,
  "proxyCountry": "",
  "respectRobots": false,
  "discoverySource": "catalog",
  "ccIndex": "",
  "ccStartPage": 0,
  "ccMaxPages": 1,
  "includePolicies": false,
  "maxPolicyPages": 2,
  "includeCollections": false,
  "flatOutput": false,
  "region": "",
  "minLeadScore": 0,
  "includeContacts": true,
  "websiteEnrichmentMode": "all"
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `summary` (type: `string`):

No description

## `errors` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "searchTerms": [
        "organic coffee"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("apivault_labs/shopify-store-leads-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "searchTerms": ["organic coffee"] }

# Run the Actor and wait for it to finish
run = client.actor("apivault_labs/shopify-store-leads-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searchTerms": [
    "organic coffee"
  ]
}' |
apify call apivault_labs/shopify-store-leads-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,apivault_labs/shopify-store-leads-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/I8jlmQxX6VkEZzWTg/builds/T724aOiycxopisgsm/openapi.json
