Tech Stack Detector: BuiltWith & Wappalyzer Alternative $2/1K
Pricing
from $1.60 / 1,000 website scans
Tech Stack Detector: BuiltWith & Wappalyzer Alternative $2/1K
Detect the tech stack of any list of websites: CMS, ecommerce platform, analytics, frameworks, CDN, hosting, payment tools. $2 per 1,000 websites, failed sites free. A BuiltWith and Wappalyzer alternative on open fingerprints, with email provider and change tracking. MCP-ready, no login.
Pricing
from $1.60 / 1,000 website scans
Rating
0.0
(0)
Developer
Don Mangu
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
8 days ago
Last modified
Categories
Share
Tech Stack Detector: Website Technology & CMS Lookup
This tech stack detector finds the technologies behind a list of websites: the CMS, ecommerce platform, analytics and tag managers, web and JavaScript frameworks, CDN, hosting and payment processors. Give it domains or URLs and it works as a bulk website technology lookup and CMS detector, returning one row per website with every technology it recognised, its version when the page shows one, a confidence score and its categories. It is a Wappalyzer and BuiltWith alternative for lead lists, market research and competitor checks, at $2 per 1,000 websites. Sites that fail are free, and no login is needed.
Each website gets one homepage request, and only when the site's robots.txt allows it. The Actor reads the response headers, cookie names (never cookie values), meta tags, script and stylesheet addresses and the HTML, and matches them against 7,628 open technology fingerprints from the webappanalyzer project (GPL-3.0).
Schedule it. Turn on Track changes since the last run and run the same list every week. The first run saves a baseline, and each later row says which technologies were added or removed and whether the email provider changed. Change tracking costs the same $2 per 1,000 websites, and sites that fail are free.
Sample output. One row per website. A real row from a test run, shortened:
{"domain": "crates.io","status": "ok","technologies": [{ "name": "SvelteKit", "version": null, "confidence": 100, "categories": ["UI frameworks"] },{ "name": "Varnish", "version": null, "confidence": 100, "categories": ["Caching"] }],"frameworks": ["Svelte"],"emailProvider": "Mailgun","dmarcPolicy": "none","pageTitle": "crates.io: Rust Package Registry","checkedAt": "2026-09-26T16:33:45.741Z","charged": true}
A BuiltWith and Wappalyzer alternative for bulk lookups
This Actor is not BuiltWith or Wappalyzer and uses no data from either. It makes one homepage request per website, only when robots.txt allows it, and matches the response against 7,628 open technology fingerprints from the webappanalyzer project (GPL-3.0). It costs $2 per 1,000 websites, and sites that fail are free.
What the tech stack lookup returns
- Technologies: name, slug, version, confidence (0 to 100), categories and the technology's website.
- Quick columns:
cms,ecommerce,analytics,frameworks,cdn,hosting,paymentProcessors,tagManagers, each a list of technology names, ready for a spreadsheet. - Email setup: the company's email provider (for example Google Workspace or Microsoft 365), its email security gateway, the services allowed to send its email (for example HubSpot, SendGrid, Zendesk), its DMARC policy and the services it has verified its domain with (for example Atlassian, Stripe, Google Search Console). Read from public DNS records, with no extra request to the website.
- Company profile: page title, description and language, the company name, legal name and logo the homepage publishes, and links to the company's own LinkedIn, X, Facebook, Instagram, YouTube, GitHub and TikTok pages. Personal profiles are left out.
- Changes since the last run: turn on change tracking, run on a schedule, and each row says which technologies were added or removed since the previous run and whether the email provider changed.
- Status for every website:
statusisokwhen the homepage loaded, or says why it did not (for examplerobots_disallowed,blocked,timeout,domain_not_found), with a plain-languageerror.
How to find the tech stack of a website, step by step
- Open the Actor and go to the Input tab.
- In Websites, enter one website per line, as a domain (
example.com) or a URL (https://www.example.com/pricing). The Actor always checks the homepage of each site. - Set Maximum websites to the number of sites you want checked. Duplicates count once.
- Optional: pick Categories (for example CMS and Ecommerce) to return only those technologies, or turn off Include versions, Email provider and DNS or Company profile and social pages.
- Optional: turn on Track changes since the last run and add a schedule (for example weekly). The first run saves the baseline; later runs fill the
changesfield. - Click Start. A run with the three example websites takes a few seconds.
- Open the Output tab. The Overview view shows the quick columns, All technologies the full list, Company and email the company and email fields, and Changes what changed since the last run. Download the results as CSV, Excel or JSON, or read them through the Apify API.
Use in Clay
Clay's documentation for its Apify integration (https://university.clay.com/docs/apify-integration-overview) says to switch the Actor input from Manual to JSON and copy the body text, to "Enter the data body in JSON format" in the Input Data section, and, "When referencing column tokens (dynamic data from your Clay table), ensure the key is in quotes, but do not put quotes around the token itself."
This Actor takes one website in a domain field and returns exactly one row for it, with no nested lists or objects, so a single table row can be passed in as one run. Input template:
{"domain": "stripe.com"}
Replace the example value with your domain column token, following Clay's quoting rule above. domain is used only when the websites list is empty. If you fill both, the Actor runs the list and returns its normal rows. A full URL such as https://www.stripe.com/pricing also works, and the Actor checks the homepage.
Fields in the single-website row, all plain text, numbers, true/false or null:
- Result:
inputUrl,finalUrl,domain,httpStatus,status(ok, or the reason the homepage could not be read),error,checkedAt,charged - Technologies:
technologyCount,technologyNames(comma separated, with the version when the page shows one) - Quick columns:
cms,ecommerce,analytics,frameworks,cdn,hosting,paymentProcessors,tagManagers, each a comma separated list of names - Email setup:
emailDomain,emailProvider,emailSecurityGateway,emailSenders,mxHosts,hasSpf,dmarcPolicy,verifiedServices,dnsError - Company profile:
pageTitle,metaDescription,language,companyName,companyLegalName,companyLogo,socialLinkedin,socialX,socialFacebook,socialInstagram,socialYoutube,socialGithub,socialTiktok
The price is the same as for a list: one website scan when the homepage loads, nothing when it does not. The list input and its output are unchanged.
How much does it cost to detect a website's tech stack?
You pay per website analyzed: one site-analyzed event, with the email, company and change fields included at no extra cost, for each website whose homepage loaded. Websites that could not be read (robots.txt does not allow it, the site blocked the request, the domain does not exist, the request timed out) return a row with the reason and are not charged. Invalid entries and duplicates are free.
Worked example: at $2.00 per 1,000 websites analyzed, a list of 500 domains where 460 homepages load and 40 fail costs 460 x $0.002 = $0.92. The 40 failed websites cost nothing.
Set a spending limit on the run and the Actor stops starting new websites when the next one would go over it. The run log and the STATS record say how many websites were left unchecked.
Input example
{"websites": ["pypi.org", "crates.io", "www.wikipedia.org"],"maxSites": 3,"includeVersions": true,"categories": [],"includeEmailDns": true,"includeCompanyProfile": true,"monitorChanges": false,"maxConcurrency": 5}
| Field | Meaning |
|---|---|
websites | Domains or URLs, one per entry. |
maxSites | Check at most this many websites (1 to 10,000). |
includeVersions | Return version numbers when the page shows them. |
categories | Return only technologies in these categories. Empty returns all. |
includeEmailDns | Add the email provider, gateway, senders, DMARC policy and verified services. On by default. |
includeCompanyProfile | Add page title, description, language, company name and logo, and company social pages. On by default. |
monitorChanges | Compare with the previous run and fill changes. Off by default. |
monitorStoreName | Key-value store in your account that keeps the last result per website (default tech-stack-monitor). Use one name per watchlist. |
maxConcurrency | Websites checked at the same time (1 to 10). |
Output example
A real row from a test run (technologies shortened):
{"inputUrl": "crates.io","finalUrl": "https://crates.io/","domain": "crates.io","httpStatus": 200,"status": "ok","technologies": [{ "name": "SvelteKit", "slug": "sveltekit", "version": null, "confidence": 100, "categories": ["UI frameworks"], "website": "https://kit.svelte.dev" },{ "name": "Varnish", "slug": "varnish", "version": null, "confidence": 100, "categories": ["Caching"], "website": "https://www.varnish-cache.org" }],"cms": [],"ecommerce": [],"analytics": [],"frameworks": ["Svelte"],"cdn": [],"hosting": [],"paymentProcessors": [],"tagManagers": [],"emailDomain": "crates.io","emailProvider": "Mailgun","emailSecurityGateway": null,"emailSenders": ["Mailgun"],"mxHosts": ["mxa.mailgun.org", "mxb.mailgun.org"],"hasSpf": true,"dmarcPolicy": "none","verifiedServices": [],"dnsError": null,"pageTitle": "crates.io: Rust Package Registry","metaDescription": "crates.io serves as a central registry for sharing crates, which are packages or libraries written in Rust that you can use to enhance your projects","language": "en","company": null,"socialProfiles": { "linkedin": null, "x": null, "facebook": null, "instagram": null, "youtube": null, "github": null, "tiktok": null },"changes": { "isFirstCheck": false, "previousCheckedAt": "2026-09-19T16:30:12.004Z", "changed": false, "added": [], "removed": [], "emailProviderBefore": null },"checkedAt": "2026-09-26T16:33:45.741Z","charged": true,"error": null}
The quick columns map to these fingerprint categories: cms (CMS), ecommerce (Ecommerce), analytics (Analytics), frameworks (Web frameworks, JavaScript frameworks), cdn (CDN), hosting (Hosting, PaaS), paymentProcessors (Payment processors), tagManagers (Tag managers).
Integrations
For a weekly watchlist, save your input as a task with Track changes since the last run on, give it its own Change history store name (monitorStoreName), and add a schedule. Each later run fills the changes field.
Google Sheets. On your saved task's Integrations tab, add the Google Sheets Import & Export Actor, connect Google, pick a spreadsheet and set Mode to append. Each run adds one row per website. The quick columns (cms, ecommerce, analytics, frameworks, cdn, hosting) are lists of technology names, ready for a sheet.
n8n. Add a Schedule Trigger, then the Apify node with Actor tasks and Run Task and Get Dataset, and pick your saved task. The node waits for the run and passes on each website as one item. To act only on sites that changed, add an IF node on changes.changed.
Make. The Apify app runs your task with Run a Task, and Get Dataset Items reads its rows. To react to scheduled runs, start with Watch Task Runs.
Zapier. The Apify app has a Finished task run trigger and a Run Task action. Add Fetch dataset items to pass the rows to the next step.
Webhooks. On a task's Integrations tab, add an HTTP webhook for Run succeeded. Apify then sends each run's details to your URL, including the defaultDatasetId that holds its rows.
Tech stack API: one request, one row per website
The API tab has ready code for JavaScript, Python and other clients. This request checks two websites and returns the rows as JSON.
curl -X POST "https://api.apify.com/v2/acts/conserving_celerytop~website-tech-stack-detector/run-sync-get-dataset-items" \-H "Authorization: Bearer <YOUR_APIFY_TOKEN>" \-H "Content-Type: application/json" \-d '{"websites": ["pypi.org", "crates.io"], "maxSites": 2, "monitorChanges": true, "monitorStoreName": "my-watchlist"}'
What "no JavaScript rendering" means
The Actor reads the page the server sends. It does not run the page's JavaScript in a browser. Technologies that are visible in that first response (headers, cookies, meta tags, script addresses, HTML markup) are found. Technologies that only appear after scripts run, for example a chat widget or an analytics tool loaded by a tag manager, may be missed. Fingerprint patterns that need a browser (JavaScript variables, network calls made later) are not used. This keeps the Actor fast and cheap and means one request per website.
Run it every day
Use this to see when a competitor or a customer changes its tools.
- Put your websites in the list.
- Turn on Track changes since the last run (
monitorChanges). - Give the list its own Change history store name (
monitorStoreName). Use one name for each watchlist. - Save the input as a task and add a schedule. Choose daily or weekly.
The first run saves a baseline for each website. Each later run adds a changes field to the row: technologies added, technologies removed, and a change of email provider. The price per website is the same with or without change tracking.
Related Actors
- Company Name to Domain: Use it to turn a list of company names into official website domains.
- Company Hiring Signals: Use it to get a 0 to 100 hiring score and open job counts for each company on your list.
- Domain Authority Checker: Use it to check domain authority for a bulk list of domains.
- DNS Lookup API: Use it to check MX, SPF, DMARC and other DNS records for a list of domains.
FAQ
Is it legal to check a website's technologies? The Actor reads only public homepages, one request per site, without logging in, and only when the site's robots.txt allows the homepage for all user agents. It does not collect personal data: cookie values are never read into the output, and no names, email addresses or phone numbers are stored. The email fields describe the company's mail setup (which provider and services it uses), not any mailbox. Social links are kept only for company pages; personal profiles are skipped. You are responsible for how you use the results; check the terms of the sites on your list.
Is this Actor affiliated with BuiltWith, Wappalyzer or Enthec? No. It is not affiliated with, endorsed by or sponsored by BuiltWith, Wappalyzer or Enthec. The names describe what the Actor does. The fingerprints come from the open webappanalyzer project under the GPL-3.0 licence; see the NOTICE file.
Why does a website show robots_disallowed?
Its robots.txt does not allow the homepage for all user agents, so the Actor did not request it. The row is free.
Why does a website show blocked?
The site answered with an access-denied or challenge page (for example HTTP 403 or a bot check). The Actor does not retry or work around it. The row is free.
Why is a technology I know about missing? It may load only through JavaScript (see above), or the open fingerprint set may not describe it. The confidence score shows how sure a match is; 100 means at least one pattern matched fully.
How many websites can I check? Up to 10,000 per run. The Actor checks up to 10 websites at a time and each website gets at most one robots.txt request and one homepage request (plus redirects and up to two retries after a network error or a server error).
How does change tracking work?
With Track changes since the last run on, each analyzed website's technology list is saved in a named key-value store in your own Apify account. The next run compares against it and writes added, removed and changed. Only websites that loaded update the saved result, so a site that is down for one run keeps its old baseline. If you change Categories, a new baseline starts for that filter.
Why is emailProvider "Other" or null?
"Other" means the domain receives mail on a server that is not a known hosted provider (often its own server or its web host). null means the domain has no mail server, or an email security gateway hides the provider; emailSecurityGateway then names the gateway.
What if a page is very large?
The first 3 MB are checked and the row says so in error.