# Tech Stack Detector - Wappalyzer & BuiltWith Alternative (`benthepythondev/tech-stack-detector`) Actor

Returns each website's email provider (Google Workspace, Microsoft 365, Zoho) and the SaaS tools connected to its domain, read from DNS MX, SPF and TXT records, plus its CMS, frameworks, analytics, payments and CDN. Bulk URL lists, plain HTTP, no browser, no API key. JSON, CSV or API.

- **URL**: https://apify.com/benthepythondev/tech-stack-detector.md
- **Developed by:** [Ben](https://apify.com/benthepythondev) (community)
- **Categories:** Lead generation, Developer tools, Other
- **Features:** Limited permissions
- **Stats:** 122 total users, 15 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 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

## 🔎 Tech Stack and Email Provider Detector for Any Website

Find out which **email provider** a company uses (Google Workspace, Microsoft 365, Zoho) and
which **SaaS tools it has connected to its domain** (Atlassian, DocuSign, OpenAI, Canva, Slack
and more), read from the domain's DNS MX, SPF and TXT records. The same row also lists the
site's **CMS, frameworks, analytics, payment provider and CDN**, found from the page's headers,
HTML, scripts and cookies. A page alone never shows the email and SaaS layer, which is what
sales teams use to qualify a lead.

Feed it a list of domains and get one structured record per site, for lead qualification,
prospect research and competitor tracking. It is plain HTTP analysis without a headless
browser, so long lists run fast, and every technology says which signal found it (`detectedBy`).
Export to JSON/CSV/Excel, run on a schedule, call via API, or connect to Make, Zapier or n8n.

### 💵 Pricing

You pay per website row: $0.0025 on the Free plan, less on paid Apify plans, plus a start fee of
$0.00005 per run. From November 12, 2026 a row costs $0.002875 on the Free plan, with the same
plan discounts; the start fee stays. A site that cannot be reached costs nothing: it gets no
dataset row and is listed with its `error` and `error_type` in the run's key-value store record
`FAILED_SITES`.

### 🧩 What is the Website Tech Stack Detector?

It turns any list of website URLs into a structured technology report. For each site
it fetches the page over HTTP, inspects the response headers, HTML, scripts, stylesheets
and meta tags, and matches them against 100+ technology signatures across 15+ categories.
You get a deduplicated list of detected technologies — each with a category and a
confidence rating — so sales, marketing and research teams can profile prospects and
competitors in bulk without manually viewing source on every page.

#### What data does it extract?

- **Email provider and senders** from MX and SPF records (Google Workspace, Microsoft 365, Zoho, SendGrid, Mailgun, Amazon SES, HubSpot...) under the category `Email`
- **SaaS tools that verified the domain** from TXT tokens (Atlassian, Stripe, Facebook, Apple, Slack, Zoom, OpenAI, Canva, DocuSign...) under the category `SaaS verification`
- **Detected technologies** — name, category, `confidence` (high/medium) and `detectedBy` (`header`, `cookie`, `html`, `script`, `meta` or `dns`) for each
- **Technology count** and a **categories summary** (techs grouped by category)
- **Server** and **X-Powered-By** headers, plus the **meta generator** tag
- **Page title** and **meta description**
- **SSL flag**, **HTTP status code** and any **redirect URL**
- **Version numbers** for common frameworks (WordPress, jQuery, Bootstrap, React, Vue, Angular) where exposed
- **Per-site timing** (`analysis_time_ms`); sites that cannot be reached are free and left out of the results

Across CMS & site builders (WordPress, Shopify, Wix, Squarespace, Webflow, Drupal, Ghost,
Contentful, Strapi), frontend frameworks (React, Next.js, Vue, Nuxt, Angular, Svelte,
Gatsby, jQuery), CSS frameworks, web servers & backends (Nginx, Apache, PHP, Express,
ASP.NET, Rails, Django, Laravel), CDN & hosting (Cloudflare, Vercel, Netlify, Heroku,
AWS, GCP, Azure, Fastly), analytics (Google Analytics, GTM, Hotjar, Mixpanel, Segment,
Amplitude, Plausible, Matomo), marketing & CRM (HubSpot, Mailchimp, Klaviyo, Salesforce,
Marketo), customer support (Intercom, Zendesk, Drift, Crisp, Tawk.to), e-commerce
(WooCommerce, Magento, BigCommerce, PrestaShop), payments (Stripe, PayPal, Braintree,
Square), security (reCAPTCHA, hCaptcha, Turnstile) and fonts.

### ⬇️ Input

Pass a list of URLs (with or without `https://`), an optional cap and the DNS switch:

| Field | Description |
|-------|-------------|
| `urls` | List of website URLs to analyze — `https://` is optional (e.g. `airbnb.com`) |
| `maxUrls` | Maximum number of URLs to process (`0` = unlimited) |
| `includeDns` | Also read each domain's MX and TXT records to find the email provider, email senders and SaaS tools (default `true`; adds one DNS lookup per site, run in parallel with the page fetch) |

#### Example input

```json
{
  "urls": [
    "https://stripe.com",
    "https://vercel.com",
    "shopify.com",
    "notion.so"
  ],
  "maxUrls": 0,
  "includeDns": true
}
```

#### Example: which email provider does a prospect use?

Input, one domain (the page fetch is optional, the answer comes from DNS):

```json
{ "urls": ["stripe.com"], "includeDns": true }
```

Output, the `Email` entry of the row (stripe.com's MX records point to `aspmx.l.google.com`):

```json
"categories": { "Email": ["Google Workspace"] }
```

### ⬆️ Output

Each analyzed site is one clean record (view as a **table**, or export **JSON / CSV / Excel**).
The sample is a real stripe.com row, shortened to five of its 16 technologies:

```json
{
  "url": "https://stripe.com",
  "domain": "stripe.com",
  "success": true,
  "technologies": [
    { "name": "Next.js", "category": "Frontend Framework", "confidence": "high", "version": null, "detectedBy": "html" },
    { "name": "Nginx", "category": "Web Server", "confidence": "high", "version": null, "detectedBy": "header" },
    { "name": "Intercom", "category": "Customer Support", "confidence": "high", "version": null, "detectedBy": "script" },
    { "name": "Google Workspace", "category": "Email", "confidence": "high", "version": null, "detectedBy": "dns" },
    { "name": "Atlassian", "category": "SaaS verification", "confidence": "high", "version": null, "detectedBy": "dns" }
  ],
  "technology_count": 16,
  "categories": {
    "Frontend Framework": ["React", "Next.js"],
    "Web Server": ["Nginx"],
    "Customer Support": ["Intercom"],
    "Payment": ["Stripe", "PayPal"],
    "Email": ["Google Workspace"],
    "SaaS verification": ["Google Search Console", "Microsoft 365", "Atlassian", "Facebook", "Apple", "DocuSign", "OpenAI", "Canva"]
  },
  "server": "nginx",
  "powered_by": null,
  "meta_generator": null,
  "title": "Stripe | Financial Infrastructure to Grow Your Revenue",
  "description": "Stripe is a financial services platform that helps all types of businesses accept payments...",
  "status_code": 200,
  "redirect_url": "https://stripe.com/en-de",
  "ssl": true,
  "error": null,
  "error_type": null,
  "analyzed_at": "2026-10-25T11:51:50.325363",
  "analysis_time_ms": 494
}
```

### 💡 Use cases

- **🎯 Sales intelligence — technographic targeting:** find companies running Shopify, HubSpot, Salesforce or any specific tool and tailor your outreach.
- **🥊 Competitive analysis:** see exactly which CMS, frameworks, analytics and payment stack your competitors run.
- **📊 Market research:** measure technology adoption across hundreds or thousands of domains to spot trends.
- **🛡️ Security & audit:** flag outdated frameworks, exposed server headers and missing protections across your own properties.

### ❓ FAQ

**How do I detect what technology a website uses?** Paste one or more URLs into `urls`
and run. For each site you get a categorized list of detected technologies (CMS,
frameworks, analytics, payments and more), each with a confidence rating.

**Which technologies can it detect?** 100+ across 15+ categories — CMS and site builders,
frontend and backend frameworks, CSS frameworks, web servers, CDN and hosting, analytics,
marketing and CRM, customer support chat, e-commerce, payment processors, security and fonts,
plus email providers, email senders and SaaS tools found in DNS.

**How does DNS detection work?** With `includeDns` on (the default) it reads the domain's
MX records (who hosts the mailboxes), its SPF record (which services may send email for
the domain) and its TXT verification tokens (which SaaS tools the company proved it owns
the domain to). These finds carry `detectedBy: "dns"` and the categories `Email` or
`SaaS verification`. They show tools a page never loads, such as Google Workspace, Microsoft
365, Atlassian or Slack. Set `includeDns` to `false` for page detection only.

**Does it use a real browser?** No. It uses fast HTTP analysis of headers, HTML, scripts,
stylesheets and meta tags — so it's quick, cheap to run at scale and avoids the blocking
issues headless browsers hit.

**Can it find websites using a specific tool (e.g. Shopify or HubSpot)?** Yes — run your
list of domains, then filter the output by technology name or category to keep only the
sites using the tool you care about.

**How accurate is the detection?** Each technology carries a `confidence` of high or medium
based on how it was matched. Strong signatures (unique scripts, headers, CDN hosts) score high.

**Do I need an API key or login?** No. It reads publicly accessible pages — just supply
the URLs.

**Can it detect version numbers?** For common frameworks (WordPress, jQuery, Bootstrap,
React, Vue, Angular) it extracts a version when the page exposes one; otherwise `version`
is `null`.

**Why didn't it detect a technology I know is there?** Some tools load only after
JavaScript executes, or are proxied behind a CDN, so they leave no HTTP-level signature.
Single-page apps may also hide indicators behind client-side rendering.

**How many URLs can I analyze at once?** As many as you like — set `maxUrls` to cap a run,
or leave it at `0` for unlimited batch processing.

**Can I run it on a schedule or via API?** Yes — schedule recurring runs in Apify, call it
via the API/SDK, or connect it to Make, Zapier or n8n.

**Is using this legal?** It only reads publicly available page data. Use it responsibly for
research, sales and audits, and follow applicable laws and each site's terms.

### Workflow: German employers from Arbeitsagentur to tech stack and email provider

**Auf Deutsch:** Arbeitgeber aus der Jobbörse der Bundesagentur für Arbeit finden, ihre Domains hier prüfen und nach CMS oder E-Mail-Anbieter filtern. Nutzen Sie die Kontaktdaten nur im Rahmen von DSGVO und UWG.

You can build a small lead list from public job posts. The [Arbeitsagentur Jobs Scraper](https://apify.com/benthepythondev/arbeitsagentur-jobs-scraper) returns employers with their public contact emails; this Actor then tells you what each one runs.

1. Run the Arbeitsagentur Actor with a keyword and a city, for example `"keywords": ["Elektriker"]`, `"locations": ["Leipzig"]`, `"maxResultsPerSearch": 25`.
2. Take the domain after the `@` in `contact_emails`. Skip gmail.com, web.de and other free mail domains.
3. Paste the domains into `urls` here and set `maxUrls` to `0`. The default is 1, so a longer list is cut to one site.
4. Filter by `categories.CMS` or `categories.Email`. The email provider is read from DNS (MX, SPF), so it works even when the page shows nothing.

Real sample, one run on October 31, 2026 (Elektriker, Leipzig, first 3 employers with a company email domain):

| Employer | Domain | Email provider | CMS |
|---|---|---|---|
| TZO Leipzig GmbH | tzoleipzig.de | Microsoft 365 | WordPress |
| ABT Pumpentechnik GmbH | abt-pumpentechnik.de | none found | WordPress |
| ZEKA Elektrobau GmbH | zeka.de | none found | none found |

"None found" means no signature was detected. It does not prove the company has no website or email.

**Responsible use.** Arbeitsagentur contact data is published for job applications. Check GDPR and the German unfair competition law (UWG) before you send unsolicited email, avoid personal mailboxes of sole traders, and verify details on the canonical arbeitsagentur.de page.

### 🔗 You might also like

- **[Favicon Extractor](https://apify.com/benthepythondev/favicon-extractor)** — favicon, Apple touch and brand icon URLs for the same websites
- **[Website Status Checker](https://apify.com/benthepythondev/website-status-checker)** — HTTP status, redirects and response time per URL
- **[Website Tech Detector](https://apify.com/benthepythondev/website-tech-detector)** — alternative website technology detection
- **[Shopify Store Scraper](https://apify.com/benthepythondev/shopify-store-scraper)** — products & data from Shopify stores
- **[Arbeitsagentur Jobs Scraper](https://apify.com/benthepythondev/arbeitsagentur-jobs-scraper)** — German employers and public contact emails, the domain list for this Actor
- **[Domain Intelligence Scraper](https://apify.com/benthepythondev/domain-intelligence-scraper)** — domain & WHOIS intelligence

***

**Keywords:** tech stack detector, email provider lookup, website technology checker, technographics, detect CMS, find Shopify stores, sales intelligence, competitor tech stack, framework detection, website analyzer, lead generation, technology lookup, what tech does a website use, web technology scraper, DNS TXT record lookup, SPF record checker, SaaS tools detection.

# Actor input Schema

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

List of website URLs to analyze. Can include or omit https://

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

Maximum number of URLs to analyze (0 = unlimited)

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

Also read each domain's MX and TXT records (SPF and domain verification tokens) to find the email provider (Google Workspace, Microsoft 365, Zoho...), email senders (SendGrid, Mailgun, HubSpot...) and SaaS tools that verified the domain (Atlassian, Stripe, Facebook, Apple...). Adds about one DNS round trip per site, run in parallel with the page fetch.

## Actor input object example

```json
{
  "urls": [
    "https://google.com",
    "https://facebook.com",
    "airbnb.com",
    "notion.so"
  ],
  "maxUrls": 1,
  "includeDns": true
}
```

# Actor output Schema

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

One row per website. Each entry in technologies has name, category, confidence, version and detectedBy: the signal that found it (header, cookie, html, script, meta or dns). DNS finds come from MX and TXT records under the categories Email and SaaS verification.

## `failedSites` (type: `string`):

Free, not in the dataset: each unreachable site with its error and error_type. Present only when at least one site failed.

# 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": [
        "https://stripe.com",
        "https://vercel.com",
        "https://shopify.com"
    ],
    "maxUrls": 1
};

// Run the Actor and wait for it to finish
const run = await client.actor("benthepythondev/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 = {
    "urls": [
        "https://stripe.com",
        "https://vercel.com",
        "https://shopify.com",
    ],
    "maxUrls": 1,
}

# Run the Actor and wait for it to finish
run = client.actor("benthepythondev/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 '{
  "urls": [
    "https://stripe.com",
    "https://vercel.com",
    "https://shopify.com"
  ],
  "maxUrls": 1
}' |
apify call benthepythondev/tech-stack-detector --silent --output-dataset

```

## MCP server setup

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