# Website Tech Stack Detector (`khadinakbar/website-tech-stack-detector`) Actor

Detect CMS, frameworks, analytics, CDNs, ecommerce platforms, and JS libraries on public website URLs via owned HTTP fingerprinting. No paid catalog APIs. One row per URL. MCP-ready.

- **URL**: https://apify.com/khadinakbar/website-tech-stack-detector.md
- **Developed by:** [Khadin Akbar](https://apify.com/khadinakbar) (community)
- **Categories:** SEO tools, Developer tools, MCP servers
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $10.00 / 1,000 tech stack detecteds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## Website Tech Stack Detector

Turn public website URLs into one structured **technology-stack dataset row** per URL for sales researchers, SEO operators, and AI agents. Each row returns categorized CMS, framework, analytics, CDN, ecommerce, JS library, and server signals with technology names, confidence, and optional evidence excerpts taken from the current public HTML and response headers.

### Best fit for this Actor

- Use this Actor when you already have https URLs and need a cheap, MCP-ready stack snapshot before enrichment, migration planning, or competitor research.
- Designed for lean owned HTTP fingerprinting: predictable Pay per event pricing, caller-paid platform usage, and no paid catalog API balance to maintain.
- Start with a single public storefront URL such as the Shopify Console prefill, then raise `maxUrls` for a bounded batch.
- Continue with [Website Stack Evidence Audit](https://apify.com/khadinakbar/website-stack-evidence-audit) when the next step is a multi-page source-evidenced audit.
- For a managed Domain Technologies catalog hybrid, then use [Wappalyzer Alternative](https://apify.com/khadinakbar/wappalyzer-alternative).

### Practical scenario

A B2B SDR collects a short competitor domain list, runs this Actor once with `maxUrls` set to three, and keeps rows where `Ecommerce` or `CMS` matches Shopify or WordPress. The fingerprint pass returns `technologyNames`, `categories`, and short evidence snippets the SDR can trust from current public pages, then the team continues into an enrichment Actor.

### Quick start input

```json
{
  "websiteUrls": ["https://www.shopify.com"],
  "maxUrls": 3,
  "includeEvidence": true
}
```

`websiteUrls` accepts full https URLs or bare domains. Prefer full https URLs. Duplicate URLs are deduped. `maxUrls` is the spend cap after dedupe.

### Input reference

| Field | Type | What it controls |
| --- | --- | --- |
| `websiteUrls` | string\[] | Public website URLs or bare domains to fingerprint. Prefill: `https://www.shopify.com`. Cap 50. |
| `startUrls` | request list | Optional alias for `websiteUrls` using Apify request-list objects. Prefer `websiteUrls` for agents. |
| `maxUrls` | integer | Hard cap on unique URLs after dedupe, 1–50. Default 25. Prefill 3. |
| `includeEvidence` | boolean | When true, each technology includes a short public-signal evidence excerpt. Default true. |
| `requestTimeoutSecs` | integer | Per-URL HTTP timeout, 5–60 seconds. Default 25. Prefill 20. |
| `proxyConfiguration` | object | Optional Apify proxy. Leave off for the default direct HTTPS path; enable Residential when a target challenges direct fetch. |

### What data you receive

Each dataset item is one public website fingerprint.

```json
{
  "inputUrl": "https://www.shopify.com",
  "finalUrl": "https://www.shopify.com/",
  "statusCode": 200,
  "technologyCount": 4,
  "technologyNames": ["Cloudflare", "Google Tag Manager", "Shopify"],
  "categories": {
    "CDN": ["Cloudflare"],
    "Ecommerce": ["Shopify"],
    "Tag manager": ["Google Tag Manager"]
  },
  "detectionMethod": "owned_http_fingerprinting",
  "outcome": "DETECTED",
  "matchFound": true
}
```

| Field | Meaning |
| --- | --- |
| `inputUrl` / `finalUrl` | Requested URL and post-redirect URL |
| `technologyNames` | Flat list of matched technologies |
| `categories` | Grouped map such as CMS, Analytics, CDN, Ecommerce |
| `technologies` | Name, category, confidence, optional evidence excerpt |
| `technologyCount` | Count of matches |
| `detectionMethod` | Always `owned_http_fingerprinting` |
| `route` | `direct` or `apify-proxy` |
| `statusCode` | Final HTTP status |

`OUTPUT` and `RUN_SUMMARY` in the default key-value store hold `outcome`, `itemsPushed`, and charged event counts. Download the dataset as JSON, CSV, Excel, or HTML.

### Use through the API

```bash
curl -X POST "https://api.apify.com/v2/acts/khadinakbar~website-tech-stack-detector/runs" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"websiteUrls":["https://www.shopify.com"],"maxUrls":1}'
```

### Use with AI agents through Apify MCP

> Detect the tech stack for https://www.shopify.com. Return technologyNames, categories, confidence, and evidence. Read the dataset overview view and OUTPUT.outcome after the run. Budget: one URL is about $0.01 event plus platform usage. Scope: public HTML and headers only. Provenance: detectionMethod equals owned\_http\_fingerprinting with scrapedAt and route.

Connect via <https://mcp.apify.com>. Tell the agent to keep `maxUrls` small on the first call and preserve `finalUrl` as the observed source URL.

### Pricing

This Actor uses **Pay per event** plus Apify **platform usage**. The live Pricing tab is the current source of truth for billing details.

- `apify-actor-start`: $0.00005 per run
- `tech-stack-detected` (primary): **$0.01** per successfully fingerprinted URL

A three-URL sample with three accepted rows is three `tech-stack-detected` events plus start and platform usage. Upstream catalog provider cost is $0 because detection is owned HTTP fingerprinting. Invalid inputs and fully unreachable targets skip the primary event.

### Best results

- Provide full `https` URLs when you already have them, and keep `maxUrls` tight while you confirm the output shape.
- Start with the Shopify Console prefill, inspect `technologyNames` and evidence excerpts, then schedule the same input for a recurring competitor watch.
- Pair Residential proxy only when a target challenges the direct HTTPS path; otherwise keep the default direct route for lower platform usage.
- Confirm `OUTPUT.outcome` and `itemsPushed` before treating an empty dataset as a finished fingerprint pass.

### Builder's note

I found that paid catalog hybrids already cover Domain Technologies enrichment in sibling Actors, so I designed this SKU as owned HTML and header fingerprinting only. I also found that conservative evidence-backed fingerprints keep every billed row tied to a public signal agents can inspect, which is why `includeEvidence` defaults to true and why the primary event fires only after a validated dataset row is ready to persist.

### Responsible use

Use this Actor for lawful collection and analysis of public website responses you are authorized to access. Follow applicable laws and site terms. Shopify and WordPress are trademarks of their respective owners. This independent Actor is not affiliated with, associated with, or endorsed by Shopify Inc. or the WordPress Foundation.

# Actor input Schema

## `websiteUrls` (type: `array`):

Public website URLs or bare domains to fingerprint. Example: https://www.shopify.com or shopify.com. Only http(s) public hosts are accepted — no localhost, private IPs, or credentialed URLs. Prefer full https URLs. Duplicate URLs are deduped. Each successful detection costs $0.01.

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

Optional alias for websiteUrls using Apify request-list objects. Prefer websiteUrls for agents. Each entry needs a public http(s) url field. Merged and deduped with websiteUrls.

## `maxUrls` (type: `integer`):

Hard cap on unique URLs processed after dedupe. Defaults to 25. Maximum 50. Lower this to bound spend. Each successful detection costs $0.01 plus platform usage.

## `includeEvidence` (type: `boolean`):

When true, each technology includes a short public-signal evidence excerpt (HTML/header snippet). Defaults to true. Set false for smaller rows when only names and categories are needed.

## `requestTimeoutSecs` (type: `integer`):

HTTP timeout per URL attempt. Defaults to 25. Range 5–60. Does not change pricing. Increase only for slow origins; prefer proxies for blocks.

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

Optional Apify proxy. Leave off for the default direct HTTPS path. Enable Apify Residential when a target returns 403/429 or Cloudflare challenges. This is not a third-party tech-catalog API.

## Actor input object example

```json
{
  "websiteUrls": [
    "https://www.shopify.com",
    "https://wordpress.org"
  ],
  "maxUrls": 3,
  "includeEvidence": true,
  "requestTimeoutSecs": 20
}
```

# Actor output Schema

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

One row per successfully fingerprinted website URL.

## `output` (type: `string`):

Final outcome, itemsPushed, urlsDetected, and chargedEventCounts.

## `runSummary` (type: `string`):

Per-URL outcomes, routes, and billing counters.

# 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 = {
    "websiteUrls": [
        "https://www.shopify.com"
    ],
    "maxUrls": 3,
    "includeEvidence": true,
    "requestTimeoutSecs": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("khadinakbar/website-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 = {
    "websiteUrls": ["https://www.shopify.com"],
    "maxUrls": 3,
    "includeEvidence": True,
    "requestTimeoutSecs": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("khadinakbar/website-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 '{
  "websiteUrls": [
    "https://www.shopify.com"
  ],
  "maxUrls": 3,
  "includeEvidence": true,
  "requestTimeoutSecs": 20
}' |
apify call khadinakbar/website-tech-stack-detector --silent --output-dataset

```

## MCP server setup

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