# Bulk Tech Stack Detector (`eliai/bulk-tech-stack-detector`) Actor

Paste a list of domains and get what each one runs: CMS, framework, hosting, analytics, payments, support widgets. Every detection returns the evidence that proved it plus a confidence level, so a wrong row is auditable. Unreachable domains are never charged.

- **URL**: https://apify.com/eliai/bulk-tech-stack-detector.md
- **Developed by:** [Anthony Snider](https://apify.com/eliai) (community)
- **Categories:** Lead generation, Developer tools, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 domain analyseds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use 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

## Bulk Tech Stack Detector

Paste a list of domains, get back what each one runs — CMS, framework, hosting, analytics,
payments, support widgets — with **the evidence that proved each detection** and a confidence
level.

Built for lists, not single lookups. Unreachable domains are reported and **never charged**.

---

### Why the evidence matters

Most detectors hand you `WordPress: true`. When that's wrong on 200 rows of a 10,000-row list, you
have no way to find which 200. Every detection here returns what proved it:

| Technology | Confidence | Evidence |
|---|---|---|
| Shopify | high | `cdn.shopify.com` |
| Vercel | high | `server: Vercel` |
| WordPress | high | `/wp-content/` |
| jQuery | low | `jquery-3.6.0.min.js` |

Now a row is auditable in two seconds instead of being taken on faith.

### Confidence is not decoration

- **high** — the site declares it, or a first-party branded asset path proves it (a `generator`
  meta tag, `cdn.shopify.com`, a `server` header)
- **medium** — a characteristic asset path or header
- **low** — a weaker heuristic, worth reporting but not worth filtering a campaign on

Flattening these into a single boolean is how a bulk list becomes untrustworthy. You can filter on
`confidence` and decide your own bar.

### Three things this deliberately does not do

**No vulnerability claims.** Some detectors report "WordPress 5.2 — 14 known CVEs". A version
string in HTML is routinely stale, cached, or spoofed, and converting it into a security assertion
is unfounded. We report the version we saw and where we saw it. Nothing further.

**No guessing.** A site we can't classify comes back with an empty technology list and
`classified: false`. Silent guessing is exactly what makes bulk output useless at scale — one
plausible-looking wrong row poisons trust in all 10,000.

**No double-counting.** `example.com` and `www.example.com` are one company. We follow redirects to
the final URL and report both it and whether a redirect happened, so your list doesn't
double-count or silently miss.

### What it detects

**CMS & builders** — WordPress, Drupal, Joomla, Ghost, Shopify, Wix, Squarespace, Webflow
**Frameworks** — Next.js, Nuxt, Gatsby, Astro, React, Vue
**Hosting & CDN** — Cloudflare, Vercel, Netlify, Fastly, CloudFront, Nginx, Apache
**Analytics** — GA4, Google Tag Manager, Meta Pixel, Hotjar, Plausible, Segment
**Marketing & support** — HubSpot, Klaviyo, Mailchimp, Intercom, Zendesk, Drift, Crisp
**Payments & security** — Stripe, PayPal, reCAPTCHA, Cloudflare Turnstile
Plus any self-declared `generator` meta tag, reported verbatim.

### Input

```json
{ "domainsText": "shopify.com\nvercel.com\nexample.com" }
````

Separators can be new lines, commas or spaces; `https://` is optional and duplicates are removed.

| Field | Type | Default | Notes |
|---|---|---|---|
| `domainsText` | string | — | Pasted list |
| `domains` | array | — | For API use |
| `domain` | string | — | A single domain |
| `maxDomains` | integer | 100 | Cap on domains, and therefore on spend |

### Output

```json
{
  "domain": "shopify.com",
  "ok": true,
  "finalUrl": "https://www.shopify.com/",
  "redirected": true,
  "technologyCount": 2,
  "technologies": [
    { "technology": "Shopify", "category": "Ecommerce", "confidence": "high", "evidence": "cdn.shopify.com" },
    { "technology": "Cloudflare", "category": "CDN", "confidence": "high", "evidence": "server: cloudflare" }
  ],
  "byCategory": { "Ecommerce": ["Shopify"], "CDN": ["Cloudflare"] },
  "classified": true
}
```

### For agents and automation

- **Capability:** bulk detection of web technologies across a domain list
- **Required input:** one of `domainsText`, `domains`, `domain`
- **Returns:** one record per domain plus a `SUMMARY`; `byCategory` is pre-grouped for filtering
- **Bounded:** `maxDomains` caps the run and the spend
- **Side effects:** none — fetches each homepage once, stores nothing externally
- **Honest unknowns:** `classified: false` with an empty list rather than a guess

### Pricing

Pay per domain successfully analysed. Unreachable domains are free.

# Actor input Schema

## `domainsText` (type: `string`):

One domain per line, or separated by commas or spaces. Duplicates removed automatically. https:// optional.

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

For API and integration use.

## `domain` (type: `string`):

Analyse a single domain.

## `maxDomains` (type: `integer`):

Safety cap. You are charged per domain successfully analysed, so this is also your budget cap.

## Actor input object example

```json
{
  "domainsText": "shopify.com\nvercel.com\nwordpress.org",
  "maxDomains": 100
}
```

# 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 = {
    "domainsText": `shopify.com
vercel.com
wordpress.org`
};

// Run the Actor and wait for it to finish
const run = await client.actor("eliai/bulk-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 = { "domainsText": """shopify.com
vercel.com
wordpress.org""" }

# Run the Actor and wait for it to finish
run = client.actor("eliai/bulk-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 '{
  "domainsText": "shopify.com\\nvercel.com\\nwordpress.org"
}' |
apify call eliai/bulk-tech-stack-detector --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Bulk Tech Stack Detector",
        "description": "Paste a list of domains and get what each one runs: CMS, framework, hosting, analytics, payments, support widgets. Every detection returns the evidence that proved it plus a confidence level, so a wrong row is auditable. Unreachable domains are never charged.",
        "version": "0.1",
        "x-build-id": "PSoPA4YVvLa9fd9Iz"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/eliai~bulk-tech-stack-detector/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-eliai-bulk-tech-stack-detector",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/eliai~bulk-tech-stack-detector/runs": {
            "post": {
                "operationId": "runs-sync-eliai-bulk-tech-stack-detector",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/eliai~bulk-tech-stack-detector/run-sync": {
            "post": {
                "operationId": "run-sync-eliai-bulk-tech-stack-detector",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "domainsText": {
                        "title": "Paste your domain list",
                        "type": "string",
                        "description": "One domain per line, or separated by commas or spaces. Duplicates removed automatically. https:// optional."
                    },
                    "domains": {
                        "title": "Domains (array)",
                        "type": "array",
                        "description": "For API and integration use.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "domain": {
                        "title": "Single domain",
                        "type": "string",
                        "description": "Analyse a single domain."
                    },
                    "maxDomains": {
                        "title": "Max domains",
                        "minimum": 1,
                        "maximum": 5000,
                        "type": "integer",
                        "description": "Safety cap. You are charged per domain successfully analysed, so this is also your budget cap.",
                        "default": 100
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
