# Tech Stack Detector - Website Technology Lookup (`dewdropped_ivory/tech-stack-detector`) Actor

Detect the technologies a website is built with: frameworks, CMS, analytics, CDN, hosting, payment and marketing tools. Matches 7,628 technologies. One record per URL with the evidence behind each match, labelled confirmed or inferred. Pay per result, $20 per 1,000 URLs.

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

## Pricing

from $5.00 / 1,000 detected stacks

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 Detector — Website Technology Lookup

Detect the technology stack behind any website: frameworks, CMS, JavaScript libraries,
analytics, CDN, hosting, payments and marketing tools. A cheaper, scriptable way to get
technology data than enterprise API tiers.

> **Unofficial.** This is an independent tool. It is not affiliated with, endorsed by, or
> sponsored by Wappalyzer, BuiltWith, or any other technology-profiling service. All
> trademarks belong to their respective owners.

> **Licence note.** The technology fingerprint data is derived from the GPL-3.0
> `enthec/webappanalyzer` database, so this Actor is distributed under GPL-3.0. The full
> licence and attribution are in `LICENSE-AND-ATTRIBUTION.md`.

Give it a list of URLs. Get back one record per site, with every technology it found and
**the evidence that produced each match** — header, HTML pattern, script URL or cookie.

### What you get

For each URL:

| Field | Description |
|---|---|
| `url`, `final_url` | Requested and post-redirect URL |
| `status_code`, `elapsed_ms` | Response status and fetch time |
| `technologies` | Flat list of detected technology names |
| `technology_count` | How many were found |
| `detail` | Per technology: `name`, `version` (when exposed), `confidence` (`confirmed` or `inferred`), `evidence[]` |
| `server`, `powered_by` | Raw `Server` / `X-Powered-By` headers |

### Why this exists

Wappalyzer and BuiltWith are excellent but their API tiers are priced for enterprises, and
the free browser extension doesn't help you **at scale or in a pipeline**. This Actor gives
you the same class of signal as clean JSON you can schedule, loop over, and feed into your
own systems — at pay-per-result pricing with no monthly seat.

### Typical uses

- **Lead qualification** — filter prospect lists by what they actually run (Shopify vs
  custom, HubSpot vs none) before your sales team wastes calls.
- **Market research** — how many sites in a niche use a given CMS, analytics tool or CDN.
- **Competitive monitoring** — watch a list of competitor domains and alert on stack changes.
- **Migration prospecting** — find sites on an old platform worth migrating.
- **Due diligence** — technical profile of an acquisition target's public estate.

### Input

```json
{
  "urls": ["https://www.shopify.com", "https://wordpress.org"],
  "timeoutSeconds": 20,
  "maxResults": 0
}
```

`urls` accepts a list of bare domains or full URLs (https:// is assumed if omitted).
`maxResults` caps processing — set it to control spend on large lists.

### Output example

```json
{
  "url": "https://www.shopify.com",
  "ok": true,
  "status_code": 200,
  "elapsed_ms": 182,
  "technologies": ["Cloudflare", "Google Analytics", "React", "Shopify", "Tailwind CSS"],
  "technology_count": 5,
  "detail": [
    {
      "name": "Shopify",
      "version": null,
      "evidence": [{"surface": "header:x-shopify-stage", "match": "x-shopify-stage: production"}]
    }
  ]
}
```

### How detection works

One HTTP GET per URL. Signals are matched across five surfaces:

1. **Response headers** — `Server`, `X-Powered-By`, `X-Generator`, platform-specific headers
2. **Cookies** — session and analytics cookie names
3. **HTML body** — library and vendor URL patterns, embedded config markers
4. **Script and asset URLs** — CDN hosts, plugin/theme paths
5. **Meta tags** — `generator` and friends

Each match records which surface fired, so results are auditable rather than a black box.
Version numbers are reported when the site exposes them.

### Pricing

Pay per result — **$5 per 1,000 results** ($0.005 per domain). No monthly fee, no seat, no minimum.
1,000 URLs ≈ $20. 100,000 URLs ≈ $2,000.

### Limitations — read before buying

Honest scope, so you can judge fit:

- **Client-side rendered sites reveal less.** If a site injects its stack in JavaScript after
  load, a plain HTTP fetch sees only the initial HTML. Single-page apps built on Next.js,
  Nuxt or similar are usually still identified from the shell, but deeply dynamic stacks
  may be under-reported.
- **Detection is evidence-based, not exhaustive.** A technology that leaves no trace in
  headers, HTML, cookies or asset URLs will not be found. Absence of a technology is not
  proof of absence.
- **Some sites hide their stack deliberately** and will return few or no matches.
- **Anti-bot protection is respected, not defeated.** If a site blocks automated requests,
  the result is an error record for that URL — no attempt is made to bypass it.
- **Versions are opportunistic.** Many sites deliberately omit them.

If you need pixel-perfect rendering or JavaScript execution for every target, use a
browser-rendering Actor instead; this one optimises for speed and cost per URL.

### Legal and ethical use

This Actor fetches **publicly accessible pages** and reports technology signals. It does not
log in, does not bypass access controls, and does not reproduce page content — the output is
a short list of technology names with evidence pointers.

You are responsible for using it lawfully: respect target sites' terms of service,
`robots.txt`, and applicable law in your jurisdiction. Do not use it to build profiles of
individuals or to facilitate unauthorised access.

### Support

Issues or feature requests: open an issue on the Actor's page. Requests for additional
technology signatures are welcome — include an example URL where the technology is visible.

# Actor input Schema

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

One or more website URLs to fingerprint.

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

Per-request timeout.

## `maxResults` (type: `integer`):

Optional cap on the number of URLs processed. 0 means no cap.

## Actor input object example

```json
{
  "urls": [
    "https://www.shopify.com",
    "https://wordpress.org"
  ],
  "timeoutSeconds": 20,
  "maxResults": 0
}
```

# Actor output Schema

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

One record per analysed URL, including the technologies detected, capability categories, and the evidence behind each match. Each technology is labelled confirmed (observed directly on the page) or inferred (implied by a confirmed technology).

# 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",
        "https://wordpress.org"
    ]
};

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

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

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,dewdropped_ivory/tech-stack-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/mtbPQWaPPiQeiOpar/builds/sKdRIKLPYPDtQTYAJ/openapi.json
