# Website Technology Detector - CMS, Analytics and Chat (`leadproof/website-technology-detector`) Actor

Detect 24 website technologies from public homepages: WordPress, Shopify, Wix, Webflow, analytics, chat tools and more. Bulk domain input, evidence for each detection, clear failure diagnostics, and JSON/CSV export. No API key required.

- **URL**: https://apify.com/leadproof/website-technology-detector.md
- **Developed by:** [Lead Proof](https://apify.com/leadproof) (community)
- **Categories:** Developer tools, Lead generation
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 website scanneds

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

## Website Technology Detector - CMS, Analytics and Chat

Scan public homepages in bulk and return recognized website technologies with the
matching evidence. Useful for agencies filtering prospect lists by CMS, analytics,
marketing or chat tools.

This first release supports 24 technologies. Detection means an indicator appeared
in the returned HTML or headers, not that a tool executes or has an active subscription.

### How to use

1. Enter website domains or URLs in **Websites or domains**.
2. Set the maximum websites and concurrency.
3. Run, then filter `technologyNames` or export the CSV.
4. Read `scanStatus` and the run summary before treating missing detections as unknown.

```json
{"websites": ["https://wordpress.org/", "https://nextjs.org/"], "maxWebsites": 10, "concurrency": 2}
```

Input paths, fragments and query strings are removed: this scans homepages only.
The same domain and its www equivalent are processed once. Distinct subdomains are
separate websites. CSV-file ingestion is not included in this release.

### Supported technologies

| Category | Technologies |
| --- | --- |
| CMS | WordPress, Drupal, Ghost, Joomla |
| Website builder | Wix, Squarespace, Webflow |
| E-commerce | Shopify, WooCommerce |
| Analytics | Google Analytics, Hotjar, Microsoft Clarity, Plausible |
| Tagging | Google tag, Google Tag Manager |
| Advertising | Meta Pixel |
| Chat / support | Intercom, Crisp, Tawk.to, Zendesk |
| Marketing | HubSpot |
| Framework | Next.js, Nuxt |
| CDN / reverse proxy | Cloudflare |

Each technology has one or more deliberately narrow signatures. The catalog is not
an exhaustive replacement for a comprehensive technology database. Generator metadata,
selected same-site assets, script sources, two inline configuration patterns, and the
Cloudflare server header are inspected. Plain article text and regular hyperlinks
are not scanned for brand names. Versions are returned only from recognized generator
metadata. Cloudflare evidence identifies a proxy/CDN signal, not the origin hosting provider.
Google tag is kept separate from Analytics because Google Ads can also use gtag.js.

### Output

One row per unique input domain, including diagnostic rows for failed sites.

| Field | Meaning |
| --- | --- |
| `website`, `domain` | Normalized requested homepage and domain |
| `finalUrl`, `httpStatus` | Final homepage URL (without query) and HTTP status, when available |
| `scanStatus` | `detected`, `no_signals`, or `failed` |
| `technologyNames`, `technologyCount` | Flat names and count, convenient for spreadsheets |
| `technologies` | Name, category, optional version and evidence objects (`type`, `marker`) |
| `error` | Sanitized failure code; null for a readable site |
| `rulesetVersion`, `scanMode` | Fingerprint version and `static_homepage` mode |
| `scrapedAt` | UTC timestamp |
| `billingEvent` | Custom event name when enabled, otherwise null |

`SUMMARY` records processed, detected, unknown and failed websites, duplicates, omitted
websites and the stopping reason. If all processed sites fail, the run fails after
saving its diagnostics. A readable page with no recognized signals is a valid result.
Mixed runs keep successful results and expose failures in their rows and summary.

### Limits and recovery

- No browser, login, JavaScript execution or remote script downloads. Dynamically
  injected tags, consent-dependent scripts, self-hosted variants and custom themes can
  be missed. A matching indicator can also be present in unused template code.
- One robots.txt request and one homepage request per site, plus at most five redirects
  for each. Redirects to other domains are reported instead of followed.
- robots.txt is respected. Unavailable or restrictive rules stop the scan; crawl delays
  above ten seconds are reported as unsupported. Bodies are bounded to 512 KB for
  robots and 2 MB for HTML; oversized responses are reported.
- DNS destinations are checked at connection time. Only public HTTP(S) destinations on
  standard ports are accepted. No cookies or raw page bodies are stored in the results.
- Input is fingerprinted before output starts. Existing dataset rows are reused on a
  restart, including rows written before a summary update. Concurrent runs must use
  separate default storage. A crash between charging and durable output cannot provide
  an exactly-once billing guarantee.

### Pricing

Pay per event: **$3 per 1,000 readable websites**, plus **$0.005 per run start at the default 256 MB memory**.
Apify charges one start unit per GB of allocated memory, with a minimum of one unit.
A readable website is charged once even when no supported technology is found.
Failed-site diagnostic rows have no website-scan charge. A run-start charge can
still apply when every site fails. Check the Pricing tab for the current rate.

The `website-scanned` event applies to `detected` and `no_signals` results.
Automatic dataset-item charging is disabled. Set a maximum cost per run to limit
charges; the Actor stops writing paid results when the event budget is exhausted.
An already-started batch of at most `concurrency` websites may finish scanning.

### Development

```sh
python -m pip install -r requirements.txt
python -m unittest discover -s test -v
python scripts/smoke.py
```

The smoke script makes six initial public requests across three sites; redirects can
add requests. It writes a local validation report. CI runs it in a separate job so that
live access problems can be distinguished from deterministic test failures.

Signature references:

- [Google tag setup](https://developers.google.com/tag-platform/gtagjs)
- [Google Tag Manager installation](https://support.google.com/tagmanager/answer/14847097)
- [Cloudflare HTTP headers](https://developers.cloudflare.com/fundamentals/reference/http-headers/)

Use public website data responsibly and respect applicable site rules.
Related LeadProof tools: [Website Email Finder](https://apify.com/leadproof/website-email-finder),
[Google Maps Scraper](https://apify.com/leadproof/google-maps-scraper), and [LeadProof](https://leadproof.co).

# Actor input Schema

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

One public website per entry. Scan homepage only; paths and query strings are discarded. Duplicates and www equivalents are scanned once.

## `maxWebsites` (type: `integer`):

Maximum unique domains to process. Any additional domains are reported in the run summary.

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

Number of websites read at once. Each site needs a robots.txt request plus its homepage, with bounded redirects.

## `requestTimeoutSeconds` (type: `integer`):

Maximum duration per request. Timeouts produce diagnostic rows instead of invented technology results.

## Actor input object example

```json
{
  "websites": [
    "https://wordpress.org/"
  ],
  "maxWebsites": 100,
  "concurrency": 5,
  "requestTimeoutSeconds": 20
}
```

# Actor output Schema

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

Includes nested matching evidence per technology.

## `csv` (type: `string`):

Website summary and technology names for spreadsheet filtering.

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

Coverage, failed sites, unknown sites and stopping reason.

## `checkpoint` (type: `string`):

Input fingerprint preventing mixing unrelated output during a restart.

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

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

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

```

## MCP server setup

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