# Website Technology Stack Detector (`keystonelabs/tech-stack-detector`) Actor

Qualify website lists by detected CMS, ecommerce platform, analytics and JavaScript technologies. Export structured technology evidence for agency research and lead enrichment. Uses public HTML and headers; no browser rendering or complete-stack guarantee.

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

## Pricing

$3.00 / 1,000 website checkeds

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

## Qualify a website list by the technology it exposes

Inspect public HTML and response headers for CMS, ecommerce, analytics and other technology signals. Use the structured output to prioritize agency research or enrich a domain list. Hidden and browser-only technologies can be missed; this is not a complete inventory or a security audit.

### Get a useful first result

1. Open the Input tab and select JSON. Paste the small example below.
2. Check Pricing and set your run spending limit, then start the run.
3. Inspect `cms`, `ecommerce`, `technologies` and `error`. An empty field is not proof that a technology is absent.
4. Export the result as JSON or CSV. Check a small sample before increasing the input size.

```json
{
  "startUrls": [
    "https://www.shopify.com",
    "https://wordpress.org",
    "https://www.hubspot.com"
  ]
}
```

The sample incurs $0.009 in Actor event fees if it returns the intended number of rows. The rate checked September 7, 2026 is $3.00 per 1,000 output rows. Check the live Pricing tab before running; taxes or other account services may be separate.

### What can I use it for?

- **Lead generation and sales prospecting.** Find every site on your list running Shopify, WooCommerce, HubSpot, Magento, Salesforce Commerce Cloud or any other platform your product integrates with, and pitch the ones that fit.
- **Competitive research.** See which frameworks, analytics suites and marketing tools your competitors rely on.
- **Migration and agency work.** Audit a client portfolio for outdated CMS versions, missing analytics, or sites still on legacy hosting.
- **Market sizing.** Measure the adoption of a technology across a set of domains.
- **Technical research.** Inspect exposed technology and version signals as a starting point for a separate technical review. This tool does not establish vulnerabilities.
- **Enriching your own data.** Attach tech-stack fields to a CRM export or a domain list in one run.

### What data does it return?

Each analyzed website produces one record. The most-used fields are lifted to the top level so the dataset is immediately filterable:

| Field | Example |
|---|---|
| `url`, `finalUrl`, `statusCode`, `title` | `https://example.com`, `200`, `Example Domain` |
| `cms` | `WordPress` |
| `ecommerce` | `Shopify` |
| `webServer` | `Nginx` |
| `cdn` | `Cloudflare` |
| `hosting` / `paas` | `Amazon Web Services` / `Vercel` |
| `analytics` | `Google Analytics, Hotjar` |
| `tagManager` | `Google Tag Manager` |
| `advertising` | `Google Ads, Meta Pixel` |
| `javascriptFrameworks` | `React, Next.js` |
| `javascriptLibraries` | `jQuery, Lodash` |
| `webFrameworks` | `Ruby on Rails` |
| `programmingLanguages` | `PHP` |
| `paymentProcessors` | `Stripe, PayPal` |
| `marketingAutomation` | `HubSpot, Klaviyo` |
| `liveChat` | `Intercom` |
| `security` | `reCAPTCHA` |
| `technologyCount` | `23` |

Below those, `technologies` holds the complete list with a `name`, all its `categories`, a detected `version` where one is exposed, a `confidence` score from 0 to 100, and the vendor `website`. `technologiesByCategory` gives the same data keyed by category name for quick grouping.

Sites that time out or refuse the connection are still returned, with an `error` field explaining why, so your input and output line up one-to-one.

#### Illustrative output

The example below explains the output shape; values are illustrative and are not a live result or a promise that every field is populated.

```json
{
  "url": "https://www.allbirds.com",
  "finalUrl": "https://www.allbirds.com/",
  "statusCode": 200,
  "title": "Allbirds: Sustainable Shoes & Clothing",
  "cms": null,
  "ecommerce": "Shopify",
  "webServer": null,
  "cdn": "Cloudflare",
  "analytics": "Google Analytics",
  "tagManager": "Google Tag Manager",
  "javascriptFrameworks": "React",
  "paymentProcessors": "Shop Pay",
  "technologyCount": 18,
  "technologies": [
    { "name": "Shopify", "categories": ["Ecommerce"], "version": null, "confidence": 100, "website": "https://www.shopify.com" },
    { "name": "Cloudflare", "categories": ["CDN"], "version": null, "confidence": 100, "website": "https://www.cloudflare.com" }
  ],
  "responseTimeMs": 412,
  "fetchedAt": "2026-09-04T21:03:11.104Z",
  "error": null
}
```

### How to use it

