Tech Stack Detector – Website Technologies
Pricing
from $2.00 / 1,000 website tech stacks
Tech Stack Detector – Website Technologies
Detect the tech stack of any website: CMS, e-commerce platform, analytics, tag managers, ad pixels, chat, payments, CDN, hosting and web server, plus SaaS verified in DNS (Google Workspace, HubSpot, Zendesk…). Live detection, one JSON record per site. $2 per 1,000 websites.
Pricing
from $2.00 / 1,000 website tech stacks
Rating
0.0
(0)
Developer
SFOLN LLC
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
Find out what any website is built with: give it domains or URLs and get one JSON record per site with every detected technology (name, categories, version, confidence and the evidence it was found by) plus headline fields: CMS, e-commerce platform, analytics, tag managers, ad pixels, live chat, payment processors, CDN, hosting, web server and frameworks. On top of the page itself it reads the TLS certificate and DNS records, so it also finds SaaS that never shows up in the HTML: the mailbox provider (Google Workspace, Microsoft 365), e-mail senders from SPF (SendGrid, Mailchimp, Amazon SES), and services verified in TXT records or behind subdomains (HubSpot, Zendesk, Stripe, Atlassian…). Built for sales prospecting by technology ("Shopify stores using Klaviyo"), competitive research, lead enrichment and AI agents.
- What you get:
technologies[],byCategory,cms,ecommercePlatform,analytics,advertising,cdn,hosting,emailProvider,saasVerifiedByDns. - Price: $2 per 1,000 websites (
tech-stack), no subscription; blocked, missing and unreachable sites are free. - Live, not a crawl database: every run loads the site now, from more than 3,500 fingerprints (Wappalyzer 6.10.54, MIT) plus our own DNS and tag-snippet rules.
- Works everywhere: API, MCP for AI agents, Make, Zapier, n8n, schedules and webhooks.
Input
| Field | Type | Default | Description |
|---|---|---|---|
urls | string[] | – | Domains (apify.com) or page URLs, one per line. A domain is analysed from its homepage (https://, falling back to http://). Duplicates are removed. |
maxPages | integer | 1 | 2 also analyses one more page of the same site (pricing, shop, blog, contact…), which catches checkout, payment and chat tools. A second page that redirects to another site is skipped with a warning. |
includeDnsSaaS | boolean | true | Read TXT, MX, SPF, NS and the CNAMEs of common subdomains for SaaS seen only in DNS. |
categories | string[] | – | Keep only these categories (e.g. CMS, Ecommerce, Analytics, Advertising, CDN). Empty = all. |
minConfidence | integer | 0 | Drop technologies detected with a lower confidence (0–100). |
maxItems | integer | 1000 | Safety cap for this run; websites beyond it are ignored and counted as inputItemsDropped in the OUTPUT record. |
concurrency | integer | 5 | Websites analysed in parallel (1–10). |
includeRaw | boolean | false | Attach the analysed pages' response headers and the DNS records used under raw. |
{"urls": ["apify.com", "https://www.allbirds.com/"],"maxPages": 2,"includeDnsSaaS": true}
Output
One dataset record per website (the technologies list is shortened here):
{"input": "wordpress.org","domain": "wordpress.org","url": "https://wordpress.org/","title": "Blog Tool, Publishing Platform, and CMS – WordPress.org","language": "en-US","technologyCount": 14,"technologyNames": ["WordPress", "C", "MySQL", "PHP", "Gutenberg", "Nginx", "Google Font API", "Google Tag Manager", "HSTS", "Priority Hints", "Open Graph", "RSS", "Google Search Console", "Help Scout"],"byCategory": { "CMS": ["WordPress"], "Blogs": ["WordPress"], "Web servers": ["Nginx"], "Tag managers": ["Google Tag Manager"], "Live chat": ["Help Scout"] },"cms": "WordPress","ecommercePlatform": null,"analytics": [],"tagManagers": ["Google Tag Manager"],"advertising": [],"marketingAutomation": [],"crm": [],"liveChat": ["Help Scout"],"paymentProcessors": [],"emailProvider": null,"emailSenders": ["Help Scout"],"hosting": [],"cdn": [],"webServer": "Nginx","javascriptFrameworks": [],"programmingLanguages": ["C", "PHP"],"saasVerifiedByDns": ["Google Search Console", "Help Scout"],"technologies": [{ "name": "WordPress", "slug": "wordpress", "categories": ["CMS", "Blogs"], "version": "6.9", "confidence": 100, "evidence": ["meta", "scriptSrc", "html"], "website": "https://wordpress.org" },{ "name": "PHP", "slug": "php", "categories": ["Programming languages"], "version": null, "confidence": 100, "evidence": ["implied"], "website": "http://php.net", "impliedBy": ["WordPress"] },{ "name": "Help Scout", "slug": "help-scout", "categories": ["Issue trackers", "Live chat"], "version": null, "confidence": 100, "evidence": ["dns-spf"], "website": "https://www.helpscout.com" }],"pagesAnalyzed": 2,"pages": [{ "url": "https://wordpress.org/", "status": 200 }, { "url": "https://wordpress.org/news/", "status": 200 }],"dnsChecked": true,"certificateIssuer": "Let's Encrypt","status": "ok","charged": true,"chargedEvent": "tech-stack","source": "website+dns","fetchedAt": "2026-10-14T10:00:00.000Z"}
| Field | Description |
|---|---|
technologies | Every detection: name, slug, categories, version (when the page reveals it), confidence (0–100), evidence (header, cookie, meta, scriptSrc, script, html, dom, url, cert, dns-txt, dns-mx, dns-spf, dns-ns, dns-cname, or implied with impliedBy), website. |
technologyNames, technologyCount, byCategory | The same list as names, its length, and grouped by category name. |
cms, ecommercePlatform, webServer | The main CMS, shop platform and web server (what the page itself shows wins over DNS-only hits, e.g. a blog. subdomain). |
analytics, tagManagers, advertising, marketingAutomation, crm, liveChat, paymentProcessors, hosting, cdn, javascriptFrameworks, programmingLanguages | Technologies per headline category. |
emailProvider, emailSenders | Mailbox provider from the MX records; services allowed to send the domain's mail (SPF includes). |
saasVerifiedByDns | Technologies seen in DNS: verification TXT tokens, MX, SPF, name servers and CNAMEs of www., help., support., status., shop., store., blog., docs., jobs., careers., go., info., mail.. |
pagesAnalyzed, pages, dnsChecked, certificateIssuer | What was looked at for this record. |
status values:
status | Meaning | Charged |
|---|---|---|
ok | The start page answered; technologies detected (the list may be empty after your filters) | tech-stack |
not_found | The domain does not resolve (domain_not_found), the page is gone (page_not_found, HTTP 404/410) or the site refused the request (site_blocked, HTTP 401/403/429/503) | no |
error | The site could not be reached (timeout, connection or TLS error) or answered another HTTP error | no |
skipped_invalid | Not a public website URL or domain (IP addresses, local names, ports other than 80/443) | no |
skipped_budget / skipped_free_plan | Your cost cap or the free-plan limit was reached | no |
The key-value store record OUTPUT holds the run summary (item counts and the events and USD charged).
Pricing
| Event | Price | When charged |
|---|---|---|
tech-stack | $0.002 per website ($2 / 1,000) | once per website whose start page answered |
There is no start fee and no charge for sites that block the request, do not exist or fail. Set Maximum cost per run to cap spend: when the cap is reached the remaining websites are returned with status: "skipped_budget" and are not charged. Accounts on the Apify free plan can process up to 10 websites per run; upgrade to any paid plan for full batches.
Use with AI agents (MCP)
Use this Actor from Claude, ChatGPT, Cursor, VS Code or any other MCP client through the Apify MCP server. Add this server URL to your client and sign in with your Apify account when asked:
https://mcp.apify.com?tools=sfoln/tech-stack-detector
To run the MCP server locally instead, start npx -y @apify/actors-mcp-server --tools sfoln/tech-stack-detector with your APIFY_TOKEN in the environment.
Example prompt:
Which CMS, e-commerce platform, analytics tools and e-mail provider do apify.com and wordpress.org use?
Runs started by an agent are billed like any other run (see Pricing). Agents can cap what a run may spend with maxTotalChargeUsd.
API usage
Run the Actor and get its dataset items in one call (the call waits up to 5 minutes for the run to finish):
curl -X POST "https://api.apify.com/v2/acts/sfoln~tech-stack-detector/run-sync-get-dataset-items" \-H "Authorization: Bearer <APIFY_TOKEN>" \-H "Content-Type: application/json" \-d '{"urls": ["apify.com"]}'
For large inputs, start the run asynchronously and download the dataset when it has finished:
# 1. Start a run: the response holds the run ID (data.id) and its dataset ID (data.defaultDatasetId)curl -X POST "https://api.apify.com/v2/acts/sfoln~tech-stack-detector/runs" \-H "Authorization: Bearer <APIFY_TOKEN>" \-H "Content-Type: application/json" \-d '{"urls": ["apify.com"]}'# 2. Repeat until data.status is SUCCEEDED (each call waits up to 60 s)curl "https://api.apify.com/v2/actor-runs/<runId>?waitForFinish=60" -H "Authorization: Bearer <APIFY_TOKEN>"# 3. Download the results (format=json, csv or xlsx)curl "https://api.apify.com/v2/datasets/<defaultDatasetId>/items?format=json" -H "Authorization: Bearer <APIFY_TOKEN>"
Python (apify-client):
from apify_client import ApifyClientclient = ApifyClient("<APIFY_TOKEN>")run = client.actor("sfoln/tech-stack-detector").call(run_input={"urls": ["apify.com"]})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item)
Instead of polling, you can attach a webhook to the run (see Integrations). The API tab of this page shows the same calls for JavaScript and the Apify CLI.
Integrations
- Make, Zapier and n8n: run
sfoln/tech-stack-detectorwith the Apify app (in n8n, the Apify node) and pass the dataset items to the next step of your workflow. - Google Sheets: add the items to a sheet with the Google Sheets step of Make, Zapier or n8n, or download them as CSV or Excel from the run's Storage tab or the API (
format=csvorformat=xlsx). - Webhooks: get a POST request when a run succeeds or fails: add a webhook in the Actor's Integrations tab, or pass
webhookswhen you start a run through the API. - Schedules: run it hourly, daily or weekly with the same input from Apify Schedules; every run keeps its results in its own dataset.
- More: Slack, Google Drive, GitHub, LangChain, LlamaIndex and other Apify integrations.
Related Actors
- Website Audit – SEO, Security, SSL & DNS
- Website Contact Details Scraper
- Domain WHOIS & DNS Lookup
- Company Enrichment – Firmographics by Domain
- SEO Competitor Analysis – Traffic & Keywords
See all our Actors on Apify Store.
FAQ
How much does it cost, and am I charged for failed items?
You pay per event at the prices under Pricing above, plus a run start fee of $0.00005 per GB of memory, with no subscription; platform usage is included. Errors and skipped items (skipped_… statuses) are never charged; a lookup that finds nothing is charged only where Pricing says so, and every record's charged field shows whether it was billed. Set Maximum cost per run to cap what a single run can spend. Some runs may be sponsored by a promotional trial: sponsored results are delivered without the usual event charge and are marked sponsored in the dataset; apify-actor-start may still be charged by Apify.
How fresh is the data?
Each run queries its source while it runs, so you get what the source returns at that moment. Source-specific details, such as how often a provider refreshes its own database, are under Limits & notes.
What are the limits?
Per-run caps (for example the maximum number of items) are listed under Input, source limits under Limits & notes, and the free-plan limit under Pricing. For big batches, start the run asynchronously (see API usage) and read the dataset when it has finished.
Can I schedule runs or get results by webhook?
Yes. Create a schedule in Apify Console to run it hourly, daily or weekly with the same input, and add a webhook to get a POST request when a run finishes (see Integrations).
What does this Actor record about my runs?
This Actor records operational metrics about each run (item counts, duration, charges, error codes and a pseudonymous hash of your Apify user ID) to monitor reliability and costs. It never stores your input or results.
How are technologies detected?
The Actor loads the page like a browser would (without running JavaScript) and matches its response headers, cookies, meta tags, script URLs, inline scripts and HTML against more than 3,500 technology fingerprints (Wappalyzer 6.10.54, MIT licence, plus our own rules for newer frameworks and tag snippets). It also reads the TLS certificate issuer and, with includeDnsSaaS, DNS records: verification tokens, mail servers, SPF senders, name servers and the CNAMEs of help., shop., status. and similar subdomains.
What can it miss?
Technologies that only load after JavaScript runs in a browser (some tag-manager payloads, single-page apps that inject everything client-side) and back-end tools that leave no trace in pages or DNS. Sites behind bot protection that refuse the request are returned with status not_found and are not charged.
How do I get help?
Open an issue in the Actor's Issues tab and include the link to the run, so we can reproduce the problem. Feature requests are welcome there too.
Limits & notes
- Pages are fetched without running JavaScript: tools that only appear after scripts run in a browser can be missed (most tag snippets, pixels and frameworks leave traces in the HTML and are found).
- At most 2 pages per site, 20 seconds and 2 MB per page; only public http(s) hosts on ports 80 and 443 are contacted, and every redirect is checked.
- DNS comes from public DNS-over-HTTPS (Cloudflare); the TLS certificate is read with a direct handshake. Nothing is cached between runs.
- Fingerprints: Wappalyzer 6.10.54 (MIT licence) plus our own rules for DNS-verified SaaS, newer frameworks (Next.js App Router, Astro, SvelteKit, Remix) and inline tag snippets.
- Sites that sit behind strict bot protection may answer 403 or a challenge page; they are returned as
not_foundwithsite_blockedand are not charged.