# Tech Stack Detector: what any website is built with (`bepolabs/tech-stack`) Actor

Reads response headers, cookies, meta tags and scripts of each homepage, then lists the technology behind it: shop system, analytics, CDN and hosting. Up to 1,000 per run, output as JSON, CSV or Excel. Costs 2.3 USD per 1,000 analysed domains.

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

## Pricing

$2.30 / 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

### 🧩 What is Tech Stack Detector?

Find out which technology runs a company's web presence with Tech Stack Detector. Feed it a batch and each row names the CMS, framework, payments, fonts and server, plus the version where one is visible. Every finding carries its evidence, so you can check it yourself. One request per entry, no browser and no proxy, keeps big runs cheap.

- **Lead generation**: find every Shopify, WordPress or HubSpot site in your list and pitch the right offer
- **Competitor research**: see which framework, analytics and hosting your competitors chose
- **Sales qualification**: enrich a CRM export with the technologies each prospect already pays for
- **Agencies and freelancers**: check a client's stack before a quote or an audit
- **Market research**: measure how common a CMS, CDN or analytics tool is across thousands of domains

![Tech Stack Detector: Any list of domains to the technologies behind each site: CMS, shop, framework, analytics, CDN and hosting.](https://api.apify.com/v2/key-value-stores/wdeAWGooHdIhvFgSY/records/tech-stack-hero.png)

#### ✨ Why use this Actor?

- ✅ **99 technologies in 22 categories**: CMS, site builders, shops, frameworks, analytics, ads, chat, consent, payments, security, fonts, CDN, hosting, servers and back ends
- ✅ **Evidence for every hit**: each technology says how it was found (header, meta tag, cookie, script URL or HTML) and whether the signal is high or medium confidence
- ✅ **Versions where visible**: WordPress, Hugo, Angular and jQuery numbers are read from the page
- ✅ **Domains or URLs**: paste bare hostnames or full addresses; duplicates merge and each one is checked once
- ✅ **Polite by default**: one homepage request per domain, robots.txt honoured, retries with backoff on network errors, 429 and 5xx
- ✅ **Pay only for answers**: 8 USD per 1,000 domains; failures and robots.txt skips cost nothing

### 📦 What data can you get with Tech Stack Detector?

| | | |
|---|---|---|
| 🌐 Domain and final URL | 🔢 HTTP status | 📝 Page title |
| 🧱 CMS and site builder | 🛒 E-commerce platform | ⚛️ JavaScript frameworks and libraries |
| 📊 Analytics and tag managers | 📣 Ad pixels and marketing automation | 💬 Live chat and cookie consent |
| ☁️ CDN, hosting and web server | 🏷️ Version, confidence and evidence | 🗂️ Technologies grouped by category |

### 🚀 How to use Tech Stack Detector

Tech Stack Detector works in a few clicks, no coding needed:

1. [Create a free Apify account](https://console.apify.com/sign-up) (the free plan includes 5 USD of monthly credit).
2. Open [Tech Stack Detector](https://apify.com/bepolabs/tech-stack) and click **Try for free**.
3. Paste your domains or URLs, one per line (up to 1,000 per run). The defaults work for most lists.
4. Click **Start** and wait for the run to finish (most runs take seconds).
5. Download your data as JSON, CSV, Excel, XML or HTML, or send it straight to Google Sheets, Make, Zapier or your AI agent.

![How Tech Stack Detector works](https://api.apify.com/v2/key-value-stores/wdeAWGooHdIhvFgSY/records/tech-stack-workflow.png)

### ⬇️ Input

Add the domains or URLs you want to analyse, up to 1,000 per run. Everything else is optional.

##### Domain or URL?

Both work. `apify.com`, `https://apify.com/pricing` and `www.bbc.co.uk/news` are all reduced to the hostname, and its homepage is fetched over https. Repeats are checked once.

##### robots.txt

`robots` is on by default: a domain whose robots.txt disallows the homepage is skipped with a clear reason and not charged. Switch it off only for sites you own or have permission to check.

##### What it looks at

Response headers, cookie names, meta tags, script, link, image and iframe URLs and the HTML. Technologies that load after a click or deeper in the site stay hidden.

| Field | Type | What it does | Default |
|---|---|---|---|
| **Domains** (`domains`) | array | Domains or URLs (the host's homepage is fetched over https). | `["apify.com","wordpress.org"]` |
| **Honour robots.txt** (`robots`) | boolean | Skip a domain whose robots.txt disallows the homepage. | `true` |
| **Maximum retries** (`maxRetries`) | integer | Retries per request with exponential backoff on network errors, 429 and 5xx. | `2` |

![Tech Stack Detector input form](https://api.apify.com/v2/key-value-stores/wdeAWGooHdIhvFgSY/records/tech-stack-input.png)

#### Input example

```json
{
    "domains": [
        "wordpress.org",
        "nextjs.org",
        "shopify.com"
    ]
}
```

### ⬆️ Output

Every domain becomes one row: the final URL after redirects, the HTTP status, the page title, each technology (name, category, confidence, version when visible, evidence), a grouped view and the count. The run summary in the key-value store (`OUTPUT`) holds the totals and every problem.

![Tech Stack Detector output table](https://api.apify.com/v2/key-value-stores/wdeAWGooHdIhvFgSY/records/tech-stack-output.png)

#### Output example

One row of the dataset (apify.com, from a real run):

```json
{
    "domain": "apify.com",
    "url": "https://apify.com/",
    "finalUrl": "https://apify.com/",
    "status": 200,
    "title": "Apify: Marketplace of ready-to-run tools for AI",
    "technologies": [
        {
            "name": "Next.js",
            "category": "JavaScript framework",
            "confidence": "medium",
            "evidence": "html"
        },
        {
            "name": "React",
            "category": "JavaScript library",
            "confidence": "medium",
            "evidence": "html"
        },
        {
            "name": "Google Tag Manager",
            "category": "Tag manager",
            "confidence": "medium",
            "evidence": "script or link URL"
        },
        {
            "name": "HubSpot",
            "category": "Marketing automation",
            "confidence": "medium",
            "evidence": "script or link URL"
        },
        {
            "name": "Amazon CloudFront",
            "category": "CDN",
            "confidence": "high",
            "evidence": "header x-amz-cf-id"
        },
        {
            "name": "HSTS",
            "category": "Security",
            "confidence": "high",
            "evidence": "header strict-transport-security"
        }
    ],
    "categories": {
        "JavaScript framework": [
            "Next.js"
        ],
        "JavaScript library": [
            "React"
        ],
        "Tag manager": [
            "Google Tag Manager"
        ],
        "Marketing automation": [
            "HubSpot"
        ],
        "CDN": [
            "Amazon CloudFront"
        ],
        "Security": [
            "HSTS"
        ]
    },
    "count": 6,
    "error": null
}
```

#### A version in the output

When the page shows a version, the technology carries it (wordpress.org, same run):

```json
{
    "name": "WordPress",
    "category": "CMS",
    "confidence": "high",
    "version": "7.2",
    "evidence": "meta generator"
}
```

View the results as a table or JSON in the Output tab and download them as JSON, CSV, Excel, XML, HTML or RSS, all fields or only those you pick.

#### ⚠️ Error items

An input that cannot be read does not stop the run and is never charged: it gets a row with an `error` field so you can see exactly what failed.

| Error | Meaning |
|---|---|
| `Domain not found (check the URL)` | The domain has no DNS entry or is misspelled |
| `HTTP 403 / HTTP 404` | The homepage answered with an error status; nothing is detected from an error page |
| `HTTP 5xx: server error at the source` | The site kept failing after the retries |
| `Timed out after 30 s without an answer` | The homepage did not answer in time |
| `skipped: robots.txt disallows the homepage` | The site's robots.txt does not allow fetching `/` and `robots` is on |

### 💰 How much does Tech Stack Detector cost?

Tech Stack Detector is priced **per event**: **8 USD per 1,000 domains** (0.008 USD per domain), with no monthly rental. Charged for each homepage that answered; failures and robots.txt skips are free.

| You get | You pay |
|---|---|
| 100 domains | 0.8 USD |
| 1,000 domains | 8 USD |
| 10,000 domains | 80 USD |
| 100,000 domains | 800 USD |

💡 Apify's free plan gives you 5 USD of credit every month, enough for about **625 domains** at no cost. Set a spending limit per run and the Actor stops there.

### ⚖️ Tech Stack Detector vs. the alternatives

| | Tech Stack Detector | Browser-extension lookups | Tech-lookup subscriptions |
|---|---|---|---|
| **Bulk lists (up to 1,000 per run)** | ✅ | ❌ one site at a time | ✅ on paid plans |
| **Evidence for every detection** | ✅ header, meta, cookie, URL or HTML | ❌ | varies |
| **JSON, CSV, Excel and API** | ✅ | ❌ | ✅ |
| **Pay per domain, no monthly plan** | ✅ 8 USD per 1,000 | free | monthly plan |
| **Works with Claude and AI agents (MCP)** | ✅ | ❌ | ❌ custom code |

### 🔌 Integrations, API and MCP

#### Connect Tech Stack Detector to your AI agent (MCP)

Give Claude, ChatGPT, Cursor or any MCP client direct access to Tech Stack Detector through the [Apify MCP server](https://mcp.apify.com). Add this URL to its settings:

```text
https://mcp.apify.com/?actors=bepolabs/tech-stack
```

For Claude Desktop, add it under `mcpServers` in `claude_desktop_config.json`:

```json
{
    "mcpServers": {
        "tech-stack": {
            "command": "npx",
            "args": [
                "-y",
                "@apify/actors-mcp-server",
                "--actors",
                "bepolabs/tech-stack"
            ],
            "env": {
                "APIFY_TOKEN": "<your Apify API token>"
            }
        }
    }
}
```

Then ask: *"Which CMS, analytics and hosting do stripe.com, notion.so and shopify.com use?"*

#### Run it from your code

Python (`pip install apify-client`):

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("bepolabs/tech-stack").call(run_input={"domains":["wordpress.org","nextjs.org","shopify.com"]})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

JavaScript (`npm install apify-client`):

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('bepolabs/tech-stack').call({"domains":["wordpress.org","nextjs.org","shopify.com"]});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

#### No-code integrations

Send results to **Google Sheets, Slack, Airtable, HubSpot, Make, Zapier, n8n** and more from the Integrations tab, start runs on a **schedule**, or trigger your own endpoint with a **webhook** when a run finishes. The [Apify API](https://docs.apify.com/api/v2) gives you full control over runs and datasets.

### ❓ FAQ

##### Which technologies can it detect?

99 technologies in 22 categories, among them WordPress, Drupal, Webflow, Wix, Squarespace, Shopify, WooCommerce, Magento, Next.js, Nuxt, React, Vue.js, Angular, Google Analytics, Tag Manager, Meta Pixel, HubSpot, Intercom, OneTrust, Stripe, Cloudflare, Vercel, Netlify, Nginx, Laravel and Django.

##### How accurate is it?

Every hit shows how it was found. Header, meta tag and cookie signals count as `high` confidence; script URLs and HTML get `medium`. Only the homepage is read, so tools that load only on inner pages or after user interaction are not seen.

##### Does it run a browser?

No. It makes one plain HTTPS request per homepage (plus robots.txt), which keeps runs cheap. Sites that build everything in the browser still show their framework, CDN and hosting in most cases.

##### How many domains can I check at once?

Up to 1,000 per run, five at a time. For bigger lists, start several runs or schedule them.

##### What if a domain does not answer?

It gets a row with an `error` (for example `Domain not found`) and costs nothing. The other domains continue.

##### Is it legal to use Tech Stack Detector?

The Actor reads one public homepage per domain, once, with an honest user agent (`BEPOLabsTechStack`), and honours robots.txt. It does not log in or collect personal data. You are responsible for how you use the results, for example in outreach, which must follow the anti-spam and data protection rules that apply to you.

##### What if something is missing or does not work?

Open an issue on the **Issues** tab; we read each one and reply. Feature requests are welcome too.

### 💬 Your feedback

Tell us what Tech Stack Detector should add on the **Issues** tab or leave a review; your notes decide what we work on next.

### 🔗 Related Actors

| Actor | What it does |
|---|---|
| 🌐 [Domain RDAP and DNS](https://apify.com/bepolabs/domain-rdap) | Domains to registrar, creation and expiry dates, age, status, nameservers, DNSSEC and DNS records from official RDAP, in bulk. |
| 📇 [Website Contacts](https://apify.com/bepolabs/website-contacts) | Company websites to emails, phone numbers and social profiles, one row per site, with a status that says why nothing was found. |
| 💼 [ATS Jobs](https://apify.com/bepolabs/ats-jobs) | Every open job from company career boards on Greenhouse, Lever, Ashby, Workable, SmartRecruiters and Recruitee in one deduped feed. |
| 📍 [OpenStreetMap Places](https://apify.com/bepolabs/osm-pois) | Shops, restaurants and offices in any city or area, with address, phone, website, opening hours and coordinates. |
| 📧 [Email Verifier](https://apify.com/bepolabs/email-dns-check) | Bulk email validation over DNS: valid, risky or invalid per address, with the reasons, a score, a typo fix, throwaway and shared-inbox flags. |
| 📢 [Google Ads Transparency Scraper](https://apify.com/bepolabs/google-ads-transparency) | Every ad a company runs on Google, by domain, advertiser ID or name, from the Ads Transparency Center. |
| 🔗 [Broken Link Checker](https://apify.com/bepolabs/link-checker) | Every link and image on your pages checked: HTTP status, each redirect hop, final URL and response time. |
| 🩺 [NPI Registry Lookup](https://apify.com/bepolabs/npi-registry) | US doctors, nurses, clinics and pharmacies from the official CMS NPI Registry, by specialty, name, NPI or place. |

# Changelog

This Actor's version history is a separate document: https://apify.com/bepolabs/tech-stack/changelog.md

# Actor input Schema

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

Domains or URLs (the host's homepage is fetched over https). Up to 1,000.

## `robots` (type: `boolean`):

Skip a domain whose robots.txt disallows the homepage.

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

Retries per request with exponential backoff on network errors, 429 and 5xx.

## Actor input object example

```json
{
  "domains": [
    "apify.com",
    "wordpress.org"
  ],
  "robots": true,
  "maxRetries": 2
}
```

# Actor output Schema

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

Dataset items, one row per result, in the overview table view.

# 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": [
        "apify.com",
        "wordpress.org"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("bepolabs/tech-stack").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": [
        "apify.com",
        "wordpress.org",
    ] }

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

```

## MCP server setup

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

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/iBR5Zs4WtQ2hIy5aB/builds/otxpG1RabMhTiCTBc/openapi.json
