# Tech Stack Detector: Website + DNS (BuiltWith Alternative) (`mr_raisin/tech-stack-detector`) Actor

Find the technologies behind any list of websites: CMS, ecommerce, analytics, ads, chat, CDN, hosting, plus email provider and SaaS tools from public DNS records. Evidence for every detection. $2 per 1,000 sites.

- **URL**: https://apify.com/mr\_raisin/tech-stack-detector.md
- **Developed by:** [Monsieur Raisin](https://apify.com/mr_raisin) (community)
- **Categories:** Lead generation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 site analyzeds

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

## Tech Stack Detector — Website + DNS

Find out what any list of websites is built with — **CMS, ecommerce platform, JavaScript framework, analytics, ad pixels,
marketing automation, live chat, consent banner, payments, CDN, hosting, web server** — and, from public DNS records,
**which email provider, email-sending tools and SaaS products the company uses** (Google Workspace, Microsoft 365, Mailchimp,
SendGrid, HubSpot, Salesforce, Atlassian, Zoom, Stripe…).

A pay-as-you-go alternative to BuiltWith and Wappalyzer lookups: **$2 per 1,000 websites**, with the evidence for every detection.

### Why this one

- **Website + DNS.** DNS signals (MX, SPF includes, domain-verification records, name servers) reveal back-office tools that never
  appear in the page, and they still work when a site blocks bots.
- **Evidence for each detection** — the header, cookie name, meta tag, HTML snippet or DNS record that matched — so you can trust
  (or filter) the result.
- **Polite and lightweight.** One request per site (the page you give, usually the home page), no crawling, a clear User-Agent,
  and **robots.txt is respected** by default. No browser, so runs are fast and cheap.
- **Fair billing.** Invalid inputs and unreachable sites with no DNS signal are not charged.

### Use cases

- Lead qualification: find Shopify stores using Klaviyo, WordPress sites without a consent banner, companies on Microsoft 365…
- Competitor and market research: which analytics, ad networks and chat tools your market uses.
- Sales and agency prospecting: enrich a list of domains before outreach.
- IT and security reviews of your own portfolio of sites (web server versions, HSTS, CDN).

### Input

| Field | Description |
|---|---|
| `urls` | Domains or URLs, e.g. `shopify.com`, `https://www.example.com/`. Required. |
| `includeDns` | Analyze public DNS records (default `true`). |
| `respectRobotsTxt` | Skip pages disallowed by robots.txt; DNS is still analyzed (default `true`). |
| `includeEvidence` | Explain each detection (default `true`). |
| `timeoutSecs` | Timeout per site, 5–60 s (default 20). |
| `maxSites` | Stop after N sites (0 = no limit). |

```json
{ "urls": ["shopify.com", "wordpress.org", "vercel.com"] }
```

### Output

One item per website:

```json
{
  "input": "wordpress.org",
  "url": "https://wordpress.org/",
  "finalUrl": "https://wordpress.org/",
  "domain": "wordpress.org",
  "status": "ok",
  "httpStatus": 200,
  "error": null,
  "title": "Blog Tool, Publishing Platform, and CMS – WordPress.org",
  "language": "en",
  "technologies": [
    { "name": "WordPress", "category": "CMS", "version": "7.2", "evidence": ["meta generator: WordPress 7.2", "html: /wp-content/"] },
    { "name": "Nginx", "category": "Web server", "version": null, "evidence": ["header server: nginx"] },
    { "name": "Google Search Console", "category": "Business tools", "version": null, "evidence": ["dns TXT google-site-verification"] }
  ],
  "categories": { "CMS": ["WordPress"], "Web server": ["Nginx"], "Business tools": ["Google Search Console"] },
  "techNames": ["WordPress", "Nginx", "Google Search Console"],
  "techCount": 3,
  "dns": { "mx": ["..."], "nameservers": ["..."], "spfIncludes": ["..."] },
  "checkedAt": "2026-09-28T12:40:51.000Z"
}
```

`status` is one of: `ok`, `http-error` (the site answered with 4xx/5xx; headers are still analyzed), `robots-disallowed`
(page not fetched, DNS analyzed), `fetch-failed` (site unreachable), `invalid` (not a public domain or URL).

Domain-verification tokens are never copied into the output: only the name of the service is reported.

### Pricing

Pay per event: **$0.002 per website analyzed** ($2 per 1,000) + $0.005 per run start.
A website is charged when its page was fetched (even with an HTTP error) or at least one technology was found.
Set a maximum cost per run in the run options: the Actor stops before exceeding it.

### Detected technologies

About 260 fingerprints written for this Actor across: CMS and site builders (WordPress, Drupal, Webflow, Wix, Squarespace,
Framer…), ecommerce (Shopify, WooCommerce, Magento, BigCommerce, PrestaShop, Salesforce Commerce Cloud…), JavaScript frameworks
(Next.js, Nuxt, Gatsby, Astro, Angular, React, Vue…), analytics and tag managers, ad pixels (Meta, Google Ads, LinkedIn, TikTok…),
marketing automation, live chat and support, consent management, payments, video, reviews, security and bot protection,
CDN and hosting, web servers and back-end frameworks; from DNS: email hosting, email security, email delivery, SaaS domain
verifications and DNS providers.

### Limits

- Only the page you give is analyzed (no crawling); technologies loaded only on other pages or injected after JavaScript runs
  may be missed. Tag-manager containers hide the tools they load.
- Some sites block automated requests; DNS results are still returned.
- DNS-verification records show that a company *set up* a tool at some point, not that it still pays for it.
- Detections are heuristics: check the evidence field when it matters.

### Responsible use

The Actor only reads what any browser or DNS resolver can see, respects robots.txt and extracts no personal data.
You are responsible for how you use the results (e.g. anti-spam rules when prospecting).

# Actor input Schema

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

Domains or URLs to analyze, one per line (e.g. shopify.com, https://www.example.com/). Only the given page is fetched (usually the home page), no crawling.

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

Read MX, TXT (SPF and domain-verification prefixes) and NS records to detect the email provider, email-sending tools, SaaS tools and DNS host. Works even when the website blocks bots.

## `respectRobotsTxt` (type: `boolean`):

Skip fetching a page that the site's robots.txt disallows (DNS is still analyzed). Recommended.

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

For each technology, show why it was detected (header, cookie name, meta tag, HTML snippet or DNS record).

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

Maximum time to wait for each page.

## `maxSites` (type: `integer`):

Stop after this many sites. 0 = no limit (your run cost limit still applies).

## Actor input object example

```json
{
  "urls": [
    "shopify.com",
    "wordpress.org",
    "vercel.com"
  ],
  "includeDns": true,
  "respectRobotsTxt": true,
  "includeEvidence": true,
  "timeoutSecs": 20,
  "maxSites": 0
}
```

# Actor output Schema

## `sites` (type: `string`):

One item per website with its detected technologies, categories and evidence.

# 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",
        "vercel.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("mr_raisin/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": [
        "shopify.com",
        "wordpress.org",
        "vercel.com",
    ] }

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

```

## MCP server setup

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