# Tech Stack Detector: Website Technology Lookup (`magicfingers/techstack-detector`) Actor

Find what any website is built with: CMS, shop platform, analytics, CDN, hosting, email provider and 190+ technologies, with evidence and a confidence score for each. Bulk lists of up to 10,000 sites. Failed sites are free.

- **URL**: https://apify.com/magicfingers/techstack-detector.md
- **Developed by:** [abdulrahman alrashid](https://apify.com/magicfingers) (community)
- **Categories:** Lead generation, Developer tools, SEO tools
- **Features:** Limited permissions
- **Stats:** 226 total users, 39 monthly users, 98.4% runs succeeded, 2 bookmarks
- **User rating**: 4.31 out of 5 stars

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-usage

## 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: Website Technology Lookup

Find out what any website is built with. Give Tech Stack Detector a list of websites and get one row per site with its CMS, shop platform, analytics, CDN, hosting, email provider and 190+ other technologies, each with the evidence that matched and a confidence score. Sites that fail to load are listed separately and are never charged.

### What is Tech Stack Detector?

Tech Stack Detector is a website technology lookup tool, an alternative to BuiltWith or Wappalyzer for lists of sites you want to check with the API or on a schedule. It reads each site's HTML, HTTP headers, cookies, script and stylesheet URLs, meta tags, robots.txt and DNS records (CNAME, NS, MX), and runs a real browser only when a page needs JavaScript to show its content.

- One row per website (or one row per website and technology, for spreadsheets).
- Main columns ready to filter on: `cms`, `ecommercePlatform`, `analytics`, `cdn`, `hosting`, `emailProvider`.
- Evidence for every detection: the header, cookie, script URL, meta tag, DNS record or JS global that matched.
- Up to 10,000 websites per run. HTTP first, so 1,000 sites finish in minutes at 1 GB of memory.

### What can it detect?

195 technologies in 34 categories:

| Category | Technologies |
|---|---|
| Email Provider (18) | Amazon SES, Barracuda, Cloudflare Email Routing, Fastmail, GoDaddy Email, Google Workspace, iCloud Mail, Mailgun, Microsoft 365, Mimecast, Namecheap Private Email, Proofpoint, Proton Mail, Rackspace Email, Titan Email, Yahoo Mail, Yandex 360, Zoho Mail |
| Analytics (13) | Amplitude, Clarity, Fathom, FullStory, Google Analytics, Google Analytics 4, Heap, Hotjar, Matomo, Mixpanel, Plausible, PostHog, Segment |
| CMS (13) | Contentful, Drupal, Ghost, HubSpot CMS, Joomla, Magento, PrestaShop, Shopify, Squarespace, Strapi, Webflow, Wix, WordPress |
| JavaScript Framework (13) | Angular, Astro, Ember.js, Gatsby, Next.js, Nuxt.js, Preact, React, Remix, Stimulus, Svelte, SvelteKit, Vue.js |
| Hosting (12) | AWS, Azure, DigitalOcean, Fly.io, GitHub Pages, Google Cloud, Heroku, Netlify, Railway, Render, Vercel, WP Engine |
| JavaScript Library (10) | Alpine.js, Axios, Backbone.js, Chart.js, D3.js, HTMX, jQuery, Lodash, Moment.js, Turbo |
| Programming Language (9) | ASP.NET, Django, Express.js, Flask, Laravel, PHP, Ruby on Rails, Spring, TypeScript |
| CDN (8) | Akamai, AWS CloudFront, Cloudflare, Fastly, jsDelivr, KeyCDN, StackPath, unpkg |
| CSS Framework (8) | Ant Design, Bootstrap, Bulma, Chakra UI, Foundation, Material UI, Semantic UI, Tailwind CSS |
| Chat & Support (8) | Crisp, Drift, Freshdesk, Intercom, LiveChat, Tawk.to, Tidio, Zendesk |
| Advertising (7) | Criteo, Facebook Pixel, Google Ads, LinkedIn Insight Tag, Pinterest Tag, TikTok Pixel, Twitter Pixel |
| Email Marketing (6) | ActiveCampaign, ConvertKit, HubSpot, Klaviyo, Mailchimp, SendGrid |
| Payment (6) | Afterpay, Braintree, Klarna, PayPal, Square, Stripe |
| Security (6) | Cloudflare Turnstile, hCaptcha, reCAPTCHA, Recaptcha Enterprise, Sucuri, Wordfence |
| A/B Testing (5) | AB Tasty, Google Optimize, LaunchDarkly, Optimizely, VWO |
| Animation (4) | Framer Motion, GSAP, Lottie, Three.js |
| Build Tool (4) | Parcel, Turbopack, Vite, Webpack |
| Error Tracking (4) | Bugsnag, Datadog RUM, LogRocket, Sentry |
| SEO (4) | Open Graph, Schema.org, Twitter Cards, Yoast SEO |
| Tag Manager (4) | Adobe Launch, Cloudflare Zaraz, Google Tag Manager, Tealium |
| Web Server (4) | Apache, LiteSpeed, Nginx, Varnish |
| Cookie Consent (3) | Cookie Notice, Cookiebot, OneTrust |
| E-commerce (3) | BigCommerce, OpenCart, Woocommerce |
| Font/Icon Library (3) | Font Awesome, Google Fonts, Typekit/Adobe Fonts |
| Maps (3) | Google Maps, Leaflet, Mapbox |
| Page Builder (3) | Beaver Builder, Divi, Elementor |
| API (2) | Apollo Client, GraphQL |
| Authentication (2) | Auth0, Okta |
| Backend (2) | Firebase, Supabase |
| PWA (2) | PWA, Service Worker |
| Performance (2) | AMP, Lazy Loading |
| UI Component (2) | Slick Slider, Swiper |
| Edge Computing (1) | Cloudflare Workers |
| Real-time (1) | Socket.io |

### How to find what a website is built with

1. Open the Actor and paste your websites into **Websites**, one per line. Bare domains such as `wordpress.org` work.
2. Keep **Mode** on `auto` unless you need every site rendered in a browser.
3. Click **Start**. Each site takes 1 to 3 seconds in the HTTP pass.
4. Open the **Output** tab, filter on `cms`, `ecommercePlatform` or any other column, and export to CSV, Excel or JSON, or read the results with the Apify API.

### How much does it cost to check 1,000 websites?

You pay per website analysed. Websites that fail to load (DNS errors, timeouts, error pages) are free and listed in the `FAILED_URLS` record of the run's key-value store. There is no extra start fee beyond the standard Apify run start.

| Event | Charged when | Free plan | Bronze | Silver | Gold |
|---|---|---|---|---|---|
| Site analysed (`site-analysed`) | One website analysed and its result saved. Sites that fail to load are not charged. | 2.00 USD per 1,000 events | 2.00 USD per 1,000 events | 1.80 USD per 1,000 events | 1.60 USD per 1,000 events |
| Actor start (`apify-actor-start`) | Charged by Apify when the run starts: once up to 1 GB of memory, then once for each extra GB. | 0.05 USD per 1,000 runs | 0.05 USD per 1,000 runs | 0.05 USD per 1,000 runs | 0.05 USD per 1,000 runs |

Example: 1,000 websites on the Bronze plan cost 1,000 x 0.002 USD = 2.00 USD, plus 0.00005 USD for the run start. Platform usage (compute, storage, traffic) is included in these prices.

Free plan: the 5 USD of monthly Apify credit covers about 2,500 websites a month when no other Actor is used.

You can set a maximum cost per run in the run options. The Actor stops starting new sites when the limit is reached, finishes the sites in progress and writes its summary.

### Input example

```json
{
    "urls": ["https://www.shopify.com", "wordpress.org", "https://react.dev"],
    "mode": "auto",
    "outputFormat": "site",
    "minConfidence": 30,
    "includeEvidence": true,
    "checkDns": true,
    "checkRobotsTxt": true,
    "maxConcurrency": 10
}
```

### Output example: site row

A row from a real run (the technologies list is shortened here):

```json
{
    "url": "https://wordpress.org",
    "finalUrl": "https://wordpress.org",
    "domain": "wordpress.org",
    "statusCode": 200,
    "https": true,
    "technologiesCount": 6,
    "categories": "CMS, SEO, Tag Manager, Web Server",
    "technologies": [
        {
            "name": "WordPress",
            "category": "CMS",
            "version": "7.2",
            "confidence": 100,
            "website": "https://wordpress.org",
            "evidence": [
                { "type": "html", "match": "wp-content/", "matches": ["wp-content/"] },
                { "type": "meta", "match": "generator=WordPress 7.2-beta5-65438", "matches": ["generator=WordPress 7.2-beta5-65438"] }
            ]
        },
        {
            "name": "Nginx",
            "category": "Web Server",
            "version": null,
            "confidence": 60,
            "website": "https://nginx.org",
            "evidence": [{ "type": "headers", "match": "server: nginx", "matches": ["server: nginx"] }]
        }
    ],
    "technologyGroups": {
        "SEO": ["Open Graph", "Twitter Cards", "Schema.org"],
        "CMS": ["WordPress"],
        "Web Server": ["Nginx"],
        "Tag Manager": ["Google Tag Manager"]
    },
    "cms": "WordPress",
    "ecommercePlatform": null,
    "analytics": [],
    "cdn": null,
    "hosting": null,
    "emailProvider": null,
    "renderedWithBrowser": false,
    "redirectedToOtherDomain": false,
    "blockedByChallenge": false,
    "analysisTimeMs": 2080,
    "analyzedAt": "2026-11-12T21:12:56.492Z"
}
```

### Output example: technology row

With `"outputFormat": "technology"` each technology gets its own row. The price stays one event per website.

```json
{
    "url": "https://www.shopify.com",
    "finalUrl": "https://www.shopify.com",
    "domain": "www.shopify.com",
    "statusCode": 200,
    "https": true,
    "cms": "Shopify",
    "ecommercePlatform": "Shopify",
    "cdn": "Cloudflare",
    "hosting": null,
    "emailProvider": "Google Workspace",
    "renderedWithBrowser": false,
    "redirectedToOtherDomain": false,
    "blockedByChallenge": false,
    "analyzedAt": "2026-11-12T21:12:59.123Z",
    "technology": "Shopify",
    "category": "CMS",
    "version": null,
    "confidence": 85,
    "website": "https://shopify.com",
    "evidence": "html: cdn.shopify.com | scripts: https://cdn.shopify.com/shopifycloud/world/brochure/production-shopify/assets/entry.client-DwpyJ0Wk.js"
}
```

### Output fields

| Field | Type | Description |
|---|---|---|
| `url` | string | Input URL, normalised (https:// added, host in lower case). |
| `finalUrl` | string | URL of the analysed page after redirects. |
| `domain` | string | Host name of the input URL. |
| `statusCode` | integer or null | HTTP status code of the final page. |
| `https` | boolean | True when the final URL uses HTTPS. |
| `technologies` | array | Site rows only. Each detected technology with its category, version (or null), confidence from 0 to 100, evidence and website. |
| `technologiesCount` | integer | Site rows only. Number of technologies at or above the minimum confidence. |
| `categories` | string | Site rows only. Comma-separated list of the categories found. |
| `technologyGroups` | object | Site rows only. Category name to list of technology names. |
| `technology` | string or null | Technology rows only. Name of the technology (null when the site shows none). |
| `category` | string or null | Technology rows only. Category of the technology. |
| `version` | string or null | Technology rows only. Version when the site exposes it, else null. |
| `confidence` | integer or null | Technology rows only. Confidence from 0 to 100. |
| `website` | string or null | Technology rows only. Home page of the technology. |
| `evidence` | string | Technology rows only. Matched signals as text, for example scripts: https://cdn.shopify.com/... |
| `cms` | string or null | Main content management system, or null. |
| `ecommercePlatform` | string or null | Main e-commerce platform, or null. |
| `analytics` | array | Site rows only. Analytics tools found. |
| `cdn` | string or null | Main CDN, or null. |
| `hosting` | string or null | Hosting or platform-as-a-service provider, or null. |
| `emailProvider` | string or null | Email provider from the domain's MX records, or null. |
| `renderedWithBrowser` | boolean | True when the browser pass ran for this site. |
| `redirectedToOtherDomain` | boolean | True when the input URL redirects to another site (for example a parked domain). |
| `blockedByChallenge` | boolean | True when the site showed a bot challenge page; the row then holds only what that page revealed (often the CDN). |
| `analysisTimeMs` | integer | Site rows only. Time spent on the site in milliseconds. |
| `analyzedAt` | string | ISO 8601 time of the analysis. |

The run also writes two records to its key-value store: `SUMMARY` (counts per technology and category, sites analysed, failed and not processed) and `FAILED_URLS` (each failed site with the reason and the number of attempts).

### Modes: auto, http, browser

- **auto** (default): the HTTP pass reads every site. A site goes to the browser pass only when its page is empty, is a small client-rendered shell (for example a single `<div id="root">` with script bundles), shows fewer than 2 technologies, returns 401, 403, 429 or 5xx, or shows a bot challenge.
- **http**: HTTP pass only. Fastest and cheapest for the platform; JavaScript globals are not checked.
- **browser**: every site is rendered in Chromium (images, fonts and media are blocked). Use 2,048 MB of memory or more; at 1,024 MB the Actor renders 1 page at a time, at 2,048 MB 3 pages, at 4,096 MB 6 pages.

### Use cases

- **Lead lists by platform**: keep only the Shopify or WooCommerce stores in a list of prospects, or every site on HubSpot.
- **Competitor research**: see which analytics, A/B testing and chat tools competitors run.
- **Audits**: check which CDN, hosting and email provider a list of client sites uses, and spot old jQuery or CMS versions.
- **Enrichment pipelines**: call the Actor with the API or from Make or n8n for each new lead, or schedule it weekly on a saved list.

### Limits

- Detection is signature-based: technologies that leave no trace in HTML, headers, cookies, DNS or JS globals are missed.
- Sites behind bot challenges return few results (often only the CDN); no bypass is attempted. Such rows have `blockedByChallenge: true`.
- Versions are shown only when the site exposes them.
- Only the page you list is read (plus robots.txt and DNS); other pages of the site are not crawled.
- At most 3 MB of HTML is read per page.
- URLs that point to private or local network addresses are refused.

### FAQ

**Am I charged for sites that fail?** No. Only websites whose result row is saved are charged. A site that loads but shows no technology above your minimum confidence is saved with `technologies: []` and is charged, because the analysis was delivered.

**What does the confidence score mean?** Each matching signal adds a weight (for example a meta generator tag or a vendor header weighs more than a word in the HTML). The score is the sum, capped at 100. Raise **Minimum confidence** to keep only strong matches.

**Why is a technology marked "implied"?** Some technologies imply others: a Next.js site runs React, a WooCommerce shop runs WordPress. The implied one gets the confidence of the one that implies it.

**I used version 1. Will my integration break?** No field was removed or renamed. See the changelog for the differences.

### Other Actors by the same author

- [App Store and Google Play Scraper](https://apify.com/magicfingers/appstore-scraper): app details and reviews from both stores.
- All Actors: [apify.com/magicfingers](https://apify.com/magicfingers)

# Changelog

This Actor's version history is a separate document: https://apify.com/magicfingers/techstack-detector/changelog.md

# Actor input Schema

## `urls` (type: `array`):

Websites or bare domains to analyse, for example https://www.shopify.com or wordpress.org. https:// is added when missing. Duplicate host names are analysed once. 1 to 10,000 per run.

## `mode` (type: `string`):

auto: HTTP first, browser only when the page needs JavaScript or shows few technologies. http: fastest, no JavaScript. browser: render every site in Chromium (use 2,048 MB of memory or more).

## `outputFormat` (type: `string`):

site: one row per website. technology: one row per website and technology, easier for spreadsheets. The price is per website in both formats.

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

Drop detections below this confidence score (0 to 100). Lower values show weaker matches.

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

Add the matched signal (header, cookie, script URL, meta tag, DNS record or JS global) for each technology.

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

Use DNS records (CNAME, NS, MX) as signals for hosting, CDN and email provider.

## `checkRobotsTxt` (type: `boolean`):

Read the site's robots.txt for platform hints (one extra small request per site).

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

Number of sites analysed at the same time (1 to 50). The browser pass uses fewer pages in parallel, set by the run's memory.

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

Optional proxy. Not needed for most sites; use a datacenter proxy if many sites rate-limit your runs.

## `navigationTimeoutSecs` (type: `integer`):

Kept from version 1. Time limit in seconds for loading a page in the browser pass (default 45).

## `waitForSecs` (type: `integer`):

Kept from version 1. Seconds to wait after the page load in the browser pass (default 1.5).

## `checkHeaders` (type: `boolean`):

Kept from version 1. Set to false to ignore HTTP response headers as signals.

## `checkCookies` (type: `boolean`):

Kept from version 1. Set to false to ignore cookie names as signals.

## Actor input object example

```json
{
  "urls": [
    "https://www.shopify.com"
  ],
  "mode": "auto",
  "outputFormat": "site",
  "minConfidence": 30,
  "includeEvidence": true,
  "checkDns": true,
  "checkRobotsTxt": true,
  "maxConcurrency": 10
}
```

# Actor output Schema

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

All rows saved by the run, as JSON.

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

Counts of sites analysed, failed and charged.

## `failedUrls` (type: `string`):

Sites that could not be analysed, with the reason. They 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 = {
    "urls": [
        "https://www.shopify.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("magicfingers/techstack-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 = { "urls": ["https://www.shopify.com"] }

# Run the Actor and wait for it to finish
run = client.actor("magicfingers/techstack-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 '{
  "urls": [
    "https://www.shopify.com"
  ]
}' |
apify call magicfingers/techstack-detector --silent --output-dataset

```

## MCP server setup

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