BuiltWith Alternative: Shopify Store List & Tech Stack Leads avatar

BuiltWith Alternative: Shopify Store List & Tech Stack Leads

Pricing

from $2.00 / 1,000 websites

Go to Apify Store
BuiltWith Alternative: Shopify Store List & Tech Stack Leads

BuiltWith Alternative: Shopify Store List & Tech Stack Leads

Lists of websites by technology: 1.5M Shopify stores, WooCommerce, Klaviyo and 7,286 more. Emails, phones and social links in each row. Filter by country, language, rank, keywords, AND / OR. No 10,000 cap. Watch for new sites, webhook. From $2 per 1,000.

Pricing

from $2.00 / 1,000 websites

Rating

0.0

(0)

Developer

Alexis Morain

Alexis Morain

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

1

Monthly active users

a day ago

Last modified

Features

Limited permissions

Share

Get lists of websites that use a given technology (Shopify, WooCommerce, Klaviyo, HubSpot, Magento and 7,286 more), with emails, phone numbers and social links in every row. Filter by country, language, domain rank and keywords, combine technologies with AND or OR, and watch for new sites on a schedule.

What does it do?

You give one or more technology names. The actor returns every website where that stack was detected, one row per site, with the contacts found on the site and its full tech stack.

  • No 10,000 row wall. Shopify in France alone is 19,952 stores. Shopify worldwide is 1,520,572. This actor pages past 10,000 rows with a cursor and goes up to 2,000,000 rows per run.
  • AND or OR between technologies. "Shopify AND Klaviyo in France" returns 3,061 stores. "Shopify OR WooCommerce" runs one search per technology and removes duplicates.
  • Contact filter. Ask for sites with an email, a phone or any social link, and the actor drops the rest before delivery. Dropped rows cost less than delivered ones (see pricing).
  • Freshness you can check. Every row has lastVisited, the date the crawler last saw the site. visitedAfter keeps only sites seen after a date.
  • Watch mode. Schedule the same search daily or weekly and get only the sites you never received before.
  • Count first. countOnly returns the number of matching sites for about $0.02, before you spend anything on rows.

Results come back instantly: the data source answers live, there is no queue.

Why use it?

Most store list actors stop at 10,000 rows per run. For Shopify in France that is half the market. For Shopify worldwide it is less than 1 %. Some have no technology filter at all, so "Shopify stores using Klaviyo" is not possible.

Most also charge you for rows without any contact. On the top 1,000 Shopify stores in France (run of November 9, 2026) we measured: email on 39 % of sites, phone on 29 %, email or phone on 46 %, at least one social link on 48 %. Smaller shops show less: on another sample of 100 stores, only 18 % had an email. Without a contact filter, 1,000 stores with an email means buying 2,500 to 5,500 rows at full price. With contactFilter: "email" you pay full price only for the 1,000 rows you keep.

These are our measured rates, not a marketing figure. They vary a lot by country, technology and site size.

Typical uses:

  • Build a lead list of Shopify or WooCommerce stores in a country for an agency, an app or a SaaS.
  • Find users of a competitor's tool (Klaviyo, Mailchimp, Intercom, Hotjar...) and pitch a switch.
  • Size a market: how many sites in Germany run Magento, how many French sites run HubSpot.
  • Get a weekly feed of newly detected stores for your outbound sequences.

What data can I extract?

FieldExampleNotes
domainexample-shop.fr
urlhttps://example-shop.fr
titleExample Shop, lunettes de soleilpage title
descriptionLunettes de soleil fabriquées en France...meta description
domainRank2140 to 1000, higher is stronger. Null for about a quarter of sites
countryFRISO code, can be WW or null
languagefrdeclared language
contentLanguagefrlanguage detected in the content
lastVisited2026-11-02T00:00:00+00:00last crawl of the site
emailcontact@example-shop.frfirst email, or null
emails["contact@example-shop.fr"]lowercased, deduplicated, valid syntax
phone+33 1 41 08 76 76first phone, or null
phones["+33 1 41 08 76 76"]HTML and street addresses removed
socialUrls["https://x.com/exampleshop"]broken links repaired, empty profiles removed
facebook, instagram, linkedin, twitter, youtube, tiktok, pinteresthttps://www.instagram.com/exampleshopfirst link per network, or null
technologies["Google Analytics", "Klaviyo", "Shopify"]flat sorted list
techStack{"ecommerce": {"ecommerce": ["Shopify"]}, ...}group, category, names
technologyCount23
matchedTechnologies["Shopify", "Klaviyo"]which of your technologies the site uses
query{"technologies": ["Shopify"], "countries": ["FR"], ...}the search that found the row
isNewtruewatch mode only, otherwise null
scrapedAt2026-11-09T14:02:11+00:00
dataSourceDataForSEO

