Website Tech Stack Detector (Wappalyzer API Scraper)
Pricing
from $0.63 / 1,000 output rows
Website Tech Stack Detector (Wappalyzer API Scraper)
Find out what technologies any website runs — JavaScript frameworks, CMS, CDNs, analytics, e-commerce platforms, web servers and more — via the Wappalyzer API. Feed it URLs or domains and get flat, CSV-ready rows, one per detected technology, with category and traffic rank. No API key needed.
Pricing
from $0.63 / 1,000 output rows
Rating
0.0
(0)
Developer
R.L.
Maintained by CommunityActor stats
1
Bookmarked
69
Total users
18
Monthly active users
5 hours ago
Last modified
Categories
Share
Website Tech Stack Detector – Wappalyzer Technology Lookup
Find out what technologies a website uses. This Actor detects the tech stack behind any website — JavaScript frameworks, CMSs, CDNs, analytics tools, e-commerce platforms, web servers, and hundreds of other categories. Give it a list of URLs or domains and it returns the technologies each site runs, powered by the Wappalyzer API.
Run it on the Apify platform to get scheduling, a REST API, webhooks, and integrations with Make, Zapier, Google Sheets, and more — no infrastructure to manage.
What does this website tech stack detector do?
For every URL or domain you provide, the Actor queries the Wappalyzer lookup API and stores the detected technologies, including each technology's name, category, version (when known), traffic rank, and icon. It's the fastest way to check what software a website is built with — in bulk, across a whole list of domains, and exportable to CSV, JSON, or Excel. No Wappalyzer API key of your own is required.
Why detect a website's technology stack?
- Lead generation & sales intelligence — find sites running a specific platform (e.g. Shopify, HubSpot) to target prospects.
- Competitive analysis — see what frameworks and tools competitors rely on.
- Market research — measure technology adoption across a list of domains.
- Security & compliance — inventory the software exposed by your own web properties.
What technologies can it detect?
Wappalyzer fingerprints well over a thousand technologies. The categories that come up most often:
| Category | Examples |
|---|---|
| CMS | WordPress, Drupal, Joomla, Ghost, Contentful, Webflow |
| E-commerce | Shopify, WooCommerce, Magento, BigCommerce, PrestaShop |
| JavaScript frameworks | React, Vue.js, Angular, Next.js, Svelte, Nuxt |
| Analytics | Google Analytics, Matomo, Mixpanel, Hotjar, Plausible |
| CDN & hosting | Cloudflare, Akamai, Fastly, AWS, Vercel, Netlify |
| Marketing & CRM | HubSpot, Salesforce, Marketo, Klaviyo, Intercom |
| Payments | Stripe, PayPal, Adyen, Klarna, Shopify Payments |
| Web servers | Nginx, Apache, LiteSpeed, IIS |
Each detected technology becomes its own row, tagged with its category, so you can filter a whole list of domains down to just the ones running a particular platform.
How to detect what technology a website uses
- Open the Actor in Apify Console.
- In the Input tab, add the URLs or domains you want to analyze (one per line). Full URLs (
https://example.com) and bare domains (example.com) both work. - Click Start.
- When the run finishes, open the Output tab to view results, or download them in JSON, CSV, Excel, or HTML.
Input
The only input is a list of websites to analyze:
{"urls": ["https://nike.com","example.com","https://github.com"]}
| Field | Type | Description |
|---|---|---|
urls | array of strings | URLs or domains to look up. A missing scheme defaults to https://. Invalid entries are skipped. |
maxConcurrency | integer | Optional. How many lookups run at once (1-25). Leave empty to let the Actor pick a value that fits the run's memory. |
proxyConfiguration | object | Optional. Defaults to Apify residential proxy — see below. |
About the proxy
The Wappalyzer API rate-limits per IP, so a bulk run needs to spread its requests across several addresses. This Actor therefore defaults to Apify's residential proxy.
Datacenter proxies do not work for this API: that pool is small and shared
across Apify users, and Wappalyzer already rate-limits it, so requests through
it come back HTTP 429 and the results are empty. Running with no proxy at all
works for small inputs but sends every lookup from a single IP, which will be
rate-limited on a large run.
Residential proxy traffic is billed by the gigabyte and costs more than
datacenter traffic. The responses here are small JSON documents, so a typical
run moves only a few megabytes — but it is a real cost on top of the per-row
charge, and you can point proxyConfiguration at a different pool, or turn the
proxy off, if that suits you better.
Output
The output is flat — one row per detected technology — so it maps cleanly to a spreadsheet. You can download the dataset in various formats such as JSON, HTML, CSV, or Excel.
Every row carries the same columns. A domain where nothing was recognised, and a domain
whose lookup failed, each get one row too — with domain filled in and a null wherever
there is nothing to report — so the column set does not change with the kind of row and a
CSV export is never ragged. Those rows are not charged.
[{"domain": "wordpress.org","technologyName": "React","technologySlug": "react","versions": "18.2.0, 18.3.1","cpe": "cpe:2.3:a:facebook:react:18.3.1:*:*:*:*:*:*:*","trafficRank": 663,"confirmedAt": 1790033696,"iconUrl": "https://www.wappalyzer.com/images/icons/React.svg","categories": "JavaScript frameworks","error": null,"errorStatus": null},{"domain": "nothing-recognised.example","technologyName": null,"technologySlug": null,"versions": null,"cpe": null,"trafficRank": null,"confirmedAt": null,"iconUrl": null,"categories": null,"error": null,"errorStatus": null},{"domain": "lookup-failed.example","technologyName": null,"technologySlug": null,"versions": null,"cpe": null,"trafficRank": null,"confirmedAt": null,"iconUrl": null,"categories": null,"error": "HTTP 502: Bad Gateway","errorStatus": 502}]
Data fields
| Field | Description |
|---|---|
domain | The looked-up website's domain (scheme and leading www. stripped). |
technologyName | Technology name (e.g. React). |
technologySlug | Wappalyzer's stable slug for the technology (e.g. react) — a safer join key than the display name. |
versions | Detected version(s), comma-separated, or null when no version is exposed. How often a version is exposed depends entirely on which sites you scan. |
cpe | CPE identifier, e.g. cpe:2.3:a:facebook:react:18.3.1:*:*:*:*:*:*:* — the key CVE databases use, so you can match a detection against known vulnerabilities. Not tied to the version column: most cpes carry a * wildcard in the version slot and match every release, and where several versions were detected the cpe pins only one of them. See the FAQ. |
trafficRank | Popularity rank of the technology, not of the site — a lower number means the technology is more widely deployed across the web. It differs between rows of the same domain, so it is not a site traffic rank. |
confirmedAt | When the detection was last confirmed, as a Unix timestamp in seconds (multiply by 1000 for a JavaScript Date). |
iconUrl | Direct URL to Wappalyzer's icon for the technology. Mostly .svg, sometimes .png — the filename comes from the API as-is. |
categories | Comma-separated category names the technology belongs to (e.g. CDN, Analytics). |
error | Why this domain's lookup failed, with the first 500 bytes of the upstream response. Null on every other row — including a domain that does not resolve, which the upstream answers with HTTP 200 and no technologies rather than an error. |
errorStatus | The HTTP status behind error, as a number, so you can branch on 404 vs 502 without parsing the text. Null when the request got no response at all, and on every row that is not an error row. |
Pricing
The current price of every event is on the Pricing tab of this Actor's page in Apify Store. That tab is generated from the Actor's own pricing record, so it is always current, and your plan's rung is applied automatically. A figure repeated here would be a second copy that drifts out of date.
You can cap what any single run may spend with Max total charge.
Tips
- Deduplication is automatic, and it works per site, not per URL:
https://example.com,example.comandhttps://example.com/aboutare one lookup and one set of rows between them. The lookup returns a stored profile of the domain, so a page path cannot change the answer — feeding a crawl's worth of page URLs costs you nothing extra. - Bare domains are fine; the Actor normalizes them to
https://. - Requests rotate through residential proxy IPs automatically; failed lookups are retried on a fresh IP with backoff. Any URL that still fails is recorded with an
errorfield instead of stopping the run.
n8n integration
Use the n8n-nodes-wappalyzer-lookup community node (source) to run this Actor directly from an n8n workflow.
FAQ, disclaimers, and support
How do I find all the websites using Shopify (or WordPress, or any platform)? Feed in your list of domains, then filter the output rows where technologyName matches the platform you care about. Each technology is its own row, so a filter or spreadsheet pivot is all it takes.
Can I check what CMS a website is built with? Yes — CMS is one of the detected categories. Look for rows whose categories field contains CMS.
What if a domain does not exist? You get the same row as a real site with nothing recognised on it — the domain, and null in every other column. The upstream answers HTTP 200 with an empty technology list either way, so there is nothing in the response to tell the two apart, and the Actor does not guess. A row with a non-null error is a third thing: the lookup itself failed and the domain was never assessed. Neither kind is charged. Check the spelling if a site you expected to have detections comes back empty.
How do I tell what the run actually covered? The run's status message counts it against what you supplied: how many inputs were scanned, how many collapsed onto a domain already being scanned, how many were not usable as a URL, how many sites returned no detections and how many lookups failed. If a run was cut short by the cost cap or the timeout, the message says so and names the domains it never reached — a missing technology in that case means unknown, not absent.
How precise is cpe? Less than it looks, and this matters if you are feeding a CVE database. Measured over 320 rows from four domains: 52 carried a cpe, and 35 of those had no version at all — their cpe has a * in the version slot, so it matches every release of the product rather than a vulnerable one. Another 35 rows had a version but no cpe. And when several versions are detected on a domain, the cpe pins exactly one: React detected at 17.0.0, 17.0.2 and 18.3.1 yields a cpe for 17.0.0 only, so a CVE lookup on it misses the other two. Use cpe to identify the product and versions to decide what to check — not the version inside the cpe.
Can I find sites running something with a known CVE? Yes — the cpe column is the CPE identifier CVE databases key on, so the output joins directly against NVD or the CVE Scraper below. Filter on cpe itself, not on versions: the two columns are independent, and a row can carry either, both or neither. Measured over 372 rows from eight domains, 39 rows had a cpe and no version while 40 had a version and no cpe — so a versions-based filter drops rows you can join on and keeps rows you cannot. How many rows carry a cpe at all depends entirely on the sites you scan.
Do I need a Wappalyzer account or API key? No. The key is bundled with the Actor, so you only pay the per-row Apify charge.
How many domains can I check at once? There is no fixed cap — pass a list of any length. Lookups run in parallel (tunable via Parallel lookups), duplicates are collapsed automatically, and you can bound total spend with the maximum-cost-per-run setting.
How accurate is the detection? Detections are fingerprint-based, so they identify technologies that leave an observable trace in the page, headers, or scripts. Something loaded only behind a login, or server-side with no client-visible signature, may not be detected. The confirmedAt timestamp tells you when Wappalyzer last verified the detection.
Is this affiliated with Wappalyzer? No. This Actor uses the public Wappalyzer API and is not an official Wappalyzer product.
Is web technology detection legal? The Actor only queries the Wappalyzer API for publicly available technology fingerprints. As with any data tool, ensure your use complies with applicable laws and the target services' terms.
Found a bug or have a feature request? Open an issue on the Actor's Issues tab. Custom solutions are available on request.
Cyber recon toolkit
Part of the Cyber recon toolkit — OSINT, attack-surface recon, and vulnerability-intel data collection for security research:
- Bugcrowd Scraper — Scrapes public Bugcrowd data: disclosed submissions, program directory, leaderboard.
- HackerOne Scraper — Scrapes public HackerOne data: Hacktivity disclosed reports, program directory, researcher leaderboard.
- Intigriti Scraper — Scrapes public Intigriti data: bug bounty/VDP program directory, researcher leaderboard and profiles.
- CVE Scraper — CVE.org vulnerability info scraper.
- TLSX - TLS Data Gathering and Analysis — Fast, configurable TLS grabber for TLS-based data collection and analysis.
- BGP.HE.NET Recon Scraper — Scrapes ASN, prefix, IP, and DNS recon data from bgp.he.net.
- gau - Get All URLs — Fetch known URLs from Wayback Machine, Common Crawl, AlienVault OTX, and URLScan.
- Git Email Extractor — Shallow-clones git repos and extracts contributor emails from commit history.
- Meta Tags Scraper — Web page metadata scraper (meta tags, Open Graph, Twitter Card).
- Universal Contact Extractor — Extract phone numbers, emails and social media URLs from web pages.
- Web Text Extractor — Extract clean text or Markdown content from web pages.
Did you find this useful?
Rate this actor on Apify! Your feedback helps other users find it and helps us keep improving it.