# 🛍️ Shopify Store Leads - Find & Enrich Shopify Stores (`renzomacar/shopify-store-leads`) Actor

Detect and enrich Shopify stores: feed a domain list or a niche + location, get one row per confirmed store with emails, socials, currency, sample products and tech stack — verified live via products.json, cart.js and theme assets. $8 per 1,000 stores.

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

## Pricing

from $8.00 / 1,000 leads

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## 🛍️ Shopify Store Leads — Find, Verify & Enrich Shopify Stores

Selling Shopify apps, agency services, 3PL/fulfillment, wholesale, or influencer collabs? Your first question about any brand is always the same: *is it actually on Shopify, and how do I reach them?* This Actor answers both at scale. Feed it a list of websites — or a niche + location to discover brands — and get back **one row per confirmed Shopify store** with emails, social profiles, store currency, sample products and tech stack. $8 per 1,000 stores; sites that turn out not to be Shopify are dropped and **never charged**.

### How verification works (no guessing)

Every candidate domain is tested live against three independent Shopify signals:

1. **`/products.json`** — Shopify's public catalog endpoint. If it answers, the store is confirmed *and* you get up to 5 sample products with prices.
2. **`/cart.js`** — Shopify's cart endpoint. If it answers, confirmed *and* you learn the store currency (`USD`, `EUR`, `GBP`...).
3. **Theme assets** — `cdn.shopify.com` / Shopify generator tags in the site HTML.

The row's `shopifySignals` field lists exactly which checks passed, so you can see *why* each store was confirmed. Stores that lock down `products.json` still get caught by the other two signals.

### Two ways to use it

**Check mode (recommended).** Paste domains into `websites` — a competitor list, a directory export, brands you scraped elsewhere. Each is verified and, when confirmed, enriched. This is the fastest, cheapest path: no discovery step, you pay only for confirmed stores.

**Discovery mode.** Leave `websites` empty and give `keywords` + `location` (e.g. "candle store" + "Los Angeles, CA"). The Actor discovers retail brands on the live business index, then keeps only the ones running Shopify. Expect a fraction of local retail to be on Shopify — set `maxResults` generously.

### Each confirmed store row

| Field | Example |
|---|---|
| `name`, `website`, `domain` | Death Wish Coffee · deathwishcoffee.com |
| `isShopify`, `shopifySignals` | true · \["products.json", "cart.js", "theme-assets"] |
| `currency` | USD |
| `productsSample[]` | up to 5 products: title, price, URL |
| `email`, `emails[]`, `emailFound` | wholesale@..., support@... |
| `socialProfiles` | Instagram, Facebook, LinkedIn, Twitter |
| `phone`, `websitePhones[]` | numbers published on the site |
| `techStack[]` | Shopify + analytics/apps detected in the HTML |
| `contactPageUrl` | direct link for manual follow-up |

Discovery-mode rows also carry `address`, `city`, `country`, `rating`, `reviewsCount` and `placeUrl` when the brand has a physical presence.

### Pricing

- **$0.008 per confirmed Shopify store** delivered — $8 per 1,000
- $0.01 one-time start fee per run
- Non-Shopify sites you checked: **$0**. Verifying a 1,000-domain list where 400 are Shopify costs $3.21 total.

### Example input

```json
{
  "websites": ["allbirds.com", "gymshark.com", "deathwishcoffee.com", "bombas.com", "colourpop.com"],
  "maxPagesPerSite": 2
}
```

Discovery instead: `{ "keywords": ["skincare store"], "location": "Miami, FL", "maxResults": 100 }`.

### FAQ

**Can it tell store size?**
Directly, no — but `productsSample`/`productsInSample`, review counts (discovery mode), currency and social presence together give a workable size proxy. `productsInSample: 10` means the catalog has at least 10 products.

**Why did a store I know is Shopify come back unconfirmed?**
Very rarely all three endpoints sit behind an aggressive bot wall. Set `onlyShopify: false` to keep every checked site with its `isShopify` flag and inspect manually — you'll be charged for those rows since they're delivered.

**Does it find `*.myshopify.com` staging domains?**
It checks the domains you give it (or discovers). Custom domains are the norm for live stores; you can paste myshopify.com subdomains directly and they verify fine.

**Where do the emails come from?**
From the store's own public pages (homepage, /contact, /about...). Wholesale and press addresses often live on those pages — gold for B2B outreach. Respect CAN-SPAM/GDPR when contacting.

**Can I feed the output of another scraper into this?**
Yes — that's the intended workflow. Any actor or export that produces domains becomes Shopify-verified, enriched leads here.

**What does a run cost if none of my domains are Shopify?**
Just the $0.01 start fee (with `onlyShopify: true`, nothing is delivered so nothing is charged per item).

### Checking whether a domain runs Shopify, without a browser extension

The usual way to answer this is to install an extension and click through sites one at a time. Here you paste the domains into **Websites to check** and the actor answers all of them in one run, from live evidence rather than a cached database:

- `https://{domain}/products.json?limit=10` returns a JSON product array → signal `products.json`, and the first five products land in `productsSample` with title, price and URL.
- `https://{domain}/cart.js` returns cart JSON with a three-letter currency → signal `cart.js`, and the currency lands in `currency`.
- The homepage HTML references `cdn.shopify.com`, a `.myshopify.com` host or a Shopify `<meta generator>` → signal `theme-assets`.

