# Shopify Store Scraper - Store Leads, Emails, Apps & Theme (`lergassy/shopify-store-intel`) Actor

Shopify store scraper for ecommerce leads: find Shopify stores by keyword or paste store URLs. One row per shop with email, phone, socials, installed apps, theme, product count and price band. Filter by country, apps and email; skipped stores are free. No login or API key.

- **URL**: https://apify.com/lergassy/shopify-store-intel.md
- **Developed by:** [Matvey](https://apify.com/lergassy) (community)
- **Categories:** Lead generation, E-commerce
- **Features:** Limited permissions
- **Stats:** 54 total users, 25 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $3.50 / 1,000 store profiles

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

### Tested head-to-head — 26 September 2026

![Shopify Store Intel tested against the five most-used Shopify store scrapers: lowest bill, most e-mails found, no charge for a non-Shopify or failed site](https://raw.githubusercontent.com/lergassy/apify-actor-assets/main/benchmarks/shopify-tested-2026-09-26b.png)

The same six addresses went to this Actor and to the five most-used Shopify store Actors on the Apify Store, from an ordinary paying account: five Shopify stores and one site that is not on Shopify.

| | This Actor | The five others |
|---|---|---|
| Charged for this run | **$0.020** | $0.030–0.092 |
| Non-Shopify or failed site billed | **No** | Yes at two of five |
| E-mails found | **25** | 0–20 |

E-mails come from every content page the store publishes (about, press, wholesale, team pages — Shopify's own `/pages.json`), the contact page and the privacy, terms and refund policies, also for headless storefronts through the store's myshopify host. The store's own addresses are listed first. Each row also carries `pageCount` and `firstPageAt` (the date of the store's oldest page — a rough store age).

### Find Shopify stores by keyword — new 1 November 2026

No list of stores yet? Type what the stores sell. **🔎 Find stores that sell…** searches Shopify's own
product catalog across all stores that list in it, collects the stores behind the matching products,
and profiles each one into the same full row: e-mails, socials, apps, theme, catalogue, price band.

```json
{
  "searchTerms": ["yoga mat", "dog treats"],
  "storeCountries": ["US"],
  "onlyWithEmail": true,
  "requiredApps": ["Klaviyo"],
  "maxStores": 100
}
```

- **Filters you only pay for when they match** — store country, ships-to country, only stores with a
  public e-mail, uses any of these apps, doesn't use these apps, minimum and maximum catalogue size.
  A store that fails a filter is not written and not charged; the search keeps going until it has
  your number of stores.
- **Each term is searched in several slices** (price tiers, shipping origin), so one keyword reaches
  well past one search page: on 1 November 2026 "coffee" gave 161 stores from a single catalog query
  and 851 different stores across eight slices.
- **Search columns** on every found store: `searchTerm`, `matchedProducts`, `catalogRating` and
  `catalogReviewCount` (review-weighted rating of the store's matching products), `sampleProductUrl`
  and `discoveredVia`.
- Search and your own list combine: stores already in **Store addresses** are not profiled twice.

On a test run the same day, "yoga mat" + "dog treats" with US stores, e-mail required and Klaviyo
required returned 10 of 10 rows matching every filter; 3 candidates that failed a filter (UK,
Canada, no Klaviyo) were skipped without charge.

### What is Shopify Store Scraper?

**Shopify Store Scraper** finds Shopify stores by keyword, or takes your list of shop addresses, and turns each store into one flat row: who the
merchant is, how to reach them, what the storefront runs on, and what the catalogue actually looks
like. It reads the JSON that every Shopify storefront publishes for its own use, so there is **no
login, no API key, no browser and no residential-proxy bill** — and no official Shopify API needed.

Give it `gymshark.com` and you get back the shop's name and country, the e-mail and phone the
merchant published, every social profile, the theme and the apps installed, the size and price band
of the catalogue, and how many products were created in the last ninety days.

### What data does Shopify Store Scraper extract?

![Shopify Store Scraper output table: one row per store with emails, theme, apps and catalogue figures](https://raw.githubusercontent.com/lergassy/apify-actor-assets/main/shopify-store-intel/shopify-store-intel-output-table.png)

| Group | Fields | Example |
|---|---|---|
| Identity | `shopName`, `shopId`, `myshopifyDomain`, `primaryDomain`, `description`, `currency`, `city`, `province`, `country` | Allbirds · 11044168 · weareallbirds.myshopify.com · USD · Beverly Hills · California · US |
| Reach and localisation | `shipsToCountries`, `shipsToCountryCount`, `locale`, `languages`, `hreflangs`, `hreflangsCount`, `hasCountrySelector`, `hasCurrencySwitcher`, `moneyFormat` | 24 countries · en · 86 hreflang locales · ${{amount}} |
| Payments | `paymentMethods`, `expressCheckout`, `bnplOffered`, `cardBrands`, `shopPayInstallments` | Visa, Mastercard, Shop Pay, Apple Pay, PayPal, Klarna · true |
| Contacts | `email`, `emails`, `emailCount`, `phones` | help@allbirds.com · 4 |
| Socials | `instagram`, `facebook`, `tiktok`, `youtube`, `x`, `linkedin`, `pinterest`, `socialCount` | https://www.instagram.com/allbirds · 5 |
| Storefront tech | `themeName`, `themeVersion`, `theme` (the merchant's own label), `headless`, `apps`, `appCount`, `appCategories`, `appCategoryCount` | Dawn · Klaviyo, Yotpo, Gorgias, Meta Pixel · Email & SMS, Reviews, Support chat, Ad pixels |
| Marketing stack | `trackingIds`, `runsMetaPixel`, `runsTiktokPixel`, `runsGoogleAds`, `hasEmailCapture`, `hasBlog` | GTM-TH8KRSBJ · true · false · false |
| SEO block | `pageTitle`, `metaDescription`, `ogTitle`, `ogDescription`, `ogImage`, `ogSiteName`, `hasStructuredData` | Allbirds: Comfortable, Sustainable Shoes & Apparel |
| Catalogue | `totalProducts`, `storeSizeBucket`, `catalogueComplete`, `productCount`, `variantCount`, `inStockVariants`, `outOfStockVariants`, `variantInStockPct`, `avgVariantsPerProduct`, `avgImagesPerProduct`, `vendorCount`, `topVendors`, `productTypes`, `productTypeCount`, `topProductTypes`, `uniqueTagsCount`, `topTags`, `duplicateDescriptionPct` | 356 · medium · false · 250 · 2 980 · 1 667 · 55.9% · 4.9 images · Allbirds, re:do · Shoes, Apparel |
| Sitemap | `sitemapProducts`, `sitemapCollections`, `sitemapPages`, `sitemapBlogs`, `sitemapArticles`, `collectionCount`, `pageCount` | 356 · 1 346 · 175 · 2 · 80 |
| Price band | `priceMin`, `priceMedian`, `priceAvg`, `priceMax`, `priceDistribution`, `avgDiscountPct`, `productsOnSalePct` | 18 · 98 · 111.08 · 285 · 44.3% off on 6% of products |
| Activity | `newestProductAt`, `oldestProductAt`, `catalogueAgeDays`, `daysSinceNewestProduct`, `newProducts7Days`, `newProducts30Days`, `productsCreatedLast90Days`, `productsUpdatedLast30Days`, `firstPageAt` | 2026-09-02 · 2019-04-11 · 2 757 days · 46 days · 0 · 4 · 37 · 128 |
| Housekeeping | `rowType`, `isShopify`, `dataLimited`, `notice`, `error`, `scrapedAt` | store · true · false |

`totalProducts` is the size of the whole catalogue, counted from the shop's product sitemap when it is
larger than the sample; `productCount` and the other catalogue figures describe the products actually
read (**💯 Products per store**, 250 by default), and `catalogueComplete` says whether that sample was the
whole catalogue.

Switch on **Add product rows** and every product arrives as its own row too, with `title`,
`handle`, `productUrl`, `vendor`, `productType`, `tags`, `publishedAt`, `available`, `imageCount`
and the price range of its variants.

#### Why the activity figures matter

A list of Shopify stores is easy to buy and mostly useless: half of it is abandoned shops. Three
fields answer the only question that decides whether a store is worth contacting — is anyone still
working on it? `productsCreatedLast90Days` counts products by their **creation** date, not their
publish date, because Shopify bumps the publish date on any re-publish and a dormant store would
otherwise look brand new.

#### What the Actor will not invent

Phone numbers come only from `tel:` links the merchant published. Scanning page text for runs of
digits returns map coordinates, order ids and timestamps dressed up as phone numbers, so an empty
`phones` cell here means the merchant published none — not that the Actor guessed badly. Over ten
well-known stores on 29 October 2026 it filled for four: large brands route support through a form.
The same rule is why there is no revenue estimate, traffic figure or lead score in the output: those
cannot be read off a storefront, only guessed at, and a number you cannot check is worse than none.

A shop that rate-limits or blocks the request comes back as an **error row saying so**, never as
"not a Shopify store", so real stores never quietly drop out of your list.

#### Headless and bot-protected stores

Big brands often put a headless front end (Hydrogen, Next.js, Astro) or a bot wall (Cloudflare,
Vercel) in front of their Shopify store. Their main address then hides the shop record and the
catalogue. The Actor goes to the Shopify host behind the front end: the `.myshopify.com` address
named in the page, the shop's checkout host, or the `.myshopify.com` address that matches the
domain. A host it finds this way counts only when the shop record names your domain as its own, so
a same-name shop in another country never lands in your row. The run log names which host was
read. On 28 October 2026 this turned skims.com, bombas.com, ruggable.com and pura.com from
nameless or error rows into full profiles.

### How much does it cost to scrape Shopify stores?

Pay per event, billed on results — not on time:

| Row | Price |
|---|---|
| Store profile | **$0.005** — $5 per 1,000 stores |
| Product row | **$0.0005** — $0.50 per 1,000 products |
| Error row, notice row, "not a Shopify store" | **free** |

Prices fall on higher Apify plans. The Apify free plan's $5 of monthly usage is about **1,000 store
profiles**, and profiling a store takes two or three HTTP requests — there is no browser and no
residential proxy in the bill.

#### Bulk export

This Actor is built for bulk jobs — put hundreds of inputs into one run, or call it from the API on
a schedule. There is **no fee per run, no fee per page and no proxy charge**: you pay for the rows
you keep, and error rows are free, so a 50,000-row job costs exactly 50,000 × the row price with
nothing added on top.

### How to scrape a Shopify store

1. Open the Actor and press **Try for free** — the form arrives filled in with `gymshark.com`.
2. Paste your own addresses into **Store URLs**, one per line. A bare domain works; so does a full
   `https://` address or a `*.myshopify.com` host.
3. Pick a **Mode**: *Store profile* for one row per shop, *Products* to add the catalogue,
   *Detect only* to sift a large domain list cheaply.
4. Press **Start**. A hundred stores take about a minute.
5. Export from the **Storage** tab as CSV, JSON or Excel, or call the API endpoint shown under
   **API** to pull the rows straight into your own tool.

### ⬇️ Input

![Shopify Store Scraper input form: store URLs, mode, contacts and catalogue switches](https://raw.githubusercontent.com/lergassy/apify-actor-assets/main/shopify-store-intel/shopify-store-intel-input-form.png)

```json
{
  "storeUrls": ["gymshark.com", "allbirds.com", "bombas.com", "ridge.com"],
  "mode": "store",
  "includeContacts": true,
  "maxProductsPerStore": 250
}
```

| Field | What it does |
|---|---|
| `searchTerms` | Keywords for what the stores sell; the Actor finds the stores and profiles them. |
| `storeUrls` | The shops to profile. Bare domain, full URL or `*.myshopify.com` — all accepted. Optional when `searchTerms` is set. |
| `storeCountries`, `shipsTo` | Only stores based in these countries; search only products shipping to this country. Two-letter codes. |
| `onlyWithEmail`, `requiredApps`, `excludeApps`, `minProducts`, `maxProducts` | Filters. A store that fails one is skipped and not charged. |
| `mode` | `store` (one row per shop), `products` (shop row plus catalogue), `detect` (is this Shopify at all). |
| `includeContacts` | Read e-mails, phone numbers and social links from the storefront. On by default. |
| `includeProducts` | Add one row per product on top of the store row. |
| `maxProductsPerStore` | Cap on product rows per shop, default 250. |
| `maxStores` | How many store rows one run delivers at most, default 100. Skipped stores don't count. |
| `concurrency` | How many shops are read at once. Five is gentle and fast enough for a hundred shops. |

#### Sift a large domain list before paying for profiles

```json
{ "storeUrls": ["example.com", "another.com", "third.com"], "mode": "detect" }
```

#### Profile a shop and pull its whole catalogue

```json
{ "storeUrls": ["kith.com"], "mode": "products", "maxProductsPerStore": 1000 }
```

### ⬆️ Output

One flat row per store — no nested objects, so the result drops straight into a spreadsheet, a CRM
import or an LLM context window.

```json
{
  "rowType": "store",
  "storeUrl": "https://allbirds.com",
  "isShopify": true,
  "shopName": "Allbirds",
  "myshopifyDomain": "weareallbirds.myshopify.com",
  "currency": "USD",
  "country": "US",
  "email": "help@allbirds.com",
  "emails": ["help@allbirds.com", "press@allbirds.com"],
  "instagram": "https://www.instagram.com/allbirds",
  "pageTitle": "Allbirds: Comfortable, Sustainable Shoes & Apparel",
  "metaDescription": "The world’s most comfortable shoes, made with natural materials.",
  "hreflangsCount": 86,
  "paymentMethods": ["Visa", "Mastercard", "Shop Pay", "Apple Pay", "PayPal"],
  "bnplOffered": true,
  "trackingIds": { "gtm": ["GTM-TH8KRSBJ"] },
  "theme": "[DNAM Theme July 2026]",
  "apps": ["Yotpo", "Google Analytics"],
  "totalProducts": 356,
  "storeSizeBucket": "medium",
  "sitemapCollections": 1346,
  "catalogueComplete": false,
  "productCount": 250,
  "priceMin": 18,
  "priceMedian": 98,
  "priceAvg": 111.08,
  "priceMax": 285,
  "priceDistribution": { "0-25": 2, "25-50": 7, "50-100": 496, "100+": 2475 },
  "avgDiscountPct": 44.3,
  "productsOnSalePct": 6,
  "variantInStockPct": 55.9,
  "duplicateDescriptionPct": 93.3,
  "productsCreatedLast90Days": 37,
  "scrapedAt": "2026-09-12T12:23:09Z"
}
```

#### Product rows

```json
{
  "rowType": "product",
  "storeUrl": "https://allbirds.com",
  "title": "Tree Runner Go",
  "handle": "tree-runner-go",
  "productUrl": "https://allbirds.com/products/tree-runner-go",
  "vendor": "Allbirds",
  "productType": "Shoes",
  "tags": ["mens", "tree", "everyday"],
  "publishedAt": "2026-08-14T00:00:00Z",
  "available": true,
  "priceMin": 98,
  "priceMax": 98,
  "imageCount": 7
}
```

### Use cases for Shopify store data

#### Agencies and freelancers

Build a prospect list of live Shopify stores in a price band, then filter by the apps they already
run: shops with no review app, no e-mail tool or no subscription app are a pitch that writes itself.

#### E-commerce competitor tracking

Follow a competitor's catalogue over time — price band, how fast they launch, what goes out of
stock — by running the same list on a schedule and comparing the exports.

#### Sales and lead enrichment

Take a domain list you already have, run **Detect only** to find which ones are Shopify, then
profile just those. You pay for detection at a fraction of a profile.

#### App and SaaS vendors

Find the stores that already run a competing app, or none at all, and size the market by catalogue
and price band rather than by guesswork.

#### AI agents and RAG

One store, one flat row, stable field names. Call it from an agent through Apify's MCP server and
drop the row into a prompt without any reshaping.

### Integrations

Use it as a Shopify store API through the [Apify API](https://docs.apify.com/api/v2), the
JavaScript or Python client, or connect it without code to Google Sheets, HubSpot, Slack, n8n,
Make, Zapier and webhooks.

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("lergassy/shopify-store-intel").call(run_input={
    "storeUrls": ["gymshark.com", "allbirds.com"], "mode": "store",
})
for store in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(store["shopName"], store.get("email"), store.get("productCount"))
```

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

const client = new ApifyClient({ token: '<YOUR_API_TOKEN>' });
const run = await client.actor('lergassy/shopify-store-intel').call({
    storeUrls: ['gymshark.com', 'allbirds.com'], mode: 'store',
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const store of items) console.log(store.shopName, store.email, store.productCount);
```

One HTTP call that runs the Actor and returns the rows in the same request — this is the endpoint
n8n, Make and AI agents use:

```bash
curl -X POST "https://api.apify.com/v2/acts/lergassy~shopify-store-intel/run-sync-get-dataset-items?token=<YOUR_API_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"storeUrls":["gymshark.com"],"mode":"store"}'
```

### 🤖 For AI agents and LLM apps

Available over the [Apify MCP server](https://mcp.apify.com), so an agent can call it directly:

```json
{
  "mcpServers": {
    "apify": {
      "command": "npx",
      "args": ["-y", "@apify/actors-mcp-server", "--actors", "lergassy/shopify-store-intel"],
      "env": { "APIFY_TOKEN": "<YOUR_API_TOKEN>" }
    }
  }
}
```

**What it answers:** is this domain a Shopify store, who runs it, how to contact them, what apps
and theme it uses, how big and how expensive the catalogue is, and whether anyone is still adding
products.

### Troubleshooting and error rows

Error and notice rows are free, and one bad address never stops the run.

```json
{
  "rowType": "error",
  "storeUrl": "https://example.com",
  "isShopify": false,
  "error": "HTTP 403 — the storefront refused the request",
  "scrapedAt": "2026-09-12T12:23:09Z"
}
```

| What you see | What it means | What to do |
|---|---|---|
| `isShopify: false` with no error | The address answered, and it is not a Shopify store | Nothing — that is the answer, and it was free |
| An error row with HTTP 403 or 429 | The storefront is behind a bot wall, and no Shopify host behind it answered for this domain | Switch **Proxy** to the residential group, or check the shop in a browser |
| A notice saying the domain does not resolve | No website answers at this address | Check the spelling |
| `dataLimited: true` | The shop hides part of its catalogue JSON | Store-level figures are still right; product rows may be short |
| `phones` empty | The merchant published no `tel:` link and no number in structured data | Use `email` or the socials — the Actor does not guess numbers from page text |
| Zero rows and one explanation row | No store addresses were given | Fill **Store URLs**, one address per line |

### ❓ FAQ

#### Is it legal to scrape Shopify stores?

The Actor reads only what a storefront publishes publicly for its own front end — the same data
your browser downloads when you open the shop. It collects no personal data beyond the business
contact details the merchant chose to publish, and it never signs in.

#### Do I need a Shopify API key or a partner account?

No. There is no login, no API key and no OAuth. That is why it costs what it costs.

#### How fast is it?

Everything a shop answers independently is requested at once, so a store costs about three round
trips rather than a dozen. Two well-known stores with contacts on took 3-5 seconds on 29 October 2026,
five shops run in parallel by default, and adding product rows costs time in proportion to the catalogue.

#### Can I use it with the Apify API?

Yes — run it from the API, the JavaScript or Python client, or with
`run-sync-get-dataset-items` to get the rows back in the same request. See **Integrations** above.

#### Can I use it through an MCP server?

Yes, through the Apify MCP server, with the config shown above.

#### Does it find every app a store uses?

It finds about 85 apps and pixels that leave a trace in the storefront: e-mail and SMS, reviews,
support chat, subscriptions, loyalty, buy now pay later, upsell, search, page builders, shipping and
returns, affiliates, analytics and ad pixels. `appCategories` groups them. An app that runs only in the admin leaves nothing public to detect.

#### What does one row cost?

$0.005 per store profile and $0.0005 per product row; errors and non-Shopify answers are free.

### Your feedback

Something missing or wrong? Open an issue on the Actor page — issues are read and answered, and
fixes ship the same week.

### You might also like

| Actor | What it does |
|---|---|
| [Website Contacts API](https://apify.com/lergassy/website-contacts-api) | E-mails, phones and socials from any website, Shopify or not |
| [Email Verifier & Phone Validator](https://apify.com/lergassy/email-phone-verifier) | Check the addresses this Actor found before you mail them |
| [US New Business Leads](https://apify.com/lergassy/us-business-filings) | Newly registered US companies, with contact details |

# Changelog

This Actor's version history is a separate document: https://apify.com/lergassy/shopify-store-intel/changelog.md

# Actor input Schema

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

Keywords for what the stores sell — <code>organic coffee</code>, <code>yoga mat</code>, <code>dog treats</code>. The Actor searches Shopify's own product catalog across all stores, collects the stores behind the matching products and profiles each one. Leave empty to profile only the addresses below.

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

Shops to profile, one per line. A bare domain is enough — <code>gymshark.com</code>, <code>allbirds.com</code> or a <code>.myshopify.com</code> address all work. Optional when <b>Find stores that sell…</b> is filled.

## `mode` (type: `string`):

<b>Store profile</b> — one row per shop with contacts, tech and catalogue figures. <b>Products</b> — the store row plus every product as its own row. <b>Detect only</b> — just answer whether the address is a Shopify store, at the lowest price.

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

Read the home page and, when nothing is there, the contact page, for email addresses, phone numbers and social profiles.

## `includeProducts` (type: `boolean`):

Also write one row per product in the store profile mode.

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

How many products to read from each shop. The catalogue figures in the store row are calculated from this sample, so leave it high for an accurate price band.

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

How many store rows one run delivers at most — addresses from your list plus stores found by the search. Stores skipped by the filters don't count.

## `concurrency` (type: `integer`):

How many shops to read at the same time.

## `storeCountries` (type: `array`):

Only stores based in these countries, as two-letter codes: <code>US</code>, <code>GB</code>, <code>DE</code>. Applied to search results and to your own list. Leave empty for any country.

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

Search only products that ship to this country (two-letter code, e.g. <code>US</code>).

## `onlyWithEmail` (type: `boolean`):

Skip stores that publish no e-mail address. Skipped stores are not written and not charged.

## `requiredApps` (type: `array`):

Only stores where at least one of these apps is detected on the storefront: <code>Klaviyo</code>, <code>Yotpo</code>, <code>Recharge</code>, <code>Gorgias</code>… Skipped stores are not charged.

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

Skip stores where any of these apps is detected — for example your own app, to find stores that don't use it yet.

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

Skip stores with fewer products in their catalogue.

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

Skip stores with more products in their catalogue.

## `proxyConfiguration` (type: `object`):

Shops behind Cloudflare or Vercel bot protection answer a datacentre address with a challenge instead of the page, so requests go through Apify Proxy by default. If a shop still refuses, switch this to the residential group.

## Actor input object example

```json
{
  "searchTerms": [
    "organic coffee",
    "yoga mat"
  ],
  "storeUrls": [
    "gymshark.com",
    "allbirds.com"
  ],
  "mode": "store",
  "includeContacts": true,
  "includeProducts": false,
  "maxProductsPerStore": 250,
  "maxStores": 100,
  "concurrency": 5,
  "storeCountries": [
    "US",
    "CA"
  ],
  "shipsTo": "US",
  "onlyWithEmail": false,
  "requiredApps": [
    "Klaviyo",
    "Recharge"
  ],
  "excludeApps": [
    "Judge.me"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `stores` (type: `string`):

One row per shop: identity, contacts, socials, theme and apps, catalogue size, price band and launch activity.

## `products` (type: `string`):

One row per product, with price range, stock, tags and images.

# 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 = {
    "storeUrls": [
        "allbirds.com"
    ],
    "mode": "store",
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("lergassy/shopify-store-intel").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 = {
    "storeUrls": ["allbirds.com"],
    "mode": "store",
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("lergassy/shopify-store-intel").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 '{
  "storeUrls": [
    "allbirds.com"
  ],
  "mode": "store",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call lergassy/shopify-store-intel --silent --output-dataset

```

## MCP server setup

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

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/begIggQ7cnK9Pxfvm/builds/RSRozi2ELh2mB1qfk/openapi.json
