Shopify Merchant Scraper — Ad Pixels & Brand Data avatar

Shopify Merchant Scraper — Ad Pixels & Brand Data

Pricing

from $5.99 / 1,000 results

Go to Apify Store
Shopify Merchant Scraper — Ad Pixels & Brand Data

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

Scrapier

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

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 storefrontStatus gate 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 TypeExtracted FieldsPrimary Use Case
Merchant lead sheetstoreName, merchantName, domain, url, email, phone, facebook, instagram, twitter, tiktok, youtube, pinterest, linkedin, socialPlatformCount, hasEmail, hasPhone, leadQualityB2B prospecting and outreach list building
Storefront commerce profileproductCount, publishedCollectionsCount, currency, moneyFormat, myshopifyDomain, merchantDescription, merchantCity, merchantProvince, shipsToCountries, acceptedCardBrands, offersShopPayInstallmentsMarket sizing, catalogue and geography research
Theme & app tech stackthemeName, themeVersion, themeRole, installedApps, installedAppsCount, themeAppExtensions, appProxyHandles, appCountCompetitive tech-stack audits
Ad & analytics pixel registryadPixelCount, adPixels[] (pixelId, pixelType, apiClientId, privacyPurposes, configHost)Martech / ad-tech competitive research
Brand-identity signalsbrandLogoUrl, brandSameAs, brandTelephone, brandAreaServed, shopId, shopIdMatchBrand audits, entity verification
Run metadatastorefrontStatus, scrapedAtRun 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

  1. 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).
  2. Paste storefront URLs into targetStores — bulk paste, upload a file, or pipe results from another Actor.
  3. Set maxStorefronts, requestConcurrency, and requestPaceSeconds to fit the run size and how politely you want to hit each store.
  4. Toggle includeAdPixels / includeBrandIdentity off if you only need the base lead sheet, and leave proxyConfiguration on its default — it escalates automatically only if a store starts blocking requests.
  5. 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.

ParameterRequiredTypeConstraintsDescription
targetStoresNoarrayeditor: stringListShopify 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.
startUrlsNoarrayeditor: stringListBase-actor-compatible alias for targetStores. A plain startUrls array from an older integration still works here — leave empty and use targetStores instead.
maxStorefrontsNointegermin 1, max 10000, prefill 100Hard cap on how many storefronts from the list will be processed. Use this to keep small test runs cheap.
maxItemsNointegermin 1, max 10000, default 100Base-actor-compatible alias for maxStorefronts.
requestConcurrencyNointegermin 1, max 50, prefill 10How many storefronts to process in parallel.
concurrencyNointegermin 1, max 50, default 10Base-actor-compatible alias for requestConcurrency.
requestPaceSecondsNonumbermin 0, max 10, prefill 0.5Polite delay inserted between requests made to the same storefront.
requestDelayNonumbermin 0, max 10, default 0.5Base-actor-compatible alias for requestPaceSeconds.
includeAdPixelsNobooleandefault trueParse 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.
includeBrandIdentityNobooleandefault trueExtract 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.
proxyConfigurationNoobjecteditor: 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, and leadQuality to 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, and productCount across 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 requests
ACTOR_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.


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.