# Website Tech Stack Detector - CMS & Frameworks (`devoted_laureate_r8f/d-tection-de-stack-technique-d-un-site`) Actor

Detect the tech stack of one website or a list of up to 1,000 domains: CMS, frameworks, analytics, CDN and server, from public headers and HTML. One structured record per site; failures are not charged.

- **URL**: https://apify.com/devoted_laureate_r8f/d-tection-de-stack-technique-d-un-site.md
- **Developed by:** [Billy Zouz](https://apify.com/devoted_laureate_r8f) (community)
- **Categories:** Developer tools, Lead generation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$8.00 / 1,000 domain 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/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

## Tech Stack Fingerprint Detector

Find out which CMS, JavaScript framework, analytics tool, CDN or server a website runs on — for one site or for a whole list of domains in a single run. The Actor fetches each site, inspects its HTTP response headers and HTML markup against a set of known signatures, and returns the matches together with the evidence that triggered each one.

### What it does

1. Fetches each website (one HTTP request per site, following redirects).
2. Reads the response headers (`Server`, `X-Powered-By`, `CF-RAY`, `Via`, ...).
3. Parses the HTML for generator meta tags, framework-specific markers (`__NEXT_DATA__`, `ng-version`, `data-v-*`, ...) and known script/CDN references.
4. Returns one structured record per website: the technologies recognized, each with a category, a confidence level and the exact piece of evidence that was matched.

Typical uses: enrich a list of leads or prospects with their CMS/e-commerce platform, check competitors' stacks, qualify agency clients before a migration, or audit a portfolio of sites.

### Input

| Field | Type | Required | Description |
|---|---|---|---|
| `url` | string | one of `url` / `urls` | A single public website URL to analyze. |
| `urls` | array of strings | one of `url` / `urls` | Batch mode: a list of websites, as full URLs (`https://example.com`) or bare domains (`example.com`). Up to 1,000 per run; duplicates are removed. |
| `timeoutSeconds` | integer | no | Maximum time to wait for each HTTP request, in seconds (1–60, default 10). |
| `maxConcurrency` | integer | no | How many websites are analyzed in parallel (1–10, default 5). |

Single website:

```json
{ "url": "https://wordpress.org" }
```

Batch of domains:

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

### Output

One dataset record per website:

```json
{
  "url": "https://wordpress.org",
  "statusCode": 200,
  "detectedTechnologies": [
    { "name": "WordPress", "category": "CMS", "confidence": "high", "evidence": "meta generator=\"WordPress 6.4\"" },
    { "name": "Nginx", "category": "Server", "confidence": "high", "evidence": "header Server=\"nginx\"" }
  ],
  "serverHeader": "nginx",
  "poweredByHeader": null,
  "fetchedAt": "2024-01-01T12:00:00.000Z"
}
```

Errors are isolated per website: if one site cannot be reached, the others are still analyzed. A failed website gets a record with `error` (message) and `errorType` (`TIMEOUT`, `FETCH_FAILED` or `INVALID_INPUT`), and is never charged.

### Use in your workflow

Replace `<APIFY_TOKEN>` with your token from Apify Console → Settings → API & Integrations.

**HTTP API (curl)** — run the Actor and get the results in one call:

```bash
curl -X POST "https://api.apify.com/v2/acts/devoted_laureate_r8f~d-tection-de-stack-technique-d-un-site/run-sync-get-dataset-items" \
  -H "Authorization: Bearer <APIFY_TOKEN>" -H "Content-Type: application/json" \
  -d '{"urls": ["wordpress.org", "vercel.com"]}'
```

**JavaScript** (`npm install apify-client`):

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('devoted_laureate_r8f/d-tection-de-stack-technique-d-un-site')
  .call({ urls: ['wordpress.org', 'vercel.com'] });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const site of items) console.log(site.url, site.detectedTechnologies.map((t) => t.name));