With countOnly, each row is {"type": "count", "technologies": [...], "filters": {...}, "totalCount": 19952} and no site row is returned. Site rows carry type: "website".

How to get a list of websites by technology

  1. Type the technology names in Technologies, as listed by the source (case does not matter). A typo stops the run before any paid call and suggests the closest names.
  2. Pick Several technologies: all (sites using every technology) or any (sites using at least one).
  3. Add countries, languages, keywords or a rank range if you need them.
  4. Set Only sites with contact details if you only want sites with an email or a phone.
  5. Set Maximum sites and start the run. Export to CSV, Excel or JSON, or read the dataset through the API.

Not sure of the exact name? The full list has 7,286 names grouped in 108 categories (for example Shopify, WooCommerce, Klaviyo, HubSpot, Google Tag Manager, Stripe). Close names are suggested when one is wrong.

How much does it cost?

You pay per event:

EventPrice
Actor start$0.002 per run
Search page$0.02 per call to the data source (up to 1,000 rows each, or one count)
Website (delivered row)$3.00 per 1,000 on the free plan, $2.70 Bronze, $2.40 Silver, $2.00 Gold and above
Skipped website$1.60 per 1,000: rows read but not delivered (contact filter, already sent by the watch, duplicate under OR)

Examples on the free plan:

RunApproximate cost
Count all Shopify stores in France (countOnly)$0.02
1,000 Shopify stores in France$3.02
19,952 Shopify stores in France (all of them)$60.26
1,000 Shopify stores in France with an email (about 2,600 rows read at 39 %)about $6
Weekly watch on Shopify France, 600 sites seen again, 100 new$1.28

With a contact filter, the actor asks for small pages as it gets close to your target, so it never reads rows it will neither deliver nor charge. That adds a few search pages to a filtered run, and keeps a 10-row test run cheap.

Set Max cost per run in the Apify console to cap any run. The actor stops cleanly at that cap and never reads rows it cannot charge for.

Input

FieldTypeDefaultDescription
technologieslist1 to 10 technology names
technologyMatchall or anyallAND or OR between technologies
countrieslist of ISO codesemptyempty means worldwide
languageslist of codesemptylanguage detected in the site content
keywordslistemptyup to 10, all must appear in the title or description
minDomainRank, maxDomainRank0 to 1000emptya minimum excludes sites without a rank
visitedAfterdate YYYY-MM-DDemptyonly sites crawled on or after this date
sortByrank, recent, domainrankstrongest first, freshest first, or A to Z
contactFilternone, email, emailOrPhone, anyContactnonedrop sites without contacts
maxItems1 to 2,000,0001000rows delivered
countOnlybooleanfalsereturn counts only
includeTechStackbooleantrueinclude technologies and techStack
monitorbooleanfalsewatch mode, see below
monitorNametextderived from the searchname of the watch
webhookUrlURLemptyreceives a JSON summary at the end of the run

With a contact filter, watch mode or any, the actor reads at most 20 times maxItems rows, then stops with a message. This keeps a rare filter from reading a whole country.

Sites whose country is unknown (WW or null) only show up when no country is selected.

Example input:

{
"technologies": ["Shopify", "Klaviyo"],
"technologyMatch": "all",
"countries": ["FR", "BE"],
"contactFilter": "email",
"maxItems": 500
}

Output

{
"type": "website",
"domain": "example-shop.fr",
"url": "https://example-shop.fr",
"title": "Example Shop, lunettes de soleil",
"domainRank": 214,
"country": "FR",
"contentLanguage": "fr",
"lastVisited": "2026-11-02T00:00:00+00:00",
"email": "contact@example-shop.fr",
"emails": ["contact@example-shop.fr"],
"phone": "+33 1 41 08 76 76",
"phones": ["+33 1 41 08 76 76"],
"instagram": "https://www.instagram.com/exampleshop",
"twitter": "https://x.com/exampleshop",
"technologies": ["Google Analytics", "Klaviyo", "Shopify"],
"technologyCount": 3,
"matchedTechnologies": ["Shopify", "Klaviyo"],
"isNew": null,
"dataSource": "DataForSEO"
}

