# Website Tech Stack Detector: CMS, Ecommerce & Analytics (`blond_terrarium/website-tech-stack-detector`) Actor

Find the technologies behind any list of websites: CMS (WordPress, Shopify, Wix, Squarespace...), frameworks, analytics, CDN, hosting, payment and email provider. Wappalyzer-style, 7,600+ fingerprints, fast, no browser. Pay only for websites where technologies were found.

- **URL**: https://apify.com/blond_terrarium/website-tech-stack-detector.md
- **Developed by:** [Mogul Tools](https://apify.com/blond_terrarium) (community)
- **Categories:** Lead generation, Developer tools, E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 website analyzeds

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

## Website Tech Stack Detector: CMS, Ecommerce, Analytics & Email Provider

Give it a list of websites and get the **technologies each one runs on**: CMS (WordPress, Shopify, Wix, Squarespace, Webflow, Drupal…), ecommerce platform, JavaScript frameworks (Next.js, React, Vue…), analytics and tag managers, CDN, hosting, payment providers, web server, programming language, security, marketing, live chat and cookie-consent tools. **Versions** are included when the site exposes them (e.g. `WordPress 7.2`, `Gutenberg 24.2.0`). From DNS it also finds the **email provider** (Google Workspace, Microsoft 365, Zoho…), email-sending services (SendGrid, Mailchimp, Amazon SES…) and DNS hosting.

It works like Wappalyzer, with **7,600+ open-source fingerprints**, but uses fast HTTP requests instead of a browser, so it's quick and cheap. In our tests a typical website took about 1.4 seconds, with 20 websites analyzed in parallel.

**You only pay for websites where technologies were found.** 404s, timeouts, anti-bot pages, non-HTML responses, robots.txt-blocked sites and sites with nothing detected are free.

### What you can use it for

- **Lead generation**: find every Shopify store, WordPress site or Wix site in a list, or prospects using a competitor's tool
- **Sales intelligence**: enrich a CRM with CMS, ecommerce platform, email provider and analytics
- **Market research**: technology adoption across an industry or a list of competitors
- **Agencies**: qualify prospects before a pitch (outdated CMS version, no analytics, no cookie banner)
- Feeding tech-stack data to AI agents (works via the Apify MCP server)

### How it detects technologies

For each website it loads the homepage (and optionally up to 2 more pages such as shop, cart, blog or pricing) and checks:

- HTTP **headers** and **cookies** (including those set during redirects)
- **HTML**, **meta tags** (generator etc.), **script URLs** and **inline JavaScript**
- **DOM selectors** on the parsed page
- **DNS**: MX (email provider), TXT/SPF (email-sending services, domain-verified SaaS) and NS (DNS hosting)

Then it applies the fingerprint rules for **implied** technologies (e.g. WordPress → PHP and MySQL, Next.js → React), **excludes** and **requires**, and extracts versions.

### Input example

```json
{
  "websites": ["allbirds.com", "wordpress.org", "https://react.dev/"],
  "maxPagesPerSite": 1,
  "checkDns": true,
  "minConfidence": 50
}
```

### Output example (one row per website)

```json
{
  "input": "react.dev",
  "domain": "react.dev",
  "url": "https://react.dev/",
  "finalUrl": "https://react.dev/",
  "status": 200,
  "title": "React",
  "technologyCount": 14,
  "technologies": [
    { "name": "Google Analytics", "version": "GA4", "categories": ["Analytics"], "confidence": 100, "website": "https://google.com/analytics", "detectedBy": ["scriptSrc", "scripts"] },
    { "name": "Next.js", "version": null, "categories": ["JavaScript frameworks", "Web frameworks", "Web servers", "Static site generator"], "confidence": 100, "website": "https://nextjs.org", "detectedBy": ["scriptSrc", "html", "js"] },
    { "name": "React", "version": null, "categories": ["JavaScript frameworks"], "confidence": 100, "website": "https://reactjs.org", "detectedBy": ["implied by Next.js"] }
  ],
  "categories": {
    "cms": [], "ecommerce": [], "analytics": ["Google Analytics"], "tagManagers": ["Google Tag Manager"],
    "cdn": ["Cloudflare"], "frameworks": ["Next.js", "React"], "payment": [], "emailProvider": [],
    "hosting": ["Vercel", "Cloudflare DNS"], "webServers": ["Next.js"], "security": ["HSTS"]
  },
  "technologyNames": ["Algolia DocSearch", "Google Analytics GA4", "Next.js", "React", "HSTS", "Open Graph", "PWA", "RSS", "Webpack", "Algolia", "Cloudflare", "Google Tag Manager", "Vercel", "Cloudflare DNS"],
  "dns": { "mx": [], "spf": [], "ns": ["hattie.ns.cloudflare.com", "junade.ns.cloudflare.com"] },
  "pagesAnalyzed": ["https://react.dev/"],
  "redirectChain": [],
  "charged": true,
  "error": null,
  "errorCode": null,
  "durationMs": 564,
  "scrapedAt": "2026-10-22T19:09:57.598Z"
}
```

`categories` always has these keys: `cms`, `ecommerce`, `analytics`, `tagManagers`, `cdn`, `frameworks`, `jsLibraries`, `payment`, `emailProvider` (from MX records), `emailServices` (sending services from SPF), `hosting`, `webServers`, `programmingLanguages`, `databases`, `security`, `marketing`, `liveChat`, `cookieCompliance`, `fonts` and `domainVerifiedServices`. The last one lists SaaS tools that only showed up as DNS TXT domain-verification records (e.g. Atlassian, Zoom, DocuSign). They are kept out of the other buckets because they describe the company, not the website.

Free rows have `charged: false`, `errorCode` and `error`. Codes are `INVALID_URL`, `DNS_ERROR`, `TIMEOUT`, `HTTP_404` (and other HTTP codes), `BLOCKED` (anti-bot page), `NOT_HTML`, `ROBOTS_DISALLOWED` and `NO_TECHNOLOGIES`. Blocked and error pages still list whatever was visible, such as the CDN or WAF. The `RUN_SUMMARY` record in the key-value store has the run totals.

### Pricing (pay per event)

You pay per **website analyzed**: the site loaded (HTTP 2xx HTML) and at least one technology was detected on the site itself. The price is per website, not per page, so `maxPagesPerSite: 3` costs the same.

| Apify plan | Price per 1,000 websites |
|---|---|
| Free | $5.00 |
| Bronze (Starter) | $4.00 |
| Silver (Scale) | $3.50 |
| Gold (Business) | $3.00 |

Failed, blocked and no-technology websites are never charged, and neither are sites where only DNS records matched. Platform usage (compute, storage) is included; you don't pay it separately. Each run also has Apify's standard start fee of $0.00005 per GB of memory. Optional Apify datacenter proxy (or your own proxy URLs) is included in the price; residential proxy isn't supported. Set **Max total charge** on the run to cap your spend. The run stops cleanly when it's reached, without storing unpaid results.

### Features

- 7,600+ technology fingerprints in 109 categories, with versions, confidence and implied technologies
- Tries `https://`, then `www.`, then `http://`; follows redirects and records the redirect chain
- Optional extra pages (shop, cart, checkout, blog, pricing, contact) to catch more tools
- DNS-based email provider and DNS hosting detection
- Polite by default: respects robots.txt, per-host delay, retries with backoff
- Refuses private/internal addresses

### Limitations

- **No JavaScript rendering.** It sees the HTML, headers and scripts the server sends. Tools that are injected later by a tag manager, or only visible as runtime JavaScript objects, may be missed. JavaScript-global fingerprints are approximated from inline scripts.
- Fingerprints that need a real browser (DOM properties, CSS rules, XHR requests), probe requests and TLS-certificate fingerprints aren't used.
- Sites with strong bot protection (Cloudflare challenge, Akamai, Amazon) may return an anti-bot page. Those rows are free. Enabling Apify datacenter proxy sometimes helps.
- If the platform resolver returns no MX/TXT/NS records, DNS is looked up via Cloudflare DNS-over-HTTPS (`cloudflare-dns.com`). Only the domain name is sent.
- Detection is only as good as the open fingerprint database; a few signals (e.g. generic "Cart Functionality") are heuristic.

### Fingerprint data and license

Technology fingerprints and categories come from **[enthec/webappanalyzer](https://github.com/enthec/webappanalyzer)** (the open-source continuation of Wappalyzer's fingerprints), licensed **GPL-3.0**. The bundled snapshot is commit `d91f7e510e93457041bea874e8a9ffb011e3e4fe` (Oct 19, 2026); its license is in `fingerprints/LICENSE`. `fingerprints/extra.json` adds a few fingerprints of our own: Next.js App Router markers, MX/SPF patterns for common email providers and sending services, a stricter Apple iCloud Mail rule, and a Wix exclusion rule. This Actor's code is licensed GPL-3.0-or-later.

### Responsible use

Only analyze sites you are allowed to access. robots.txt is respected by default, and each site gets 1–3 requests plus a robots.txt request.

# Actor input Schema

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

Domains or URLs, e.g. 'allbirds.com' or 'https://www.example.com/'. One row per website.

## `maxPagesPerSite` (type: `integer`):

1 = homepage only (fastest). 2-3 also checks linked shop/cart/blog/pricing/contact pages to catch more tools. Price is per website, not per page.

## `checkDns` (type: `boolean`):

Reads MX, TXT (SPF/verification) and NS records to detect e.g. Google Workspace, Microsoft 365, Mailchimp, Cloudflare DNS.

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

Drop weaker detections.

## `includeFailedSites` (type: `boolean`):

Adds a free row with the reason so you can see every input.

## `respectRobotsTxt` (type: `boolean`):

Skip disallowed pages.

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

Pages of one website are always fetched one by one, with the delay below.

## `requestDelayMs` (type: `integer`):

Politeness per host.

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

Per request.

## `maxRetries` (type: `integer`):

For timeouts, resets, 429 and 5xx.

## `userAgent` (type: `string`):

Leave empty for the default browser-compatible UA.

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

Optional. Apify datacenter proxy or your own proxy URLs. Residential proxy isn't supported (it would raise the price for everyone).

## Actor input object example

```json
{
  "websites": [
    "allbirds.com",
    "wordpress.org",
    "react.dev"
  ],
  "maxPagesPerSite": 1,
  "checkDns": true,
  "minConfidence": 50,
  "includeFailedSites": true,
  "respectRobotsTxt": true,
  "maxConcurrency": 20,
  "requestDelayMs": 300,
  "requestTimeoutSecs": 20,
  "maxRetries": 1,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `overview` (type: `string`):

Websites with CMS, ecommerce, frameworks, analytics, CDN, hosting, payment and email provider.

## `results` (type: `string`):

Every row incl. the full technologies list and failed websites.

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

Totals: analyzed (charged), no technologies and failed (not charged).

# 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": [
        "allbirds.com",
        "wordpress.org",
        "react.dev"
    ],
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("blond_terrarium/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": [
        "allbirds.com",
        "wordpress.org",
        "react.dev",
    ],
    "proxyConfiguration": { "useApifyProxy": False },
}

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

```

## MCP server setup

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