Shopify Merchant Scraper — Ad Pixels & Brand Data
Pricing
from $5.99 / 1,000 results
Shopify Merchant Scraper — Ad Pixels & Brand Data
Shopify Merchant Scraper extracts merchant and brand data, including store details, advertising pixels, technologies, social profiles, contact information, and ecommerce signals. Discover Shopify brands, analyze marketing stacks, and build targeted merchant lists for research and prospecting.
Pricing
from $5.99 / 1,000 results
Rating
0.0
(0)
Developer
Scrapier
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
4 days ago
Last modified
Categories
Share
Shopify Merchant Scraper — Ad Pixels & Brand Data
Shopify Merchant Scraper — Ad Pixels & Brand Data turns a list of Shopify storefront URLs into one structured row per store: the full merchant-contact lead sheet (email, phone, seven social platforms, catalogue size, currency) plus two feature blocks unique to this variant — a homepage-embedded ad and analytics pixel registry, and a brand-identity signal block built from Organization structured data, the store's real theme identity, and a shop-ID integrity cross-check. Every response is structured JSON, ready to pass to an LLM, load into a CRM, or feed a monitoring pipeline. No Shopify account or login is required.
🧭 What is Shopify Merchant Scraper — Ad Pixels & Brand Data?
It's a bulk Shopify storefront analyzer: you supply a list of store URLs, and it returns one enriched lead row per store — no query, no search, no crawling beyond the homepage and a handful of well-known public paths. It combines the base merchant-lead dataset (contacts, socials, catalogue size, commerce configuration) with this variant's own extraction: the storefront's marketing/ad-tech pixel registry and its brand-identity signals. No Shopify account, API key, or app installation is required — every field is parsed from HTML and JSON the storefront already serves publicly.
- 🏪 Verified merchant identity, contact channels, and 7-platform social detection
- 📦 Authoritative catalogue size and commerce configuration from
/meta.json - 📡 A raw ad/analytics pixel registry (
adPixels[]) — ids and hosts only, never a guessed vendor name - 🎨 Organization structured-data brand signals (logo, official social/press links, telephone, area served)
- 🎨 Real installed-theme identity and a shop-ID cross-check between two independent homepage/JSON sources
- 🚦 An explicit
storefrontStatusgate instead of a silent, all-null row on closed or blocked stores
📊 What data can you get with Shopify Merchant Scraper — Ad Pixels & Brand Data?
Every run returns one row per storefront, built from six groups of fields:
| Result Type | Extracted Fields | Primary Use Case |
|---|---|---|
| Merchant lead sheet | storeName, merchantName, domain, url, email, phone, facebook, instagram, twitter, tiktok, youtube, pinterest, linkedin, socialPlatformCount, hasEmail, hasPhone, leadQuality | B2B prospecting and outreach list building |
| Storefront commerce profile | productCount, publishedCollectionsCount, currency, moneyFormat, myshopifyDomain, merchantDescription, merchantCity, merchantProvince, shipsToCountries, acceptedCardBrands, offersShopPayInstallments | Market sizing, catalogue and geography research |
| Theme & app tech stack | themeName, themeVersion, themeRole, installedApps, installedAppsCount, themeAppExtensions, appProxyHandles, appCount | Competitive tech-stack audits |
| Ad & analytics pixel registry | adPixelCount, adPixels[] (pixelId, pixelType, apiClientId, privacyPurposes, configHost) | Martech / ad-tech competitive research |
| Brand-identity signals | brandLogoUrl, brandSameAs, brandTelephone, brandAreaServed, shopId, shopIdMatch | Brand audits, entity verification |
| Run metadata | storefrontStatus, scrapedAt | Run auditing and data freshness |
📡 Ad & Analytics Pixel Registry and Brand-Identity Signals
This is the feature set that separates this variant from a plain Shopify lead scraper. adPixels[] is parsed straight from the storefront's own webPixelsConfigList — the same registry the store itself loads to fire its marketing and analytics tags. Each entry carries pixelId, pixelType, the numeric apiClientId, the pixel's declared privacyPurposes[], and configHost — a real hostname the Actor extracts from the pixel's own configuration blob (with Shopify's own infrastructure hosts filtered out). No public mapping from apiClientId to a vendor brand name exists, so this Actor never guesses one — you get the raw, verifiable ids instead. The brand-identity block runs alongside it: brandLogoUrl, brandSameAs, brandTelephone, and brandAreaServed come from the homepage's Organization-typed JSON-LD, and shopId / shopIdMatch cross-check the shop ID embedded in the homepage's pixel loader against the ID in /meta.json.
{"adPixelCount": 2,"adPixels": [{ "pixelId": "gid://shopify/WebPixel/123", "pixelType": "APP", "apiClientId": 580111, "privacyPurposes": ["ANALYTICS", "MARKETING"], "configHost": "webhooks.fivetran.com" },{ "pixelId": "gid://shopify/WebPixel/456", "pixelType": "CUSTOM", "apiClientId": null, "privacyPurposes": ["ANALYTICS"], "configHost": null }],"brandLogoUrl": "https://cdn.shopify.com/s/files/1/0554/9812/files/logo.png","brandSameAs": ["https://www.instagram.com/kyliecosmetics/", "https://www.facebook.com/KylieCosmetics/"],"shopId": 12345678,"shopIdMatch": true}
⚠️ brandLogoUrl, brandSameAs, brandTelephone, and brandAreaServed are only populated on storefronts that actually publish Organization-typed structured data — an empty result on these fields means the store didn't publish it, not that the Actor missed it.
🏪 Verified Merchant Lead Sheet
The base of every row is the same merchant-lead sheet the underlying Shopify Merchant Scraper produces: real merchant name, myshopify.com domain, description, city/province, currency, and money format — all read from the storefront's own /meta.json, which also supplies productCount as an authoritative published-product count rather than a paginated products.json figure. Contact email and phone are pulled from the homepage plus four known contact paths, and social links are detected across seven platforms. leadQuality is a deterministic, non-AI label derived from hasEmail, hasPhone, and socialPlatformCount.
💡 Why not build this yourself?
Shopify does not expose a public API endpoint for pulling another merchant's ad-pixel registry or brand-identity data by domain. Both the Admin API and the Storefront API require an access token issued from inside the target store's own admin — either through a custom app installed by that store's owner, or through the storefrontAccessTokenCreate mutation called with that store's Admin credentials (confirmed on Shopify's developer docs as of 2026-08-15). There is no equivalent for a third party researching a store it doesn't own.
That leaves homepage HTML and the handful of public JSON endpoints (/meta.json, the embedded webPixelsConfigList, Organization JSON-LD, Shopify.theme) as the only real signal source — and each of them is theme-dependent, changes shape between Shopify theme versions, and can start returning 403/429 responses under sustained request volume. Building and maintaining regex- and JSON-shape-tolerant parsers for all of that, plus a proxy-escalation strategy for blocked requests, across thousands of storefronts running different themes, is the maintenance burden this Actor exists to absorb.
🔍 What's the difference between a Shopify lead scraper and an ad-pixel & brand-data scraper?
A plain Shopify lead scraper stops at contact and commerce data: email, phone, socials, product count, currency. It tells you a store exists and how to reach it, but nothing about how the brand actually markets itself. This Actor returns the same lead sheet plus two additional layers a plain lead scraper omits entirely: the storefront's own ad/analytics pixel registry, arriving in adPixels[], and its brand-identity signals, arriving in the brand*, theme*, and shopId* fields. If your workflow only needs a contact list, toggle includeAdPixels and includeBrandIdentity off and this Actor behaves like the plain lead sheet. If you need to know what tracking and analytics stack a brand runs, or verify its official brand identity in bulk, those two toggles are what a contact-only scraper can't give you.
🚀 How to scrape Shopify storefronts with Shopify Merchant Scraper — Ad Pixels & Brand Data
- Open Shopify Merchant Scraper — Ad Pixels & Brand Data on its Apify Store listing and click Try for free (or Run if you already have it in your Console).
- Paste storefront URLs into
targetStores— bulk paste, upload a file, or pipe results from another Actor. - Set
maxStorefronts,requestConcurrency, andrequestPaceSecondsto fit the run size and how politely you want to hit each store. - Toggle
includeAdPixels/includeBrandIdentityoff if you only need the base lead sheet, and leaveproxyConfigurationon its default — it escalates automatically only if a store starts blocking requests. - Click Start and read rows from the Output tab as JSON, CSV, or Excel, or pull them programmatically with
apify_client.
📦 How to run multiple storefronts in one job
targetStores accepts an array of URLs directly, a file upload, or a piped output from another Actor — there's no separate batch mode to configure. maxStorefronts (1–10,000) caps how many of the URLs you supplied are actually processed, and requestConcurrency (1–50) controls how many storefronts are worked on in parallel within that run.
⬇️ Input
targetStores accepts a plain list of storefront URLs — no query syntax, no filters beyond the list itself and how many/how fast to process. Every parameter below is optional; the schema declares no required fields, but the run produces zero rows if you leave both URL fields empty.
| Parameter | Required | Type | Constraints | Description |
|---|---|---|---|---|
targetStores | No | array | editor: stringList | Shopify storefront URLs to pull ad-pixel and brand-identity data from (e.g. https://kyliecosmetics.com/). Bulk paste, upload a list, or pipe from another actor. |
startUrls | No | array | editor: stringList | Base-actor-compatible alias for targetStores. A plain startUrls array from an older integration still works here — leave empty and use targetStores instead. |
maxStorefronts | No | integer | min 1, max 10000, prefill 100 | Hard cap on how many storefronts from the list will be processed. Use this to keep small test runs cheap. |
maxItems | No | integer | min 1, max 10000, default 100 | Base-actor-compatible alias for maxStorefronts. |
requestConcurrency | No | integer | min 1, max 50, prefill 10 | How many storefronts to process in parallel. |
concurrency | No | integer | min 1, max 50, default 10 | Base-actor-compatible alias for requestConcurrency. |
requestPaceSeconds | No | number | min 0, max 10, prefill 0.5 | Polite delay inserted between requests made to the same storefront. |
requestDelay | No | number | min 0, max 10, default 0.5 | Base-actor-compatible alias for requestPaceSeconds. |
includeAdPixels | No | boolean | default true | Parse the storefront's homepage-embedded pixel registry (ad/analytics tracking tags) into adPixels[] — raw client IDs, pixel type, and privacy purposes only. Never a guessed vendor name. |
includeBrandIdentity | No | boolean | default true | Extract Organization structured data (logo, official social/press links), the storefront's real theme identity, and a shop-ID integrity cross-check into the brand* / theme* / shopId* fields. |
proxyConfiguration | No | object | editor: proxy, default {"useApifyProxy": false} | Use Apify Proxy, custom proxy URLs, or no proxy. |
For each alias pair (targetStores/startUrls, maxStorefronts/maxItems, requestConcurrency/concurrency, requestPaceSeconds/requestDelay), the first field in the pair wins whenever both are supplied.
Example input
{"targetStores": ["https://kyliecosmetics.com/","https://www.allbirds.com/","https://www.gymshark.com/"],"maxStorefronts": 100,"requestConcurrency": 10,"requestPaceSeconds": 0.5,"includeAdPixels": true,"includeBrandIdentity": true,"proxyConfiguration": { "useApifyProxy": false }}
Common pitfall: maxStorefronts only trims the list you supplied — it does not discover additional stores. If you set maxStorefronts to 500 but only give 20 URLs, the run still produces 20 rows, not 500. Also, URLs without a scheme are auto-prefixed with https://, and duplicate URLs in the list are silently deduplicated before processing.
⬆️ Output
Every run's results land in the Actor's Apify dataset in the same 46-key schema on every row, exportable as JSON, CSV, Excel, or XML from the Output tab, or pulled programmatically via the API or apify_client. Fields that couldn't be found are returned as null (or an empty array for list fields) rather than omitted — the schema shape never changes between rows.
⚠️ Every processed storefront is charged under the row_result event, including unreachable, password-protected, or no-catalogue stores that return a mostly-null row — there's no separate uncharged error/accounting event, so maxStorefronts doubles as a cost cap.
📋 Scraped results
[{"storeName": "Kylie Cosmetics by Kylie Jenner | Kylie Jenner Fragrances | Kylie Skin","merchantName": "Kylie Cosmetics","domain": "kyliecosmetics.com","url": "https://kyliecosmetics.com/","storefrontStatus": "open","email": "customerservice@kyliecosmetics.com","phone": "1-877-916-6128","facebook": "https://www.facebook.com/KylieCosmetics/","instagram": "https://www.instagram.com/kyliecosmetics/","twitter": "https://twitter.com/kyliecosmetics","tiktok": null,"youtube": null,"pinterest": null,"linkedin": null,"socialPlatformCount": 3,"hasEmail": true,"hasPhone": true,"leadQuality": "high","productCount": 238,"publishedCollectionsCount": 226,"currency": "USD","moneyFormat": "${{amount}}","myshopifyDomain": "kylie-cosmetics.myshopify.com","merchantDescription": "Shop Kylie Cosmetics by Kylie Jenner.","merchantCity": "Calabasas","merchantProvince": "CA","shipsToCountries": ["US", "CA", "GB"],"acceptedCardBrands": ["visa", "mastercard", "american_express"],"offersShopPayInstallments": true,"themeName": "KYLIE","themeVersion": "12.1.0","themeRole": "main","installedApps": ["klaviyo", "yotpo"],"installedAppsCount": 2,"themeAppExtensions": ["klaviyo"],"appProxyHandles": ["yotpo"],"appCount": 2,"adPixelCount": 2,"adPixels": [{ "pixelId": "gid://shopify/WebPixel/123", "pixelType": "APP", "apiClientId": 580111, "privacyPurposes": ["ANALYTICS", "MARKETING"], "configHost": "webhooks.fivetran.com" },{ "pixelId": "gid://shopify/WebPixel/456", "pixelType": "CUSTOM", "apiClientId": null, "privacyPurposes": ["ANALYTICS"], "configHost": null }],"brandLogoUrl": "https://cdn.shopify.com/s/files/1/0554/9812/files/logo.png","brandSameAs": ["https://www.instagram.com/kyliecosmetics/", "https://www.facebook.com/KylieCosmetics/"],"brandTelephone": null,"brandAreaServed": "US","shopId": 12345678,"shopIdMatch": true,"scrapedAt": "2026-08-15T10:03:57.462Z"},{"storeName": "Allbirds | Sustainable Shoes & Apparel","merchantName": "Allbirds, Inc.","domain": "www.allbirds.com","url": "https://www.allbirds.com/","storefrontStatus": "open","email": "help@allbirds.com","phone": null,"facebook": "https://www.facebook.com/allbirds/","instagram": "https://www.instagram.com/allbirds/","twitter": null,"tiktok": "https://www.tiktok.com/@allbirds","youtube": null,"pinterest": null,"linkedin": null,"socialPlatformCount": 3,"hasEmail": true,"hasPhone": false,"leadQuality": "medium","productCount": 84,"publishedCollectionsCount": 41,"currency": "USD","moneyFormat": "${{amount}}","myshopifyDomain": "allbirds.myshopify.com","merchantDescription": null,"merchantCity": null,"merchantProvince": null,"shipsToCountries": ["US"],"acceptedCardBrands": ["visa", "mastercard", "amex", "discover"],"offersShopPayInstallments": true,"themeName": "Allbirds","themeVersion": "4.3.2","themeRole": "main","installedApps": ["gorgias"],"installedAppsCount": 1,"themeAppExtensions": [],"appProxyHandles": ["gorgias"],"appCount": 1,"adPixelCount": 1,"adPixels": [{ "pixelId": "gid://shopify/WebPixel/789", "pixelType": "APP", "apiClientId": 165719, "privacyPurposes": ["ANALYTICS"], "configHost": "connect.facebook.net" }],"brandLogoUrl": null,"brandSameAs": [],"brandTelephone": null,"brandAreaServed": null,"shopId": 21398765,"shopIdMatch": null,"scrapedAt": "2026-08-15T10:04:12.108Z"},{"storeName": null,"merchantName": null,"domain": "example-locked-store.myshopify.com","url": "https://example-locked-store.myshopify.com/","storefrontStatus": "password_protected","email": null,"phone": null,"facebook": null,"instagram": null,"twitter": null,"tiktok": null,"youtube": null,"pinterest": null,"linkedin": null,"socialPlatformCount": 0,"hasEmail": false,"hasPhone": false,"leadQuality": "unqualified","productCount": null,"publishedCollectionsCount": null,"currency": null,"moneyFormat": null,"myshopifyDomain": null,"merchantDescription": null,"merchantCity": null,"merchantProvince": null,"shipsToCountries": [],"acceptedCardBrands": [],"offersShopPayInstallments": null,"themeName": null,"themeVersion": null,"themeRole": null,"installedApps": [],"installedAppsCount": 0,"themeAppExtensions": [],"appProxyHandles": [],"appCount": 0,"adPixelCount": 0,"adPixels": [],"brandLogoUrl": null,"brandSameAs": [],"brandTelephone": null,"brandAreaServed": null,"shopId": null,"shopIdMatch": null,"scrapedAt": "2026-08-15T10:04:30.775Z"}]
🎯 How can I use the data extracted with Shopify Merchant Scraper — Ad Pixels & Brand Data?
- 📡 Ad-tech and martech researchers: compare
adPixels[]across a niche's storefronts to see which analytics and marketing platforms brands actually load, not what their marketing pages claim. - 🎯 B2B prospecting and sales teams: filter rows on
hasEmail,hasPhone, andleadQualityto build an outreach list of storefronts with confirmed contact channels. - 🤖 AI engineers and LLM developers: call the Actor from an agent, pass the returned JSON straight into a prompt as grounding context, and let the model reason over verified merchant and tech-stack data instead of guessing.
- 📊 Market researchers and competitive-intelligence teams: join
themeName,installedApps, andproductCountacross a competitor set to map catalogue size and tech-stack adoption in one pass.
📈 How do you monitor ad-pixel and brand-identity changes over time?
Tracking a brand's marketing stack over time means re-running the same storefront list on a schedule and diffing the fields that actually change: adPixels[] and adPixelCount when a store adds or drops a tracking pixel, installedApps[] / installedAppsCount when it installs or removes an app, and themeName / themeVersion when it redesigns its storefront. brandSameAs[] and brandLogoUrl shift far less often, but are worth including in the diff for brand-identity audits.
The practical loop: run the Actor on a fixed list of storefronts, store the dataset from that run, run it again on the same list later, and compare row-by-row on domain. A new entry in adPixels[] with a configHost you haven't seen before, or a changed themeVersion, is your alert signal — everything else in the row acts as the join key and context for that change.
This Actor has no built-in diffing or scheduling of its own. To automate the loop, use Apify's Schedule feature (Console → Schedules) to run it on a cron interval against the same targetStores list, then compare each run's dataset to the previous one in your own pipeline or downstream tool.
🔌 Integrate Shopify Merchant Scraper — Ad Pixels & Brand Data and automate your workflow
Shopify Merchant Scraper — Ad Pixels & Brand Data works with any language or tool that can send an HTTP request, and with the official apify_client SDKs for Python and JavaScript.
🐍 REST API with Python
import requestsACTOR_ID = "<your-actor-id-or-username~actor-name>"TOKEN = "<APIFY_API_TOKEN>"resp = requests.post(f"https://api.apify.com/v2/acts/{ACTOR_ID}/run-sync-get-dataset-items",params={"token": TOKEN},json={"targetStores": ["https://kyliecosmetics.com/"],"maxStorefronts": 50,"includeAdPixels": True,"includeBrandIdentity": True,},)rows = resp.json()for row in rows:print(row["domain"], row["storefrontStatus"], row["adPixelCount"])
⏰ Scheduled monitoring and delivery
Use Apify's Schedule feature in the Console to run this Actor on a recurring cron interval against a fixed targetStores list without writing any code. Combine it with Apify's run/dataset webhooks to notify your own system when a scheduled run finishes, or pull the latest dataset items on demand via the API or apify_client.
⚖️ Is it legal to scrape Shopify storefronts?
Yes — this Actor collects only data a storefront already publishes publicly: homepage HTML, the /meta.json endpoint, embedded JSON-LD, and the pixel registry the store itself loads for every visitor. Nothing requires authentication or bypasses access controls; password-protected stores are flagged as password_protected, not bypassed.
The data returned here is business and product data — merchant identity, catalogue metrics, and a store's own marketing/tech-stack configuration — not personal profiles of individuals, so GDPR's personal-data framework generally does not attach to it. The applicable considerations are each storefront's own terms of service and, in some jurisdictions, database-rights protections over the compiled data. Where a row includes a business contact email or phone number, using it for outreach may still fall under regional anti-spam or marketing-consent rules (e.g. CAN-SPAM, CASL) independent of scraping legality. Consult your legal team before bulk storage or commercial use of the output.
❓ Frequently asked questions
Does this Actor require a Shopify account or API credentials?
No. It reads homepage HTML and public JSON endpoints (/meta.json, the embedded pixel registry, JSON-LD) that any visitor's browser already loads — no login, app installation, or API token for the target store is needed.
How many storefronts can I process in one run?
maxStorefronts (or its alias maxItems) accepts 1–10,000, defaulting to 100. That cap only trims the list you supply — it never expands your output beyond the number of URLs you provided in targetStores/startUrls.
Does the ad-pixel registry tell me which vendor each pixel belongs to?
No — and it deliberately doesn't guess. There's no public mapping from a pixel's apiClientId to a vendor brand name, so this Actor ships the raw pixelId, pixelType, apiClientId, privacyPurposes[], and any real hostname (configHost) it can extract from the pixel's own configuration, rather than fabricating a vendor label.
How often are the brand-identity fields populated?
brandLogoUrl, brandSameAs, brandTelephone, and brandAreaServed only populate when a storefront publishes Organization-typed JSON-LD structured data. A null/empty result on these fields means the store didn't publish that data — not that the Actor failed to find it.
What happens on a closed or password-protected store?
storefrontStatus returns password_protected, unreachable, or no_public_catalogue instead of a silent, all-null row, so you can filter these out downstream without guessing why a row is empty.
Are all processed storefronts charged, even ones that return no data?
Yes. Every storefront the Actor attempts is pushed to the dataset and charged under the row_result event, including unreachable or password-protected stores — there's no separate uncharged error event. Set maxStorefronts deliberately if you're testing against an unfamiliar list.
How do I monitor a brand's ad-tech and theme changes over time?
Run the Actor on the same targetStores list on a recurring Apify Schedule, and diff each new run's adPixels[], installedApps[], and themeVersion against the previous run's dataset. A new configHost or a version bump is your change signal.
Does this Actor work with Claude, ChatGPT, and AI agent frameworks?
It isn't published as an MCP server. It's callable as a standard HTTP endpoint through the Apify API or apify_client, so any agent framework that can make an HTTP request can call it, pass a query, and ground its next answer on the returned JSON.
Can I run this without managing proxies myself?
Yes. By default the Actor makes direct requests with no proxy. If a storefront starts returning blocked responses (status codes like 403, 429, or 503, or a connection failure), it automatically escalates to Apify's datacenter proxy group and then to residential proxies, staying on residential for the rest of that request's retries once escalated — you only need to enable Apify Proxy in proxyConfiguration if you want it available from the start.
💬 Your feedback
Found a bug, or need a field this Actor doesn't extract yet? Use the Issues tab on this Actor's Apify Store page, or message the developer directly through Apify Console — that's the fastest way to reach the Scrapier team and get it looked at.