# Tech Stack Detector (`lergassy/tech-stack-detector`) Actor

Find out what any website runs on: CMS, e-commerce platform, framework, analytics, ad pixels, payments, hosting, CRM and chat — 220 signatures — plus the e-mails, phones and social profiles from the same page, in one row per website.

- **URL**: https://apify.com/lergassy/tech-stack-detector.md
- **Developed by:** [Matvey](https://apify.com/lergassy) (community)
- **Categories:** Lead generation, Developer tools, Agents
- **Stats:** 2 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $35.00 / 1,000 websites

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

**Tech Stack Detector** tells you what a website is built on — CMS, e-commerce platform, front-end framework, analytics, advertising pixels, payments, hosting and CDN, CRM and e-mail tools, live chat, cookie consent, reviews, A/B testing — **209 signatures across 32 categories**. Paste one domain or ten thousand; every website comes back as one flat row.

And because the home page is already fetched, the same row carries the **e-mails, phone numbers and social profiles** found on it. One run gives you the technology list *and* the way to contact whoever runs it — which is what a prospect list actually needs.

No API key, no browser, no subscription. Sites that refuse to answer are reported as such and are **never billed**.

### What is Tech Stack Detector?

It is a **Wappalyzer and BuiltWith alternative** you can call from an API, a spreadsheet or an AI agent. Give it a list of websites; get back, per website: what they run, in which category, whether the evidence came from the page or from a response header, and how to reach them.

Typical uses: building prospect lists ("Shopify stores that do not use Klaviyo yet"), qualifying inbound leads before a sales call, competitive research on a market segment, auditing a portfolio of client sites, and enriching a CRM with firmographic signals.

### What it detects

| Category | Examples |
|---|---|
| E-commerce | Shopify, WooCommerce, Magento, BigCommerce, PrestaShop, Ecwid |
| CMS and builders | WordPress, Wix, Squarespace, Webflow, Drupal, Joomla, Tilda, HubSpot CMS |
| Front-end | Next.js, Nuxt, React, Vue, Angular, Svelte, Gatsby, Astro, jQuery, Bootstrap, Tailwind |
| Analytics | GA4, Universal Analytics, Matomo, Plausible, Hotjar, Clarity, Mixpanel, Amplitude, Heap |
| Ad pixels | Meta, Google Ads, TikTok, LinkedIn, X, Pinterest, Snapchat, Reddit, Criteo, Taboola |
| Marketing and CRM | HubSpot, Marketo, Klaviyo, Mailchimp, ActiveCampaign, Omnisend, Segment, Tealium, Braze |
| Payments | Stripe, PayPal, Square, Klarna, Afterpay, Zip, Apple Pay |
| Hosting, CDN, server | Cloudflare, Vercel, Netlify, Akamai, Fastly, CloudFront, nginx, Apache, LiteSpeed, IIS |
| Consent and security | OneTrust, Cookiebot, CookieYes, Usercentrics, reCAPTCHA, hCaptcha, Turnstile |
| Chat, booking, reviews | Intercom, Zendesk, Tawk, Crisp, Calendly, Acuity, Mindbody, Yotpo, Judge.me, Trustpilot |
| A/B, search, video, monitoring | Optimizely, VWO, Adobe Target, Algolia, Vimeo, Wistia, Sentry, New Relic, Datadog |

### What the numbers actually are

Measured on 16 September 2026 against 97 real websites — a mix of small businesses taken from social-profile links and well-known brands across retail, media, SaaS and local services, in several countries:

| | |
|---|---|
| Websites that answered | **88%** directly, **92%** when blocked ones are retried through a proxy |
| Technologies found per website | **4 on average**, median 4, best 12 |
| Websites with at least one technology | **95%** of those that answered (81 of 85) |
| Social profiles found | **78%** of websites |
| E-mail on the home page | **28%** of websites |
| Median time per website | about **1.5 seconds** |

The 8% that refuse everything are heavy retail and media sites behind enterprise bot protection. They come back as an error row with the reason, not as an empty result pretending to be one, and they cost nothing.

### How much does it cost?

**$0.05 per website** — one row, one charge, no start fee.

- Sites that refuse every attempt: **$0**.
- Sites removed by your own filters: **$0**.
- Contacts, categories, titles and headers: included, not an add-on.

A thousand domains is $50. The API this replaces starts at several hundred dollars a month for a fixed quota.

### How to use it in three steps

1. Paste domains into **🌐 Websites** — `shopify.com`, `gymshark.com`, or a list of ten thousand from a sheet.
2. If you are building a prospect list, fill in **✅ Keep only sites that use** and **🚫 Drop sites that use**. Filtered-out sites are not billed.
3. Press **Start**, then download JSON, CSV or Excel — or call the run from the API, n8n, Make, Zapier or an AI agent.

### ⬇️ Input

```json
{
  "domains": ["gymshark.com", "allbirds.com", "brooklinen.com"],
  "mustUse": ["shopify"],
  "mustNotUse": ["klaviyo"],
  "includeContacts": true
}
```

That input answers a real sales question: *Shopify stores that have not bought Klaviyo yet* — with the e-mail address to write to, in the same row.

#### Filters

**✅ Keep only sites that use** requires every named technology; **🚫 Drop sites that use** removes a site if any of them is present. Names are matched loosely, so `shopify` matches both Shopify and Shopify Plus. **🗂️ Only these categories** narrows what appears in the row when you only care about, say, payments.

### ⬆️ Output

```json
{
  "type": "website",
  "domain": "gymshark.com",
  "technologies": ["Shopify", "Google Tag Manager", "Klaviyo", "Cloudflare"],
  "technologyCount": 4,
  "categories": ["cdn", "ecommerce", "email_marketing", "tag_manager"],
  "ecommerce": "Shopify",
  "hosting": ["Cloudflare"],
  "marketing": ["Klaviyo"],
  "adsPixels": ["Meta Pixel"],
  "emails": ["press@gymshark.com"],
  "instagram": "https://instagram.com/gymshark",
  "title": "Gymshark",
  "readVia": "direct",
  "scrapedAt": "2026-09-16T12:04:11.004Z"
}
```

`technologiesDetailed` adds, per technology, its category and whether the evidence was in the page or in a response header — so you can tell a script tag from a CDN header when it matters. Two table views come with the dataset: **Tech stack** and **Contacts**.

### Use cases

#### Prospect lists for anyone selling to online stores

Filter by platform, exclude the competitor's tool, keep the e-mail. That is the whole workflow, in one actor.

#### Qualifying inbound leads

Before the call, know whether they are on Shopify or Magento, whether they already run a consent platform, and which analytics they trust.

#### Competitive and market research

Scan a market segment and count platforms, pixels and payment providers. The category fields make the aggregation a one-liner.

#### Agencies auditing client sites

Check a portfolio for missing pixels, missing consent banners or duplicate analytics, on a schedule.

#### AI agents

Flat row, no required fields, 209 named signatures — callable from the Apify API or the Apify MCP server without reading this page.

### Integrations

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("lergassy/tech-stack-detector").call(run_input={
    "domains": ["gymshark.com", "allbirds.com"],
    "mustUse": ["shopify"],
})
for site in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(site["domain"], site["technologies"], site["emails"])
```

Works the same from n8n, Make, Zapier, Google Sheets, a webhook, or the [Apify MCP server](https://mcp.apify.com).

### ❓ FAQ

#### Is this legal?

It reads the public home page of a website, exactly as a browser would, and stores no personal data beyond the contact details the site publishes itself. That is generally lawful, but what you do with contact data is regulated — check GDPR, the Australian Privacy Act or your local equivalent before you e-mail anyone.

#### How is it different from Wappalyzer or BuiltWith?

Same job, no subscription and no quota: you pay $0.05 for each website you actually look up. This one also returns the contacts in the same row, which those two sell separately.

#### Why does a site come back with no technologies?

Either it genuinely runs nothing detectable from the home page, or everything is loaded later by JavaScript. Signatures are matched against resource URLs, script bodies and response headers rather than page text, so the word "Shopify" in a blog post is not counted as an installation.

#### What about sites that block scrapers?

Blocked sites are retried from residential addresses when that option is on. About 8% of the web's most heavily defended sites still refuse everyone; you get an error row with the reason and no charge.

#### Can I use it with the API or an MCP server?

Yes to both, and there are no required input fields, so an agent can call it correctly on the first try.

### Your feedback

A technology missing from the signature list? Open an issue on the **Issues** tab and it gets added — that list is the product.

### You might also like

| Actor | What it does |
|---|---|
| [Website Tech Gap Scanner](https://apify.com/lergassy/website-tech-gap-scanner) | The same detection turned into a sales report: what a site is missing and what to pitch |
| [Website Contacts API](https://apify.com/lergassy/website-contacts-api) | Contacts in depth: crawls beyond the home page for e-mails and phones |
| [Email Finder API](https://apify.com/lergassy/email-finder-api) | A name and a domain in, the likely work e-mail out |
| [Email & Phone Verifier](https://apify.com/lergassy/email-phone-verifier) | Checks the addresses and numbers before you use them |

# Actor input Schema

## `domains` (type: `array`):

Domains or full URLs to look up — <b>shopify.com</b>, <b>https://gymshark.com</b>. One row comes back per website.

## `startUrls` (type: `array`):

The same thing from a file or a Google Sheet, for long lists.

## `categoriesFilter` (type: `array`):

Leave empty for everything the site uses. Pick a few to keep the rows narrow — for example only e-commerce and payments.

## `mustUse` (type: `array`):

Technology names, matched loosely: <b>shopify</b>, <b>klaviyo</b>. A site must use all of them to be delivered — and a site that is filtered out is not charged.

## `mustNotUse` (type: `array`):

The opposite: skip anything already running these. <b>hubspot</b>, <b>intercom</b> — the classic way to find prospects who have not bought your competitor yet.

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

E-mails, tel: numbers and social profiles found on the home page, in the same row as the technologies. Free — it is the page we already fetched.

## `includeSignals` (type: `boolean`):

Page title, meta description, generator tag, server and x-powered-by headers.

## `useProxyWhenBlocked` (type: `boolean`):

Most sites answer a direct request. The ones that refuse are retried from residential addresses, which lifted coverage from 88% to 92% in testing. Turn it off for the cheapest, fastest run.

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

How many websites to read at the same time.

## `maxItems` (type: `integer`):

A hard ceiling on what one run delivers and bills.

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

Used only for sites that refuse a direct request.

## Actor input object example

```json
{
  "domains": [
    "shopify.com",
    "gymshark.com",
    "notion.so"
  ],
  "startUrls": [],
  "categoriesFilter": [],
  "mustUse": [],
  "mustNotUse": [],
  "includeContacts": true,
  "includeSignals": true,
  "useProxyWhenBlocked": true,
  "concurrency": 10,
  "maxItems": 10000,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `websites` (type: `string`):

One row per website: every technology detected with its category, plus the e-mails, phones and social profiles found on the same page.

# 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 = {
    "domains": [
        "shopify.com",
        "gymshark.com",
        "notion.so"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("lergassy/tech-stack-detector").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 = {
    "domains": [
        "shopify.com",
        "gymshark.com",
        "notion.so",
    ],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("lergassy/tech-stack-detector").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 '{
  "domains": [
    "shopify.com",
    "gymshark.com",
    "notion.so"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call lergassy/tech-stack-detector --silent --output-dataset

```

## MCP server setup

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

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/8jqX9Ff9qcxS4naCO/builds/OIhU1UKQtg6CgMDfE/openapi.json
