BuiltWith Domain Tech Stack Scraper

Detect website technologies from domain lists for sales, SEO, martech, and competitive-intelligence workflows. Export categorized tech stack rows.

Data fields

FieldTypeDescription
domainstringOriginal domain or URL supplied by the user.
normalizedDomainstringLowercase hostname used to group results.
sourceUrlstringInitial homepage URL requested by the Actor.
finalUrlstringFinal public URL after validated redirects.
statusCodeintegerHTTP response status of the analyzed page.
redirectCountintegerNumber of followed redirects.
pageTitlestring | nullHTML title of the analyzed page.
technologyNamestring | nullDetected technology, or null on an uncharged status row.

Input preview

domainsDomains or URLs *
maxDomainsMaximum domains
includeCategoriesInclude only categories
maxRunSecondsMaximum processing time
resumeFromCheckpointResume unfinished work
proxyConfigurationProxy configuration

API and agents

This actor can be run through Apify API, datasets, webhooks, schedules, and the official Apify MCP server.

Ready-to-run examples

Open a saved Apify example, adjust the input, and run the actor in your own Apify account.

View all examples

How this actor works

See example inputs, outputs, API usage, and practical limits before running this actor on Apify.

Open Apify page

Detect technologies exposed by public websites from a list of domains or URLs. The Actor inspects the homepage response once and combines headers, cookie names, metadata, script sources, stylesheet links, and HTML markers into one row per detected technology.

Use it for lead enrichment, migration research, martech audits, SEO reviews, and competitor monitoring. It is an independent detector: it does not scrape or query a third-party technology database.

What does Website Technology Stack Detector do?

  • 60+ curated detections across CMS, ecommerce, analytics, advertising, marketing, support, payments, frameworks, hosting, CDN, web servers, and consent tools
  • deterministic confidence, safe evidence labels, and versions when a public signal exposes one
  • validated redirects, bounded retries, anti-bot challenge detection, and private-network protection
  • resumable progress for larger lists, with completed in-flight domains recovered from the dataset to prevent duplicate item charges
  • one dataset row per technology, plus free status rows for no-match and request-error outcomes

Who is it for?

  • sales and growth teams enriching lead lists with visible platform signals
  • agencies comparing client and competitor website stacks
  • developers routing domains by framework, hosting, or infrastructure
  • ecommerce and martech teams auditing storefront, payment, analytics, and support tools

Input settings

Field Description
domains Required public domains or HTTP(S) URLs. Bare domains try HTTPS first.
maxDomains Safety cap after duplicate targets are removed; default 3.
includeCategories Optional multiselect category filter.
maxRunSeconds Processing budget from 45 to 300 seconds; default 300.
resumeFromCheckpoint Resume matching work from the same default key-value store; default true.
proxyConfiguration Optional proxy settings; direct connections are the default.

Example input

{
  "domains": ["wordpress.org", "shopify.com", "vercel.com"],
  "maxDomains": 3,
  "includeCategories": ["CMS", "Ecommerce", "Hosting"]
}

Credentials, custom ports, IP literals, single-label/local hosts, and redirects to private or reserved networks are rejected.

Example output

{
  "domain": "wordpress.org",
  "normalizedDomain": "wordpress.org",
  "sourceUrl": "https://wordpress.org/",
  "finalUrl": "https://wordpress.org/",
  "statusCode": 200,
  "redirectCount": 0,
  "pageTitle": "Blog Tool, Publishing Platform, and CMS – WordPress.org",
  "technologyName": "WordPress",
  "category": "CMS",
  "subcategory": "Content management system",
  "description": "Open-source content management system.",
  "vendorUrl": "https://wordpress.org/",
  "confidence": 96,
  "version": null,
  "evidenceType": "link",
  "evidenceDetail": "WordPress asset path",
  "sourceSection": "link: WordPress asset path",
  "firstDetected": null,
  "lastDetected": null,
  "scrapedAt": "2026-07-20T12:00:00.000Z"
}

confidence is the strength assigned to the matched rule, not a statistical probability. firstDetected and lastDetected remain nullable compatibility fields because a live passive scan has no historical database. Raw cookies, headers, page snippets, IDs, and keys are never copied into evidence fields.

How detection works

The Actor downloads the public page HTML without executing JavaScript. It evaluates several passive signal families and keeps the strongest deterministic match for each technology. Framework relationships can add an implied row—for example, a strong Next.js signal can imply React—unless a stronger direct React signal already exists.

This bounded approach is faster and less failure-prone than launching a browser for every domain. It also means technologies loaded only after interaction, consent, client-side network calls, login, or bot checks may not be visible. GraphQL is detected when an Apollo Client signal is present; the Actor does not probe arbitrary /graphql endpoints because unrelated websites do not share a safe, stable GraphQL contract.

API usage

Node.js

import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('fetch_cat/builtwith-domain-tech-stack-scraper').call({
  domains: ['wordpress.org', 'shopify.com'],
  maxDomains: 2,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

Python

from apify_client import ApifyClient
import os

client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('fetch_cat/builtwith-domain-tech-stack-scraper').call(run_input={
    'domains': ['wordpress.org', 'shopify.com'],
    'maxDomains': 2,
})
print(client.dataset(run['defaultDatasetId']).list_items().items)

cURL

curl "https://api.apify.com/v2/acts/fetch_cat~builtwith-domain-tech-stack-scraper/runs?token=$APIFY_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"domains":["wordpress.org","shopify.com"],"maxDomains":2}'

MCP and automation

Use the Actor through Apify MCP at:

https://mcp.apify.com/?tools=fetch_cat/builtwith-domain-tech-stack-scraper

Claude Code setup:

claude mcp add apify-tech-detector "https://mcp.apify.com/?tools=fetch_cat/builtwith-domain-tech-stack-scraper"

Claude Desktop or another compatible client can use:

{
  "mcpServers": {
    "apify-tech-detector": {
      "url": "https://mcp.apify.com/?tools=fetch_cat/builtwith-domain-tech-stack-scraper"
    }
  }
}

Example agent prompts:

  • “Detect ecommerce and payment technologies for these domains.”
  • “Compare the CMS and hosting stack across this competitor list.”
  • “Return domains where HubSpot, Klaviyo, or Intercom is visible.”

For recurring monitoring, save the input as an Apify Task and schedule it. A task that needs to continue a checkpoint must reuse the same default key-value store.

Support

If a public website produces an unexpected result, open an Actor issue and include the Apify run ID or run URL, the input JSON, expected output, actual output, and one reproducible public URL. Remove tokens, credentials, customer data, and private URLs before posting.

Responsible use

Use the Actor only on public websites and comply with applicable terms, laws, and outreach rules. Keep request volume reasonable. Technology signals can be incomplete or stale, so validate consequential decisions with the website owner or another authorized source.

Common questions

Questions and answers reused from the canonical actor README.

Why did I get No technologies detected?

The page was reachable, but none of the configured signatures matched the public response. The website may still use server-side or dynamically loaded tools.

Why did I get a request-error row?

DNS, transport, HTTP, content-type, response-size, redirect safety, or anti-bot validation prevented analysis. A proxy may help with access blocks, but it cannot reveal technology hidden behind login or client interaction.

Why is a version null?

Versions are returned only when the matched response itself exposes a short, validated version string. The Actor does not download JavaScript bundles solely to infer versions.

Can it scan internal sites?

No. This public-web Actor intentionally blocks local, private, reserved, credentialed, IP-literal, and custom-port targets.