# Website Tech Stack Detector - CMS, Framework & Analytics (`apisight/website-tech-stack-scanner`) Actor

Detect the technology behind any website: CMS, ecommerce platform, JS framework, hosting, CDN, analytics, payment and cookie-consent tools, plus a security-header scorecard.

- **URL**: https://apify.com/apisight/website-tech-stack-scanner.md
- **Developed by:** [Apisight](https://apify.com/apisight) (community)
- **Categories:** Developer tools, SEO tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $50.00 / 1,000 analysed domains

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 Scanner — CMS, Framework & Analytics Detector

Find out what any website is built with. Give it a list of domains and it returns the
CMS, ecommerce platform, JavaScript framework, hosting, CDN, analytics, payment
providers and cookie-consent tool behind each one — plus a security-header scorecard.

Built for competitive research, lead qualification by technology, migration audits and
agency prospecting. Works on a single domain or thousands.

### What it detects

Over 150 technologies across 30 categories:

| Category | Examples |
|---|---|
| CMS | WordPress, Drupal, Webflow, Squarespace, Wix, Ghost, TYPO3, Sitecore, AEM, Contentful, Sanity, Framer |
| Ecommerce | Shopify, WooCommerce, Magento, PrestaShop, BigCommerce, Shopware, Salesforce Commerce, Lightspeed |
| JS framework | React, Next.js, Vue, Nuxt, Angular, Svelte, SvelteKit, Astro, Remix, Gatsby, Alpine.js, htmx |
| Hosting / CDN | Vercel, Netlify, Cloudflare, Fastly, Akamai, CloudFront, WP Engine, Kinsta, Heroku, Render, Fly.io |
| Analytics | GA4, Google Tag Manager, Plausible, Fathom, Matomo, PostHog, Mixpanel, Amplitude, Segment, Hotjar, Clarity |
| Advertising | Meta Pixel, Google Ads, TikTok, LinkedIn Insight, Pinterest, Reddit |
| Payment | Stripe, PayPal, Mollie, Adyen, Klarna, Afterpay, Apple Pay |
| Consent (CMP) | Cookiebot, OneTrust, Usercentrics, CookieYes, Iubenda, Complianz, Osano, Termly |
| Also | web servers, runtimes, live chat, error monitoring, A/B testing, reviews, page builders, SEO plugins |

Version numbers are extracted where the site discloses them (for example `nginx 1.27.3`,
`WordPress 6.8.1`, `Ghost 5.118`).

### Input

```json
{
  "startUrls": ["apify.com", "shopify.com", "wordpress.org"],
  "includeSecurityHeaders": true,
  "maxConcurrency": 10,
  "requestTimeoutSecs": 20
}
```

| Field | Type | Default | Notes |
|---|---|---|---|
| `startUrls` | array | — | Domains or full URLs. `example.com` and `https://example.com/` both work. Duplicates are removed. |
| `includeSecurityHeaders` | boolean | `true` | Adds the security-header scorecard. No extra cost. |
| `maxConcurrency` | integer | `10` | 1–25. |
| `requestTimeoutSecs` | integer | `20` | 5–60. |

### Output

One record per domain:

```json
{
  "domain": "allbirds.com",
  "status": "ok",
  "httpStatus": 200,
  "responseTimeMs": 412,
  "pageTitle": "Allbirds | Everyday Shoes",
  "https": true,
  "technologyCount": 9,
  "summary": {
    "cms": [],
    "ecommerce": ["Shopify"],
    "jsFramework": ["React"],
    "hosting": ["Cloudflare"],
    "analytics": ["Google Tag Manager", "Google Analytics 4"],
    "payment": ["Stripe", "Apple Pay"],
    "consentPlatform": ["OneTrust"]
  },
  "technologies": [
    {
      "name": "Shopify",
      "category": "Ecommerce",
      "version": null,
      "confidence": "high",
      "matchedOn": ["header", "html"],
      "evidence": "x-shopify-stage: production | markup: cdn.shopify.com"
    }
  ],
  "security": {
    "headerScore": 67,
    "headersPresent": {
      "strictTransportSecurity": true,
      "contentSecurityPolicy": false,
      "xFrameOptions": true,
      "xContentTypeOptions": true,
      "referrerPolicy": true,
      "permissionsPolicy": false
    },
    "versionDisclosure": { "server": "nginx/1.27.3" }
  },
  "scannedAt": "2026-09-30T09:14:02Z"
}
```

Every technology carries its own `evidence` and `confidence`, so you can verify any
detection rather than trusting a bare label.

- `confidence: "high"` — matched a response header, cookie or `<meta generator>` tag, or
  matched two independent signals.
- `confidence: "medium"` — matched a single markup or asset-URL signal.

### Pricing and what you are charged for

| Event | Price | When |
|---|---|---|
| `domain-analysed` | $0.05 | Once per domain **successfully** analysed |
| `apify-actor-start` | $0.00005 | Once per run (a twentieth of a cent) |

**You are not charged for results you cannot use.** A target that returns
`status: "blocked"` or `status: "error"` costs you nothing. Those records still appear in
your dataset, with a `blockReason` explaining exactly what happened — we would rather hand
you an honest failure you can see than a half-empty guess you would have to catch yourself.

There is no per-record dataset charge, so a run full of blocked sites costs you essentially
nothing beyond the fraction-of-a-cent start fee.

### Honest limitations

- **Sites behind bot protection cannot be fingerprinted.** Some sites (Cloudflare
  challenges, DataDome, PerimeterX, Incapsula) serve an interstitial instead of the real
  page. These are reported as `status: "blocked"` and are not billed. This is a hard limit
  of any HTTP-based scanner, and we would rather tell you than return a half-empty guess.
- **Detection is based on the homepage.** Technologies that only load on checkout, login or
  deep pages may be missed. Pass those specific URLs directly if you need them.
- **Client-side-only technologies may be under-reported**, since no JavaScript is executed.
  This keeps the scanner fast and cheap; for full rendering you would need a browser-based
  tool.
- **No personal data.** This Actor reads only public technical metadata — HTTP headers,
  markup and asset URLs. It does not collect emails, names, contact details or any personal
  data, and is not intended for building contact lists.

### Common uses

- **Agency prospecting** — find every prospect still on an outdated CMS.
- **Competitive research** — see which analytics, payment and CMP vendors a market uses.
- **Lead qualification** — filter a domain list down to Shopify or WooCommerce stores.
- **Migration and due diligence** — inventory a portfolio of sites before a replatform.
- **Compliance review** — check which consent platform and security headers a site uses.

### FAQ

**Can I scan thousands of domains?**
Yes. Pass them all in `startUrls` and raise `maxConcurrency`. Cost scales linearly with
successfully analysed domains only.

**Why does a site show fewer technologies than I expect?**
Either it is behind bot protection (check `status` and `blockReason`), or the technology
only appears on pages other than the homepage, or it is injected by JavaScript at runtime.

**Is the version number always present?**
No. Most sites deliberately hide version numbers. We report a version only when the site
discloses it, and never guess.

# Actor input Schema

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

Domains or URLs to analyse. Both "example.com" and "https://example.com/" work.

## `includeSecurityHeaders` (type: `boolean`):

Adds an HTTP security-header scorecard (HSTS, CSP, X-Frame-Options, and version disclosure) to every result. No extra cost.

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

Routes requests through Apify Proxy. Strongly recommended: many sites rate-limit shared cloud IPs, and blocked targets are never charged, so proxying gets you more usable results for the same spend.

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

How many sites to scan at once. Higher is faster; lower is gentler on the targets.

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

Seconds to wait for each site before giving up.

## Actor input object example

```json
{
  "startUrls": [
    "apify.com",
    "shopify.com",
    "wordpress.org"
  ],
  "includeSecurityHeaders": true,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "maxConcurrency": 10,
  "requestTimeoutSecs": 20
}
```

# Actor output Schema

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

All scan results: one record per target with its CMS, ecommerce platform, JS framework, hosting, CDN, analytics, payment and consent tooling, each detection carrying its own evidence and confidence. Records with status 'blocked' or 'error' are included for transparency and are 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 = {
    "startUrls": [
        "apify.com",
        "shopify.com",
        "wordpress.org"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("apisight/website-tech-stack-scanner").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 = {
    "startUrls": [
        "apify.com",
        "shopify.com",
        "wordpress.org",
    ],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("apisight/website-tech-stack-scanner").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 '{
  "startUrls": [
    "apify.com",
    "shopify.com",
    "wordpress.org"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call apisight/website-tech-stack-scanner --silent --output-dataset

```

## MCP server setup

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

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/cZ13m8HAec1nBcHAH/builds/tdmsAcwpcFrLrcs29/openapi.json
