# Website Tech Stack Detector: 7,600+ Technologies & Email Stack (`luke-main/website-tech-stack-detector`) Actor

Bulk Wappalyzer and BuiltWith alternative. Detect CMS, ecommerce, analytics, ad pixels, frameworks, CDN, hosting, payments, live chat and email provider (MX, SPF, DMARC) for any list of websites. US$3 per 1,000 sites, unreachable sites free.

- **URL**: https://apify.com/luke-main/website-tech-stack-detector.md
- **Developed by:** [Luke Main](https://apify.com/luke-main) (community)
- **Categories:** Developer tools, Lead generation, SEO tools
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$3.00 / 1,000 website analyseds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## Website Tech Stack Detector: 7,600+ Technologies & Email Stack

Find out **what any website is built with**, in bulk. Paste a list of domains and get one clean row per site with its **CMS, ecommerce platform, analytics, ad pixels, tag managers, JavaScript frameworks, CDN, hosting, payment processors, live chat, marketing automation and CRM**, plus its **email provider (Google Workspace, Microsoft 365, ...), SPF, DMARC policy and DNS host**.

A low-cost **Wappalyzer and BuiltWith alternative** for lead generation, competitor research, sales prospecting and agency audits.

**US$3 per 1,000 websites analysed. No start fee. Unreachable or invalid websites are free.** DNS and email checks are included at no extra cost.

> Built with AI and maintained by Luke Main (Apify: luke-main). Detection uses the open-source [webappanalyzer](https://github.com/enthec/webappanalyzer) fingerprint set (GPL-3.0, 7,600+ technologies), refreshed on every build. Not affiliated with Wappalyzer or BuiltWith.

### Why this detector

- **7,600+ technologies, not 100.** Many low-cost detectors check a hand-written list of 85-200 signatures. This one uses the full community fingerprint database (headers, cookies, meta tags, HTML, script URLs, inline scripts, CSS selectors, DNS records), with versions where the site exposes them.
- **Email stack for free.** MX, SPF and DMARC are looked up for every domain, so you also learn who runs their email and whether DMARC is enforced (`none`, `quarantine`, `reject`). Handy for deliverability, IT and security prospecting.
- **Lead-list filter.** Give a `technologyFilter` such as `Shopify, Klaviyo` and every row gets `matchesFilter` and `matchedTechnologies`. Turn on `onlyMatching` to keep only the hits.
- **Evidence you can trust.** Each detection carries a `confidence` score, `detectedVia` (`website`, `dns` or `implied`) and up to 3 evidence strings, e.g. `header: server: cloudflare` or `scriptSrc: https://cdn.shopify.com/...`.
- **Flat columns for spreadsheets, full JSON for agents.** `cms`, `ecommerce`, `analytics`, `cdn`, `hosting`, `emailProviders`... are ready to filter in Excel or Google Sheets; the `technologies` array has everything.
- **Fast and light.** Plain HTTP with a real-browser TLS fingerprint, no browser and no proxy costs. Fingerprints are pre-filtered so only relevant patterns run on each page.

### Input

| Field | Default | What it does |
|---|---|---|
| `websites` | (required) | Domains or URLs, one per line. `https://` is added if missing. |
| `technologyFilter` | empty | Technology names to flag, e.g. `Shopify`, `WooCommerce`, `HubSpot`. |
| `filterMode` | `any` | `any` = uses at least one; `all` = uses every one. |
| `onlyMatching` | false | Save only matching sites (all reachable sites are still analysed and charged). |
| `includeDns` | true | MX, TXT, NS, SOA, DMARC lookups (free). |
| `includeEvidence` | true | Up to 3 evidence strings per technology. |
| `minConfidence` | 50 | Hide weaker detections. |
| `maxWebsites` | 1000 | Hard cap, also caps your cost. |
| `maxConcurrency` | 10 | Sites analysed in parallel. |
| `requestTimeoutSecs` | 20 | Per-site timeout. |

```json
{
  "websites": ["allbirds.com", "gymshark.com", "wordpress.org"],
  "technologyFilter": ["Shopify", "Klaviyo"],
  "filterMode": "any"
}
```

### Output

One dataset row per website:

```json
{
  "input": "wordpress.org",
  "domain": "wordpress.org",
  "finalUrl": "https://wordpress.org/",
  "statusCode": 200,
  "title": "Blog Tool, Publishing Platform, and CMS – WordPress.org",
  "technologyCount": 12,
  "cms": ["WordPress"],
  "webServers": ["Nginx"],
  "tagManagers": ["Google Tag Manager"],
  "programmingLanguages": ["PHP"],
  "emailProviders": [],
  "technologies": [
    {
      "name": "WordPress",
      "detectedVia": "website",
      "version": "7.2",
      "confidence": 100,
      "categories": ["CMS", "Blogs"],
      "website": "https://wordpress.org",
      "saas": null,
      "openSource": true,
      "pricing": null,
      "cpe": "cpe:2.3:a:wordpress:wordpress:*:*:*:*:*:*:*:*",
      "evidence": ["meta: generator=WordPress 7.2"]
    }
  ],
  "dns": {
    "mxRecords": ["..."],
    "nameservers": ["..."],
    "spf": "v=spf1 ...",
    "dmarc": "v=DMARC1; p=reject; ...",
    "dmarcPolicy": "reject",
    "txtVerifications": ["google-site-verification"]
  },
  "matchesFilter": false,
  "matchedTechnologies": [],
  "responseTimeMs": 820,
  "analyzedAt": "2026-11-13T00:00:00+00:00",
  "error": null
}
```

Flat columns: `cms`, `ecommerce`, `analytics`, `tagManagers`, `advertising`, `jsFrameworks`, `webFrameworks`, `uiFrameworks`, `pageBuilders`, `webServers`, `cdn`, `hosting`, `emailProviders` (who receives the domain's mail, from MX records), `emailServices` (all email tools seen, incl. sending services like SendGrid or Amazon SES and TXT verifications), `paymentProcessors`, `marketingAutomation`, `crm`, `liveChat`, `cookieCompliance`, `security`, `ai`, `programmingLanguages`.

The key-value store record `SUMMARY` has run totals and the **top 50 technologies across your list** (great for market-share snapshots).

### Use cases

- **Lead generation:** find Shopify, WooCommerce, Magento or BigCommerce stores in your prospect list, or sites using a competitor's tool (HubSpot vs Klaviyo vs Mailchimp).
- **Sales qualification:** enrich a CRM export with CMS, ecommerce platform and email provider before outreach.
- **Competitor research:** see what analytics, A/B testing, chat and payment tools competitors run.
- **Agencies and freelancers:** audit a client's stack in seconds and spot outdated versions.
- **Security and IT:** check DMARC enforcement and email providers across a portfolio of domains.
- **AI agents:** a single call returns stable JSON an LLM can reason over.

### Integrations

- **Google Sheets / Excel / CSV:** export the dataset from the run page, or use the Apify Google Sheets integration to append each run.
- **Zapier, Make and n8n:** trigger a run when a new lead lands in your CRM, then write `cms`, `ecommerce` and `emailProviders` back to the record.
- **Webhooks:** add an Apify webhook on `ACTOR.RUN.SUCCEEDED` to push results to your own endpoint.
- **API and SDKs:** call `luke-main/website-tech-stack-detector` from the Apify API, the JavaScript or Python client, or `run-sync-get-dataset-items` for one-shot lookups.
- **LangChain, LlamaIndex and MCP:** use it as a tool through the Apify LangChain/LlamaIndex integrations or the Apify MCP server so your agent can ask "what is example.com built with?".

```python
from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("luke-main/website-tech-stack-detector").call(run_input={"websites": ["allbirds.com"]})
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(row["domain"], row["ecommerce"], row["emailProviders"])
```

### Pricing

Pay per event: **US$0.003 per website analysed** (US$3 per 1,000). No start fee. Sites that cannot be reached, or invalid inputs, are not charged. Set a maximum total charge on the run to cap spend.

### Limits and honest notes

- **No browser.** Detection reads the HTML, headers, cookies, script URLs and inline scripts the server returns, plus DNS. Technologies that only reveal themselves after JavaScript runs in a browser (some single-page apps and tag-manager-loaded tools) can be missed. JavaScript globals are only detected when they are assigned in the page source.
- **Home page only.** Each website is one request to the URL you give (following redirects). Pass a deeper URL if you want a specific section analysed.
- **Bot protection.** Some sites answer with a challenge page (Cloudflare, Akamai). Those rows show what could be seen and an `error` such as `blocked_or_challenge_403`.
- **DNS detections** (`detectedVia: "dns"`) show services the company uses (email, verified SaaS like DocuSign or Atlassian), not necessarily what the website runs.
- Please use it on public websites in line with their terms; it makes one ordinary page request per site, like a browser visit.

### Changelog

- **0.1** (Nov 2026): first release. 7,600+ fingerprints, DNS/email stack, technology filter, evidence and confidence.

### Support

Open an issue on the Actor's Issues tab. Feature requests (extra pages per site, browser mode, CSV upload) are welcome.

# Actor input Schema

## `websites` (type: `array`):

Domains or URLs, one per line (e.g. shopify.com or https://www.example.com/). Duplicates are removed.

## `technologyFilter` (type: `array`):

Optional. Technology names to look for, e.g. Shopify, WooCommerce, HubSpot, Klaviyo. Each row gets matchesFilter and matchedTechnologies. Names match the 'name' field in the output.

## `filterMode` (type: `string`):

any = a site matches if it uses at least one filter technology; all = it must use every one.

## `onlyMatching` (type: `boolean`):

Only save sites that match the technology filter. Every reachable site is still analysed and charged.

## `includeDns` (type: `boolean`):

Looks up MX, TXT, NS, SOA and DMARC records to detect email providers (Google Workspace, Microsoft 365...), DNS hosts and SaaS tools verified on the domain. Free.

## `includeEvidence` (type: `boolean`):

Show up to 3 signals per technology (header, script URL, meta tag, DNS record...).

## `minConfidence` (type: `integer`):

Hide detections below this confidence.

## `maxWebsites` (type: `integer`):

Hard cap on websites processed (also caps your cost).

## `maxConcurrency` (type: `integer`):

Websites analysed in parallel.

## `requestTimeoutSecs` (type: `integer`):

How long to wait for each website to respond.

## Actor input object example

```json
{
  "websites": [
    "wordpress.org",
    "allbirds.com",
    "vercel.com"
  ],
  "filterMode": "any",
  "onlyMatching": false,
  "includeDns": true,
  "includeEvidence": true,
  "minConfidence": 50,
  "maxWebsites": 1000,
  "maxConcurrency": 10,
  "requestTimeoutSecs": 20
}
```

# Actor output Schema

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

No description

## `summary` (type: `string`):

No description

# 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 = {
    "websites": [
        "wordpress.org",
        "allbirds.com",
        "vercel.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("luke-main/website-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 = { "websites": [
        "wordpress.org",
        "allbirds.com",
        "vercel.com",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("luke-main/website-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 '{
  "websites": [
    "wordpress.org",
    "allbirds.com",
    "vercel.com"
  ]
}' |
apify call luke-main/website-tech-stack-detector --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,luke-main/website-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/qdnMWiHXJSQNcfRQB/builds/jvDdoNMRSayAU0S8M/openapi.json
