Website Tech Stack Scanner
Pricing
from $4.64 / 1,000 domain scanneds
Website Tech Stack Scanner
Give it a list of domains and get back what each site runs: e-commerce platform, CMS, frameworks, analytics, payments, CDN, hosting and mail stack. Every detection carries its confidence and the evidence that triggered it, because a stack claim without evidence is a guess. No API key, no login.
Pricing
from $4.64 / 1,000 domain scanneds
Rating
0.0
(0)
Developer
Lowland Data
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Feed it a list of domains (leads, clients, competitors) and get back what each site runs: e-commerce platform, CMS, frameworks, analytics, payments, CDN, hosting, mail stack. One row per domain, and every detection carries its confidence and the evidence that triggered it, because a stack claim without evidence is a guess.
Live health record: lowlanddata.com/status/website-tech-scanner - 30-day success rate and daily canary results, failures included. Full input/output reference: tool page.
Organization-level data only, by design: domains and technologies, never owners, never emails. The tools this replaces sell you the shop owners' contact details alongside the stack: this one never will, and that is the point.
Quick start (30 seconds)
- Paste your domains, one per line, bare domains or full URLs both work. The prefill runs as-is.
- Hit Start. A few seconds per domain later:
{"domain": "www.allbirds.com","finalUrl": "https://www.allbirds.com/","ecommerce": "Shopify","cms": null,"frameworks": null,"analytics": "Google Tag Manager","payments": null,"cdn": "Cloudflare","hosting": null,"mail": null,"technologies": [{ "technology": "Shopify", "confidence": 100, "evidence": ["script cdn.shopify.com/s/..."] },{ "technology": "Cloudflare", "confidence": 100, "evidence": ["header server: cloudflare"] }],"detectedCount": 8,"scannedAt": "2026-09-05T14:00:00.000Z"}
Flat columns carry the single best answer per bucket; technologies carries everything above your confidence floor, evidence included.
Who uses this
- Agencies qualify a lead list before pitching: which prospects run WooCommerce (your specialty), which sit on a platform worth a migration pitch, which already carry a competitor's tag.
- Freelancers and MSPs audit a new client's site in one run instead of view-source archaeology: stack, analytics, CDN, mail provider, one row.
- SaaS teams check whether trial signups actually installed the snippet, and what the rest of their stack looks like.
- Market researchers answer questions like "what do Belgian webshops actually run" from their own domain lists.
What it detects
About 5,400 technologies across e-commerce platforms, CMSs, JavaScript and web frameworks, analytics, payment processors, CDNs, hosting, mail providers, security layers and advertising tags.
That number deserves the arithmetic behind it. The fingerprint corpus lists 7,722 technologies; this actor reads a page over HTTP and never runs a browser, so it can only evaluate the fingerprints expressed as headers, cookies, meta tags, script sources, HTML patterns, URLs and DNS records, 5,390 of them. The remaining 2,332 are defined by JavaScript variables or DOM state that only exist once a page has executed, and no HTTP-only scanner can see them. Anyone quoting the full 7,600 for a fetch-based detector is quoting a catalogue, not a capability.
Mail detection is MX-based: a verification TXT record never claims the mail column, because proving a vendor relationship is not the same as hosting the mailbox.
Fingerprints: the corpus is enthec/webappanalyzer, the community continuation of Wappalyzer's, redistributed verbatim under GPL-3.0 and loaded as data at runtime. It is re-vendored by hand rather than tracked live, so the version stamp in the run log tells you how current it is.
How much does it cost?
$4.99 per 1,000 domains scanned, pay-as-you-go: a 500-domain list is about $2.50, once, against the $295 a month the incumbent tools charge for the same question. A domain that cannot be fetched is reported as a failure and never billed as a result.
Not technical? Let your AI assistant set it up
Paste this to Claude, ChatGPT or Cursor with your list:
I want to know what technology a list of websites runs, using the Apify actorlowlanddata/website-tech-scanner. Build me the input JSON.Fields:- domains: array of domains or URLs (required, up to 10,000)- includeDns: boolean, adds mail-stack detection via MX/TXT (default true)- minConfidence: 0-100, drop weaker detections (default 50)- maxItems: cap on scanned domains (default 1000)Here is my list: <paste domains>Give me the JSON only, then tell me how to run it and export the resultsto a spreadsheet.
Input
| Field | Type | Default | Notes |
|---|---|---|---|
domains | string[] | - | Bare domains or URLs; normalized to hostnames. |
includeDns | boolean | true | MX/TXT lookups for the mail stack. |
minConfidence | integer | 50 | Confidence floor; kept detections always carry evidence. |
maxItems | integer | 1000 | Upper bound on scanned domains. |
expectations | object | - | Accuracy-canary mode: fail the run if a domain misses an expected technology. For scheduled QA, not everyday scans. |
Use it from your code
curl -X POST \"https://api.apify.com/v2/acts/lowlanddata~website-tech-scanner/run-sync-get-dataset-items?token=$APIFY_TOKEN" \-H 'Content-Type: application/json' \-d '{"domains":["wordpress.org","www.allbirds.com"]}'
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('lowlanddata/website-tech-scanner').call({domains: ['client-a.be', 'client-b.nl', 'prospect.de'],});const { items } = await client.dataset(run.defaultDatasetId).listItems();
from apify_client import ApifyClientclient = ApifyClient(token=os.environ["APIFY_TOKEN"])run = client.actor("lowlanddata/website-tech-scanner").call(run_input={"domains": open("domains.txt").read().split(),"minConfidence": 60,})for row in client.dataset(run["defaultDatasetId"]).iterate_items():print(row["domain"], row["ecommerce"], row["cms"], row["cdn"])
A few hundred domains fit inside the 300-second synchronous wall; larger lists run asynchronously.
Use it with AI agents (MCP)
$claude mcp add apify --transport http "https://mcp.apify.com?actors=lowlanddata/website-tech-scanner"
Cursor or Claude Desktop: add a custom connector with https://mcp.apify.com?actors=lowlanddata/website-tech-scanner. Sign in with your Apify account when prompted. Runs are billed to it. Details: Apify MCP docs.
Prompts that work once connected:
- "What do these ten websites run? Flag anything on Magento."
- "Which of my prospect list is on Shopify with Klarna enabled?"
- "Check what stack my competitor's site uses and summarize it."
Is this legal?
Yes. The scanner performs one polite homepage request per domain (the same request any visitor's browser makes) plus public DNS lookups, and reads what the site itself announces: headers, script URLs, meta tags. Nothing is bypassed, nothing logged in, nothing probed beyond the front door. And the output contains no personal data at all: no names, no emails, no phone numbers: technology facts about organizations' websites.
Honest limits
- Headless setups undercount. A Shopify store rendered through a custom Next.js frontend can read as Next.js only: the homepage does not always betray the commerce engine behind it. Detections are labeled with what the page actually shows.
- Detection is probabilistic. That is why every detection ships with confidence and evidence, and why
minConfidenceexists. An empty column means "not detectable from the front door", not "definitely absent". - A blocked or unreachable domain is reported as a per-domain failure (uncharged), not silently skipped.
Related actors
- Tech Change Monitor, the alerting sibling: remembers each domain's stack and reports only changes. Watching beats re-scanning.
Troubleshooting
- "Accuracy check failed: ...": you set
expectationsand a domain missed one; this mode exists for scheduled QA and fails loudly by design. - A technology you can see is missing: check
minConfidence; weak-evidence detections sit below 50 by default. Still missing at 0? Open an issue with the domain: fingerprint gaps are fixable and reports are read daily. - Fewer rows than domains: unreachable domains are reported in the run's summary as failures, never billed as results.