The dataset has four views in the console: Websites, Contacts, Tech stack and Counts.

Run it from your code

Python:

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("alexmorain/tech-stack-leads").call(run_input={
"technologies": ["WooCommerce"],
"countries": ["US"],
"contactFilter": "emailOrPhone",
"maxItems": 1000,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item["domain"], item["email"], item["phone"])

JavaScript:

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('alexmorain/tech-stack-leads').call({
technologies: ['HubSpot'],
countries: ['DE'],
maxItems: 1000,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.length);

cURL (waits for the run and returns the rows):

curl -X POST "https://api.apify.com/v2/acts/alexmorain~tech-stack-leads/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>" \
-H "Content-Type: application/json" \
-d '{"technologies": ["Shopify"], "countries": ["FR"], "maxItems": 100}'

Watch for new sites

Turn on monitor and schedule the run (daily or weekly). The first run delivers the usual list and remembers every domain it sent. Each later run asks only for sites crawled since the previous run, and delivers the ones you never received, with isNew: true. Sites you already have are counted as skipped websites.

Be clear on what "new" means. The data source gives no adoption date. The watch returns sites that were detected or crawled again since the last run and that you never received. On Shopify France, about 3 % of stores are crawled again in a week, so a weekly watch reads a few hundred rows and costs about a dollar.

Several watches can live side by side: give each one its own monitorName. Changing the search under the same name mixes the history, so use a new name for a new search.

Add webhookUrl to receive a summary at the end of each run (run id, dataset id, rows delivered, rows skipped). Plug it into Zapier, Make, n8n or your CRM.

Tips

  • Run countOnly first. A count costs $0.02 and tells you how big the full list is.
  • Use sortBy: "recent" with visitedAfter for the freshest sites, or sortBy: "rank" for the biggest ones first.
  • A minimum rank removes sites without a rank (about 26 % of them). Leave it empty if you want small shops.
  • For outbound, contactFilter: "email" costs less than buying raw rows and filtering in a spreadsheet, and the gap grows as the email rate drops.
  • languages uses the detected content language, so ["fr"] with ["BE", "CH"] targets French-speaking sites in Belgium and Switzerland.

FAQ

Where does the data come from? From the DataForSEO technology database, used under an agreement with DataForSEO. It is built by a crawler that reads public pages and detects technologies from their code.

Why do my numbers differ from BuiltWith or another tool? Each database crawls a different set of sites and counts differently. Some lists announce 3.5 million Shopify stores, others 950,000. This one finds 1,520,572 today. Run countOnly to get the exact number for your search before you buy.

Is it legal to collect these emails? The actor only returns contacts published on public websites, but public does not mean free of rules. In the EU and the UK, an email or phone number is personal data as soon as it identifies a person (jane.doe@shop.com, a mobile number), and generic addresses like contact@ can still fall under it for a sole trader. Once you download the rows, you are the data controller under the GDPR, not this actor and not Apify.

In practice, for B2B prospecting:

  • Rely on legitimate interest, and write down why the offer is relevant to the business you contact.
  • Tell people where you got their details, at the latest in your first message.
  • Give an easy way to opt out (an unsubscribe link or a reply), honor it right away, and keep a suppression list so a later run does not bring them back.
  • Delete data you no longer use, and answer access or deletion requests.
  • Follow the local rules on unsolicited email and calls (ePrivacy, CAN-SPAM in the US, do-not-call lists such as Bloctel in France).

This is not legal advice. Check with your counsel before a large campaign.

Can I check the stack of a list of domains I already have? Not in this version. This actor goes from a technology to the sites, not from a site to its technologies.

What happens if a run is interrupted? The actor saves its position and resumes where it stopped. Rows already delivered are skipped and not charged again.

The run failed with "unknown technology". Did I pay? Only the actor start ($0.002). Names, countries and languages are checked before any paid call. The error message lists the closest valid names.

⌂ 换网址