```

**Python** (`pip install apify-client`):

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("devoted_laureate_r8f/d-tection-de-stack-technique-d-un-site").call(
    run_input={"urls": ["wordpress.org", "vercel.com"]}
)
for site in client.dataset(run.default_dataset_id).iterate_items():
    print(site["url"], [t["name"] for t in site["detectedTechnologies"]])
```

**AI agents (MCP)** — expose only this Actor as a tool through the Apify MCP server:

```json
{
  "mcpServers": {
    "tech-stack": {
      "url": "https://mcp.apify.com?tools=devoted_laureate_r8f/d-tection-de-stack-technique-d-un-site",
      "headers": { "Authorization": "Bearer <APIFY_TOKEN>" }
    }
  }
}
```

For agents: call it when you need to know what a website is built with. Input: `url` (one site) or `urls` (list). Output: one record per site with `detectedTechnologies[]` (`name`, `category`, `confidence`, `evidence`). Cost: $0.008 per website successfully analyzed; failures are free.

### Pricing

Pay per event: **$0.008 per domain analyzed**. One website fetched and its technology stack detected (charged once per site, whatever the number of technologies found).

You only pay for these events: the platform usage of the run is covered by the Actor. Failed fetches are not charged. You can cap the cost of a run with the maximum charge setting of your run.

### Limits

- Up to 1,000 websites per run (split larger lists into several runs).
- Analyzes the page returned by a single HTTP request (no JavaScript rendering, no headless browser) — technologies that are only injected client-side after the page loads may be missed.
- Detects a curated list of popular CMSs, JS frameworks, analytics tools, CDNs, caches, servers and backend languages/frameworks; niche or custom stacks may go unidentified.
- Public pages only — no login, no personal data is collected or stored.
- `timeoutSeconds` is capped at 60 seconds per website.

### FAQ

**How are technologies detected?**

From public signals only: response headers, HTML markup, script and stylesheet URLs and meta generator tags. No login and no browser are used.

**Why might a technology be missing?**

Technologies that leave no public trace (server-side only, or loaded after user interaction) cannot be seen without a browser.

**Can I analyze a list of domains?**

Yes: put up to 1,000 URLs or bare domains in 'urls'. Each site is analyzed separately; a site that cannot be reached gets an error record and is not charged.

### Related tools

- [HTTP Security Headers Checker - Grade & Fixes](https://apify.com/devoted_laureate_r8f/audit-des-en-t-tes-de-s-curit-http) — check the security headers of the sites you just profiled

# Actor input Schema

## `url` (type: `string`):

One public website URL to analyze (e.g. https://wordpress.org). Use `urls` instead for a batch.

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

Batch mode: list of websites as full URLs or bare domains (e.g. shopify.com). Up to 1,000 per run, duplicates removed. Each website is analyzed and charged separately; failures are not charged.

## `timeoutSeconds` (type: `integer`):

Maximum time to wait for each website's HTTP request, in seconds (1-60).

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

How many websites are analyzed in parallel (1-10).

## Actor input object example

```json
{
  "url": "https://www.apify.com",
  "timeoutSeconds": 10,
  "maxConcurrency": 5
}
```

# 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 = {
    "url": "https://www.apify.com"
};

// Run the Actor and wait for it to finish
const run = await client.actor("devoted_laureate_r8f/d-tection-de-stack-technique-d-un-site").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 = { "url": "https://www.apify.com" }

# Run the Actor and wait for it to finish
run = client.actor("devoted_laureate_r8f/d-tection-de-stack-technique-d-un-site").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 '{
  "url": "https://www.apify.com"
}' |
apify call devoted_laureate_r8f/d-tection-de-stack-technique-d-un-site --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,devoted_laureate_r8f/d-tection-de-stack-technique-d-un-site"
        }
    }
}
```

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/03K3HsRvvtvmxh3jg/builds/hYqKyKwiph8pKFH6t/openapi.json
