# Website Technology Detector: Tech Stack Scanner (`apifmcpfactory/tech-stack-detector`) Actor

Detects the technologies a website is built with (CMS, ecommerce, analytics, frameworks; 7,500+ signatures) - use when you need a site's tech stack for lead qualification or competitor research; $0.005 per site checked.

- **URL**: https://apify.com/apifmcpfactory/tech-stack-detector.md
- **Developed by:** [Howth Technology Factory](https://apify.com/apifmcpfactory) (community)
- **Categories:** Developer tools, Lead generation, SEO tools
- **Stats:** 1 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.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.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

Find out what any website is built with — CMS, ecommerce platform, JavaScript framework, analytics, CDN and hosting — from a single URL, matched against more than 7,500 technology signatures. Pass one URL or a list of thousands; results come back as structured rows you can filter, sort and export.

### 1. Why use Website Technology Detector

Knowing a site's stack changes what you do next. A sales team qualifying leads wants the shops running a particular ecommerce platform. An agency pitching a replatform wants to know which prospects are on an ageing CMS. A security reviewer wants an inventory of what a portfolio of sites actually runs.

Doing this by hand means opening each site, viewing source, hunting for a generator tag, recognising a script domain, and guessing at the rest. It takes a few minutes per site and the answer depends on how much you happen to recognise. At a hundred sites it stops being feasible.

This Actor does the recognition part against a maintained fingerprint dataset, so the answer is the same whoever runs it, and a list of a thousand sites is one run rather than a week.

### 2. Key features

- **7,500+ technology signatures** covering CMS, ecommerce, frameworks, analytics, tag managers, CDNs, hosting, payment and more.
- **One URL or a bulk list** in the same input field — no separate bulk mode.
- **Evidence, not just labels.** Each result carries the final URL, HTTP status, page title, the response headers used as signals, and the generator meta tag — so you can see why a call was made.
- **Per-technology detail.** Every hit returns its name, one or more category labels, a version where the site exposes one, and a 0–100 confidence score.
- **Redirect-aware.** Reports the final URL after redirects, so a domain that has moved is visible as moved.
- **Parallel fetching** with configurable concurrency.
- **Capped page reads.** Each page is read up to a fixed byte ceiling and streamed, so one enormous page cannot stall a run.
- **Per-site error isolation.** A site that blocks automated traffic returns an error row; the rest of the run continues.
- **Public pages only.** Nothing behind a login is touched.

### 3. Who it's for

**For sales and lead generation.** Feed in a list of prospect domains and filter the output to the ones running the platform your product integrates with, so outreach goes to accounts where the integration story is already true.

**For agencies and consultants.** Before a pitch, check the prospect's stack and open with what they actually run rather than a generic capability deck.

**For operations.** Audit a portfolio of company and campaign sites and find the ones still carrying an analytics tag or tag manager that was supposed to be removed.

**For developers and AI agents.** Call it as an enrichment step in a CRM pipeline: submit a domain, attach the detected stack to the record, and route the lead on what came back.

### 4. How to use it

1. Open the Actor and click **Try for free**.
2. Put your URLs in the **URLs** field, one per line, each including the scheme (`https://www.shopify.com`).
3. Optionally adjust **Max concurrency** — how many sites are fetched at once.
4. Click **Start**.
5. Open the **Output** tab when the run finishes. Export as JSON, CSV or Excel.

### 5. Input parameters

| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| `urls` | array of strings | Yes | `["https://www.wordpress.org","https://www.shopify.com"]` | Website URLs to inspect, one full URL per entry including the scheme. |
| `maxConcurrency` | integer | No | `10` | How many websites are fetched in parallel. Minimum 1. Lower it if you are scanning many pages on one host. |

### 6. Output

A real result, from a live run, abridged to three of the nine technologies returned:

```json
{
  "url": "https://www.wordpress.org",
  "finalUrl": "https://wordpress.org/",
  "httpStatus": 200,
  "pageTitle": "Blog Tool, Publishing Platform, and CMS – WordPress.org",
  "headers": {
    "server": "nginx",
    "x-powered-by": null,
    "x-generator": null
  },
  "metaGenerator": "WordPress 7.1-beta3-62878",
  "technologies": [
    { "name": "WordPress", "categories": ["CMS", "Blogs"], "version": "7.1", "confidence": 100 },
    { "name": "MySQL", "categories": ["Databases"], "version": null, "confidence": 100 },
    { "name": "Google Tag Manager", "categories": ["Tag managers"], "version": null, "confidence": 100 }
  ],
  "fetchTimeMs": 472
}
```

`error` is **omitted entirely** on a successful row rather than set to null, so test for its presence, not its value.

### 7. Output fields

| Field | Meaning |
|---|---|
| `url` | The URL exactly as submitted. |
| `finalUrl` | Where the request landed after redirects. Differs from `url` when the site has moved or forces a canonical host. |
| `httpStatus` | HTTP status of the final response. |
| `pageTitle` | The page's `<title>`, useful for confirming you reached the intended site. |
| `headers` | Selected response headers used as detection signals: `server`, `x-powered-by`, `x-generator`. Null where the header was absent. |
| `metaGenerator` | The `<meta name="generator">` value when present — often the single strongest CMS signal, and frequently carries an exact version. |
| `technologies` | **The detection result.** An array of objects, one per technology found. |
| `technologies[].name` | Technology name, e.g. `WordPress`, `Nginx`, `Google Tag Manager`. |
| `technologies[].categories` | Array of category labels, e.g. `["CMS","Blogs"]`. A technology can sit in more than one. |
| `technologies[].version` | Detected version when the signal exposes one, otherwise null. |
| `technologies[].confidence` | 0–100 score for how strong the matching signal was. |
| `fetchTimeMs` | How long the fetch took, in milliseconds. |
| `error` | Populated when the site could not be read. **Absent from successful rows.** |

To filter to one category, filter on `technologies[].categories` — for example keep only rows where any entry has category `Ecommerce`.

### 8. How it works

Each URL is normalised, then fetched once with redirects followed. The response is streamed and read up to a fixed byte ceiling, so a very large page is truncated rather than allowed to consume the run's memory.

The fetched HTML, response headers, cookies and script URLs are matched against the bundled fingerprint dataset. The dataset ships inside the image and is loaded once at startup, so there is no per-request lookup against an external service and no API key to supply.

Sites are processed in parallel up to `maxConcurrency`. Each site is isolated: a timeout, a block page or a DNS failure produces an error row for that site only.

### 9. API & MCP usage

**cURL**

```bash
curl -X POST "https://api.apify.com/v2/acts/apifmcpfactory~tech-stack-detector/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"urls":["https://www.shopify.com","https://www.wordpress.org"],"maxConcurrency":10}'
```

**As an Apify MCP tool.** This Actor is callable directly by AI agents such as Claude and Cursor. Usage bills through your own Apify account.

```
https://mcp.apify.com?tools=apifmcpfactory/tech-stack-detector
```

Claude Desktop (`claude_desktop_config.json`):

```json
{
    "mcpServers": {
        "tech-stack-detector": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com?tools=apifmcpfactory/tech-stack-detector",
                "--header",
                "Authorization: Bearer YOUR_APIFY_TOKEN"
            ]
        }
    }
}
```

**As an MCP tool.** The same detection is available as a hosted MCP server for AI agents, with `detect_stack` for one URL and `bulk_detect_stack` for up to 50. See the product page for that endpoint.

### 10. Pricing

$0.005 per site checked, billed per site written to the dataset. Sites that fail to resolve are not charged.

A 1,000-domain prospect list costs $5.00.

### 11. Limits & performance

| | |
|---|---|
| Memory | 256 MB |
| Default concurrency | 10 sites in parallel |
| Page read | Capped and streamed per page |
| Fingerprints | Loaded once at startup, held for the process lifetime |

### 12. Limitations

- **Detection is signature-based.** A technology that leaves no observable trace in the HTML, headers, cookies or script URLs cannot be seen. Some server-side components *are* detected — response headers and platform conventions routinely reveal the web server, language and database — but anything genuinely internal is invisible from the outside.
- **Absence is not proof of absence.** A missing technology means no signature matched, not that the site definitely does not use it.
- **Confidence is signal strength, not certainty.** A score of 100 means the fingerprint matched cleanly, not that the finding has been independently confirmed.
- **Versions are reported only when exposed.** Most technologies return `version: null`; a version appears only where the site publishes it, such as a generator meta tag.
- **Some sites block automated traffic.** Those return an error row rather than a partial guess.
- **One page per site.** Detection reads the URL you supply. A technology used only in a checkout or account area will not be seen from the homepage.
- **Public pages only.** Nothing behind a login or paywall is fetched.
- **Fingerprints age.** New platform versions can change their signals; the dataset is refreshed periodically, not continuously.

### 13. FAQ

**How many technologies can it detect?** More than 7,500 signatures, spanning CMS, ecommerce, frameworks, analytics, tag managers, CDNs, hosting and payment providers.

**Can I check a list of websites at once?** Yes. Put every URL in the `urls` field; there is no separate bulk mode.

**Why did a site return an error?** Most often it blocks automated requests, timed out, or the domain no longer resolves. The `error` field says which.

**Why does `finalUrl` differ from what I submitted?** The site redirected. That is itself useful signal — it shows canonical host choices and domains that have moved.

**Does it detect the server language or database?** Often, yes. Response headers and platform conventions frequently reveal the web server, programming language and database — a WordPress site, for example, typically returns Nginx, PHP and MySQL alongside the CMS itself. What it cannot see is anything that leaves no observable trace.

**What does the confidence score mean?** How strong the matching signal was, from 0 to 100. It measures signal strength, not independent verification.

**Why is `version` usually null?** Most technologies do not publish their version publicly. Where a site does expose one — commonly through a generator meta tag — it is reported.

**Do I need an API key for a third-party service?** No. The fingerprint dataset ships inside the Actor.

**Will it log into sites or bypass protection?** No. Public pages only, and no attempt is made to defeat bot protection.

# Actor input Schema

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

Website URLs to inspect, one full URL per entry including the scheme, e.g. "https://www.shopify.com" (bare domains without https:// will fail). Each URL produces exactly one result item and is billed at $0.005. If omitted, two demo sites (wordpress.org, shopify.com) are used — always pass your own list.

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

How many websites are fetched in parallel. Integer, minimum 1, e.g. 10. If omitted, defaults to 10, which is right for most batches; lower it only if target sites rate-limit or block you.

## Actor input object example

```json
{
  "urls": [
    "https://www.wordpress.org",
    "https://www.shopify.com"
  ],
  "maxConcurrency": 10
}
```

# Actor output Schema

## `results` (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 = {
    "urls": [
        "https://www.wordpress.org",
        "https://www.shopify.com"
    ]
};

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

# Run the Actor and wait for it to finish
run = client.actor("apifmcpfactory/tech-stack-detector").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).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.wordpress.org",
    "https://www.shopify.com"
  ]
}' |
apify call apifmcpfactory/tech-stack-detector --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=apifmcpfactory/tech-stack-detector",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/y2YttRMumqaaf9EzG/builds/vpmONhjiKHwdBn9EL/openapi.json