`shopifySignals` shows you exactly which of the three fired, so you can judge the verdict instead of trusting a boolean. `isShopify` is true when at least one fired. Each domain gets a 15-second hard wall and each probe a 9-second timeout, so a dead host slows nothing down.

With `onlyShopify` on (the default) non-Shopify sites are dropped and never charged. Turn it off when you want the full audit of your list — every domain returned with `isShopify` true or false.

### Building a niche store list from scratch

If you do not have domains yet, leave **Websites to check** empty and use the keyword and location fields instead. The actor discovers brands from the live business index and then puts every one of them through the same three-signal verification, so what comes back is a list of confirmed stores, not guesses:

```
candle store
home fragrance shop
jewelry store
skincare boutique
streetwear store
coffee roaster
```

Discovery is geographic, which makes this the right mode for finding brands with a physical presence — a roaster, a boutique, a studio — and the wrong mode for pure online-only DTC labels with no storefront. For those, feed the domains directly.

### What a store row gives an agency or app developer

Beyond the Shopify verdict, every confirmed store carries the things an outreach sequence needs: `email` and `emails` scraped from the store's own pages, `contactPageUrl`, `socialProfiles` (LinkedIn, Facebook, Instagram, Twitter/X), `phone` and `websitePhones`, and `techStack` — which reveals the analytics, chat and payment tooling already installed.

Two columns do work nobody expects. `currency` tells you the store's home market before you write a word, which stops a US-only offer landing in a GBP store's inbox. `productsSample` with `productsInSample` tells you what they actually sell and at what price point, so a $9 accessory brand and a $400 furniture brand never end up in the same sequence.

# Actor input Schema

## `websites` (type: `array`):

Domains or URLs, one per line. Each one is verified live against Shopify endpoints (products.json, cart.js, theme assets) and — if it is a Shopify store — enriched with emails, socials, currency and sample products. Non-Shopify sites are dropped and never charged. When set, this list overrides discovery by keywords/location.

## `keywords` (type: `array`):

Used only when 'Websites to check' is empty. Retail niches to discover via the live business index, one per line: 'boutique', 'candle store', 'jewelry store', 'skincare store', 'coffee roaster', 'streetwear store'... Brands found are then filtered to Shopify-only.

## `location` (type: `string`):

City, region or country to discover stores in, e.g. 'Los Angeles, CA', 'Miami, FL', 'London, UK'. Used together with niche keywords when no website list is given.

## `searchQueries` (type: `array`):

Full discovery searches, one per line (e.g. 'candle store in Austin, TX'). When set, these override keywords + location. Ignored when a website list is given.

## `maxResults` (type: `integer`):

Discovery mode only: maximum businesses to find per search before Shopify filtering. Expect roughly 5-20% of local retail brands to run on Shopify, so set this higher than the store count you want.

## `onlyShopify` (type: `boolean`):

Drop sites where no Shopify signal was found (you are not charged for dropped sites). Disable to keep every checked site with an isShopify true/false flag.

## `maxPagesPerSite` (type: `integer`):

How many pages to check on each store when hunting for emails (homepage, /contact, /about...). More pages = more emails found, slightly slower run.

## `includeGenericEmails` (type: `boolean`):

Keep every published address, including shared inboxes like info@, hello@ and contact@. Disable to drop only non-deliverable system addresses (noreply@, no-reply@, donotreply@, mailer-daemon@, postmaster@, webmaster@, hostmaster@, abuse@).

## `language` (type: `string`):

Language code for discovery-mode searches (e.g. 'en', 'es', 'fr', 'de').

## Actor input object example

```json
{
  "websites": [
    "allbirds.com",
    "gymshark.com",
    "deathwishcoffee.com",
    "bombas.com",
    "colourpop.com"
  ],
  "maxResults": 25,
  "onlyShopify": true,
  "maxPagesPerSite": 1,
  "includeGenericEmails": true,
  "language": "en"
}
```

# Actor output Schema

## `leads` (type: `string`):

Confirmed Shopify stores with emails, social profiles, currency, sample products and tech stack — one item per store in the default dataset.

# 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 = {
    "websites": [
        "allbirds.com",
        "gymshark.com",
        "deathwishcoffee.com",
        "bombas.com",
        "colourpop.com"
    ],
    "maxPagesPerSite": 1
};

// Run the Actor and wait for it to finish
const run = await client.actor("renzomacar/shopify-store-leads").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 = {
    "websites": [
        "allbirds.com",
        "gymshark.com",
        "deathwishcoffee.com",
        "bombas.com",
        "colourpop.com",
    ],
    "maxPagesPerSite": 1,
}

# Run the Actor and wait for it to finish
run = client.actor("renzomacar/shopify-store-leads").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 '{
  "websites": [
    "allbirds.com",
    "gymshark.com",
    "deathwishcoffee.com",
    "bombas.com",
    "colourpop.com"
  ],
  "maxPagesPerSite": 1
}' |
apify call renzomacar/shopify-store-leads --silent --output-dataset

```

## MCP server setup

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

```

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/KX1tYKgVD1z9P32Tp/builds/h8yHL2h3sdm2fwiHM/openapi.json