1. Add the websites you want analyzed under **Websites to analyze**. You can paste a list, upload a file, or pass them through the API as `startUrls`.
2. Click **Start**. The defaults are tuned for most jobs.
3. Download the results as JSON, CSV, Excel or XML from the **Output** tab, or read them straight from the dataset via the API.

For large lists, raise **Max concurrency** to speed things up, or lower it if all your URLs sit on one domain and you want to be polite to that server. Turn on **Proxy configuration** only if a target site blocks the platform's IP range — most do not.

#### Finding sites that use a specific technology

If you only care about one platform — every Shopify store in a list of 5,000 domains, say — put its name under **Only interested in these technologies**. Every result then carries a `matchesFilter` flag and a `matchedTechnologies` list. Switch on **Store only matching websites** and the sites that do not match are analyzed but not saved, so you pay only for the ones you wanted. Names are matched case-insensitively against the detected technology names, and you can list several at once (`Shopify`, `WooCommerce`, `Magento`) to catch any of them.

#### Input

```json
{
  "startUrls": [
    "https://www.shopify.com",
    "wordpress.org",
    "https://www.hubspot.com/"
  ],
  "maxConcurrency": 10,
  "timeoutSecs": 25
}
```

### How detection works

The detector fetches each page once and inspects the response headers, cookies, HTML, script sources, inline scripts and meta tags against a database of more than 7,600 technology fingerprints across 100+ categories. When one technology reliably implies another — a WooCommerce store implies WordPress, a Shopify store implies the Liquid template language — the implied technology is added with a lower confidence score so you can tell direct evidence from inference.

Because no browser is involved, signals that only appear after JavaScript executes are not evaluated. In practice the headers, cookies and script sources on the initial response reveal the overwhelming majority of a site's stack; the trade-off buys you speed and a much lower cost per site.

The fingerprint database is the open-source webappanalyzer technology dataset, used under the GNU GPL v3. The matching engine in this actor is original code.

### Pricing

You pay per website analyzed. There are no subscriptions, seats or minimums, and you can cap the maximum spend of any run before you start it.

### Scope and responsible use

This actor requests only the publicly served homepage of each URL you provide, exactly as a browser would when you visit the site. It requires no login, no cookies and no credentials, and it does not attempt to bypass any access control or bot-protection challenge. You are responsible for using the results in accordance with the laws that apply to you and the terms of the websites you analyze.

### Limitations

- Very large retail and media homepages that deliberately stall automated traffic can exceed the request timeout; they come back as rows with an `error` rather than being dropped.
- One request per URL; the actor does not crawl beyond the page you give it.
- Sites that serve their entire interface through client-side JavaScript may expose fewer signals.
- Version numbers are reported only when a site publishes them in a header, script path or meta tag.

### Something not detected?

Open an issue on this actor's **Issues** tab with the URL and the technology you expected. Fingerprints are refreshed regularly and reproducible misses are usually fixed within days.

### Before a larger run

Error rows are also charged. Start small and inspect errors before processing a long list. These are paid examples, not a free-results offer. No source-site API key is needed for the example in Console; programmatic Apify API access still requires Apify authentication.

Five internal launch smoke rounds passed on September 6, 2026. This describes small-input test coverage, not customer reviews, a service-level guarantee or a large-batch benchmark. Website behavior and data availability can change.

# Actor input Schema

## `startUrls` (type: `array`):

One website per line — bare domains like allbirds.com are fine, full URLs work too. Duplicates are removed. Each website becomes one result with its full detected technology stack.

## `filterTechnologies` (type: `array`):

Optional. Technology names to check for, e.g. Shopify, WordPress, WooCommerce, HubSpot, React. Each result gets a matchesFilter flag and a matchedTechnologies list. Leave empty to just detect everything.

## `onlyMatching` (type: `boolean`):

When on, websites that do not use any of the filter technologies are analyzed but not saved, so you pay only for the matches. Requires at least one filter technology.

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

How many websites to analyze in parallel. Lower it if you are analyzing many pages on the same domain.

## `timeoutSecs` (type: `integer`):

Give up on a website after this many seconds. Large media and retail homepages can take 30 seconds or more to respond under load.

## `proxyConfiguration` (type: `object`):

Optional. Route requests through Apify Proxy if some target sites block your IP.

## Actor input object example

```json
{
  "startUrls": [
    "https://www.shopify.com",
    "https://wordpress.org",
    "https://www.hubspot.com"
  ],
  "filterTechnologies": [],
  "onlyMatching": false,
  "maxConcurrency": 20,
  "timeoutSecs": 45,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

Dataset of analyzed websites. Each item lists detected technologies with category, version and confidence.

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

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

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

```

## MCP server setup

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