# Website Tech Stack Detector (`asgardlabs/site-technology-lookup`) Actor

What any website is built with, with the evidence: CMS, ecommerce, frameworks, analytics, marketing tools, chat, payments, CDN, email provider, plus contacts. Up to 7,600+ technologies. Half a cent per site; blocked or dead sites are not charged.

- **URL**: https://apify.com/asgardlabs/site-technology-lookup.md
- **Developed by:** [Asgard Labs](https://apify.com/asgardlabs) (community)
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 sites

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 Tech Stack Detector – CMS, ecommerce, analytics, email provider of any site

Paste a list of websites. Get back, for each one, what it is built with: CMS, ecommerce platform, JavaScript frameworks, analytics and tag managers, marketing and email tools, live chat, payment processors, CDN, hosting, security, and the company's email provider. Plus the contact email, phone numbers and the company's own social profiles from the home page.

Up to 7,600+ technologies are recognised with the extended catalogue (fetched when the run starts), 2,900+ with the bundled baseline. Every detection shows the evidence it was based on, so you can trust it or discard it. Results come with ready-made filters: "is Shopify", "has live chat", "uses Cloudflare", "email provider is Google Workspace".

### Website technology data per site

- **technologies** – name, version when visible, confidence, categories, description, and the evidence (header, script, cookie, DNS record…).
- **summary** – the same list grouped for filtering: cms, ecommerce, framework, language, server, cdn, hosting, analytics, marketing, payments, chat, security, ui, maps, video, search.
- **flags** – isShopify, isWordPress, isWooCommerce, hasEcommerce, hasLiveChat, hasAnalytics, hasPaymentProcessor, usesCloudflare, emailProvider.
- **contacts** – bestEmail (the site's own address, mailto links first), emails, phones, socials (LinkedIn, X, Facebook, Instagram, YouTube, TikTok, GitHub, Pinterest). Only the company's own profiles; share links, pixels and demo addresses are filtered out.
- **server, poweredBy, generator, title, finalUrl, status, durationMs**.
- **ok / blocked / error** – whether the page was really read. Bot walls are reported as `blocked`, errors are in plain words ("timeout", "ENOTFOUND (domain not found)", "http 404").

### Use cases

- Build a list of Shopify stores that use Klaviyo.
- Find every company on your list running HubSpot.
- Check which competitors moved to Next.js.
- Enrich a lead list with email provider and contact email.

### Input

| Field | Default | Meaning |
|---|---|---|
| `urls` | – | Domains or full URLs, one per line. `example.com` is enough. Thousands per run are fine. |
| `extended` | true | On: the full community catalogue (7,600+ technologies) is fetched from its public source when the run starts and cached for 7 days. Off, or when the fetch fails: the bundled baseline of 2,900+ technologies. The run log says which was used. |
| `dnsLookup` | true | Read MX, TXT, NS, SOA and CNAME records: email provider and DNS-based tools. |
| `robots` | true | Also read robots.txt (a few technologies reveal themselves there). |
| `contacts` | true | Extract emails, phones and social links. |
| `includeDns` | false | Put the raw DNS records in the output. |
| `timeoutSecs` | 25 | Time budget per site. A site never takes longer than this plus about two seconds. |
| `concurrency` | 10 | Sites processed in parallel. |

### Output example

```json
{ "url": "allbirds.com", "finalUrl": "https://www.allbirds.com/", "status": 200, "ok": true, "blocked": false, "error": null,
  "title": "Allbirds: Comfortable, Sustainable Shoes & Apparel", "server": "cloudflare",
  "technologies": [ { "name": "Shopify", "version": null, "confidence": 100, "categories": ["Ecommerce"], "evidence": ["scriptSrc: cdn.shopify.com"] }, … ],
  "summary": { "ecommerce": ["Shopify"], "analytics": ["Google Tag Manager"], "payments": ["Apple Pay", "PayPal"], "cdn": ["Cloudflare"], "total": 6, … },
  "contacts": { "bestEmail": "help@allbirds.com", "emails": ["help@allbirds.com"], "phones": ["+1 (424) 363-8064"], "socials": { "instagram": "https://www.instagram.com/allbirds", … } },
  "flags": { "isShopify": true, "hasEcommerce": true, "hasPaymentProcessor": true, "usesCloudflare": true, "emailProvider": "Google Workspace" },
  "durationMs": 1356 }
```

### How to use

1. Paste your website domains, one per line into the input form. The example input is ready to run as is.
2. Click **Start**. Rows appear in the **Output** tab as they are found.
3. Download the table as CSV, JSON or Excel, or read it through the API.

### Pricing

Pay per event: **`site` = $0.005** for every website whose page was actually read (`ok: true`). Blocked, broken, unreachable or non-HTML sites are reported but free. 1,000 websites = $5.

### How it works and what it cannot do

One request per site, like a normal browser visit, plus DNS and robots.txt. No headless browser and no proxies, which is why it is fast and cheap. Technologies that only reveal themselves after JavaScript runs in a browser (about 7% of the fingerprint library, Adobe Analytics for example) can be missed. Sites that block automated visitors are reported as `blocked` and not charged.

### Fingerprint data and licences

Bundled: `data/mit/`, Wappalyzer 6.10.26 technology definitions, MIT License (notice included). This baseline of 2,900+ technologies is the only fingerprint data shipped with the actor.
Fetched at run time when `extended` is on: the community-maintained webappanalyzer catalogue (GPL-3.0), downloaded from its public source into the run owner's own key-value store and refreshed weekly. It is not redistributed with this actor. Details in `NOTICE.md`.

### Use from code or an AI agent

Every run can be started and read through the Apify API, the JavaScript and Python clients, or an AI agent with tool access. Open the **API** tab on this page for ready-made snippets. Pricing is per event, so an agent pays only for what it receives.

### FAQ

**How accurate is it without a browser?**
It reads HTML, headers, cookies, scripts, meta tags and DNS. Technologies that only appear after JavaScript runs in a browser, about 7% of the catalogue, can be missed. Every detection shows its evidence.

**Why does it list tools like DocuSign or Miro for a shop?**
Those come from domain-verification records in the site's DNS. The evidence field says so. They are real signals that the company uses the tool.

**What is the extended catalogue?**
A community-maintained set of 7,600+ fingerprints fetched at the start of the run. If it cannot be fetched, the bundled baseline of 2,900+ is used and the run log says which.

**Are blocked or dead sites charged?**
No. Bot walls, errors, timeouts and non-HTML answers are reported and free.

**Can I filter for "is Shopify" or "has live chat"?**
Yes. Every row carries ready-made flags such as `isShopify`, `hasLiveChat`, `usesCloudflare` and `emailProvider`.

# Actor input Schema

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

Domains or URLs, one per line. Up to thousands per run.

## `extended` (type: `boolean`):

On: the full community catalogue (7,600+ technologies) is fetched from its public source at the start of the run and cached for 7 days. Off, or when it cannot be fetched: the bundled baseline of 2,900+ technologies is used. The run log states which one was used.

## `dnsLookup` (type: `boolean`):

Adds email provider, DNS-based SaaS detection. Small extra latency.

## `robots` (type: `boolean`):

Also read the site's robots.txt; some tools and crawler rules are only visible there.

## `contacts` (type: `boolean`):

Add the site's own emails, phone numbers and social profiles to each result.

## `includeDns` (type: `boolean`):

Attach the MX, TXT, NS, CNAME and SOA records that were looked up. Off by default to keep rows small.

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

Time budget per site. A site never takes longer than this plus about two seconds.

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

How many sites to process at the same time. Ten per GB of run memory is the safe ceiling, and the actor lowers the value to fit.

## Actor input object example

```json
{
  "urls": [
    "shopify.com",
    "wordpress.org",
    "https://stripe.com",
    "apify.com"
  ],
  "extended": true,
  "dnsLookup": true,
  "robots": true,
  "contacts": true,
  "includeDns": false,
  "timeoutSecs": 25,
  "concurrency": 10
}
```

# Actor output Schema

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

One row per website: technologies with evidence, summary by category, flags (isShopify, usesCloudflare, emailProvider…), contacts, or ok:false with a plain error.

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

Counts, skipped inputs with reasons, errors in plain words, charge-limit state.

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

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

# Run the Actor and wait for it to finish
run = client.actor("asgardlabs/site-technology-lookup").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": [
    "shopify.com",
    "wordpress.org",
    "https://stripe.com",
    "apify.com"
  ]
}' |
apify call asgardlabs/site-technology-lookup --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,asgardlabs/site-technology-lookup"
        }
    }
}
```

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/BQkhzJvNQ5ocn8XJ1/builds/7bmTf7JCgBbLLVfrG/openapi.json
