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

Find out what any website is built on. Detects frameworks, CDNs, ecommerce platforms, CMSs, analytics, support widgets and payment providers from one polite request — and reports the evidence behind every single detection, so you can check the answer instead of trusting it.

- **URL**: https://apify.com/appdata-labs/tech-stack-detector.md
- **Developed by:** [Kobkoon Janngam](https://apify.com/appdata-labs) (community)
- **Categories:** Agents, MCP servers, Lead generation
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$4.00 / 1,000 site analyseds

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?

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

## Tech Stack Detector — website technology lookup, with the evidence attached

**Find out what any website is built on.** Frameworks, CDNs, ecommerce platforms, CMSs, analytics, chat widgets, payment providers — from one polite request per site.

**Quick start:** press **Start** with no configuration at all. It ships with twelve well-known sites so a single run shows you the whole output shape. Then paste in your own list.

### Sample output

| url | title | technologyCount | categories | server |
|---|---|---|---|---|
| https://shopify.com/ | Shopify | 2 | CDN, Ecommerce | cloudflare |
| https://vercel.com/ | Vercel | 2 | Framework, Hosting | Vercel |
| https://wordpress.org/ | WordPress.org | 3 | Analytics, CMS, Web server | nginx |
| https://gitlab.com/ | GitLab | 3 | CDN, Framework, Marketing | cloudflare |

Every row also carries `target`, `finalUrl`, `httpStatus`, `reachable`, `robotsAllowed`, `robotsReason`, `description`, `poweredBy`, `checkedAt`, `error`, and a `technologies` array where each entry has a `name`, a `category` and an `evidence` string.

### Why this one

**Every detection carries its evidence.** A bare list of technology names is unfalsifiable — you either trust it or you do not, and you have no way to tell which. Here each entry says exactly what matched:

```json
{ "name": "Shopify", "category": "Ecommerce",
  "evidence": "page references cdn.shopify.com/shopifycloud/..." }
```

You can check it. You can argue with it. And when a signature is wrong, you can see *why* it was wrong instead of quietly building a campaign on it.

**A site's own claim is labelled as its own claim.** The `<meta name="generator">` tag is the one signal a site can set to anything at all, so anything found only there is filed under the category `Self-declared` rather than mixed in with things we actually detected.

**Nothing matched means nothing matched.** A plain HTML page returns an empty list, not a hopeful guess. The signatures match real markers — `/_next/static/`, `cdn.shopify.com`, a `cf-ray` header — never the vendor's name in prose, so a careers page that says "we use React" does not become a React detection.

**It reads the site's robots.txt first.** You named the target, so this is not crawling — but the Actor still checks and skips any path the site asks automated clients to leave alone, and says so in `robotsAllowed` and `robotsReason` rather than doing it silently. A skipped fetch and a site with no technology are very different answers.

### What you can do with it

- **Qualify leads before you write to them.** Knowing a prospect runs Shopify, HubSpot and Klaviyo tells you what to sell and what to say.
- **Size a market.** Run a list of a thousand competitors' customers and count how many are on the platform you integrate with.
- **Watch a competitor's stack change.** Schedule it and diff `technologies` over time; a new analytics vendor or a CMS migration is a visible event.
- **Audit your own estate.** Point it at every domain you own and find the forgotten WordPress install.
- **Feed an AI agent.** Rows are around 1 KB, identically shaped, and every claim is accompanied by its justification, which is exactly what a model needs to reason rather than parrot.

### Input

| Field | Default | Notes |
|---|---|---|
| `websites` | 12 sample sites | A bare domain or a full URL. A URL with a path analyses that page, not the home page. |
| `respectRobots` | `true` | Skips paths the site's robots.txt disallows, and reports it. Turn off only for sites you own. |
| `onlyWithTechnologies` | `false` | Drops rows where nothing was detected. You are charged per row returned, so this is cheaper on long lists. |
| `concurrency` | `5` | Parallel fetches. One request per site either way. |

### Limits worth knowing before you buy

**This reads the HTML the server returns; it does not run JavaScript.** A technology loaded only after the page boots in a browser will not be seen. That keeps the Actor fast and cheap — around a second per site — and it means the answer is "what the page declares", not "everything running in a session".

Detection is signature-based, so it finds what it has a signature for. Around sixty technologies across hosting, CDN, frameworks, CMS, ecommerce, analytics, marketing, support, payments and monitoring — the ones that matter for qualifying a company, not an exhaustive registry.

Sites behind an aggressive bot wall will answer with a challenge page. That is reported as the HTTP status it was, not silently turned into an empty result.

### Pricing

Pay per site returned. Sites removed by your filters are not charged, and duplicates are dropped before anything is counted.

### Disclaimer

This Actor fetches pages you name, one request each, identifying itself honestly
in its user agent. It scrapes no website catalogue and calls no third-party API —
there is nothing between you and the site you asked about.

It reads each target's `robots.txt` and honours it by default. Technology names
are trademarks of their respective owners and are used here only to describe
what a page appears to be built with; this Actor is not affiliated with, endorsed
by or connected to any of them.

Detection is inference from public evidence, not certainty. The `evidence` field
exists so you can judge each conclusion yourself rather than take it on trust.

# Actor input Schema

## `websites` (type: `array`):

The sites to look up. A bare domain (stripe.com) or a full URL both work, and a URL with a path analyses that exact page rather than the home page.

## `respectRobots` (type: `boolean`):

On by default. The Actor reads the target robots.txt first and skips any path the site asks automated clients to leave alone, reporting that it did so. Turn it off only for sites you own or have permission to test.

## `onlyWithTechnologies` (type: `boolean`):

Drops rows where nothing matched — usually a site that is unreachable, blocked, or built entirely from plain HTML. You are charged per row returned, so this is also the cheaper way to scan a long list.

## `concurrency` (type: `integer`):

How many sites are requested in parallel. One request per site either way; this only controls how quickly a long list is worked through.

## Actor input object example

```json
{
  "websites": [
    "stripe.com",
    "https://shopify.com/pricing"
  ],
  "respectRobots": true,
  "onlyWithTechnologies": false,
  "concurrency": 5
}
```

# Actor output Schema

## `rows` (type: `string`):

One row per site: the technologies found, the category of each, and the exact evidence that identified it.

## `summary` (type: `string`):

How many sites were reachable, how many were skipped for robots.txt, and which technologies came up most often across the list.

# 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 = {
    "websites": [
        "shopify.com",
        "vercel.com",
        "wordpress.org",
        "basecamp.com",
        "apify.com",
        "stripe.com",
        "notion.so",
        "figma.com",
        "linear.app",
        "openai.com",
        "cloudflare.com",
        "gitlab.com"
    ],
    "respectRobots": true,
    "onlyWithTechnologies": false,
    "concurrency": 5
};

// Run the Actor and wait for it to finish
const run = await client.actor("appdata-labs/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 = {
    "websites": [
        "shopify.com",
        "vercel.com",
        "wordpress.org",
        "basecamp.com",
        "apify.com",
        "stripe.com",
        "notion.so",
        "figma.com",
        "linear.app",
        "openai.com",
        "cloudflare.com",
        "gitlab.com",
    ],
    "respectRobots": True,
    "onlyWithTechnologies": False,
    "concurrency": 5,
}

# Run the Actor and wait for it to finish
run = client.actor("appdata-labs/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 '{
  "websites": [
    "shopify.com",
    "vercel.com",
    "wordpress.org",
    "basecamp.com",
    "apify.com",
    "stripe.com",
    "notion.so",
    "figma.com",
    "linear.app",
    "openai.com",
    "cloudflare.com",
    "gitlab.com"
  ],
  "respectRobots": true,
  "onlyWithTechnologies": false,
  "concurrency": 5
}' |
apify call appdata-labs/tech-stack-detector --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,appdata-labs/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/PiZhOWOYAR2NAQFrs/builds/QyXb5cAOWLhIuAoS7/openapi.json
