# Website Tech Stack Scraper (`silentflow/website-tech-stack-scraper`) Actor

Detect the technology stack of any website from a list of domains: CMS, ecommerce, analytics, advertising, frameworks, CDN, WAF and payments, 6,633 technologies with versions. Adds the email provider, DNS provider and certificate issuer from live DNS. Technographic data for lead enrichment.

- **URL**: https://apify.com/silentflow/website-tech-stack-scraper.md
- **Developed by:** [SilentFlow](https://apify.com/silentflow) (community)
- **Categories:** Lead generation, SEO tools, Business
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.15 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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 Scraper

**Turn a list of domains into a full technographic profile of every company behind them. 30 sites analyzed in 12 seconds, with a median of 20 technologies found per site.**

### How it works

![How it works](https://api.apify.com/v2/key-value-stores/Kb2co1eQFSOItSEa2/records/how-it-works-v1.png)

Give the scraper a list of domains. It visits each website, reads what the page and the server reveal, resolves the domain's nameservers and other DNS records, and returns one tidy row per site listing every technology it recognized, grouped into categories. The fingerprinting runs on the live response, so the answer describes the site as it is served today.

### ✨ Why teams choose this over other website technology scrapers

Do you keep paying for a technology lookup that returns a cached snapshot from last year? Have you ever exported a lead list only to find the platform column empty for half the rows? Do you need to know not just the CMS, but who hosts the company's email and who issues its certificates?

- 🎯 **Live detection, never a stale directory.** Every result comes from reading the website at the moment of the run. Directory products such as BuiltWith serve you a record that was crawled at some point in the past. This one tells you what the site is running right now, which matters when you are timing outreach around a replatform.
- 📚 **6,633 technologies across 115 categories.** The detection library spans CMS, ecommerce, analytics, advertising and tracking pixels, JavaScript frameworks and libraries, UI frameworks, web servers, programming languages, hosting, CDN, WAF and bot management, payment processors, buy now pay later, CRM, marketing automation, live chat, A/B testing, cookie compliance, fonts, video players, search engines, reviews, and accessibility. 738 of them report a version number when the site exposes one.
- 🌐 **Email, DNS and certificate signals a page scrape cannot see.** It resolves MX records to name the email provider, NS records to name the nameserver and DNS provider, TXT and SPF records to reveal the SaaS tools a company has verified its domain with, and reads the SSL certificate to name its issuer, the certificate authority. In a 30 domain benchmark, 26 sites returned both an email provider and a DNS provider.
- ⚡ **Built for bulk technographic enrichment.** 30 domains finished in 12 seconds in our benchmark, roughly 150 domains a minute, so a 1,000 domain list clears in under ten minutes.
- 🧩 **Categories you can filter on immediately.** Every technology carries one or more category labels and each row ships a `categoriesSummary` count, so segmenting a list by "uses Shopify" or "runs a WAF" is one filter, not a text search.
- 🔓 **No account, no API key, no third party credits.** You do not need a BuiltWith subscription, a Wappalyzer account, or any key from another service. Everything happens inside the run.
- 📊 **A confidence score on every hit.** Each detection reports how strong its evidence was, from a server header match down to a weaker page signal, so you can keep only the detections you trust.
- 🛠️ **Flat, predictable output.** One record per domain with 11 top level fields, ready for a spreadsheet, a CRM import, or a warehouse table.

### 🎯 What you can do with website technology data

| Team | What they build |
| --- | --- |
| Sales | Account lists filtered to the exact ecommerce platform, payment processor, or CRM a prospect already runs, so the first line of the email names their actual stack |
| Marketing | Market share reports counting how many of 5,000 tracked domains run each analytics tool, ad pixel, or consent platform, refreshed on a schedule |
| Competitive intelligence | A live map of which technologies competitors adopt and drop, built by re-running the same domain list every month and diffing the technology names |
| Agencies | A technology audit of a prospect before the pitch, including the CMS, the page builder, the hosting provider, and whether the site sits behind a WAF |
| RevOps | A technographic column added to every account record in the CRM, so routing and scoring rules can key off the platform a company runs |
| Investors | Adoption signal across a portfolio or a target market, measured as the count of domains in a segment running a given vendor |
| Security research | An inventory of the web servers, certificate issuers, and bot management products in use across a set of domains, built by website fingerprinting rather than by asking each vendor |
| Recruiters | Company shortlists built from the frameworks and programming languages a site actually runs, instead of from job ad keywords |

### 📥 Input parameters

| Field | Type | Description |
| --- | --- | --- |
| `startDomains` | array | Required. One or more domains or website URLs to analyze, for example `shopify.com`. Full URLs are accepted and the host is extracted for you. |
| `maxItems` | integer | The maximum number of domains to analyze in this run. Default 100. |
| `debugMode` | boolean | Adds verbose logging to the run log. Off by default. |

Example input:

```json
{
  "startDomains": ["shopify.com", "stripe.com", "nike.com"],
  "maxItems": 100
}
```

### 📊 Output data

One record per domain. A retailer running a full commerce stack:

```json
{
  "domain": "walmart.com",
  "url": "https://www.walmart.com/",
  "statusCode": 200,
  "title": "Walmart | Save Money. Live better.",
  "technologyCount": 20,
  "technologies": [
    { "name": "Akamai", "categories": ["CDN"], "website": "https://www.akamai.com", "confidence": 100 },
    { "name": "Akamai Bot Manager", "categories": ["WAF", "Security"], "website": "https://www.akamai.com", "confidence": 100 },
    { "name": "HSTS", "categories": ["Security"], "website": "https://developer.mozilla.org", "confidence": 100 },
    { "name": "React", "categories": ["JavaScript frameworks"], "website": "https://react.dev", "confidence": 80 }
  ],
  "categoriesSummary": {
    "Advertising": 3, "Analytics": 1, "CDN": 2, "DNS": 1, "Email hosting": 1,
    "JavaScript frameworks": 2, "JavaScript libraries": 2, "Payment processors": 1,
    "SSL/TLS certificate authorities": 1, "Security": 3, "WAF": 2, "Web frameworks": 1
  },
  "emailProvider": "Proofpoint",
  "dnsProvider": "Akamai Edge DNS",
  "certificateIssuer": "GlobalSign",
  "scrapedAt": "2026-09-12T16:39:30Z"
}
```

A SaaS company, where the interesting signal is the search, consent and marketing layer:

```json
{
  "domain": "algolia.com",
  "url": "https://www.algolia.com/",
  "statusCode": 200,
  "title": "Algolia | AI Search That Understands",
  "technologyCount": 24,
  "technologies": [
    { "name": "Algolia", "categories": ["Search engines"], "website": "https://www.algolia.com", "confidence": 80 },
    { "name": "Cloudflare", "categories": ["CDN", "DNS"], "website": "https://www.cloudflare.com", "confidence": 100 },
    { "name": "OneTrust", "categories": ["Cookie compliance"], "website": "https://www.onetrust.com", "confidence": 60 }
  ],
  "categoriesSummary": {
    "Analytics": 3, "CDN": 2, "Cookie compliance": 1, "Customer data platform": 1,
    "DNS": 1, "Development": 4, "Email hosting": 1, "JavaScript libraries": 4,
    "Marketing automation": 1, "SEO": 1, "Search engines": 2, "Security": 2, "WAF": 1
  },
  "emailProvider": "Google Workspace",
  "dnsProvider": "Cloudflare",
  "certificateIssuer": "Google Trust Services",
  "scrapedAt": "2026-09-12T16:39:30Z"
}
```

### 🗂️ Data fields

11 top level fields per domain, plus 5 fields on every technology in the list.

**Identity and response**

| Field | Type | Description |
| --- | --- | --- |
| `domain` | string | The domain you requested, normalized |
| `url` | string | The final URL analyzed after redirects |
| `statusCode` | integer | HTTP status returned by the website |
| `title` | string | The page title of the site |
| `scrapedAt` | string | Timestamp of the analysis, ISO 8601 |

**Detected stack**

| Field | Type | Description |
| --- | --- | --- |
| `technologyCount` | integer | Number of technologies detected on this domain |
| `technologies` | array | The detected technologies |
| `technologies[].name` | string | Technology name, for example WordPress, Stripe, React |
| `technologies[].categories` | array | One or more category labels, for example `["WAF", "Security"]` |
| `technologies[].website` | string | Official website of the technology vendor |
| `technologies[].version` | string | Version number when the site exposes one |
| `technologies[].confidence` | integer | Evidence strength from 0 to 100 |
| `categoriesSummary` | object | Count of detected technologies per category |

**Infrastructure rollups**

| Field | Type | Description |
| --- | --- | --- |
| `emailProvider` | string | Email host resolved from MX records, for example Google Workspace or Microsoft 365 |
| `dnsProvider` | string | DNS provider resolved from nameserver records, for example Cloudflare or Route 53 |
| `certificateIssuer` | string | Certificate authority that signed the site's SSL certificate, for example Let's Encrypt or Sectigo |

### 🚀 Examples

**Check a single site**

```json
{ "startDomains": ["example.com"], "maxItems": 1 }
```

**Audit a list of prospects before a pitch**

```json
{ "startDomains": ["acme.com", "globex.com", "initech.com"], "maxItems": 500 }
```

**Find which of your accounts run on Shopify**

Run your account domains through, then keep the rows whose `categoriesSummary` contains `Ecommerce`, and read the technology named Shopify.

```json
{ "startDomains": ["allbirds.com", "gymshark.com", "bombas.com", "figs.com"], "maxItems": 1000 }
```

**Map the email and DNS providers across a market segment**

```json
{ "startDomains": ["hubspot.com", "zendesk.com", "slack.com", "notion.so", "figma.com"], "maxItems": 200 }
```

**Run a large technographic enrichment pass**

```json
{ "startDomains": ["domain0001.com", "domain0002.com", "domain9999.com"], "maxItems": 10000 }
```

### 🤖 Copy to your AI assistant

Paste this block into Claude, ChatGPT, or Cursor to give it full context about this scraper:

```
You have access to the Website Tech Stack Scraper on Apify: silentflow/website-tech-stack-scraper

What it does: takes a list of domains and returns the technologies each website runs,
plus the email provider, DNS provider and SSL certificate authority resolved from DNS.
It detects 6,633 technologies across 115 categories.

Input schema:
- startDomains (required, array of strings): domains or website URLs, e.g. ["shopify.com"]
- maxItems (integer, default 100, max 10000): cap on domains analyzed this run
- debugMode (boolean, default false): verbose run log

Output, one record per domain (11 top-level fields):
- domain (string), url (string), statusCode (integer), title (string), scrapedAt (string, ISO 8601)
- technologyCount (integer)
- technologies (array of objects): name (string), categories (array of strings),
  website (string), version (string, when exposed), confidence (integer 0-100)
- categoriesSummary (object): category name -> count
- emailProvider (string), dnsProvider (string), certificateIssuer (string)

Pay per result, one charge per domain analyzed. Use apify-client for Python or JS.
```

### 💻 Integrations

#### Build a lead list segmented by ecommerce platform

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("silentflow/website-tech-stack-scraper").call(run_input={
    "startDomains": ["allbirds.com", "gymshark.com", "bombas.com", "figs.com"],
    "maxItems": 1000,
})

shopify_accounts = []
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    platforms = [t["name"] for t in item["technologies"] if "Ecommerce" in t["categories"]]
    if "Shopify" in platforms:
        shopify_accounts.append((item["domain"], item["emailProvider"]))

for domain, email_host in shopify_accounts:
    print(f"{domain} runs Shopify, email on {email_host}")
```

#### Monitor a competitor set for stack changes

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });
const run = await client.actor('silentflow/website-tech-stack-scraper').call({
    startDomains: ['competitor-a.com', 'competitor-b.com', 'competitor-c.com'],
    maxItems: 100,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
const snapshot = Object.fromEntries(
    items.map((i) => [i.domain, i.technologies.map((t) => t.name).sort()]),
);

// Compare against last month's snapshot to see what each competitor adopted or dropped.
console.log(JSON.stringify(snapshot, null, 2));
```

#### Export a technographic column straight to CSV

```python
import csv
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("silentflow/website-tech-stack-scraper").call(run_input={
    "startDomains": ["shopify.com", "stripe.com", "nike.com"],
})

with open("technographics.csv", "w", newline="") as f:
    writer = csv.writer(f)
    writer.writerow(["domain", "technology_count", "email_provider", "dns_provider", "technologies"])
    for item in client.dataset(run["defaultDatasetId"]).iterate_items():
        writer.writerow([
            item["domain"], item["technologyCount"], item.get("emailProvider", ""),
            item.get("dnsProvider", ""), "; ".join(t["name"] for t in item["technologies"]),
        ])
```

### 📈 Performance

Measured on a 30 domain benchmark of large public websites.

| Metric | Value |
| --- | --- |
| Domains analyzed | 30 of 30, no failures |
| Total run time | 12 seconds |
| Throughput | About 150 domains a minute |
| 1,000 domain list | Under ten minutes |
| Technologies found per site | Median 20, mean 19.2, range 6 to 31 |
| Sites returning an email provider | 26 of 30 |
| Sites returning a DNS provider | 26 of 30 |

Domains are analyzed in parallel, so throughput holds as the list grows.

### 💾 Data export

Results land in a standard Apify dataset. Download them as JSON, CSV, Excel, XML, HTML table, or JSON Lines from the run's Storage tab, or pull them programmatically:

```
https://api.apify.com/v2/datasets/{DATASET_ID}/items?format=csv&token=YOUR_TOKEN
```

The same dataset feeds Apify integrations, so results can be pushed to Google Sheets, Airtable, Slack, a webhook, or a warehouse without an export step.

### 💡 Tips for best results

- Pass clean apex domains such as `example.com`. Full URLs work too, and a leading `www.` is stripped for you.
- De-duplicate your input list before the run. Two spellings of the same host are two results and two charges.
- Filter on `confidence` when precision matters more than recall. Detections at 100 come from response headers, cookies, or DNS records, which are the hardest signals to fake.
- Read `categoriesSummary` rather than scanning the technology list when you only need a yes or no on a category such as `Ecommerce` or `WAF`.
- A site that answers with a non-200 status can still return an infrastructure profile from its DNS records, so check `emailProvider` and `dnsProvider` before discarding a row.

### ❓ FAQ

**Which technologies can it detect?**
6,633 technologies across 115 categories, covering CMS, ecommerce platforms, payment processors, buy now pay later, analytics, advertising and tracking pixels, tag managers, JavaScript frameworks and libraries, UI frameworks, web servers, programming languages, hosting, CDN, WAF and bot management, CRM, marketing automation, live chat, A/B testing, cookie compliance, fonts, video players, search engines, reviews, and accessibility.

**Is this a BuiltWith or Wappalyzer alternative?**
Yes, and you need no account with either. The difference is where the answer comes from: a directory hands you a record crawled at some earlier date, while this reads the live site during the run.

**Do I need an API key or a subscription anywhere else?**
No. There is nothing to sign up for beyond Apify itself.

**Can it identify the ecommerce platform a store runs?**
Yes. Ecommerce platform identification is one of the strongest signal groups, covering Shopify, WooCommerce, Magento, BigCommerce, PrestaShop, Salesforce Commerce Cloud, and many more, and the result is labeled with the `Ecommerce` category.

**Does it detect the CMS?**
Yes. Used as a CMS detector it recognizes WordPress, Drupal, Joomla, Webflow, Wix, Squarespace, Contentful, and hundreds of others, with a version number when the site publishes one.

**Do you detect email and DNS providers?**
Yes. MX records name the email host, nameserver records name the DNS provider, and TXT and SPF records reveal SaaS tools that a company has verified its domain with. The SSL certificate also names the issuing certificate authority.

**What does confidence mean?**
A score from 0 to 100 describing how strong the evidence was. Matches from response headers, cookies, and DNS records score highest, page content scores lower.

**How fresh is the data?**
It reflects the website at the moment of the run. Re-running the same list on a schedule and diffing the technology names is how teams track adoption over time.

**Can I use it on a single domain?**
Yes. Pass one domain with `maxItems` set to 1 and it behaves as a website technology checker for that site.

**What happens if a site is unreachable?**
The row is still useful when DNS resolves: you get the infrastructure rollups even when the page itself did not return content. When nothing at all resolves, the domain is reported as failed in the run log and is not charged as a result.

### ⚖️ Legal

This scraper reads publicly available information that websites publish to every visitor: the public homepage, the HTTP response headers that accompany it, the TLS certificate presented by the server, and public DNS records. It collects no personal data, so GDPR, CCPA, and PIPL obligations around personal information are not triggered by the output. You remain responsible for how you use the results, including applicable terms of the sites you analyze and any marketing or outreach rules in your jurisdiction.

### 🔗 Related scrapers

- [Domain Enricher](https://apify.com/silentflow/domain-enricher) for company details resolved from a domain
- [Storeleads Scraper](https://apify.com/silentflow/storeleads-scraper-ppe) for ecommerce store lead lists
- [Trustpilot Enricher](https://apify.com/silentflow/trustpilot-enricher) for review reputation on a domain
- [French Company Prospector](https://apify.com/silentflow/french-company-prospector) for French company discovery and filtering
- [UK Companies House Enricher](https://apify.com/silentflow/uk-companies-house-enricher) for UK registry data

### 📬 Support

Want a technology added to the detection library, or unsure how to read a result? Open the Issues tab on this Actor's page and describe the domain and what you expected to see.

***

Detection is powered in part by the open-source Wappalyzer fingerprint database (via projectdiscovery/wappalyzergo, MIT licensed).

# Actor input Schema

## `startDomains` (type: `array`):

Domains or website URLs to analyze (e.g. shopify.com). URLs are accepted too, the host is extracted automatically.

## `maxItems` (type: `integer`):

The maximum number of domains to analyze in this run.

## `debugMode` (type: `boolean`):

Activate to see detailed logs.

## Actor input object example

```json
{
  "startDomains": [
    "shopify.com"
  ],
  "maxItems": 100,
  "debugMode": false
}
```

# Actor output Schema

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

One record per domain: domain, url, statusCode, title, technologyCount, technologies (name, categories, website, version, confidence), categoriesSummary, emailProvider, dnsProvider, certificateIssuer, scrapedAt.

# 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 = {
    "startDomains": [
        "shopify.com"
    ],
    "maxItems": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("silentflow/website-tech-stack-scraper").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 = {
    "startDomains": ["shopify.com"],
    "maxItems": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("silentflow/website-tech-stack-scraper").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 '{
  "startDomains": [
    "shopify.com"
  ],
  "maxItems": 100
}' |
apify call silentflow/website-tech-stack-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,silentflow/website-tech-stack-scraper"
        }
    }
}
```

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/VsEQmSNYZCRKgexdN/builds/n2YRbrY2UP1i9XHnb/openapi.json
