Website Tech Stack Detector: CMS, Frameworks & Hosting avatar

Website Tech Stack Detector: CMS, Frameworks & Hosting

Pricing

$1.20 / 1,000 website analyseds

Go to Apify Store
Website Tech Stack Detector: CMS, Frameworks & Hosting

Website Tech Stack Detector: CMS, Frameworks & Hosting

Find the CMS, ecommerce platform, frameworks, analytics, hosting, CDN, email provider and 6,700+ other technologies behind any list of websites. One row per site, with versions and evidence.

Pricing

$1.20 / 1,000 website analyseds

Rating

0.0

(0)

Developer

vantum

vantum

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

5 days ago

Last modified

Security

Limited permissions

Share

Website Tech Stack Detector

Paste a list of websites and get one row per site listing what it runs on:

  • CMS and ecommerce platform, e.g. WordPress 7.2, Shopify, Magento, Wix, Webflow or Squarespace;
  • frameworks and libraries, e.g. Next.js, Nuxt, React, Vue, Angular, Astro, SvelteKit, jQuery 3.7.1 or Bootstrap 5.3.2;
  • marketing and sales tools: analytics, tag managers, ad pixels, marketing automation, CRM, live chat, A/B testing, reviews, cookie consent and payments;
  • infrastructure: hosting and PaaS, CDN, web server, reverse proxy, language, caching, security/WAF and the TLS certificate issuer and expiry;
  • email setup from DNS: email provider (Google Workspace, Microsoft 365…), sending services in SPF (SendGrid, Mailchimp, HubSpot, Zendesk…), domain verifications (which SaaS tools the company verified) and nameservers;
  • company details: page title, description, language, social profiles (LinkedIn, X, Facebook, Instagram, YouTube, TikTok, GitHub, Pinterest) and mailto: emails.

Each technology comes with its version when the site exposes it, a confidence score, its categories, its CPE (for security teams), the evidence that matched and which technology implied it.

Detection uses the open-source webappanalyzer fingerprint set: 7,600+ technologies in the format popularised by Wappalyzer, pinned to a known commit. It runs over plain HTTP and DNS with no browser, so it is fast. $1.20 per 1,000 websites. Sites that fail, block the request or are not HTML pages are free, and so are dry runs.

Why this one

This ActorTypical tech-stack actors
Price$0.0012 per website, no start fee$0.0015–$0.10 per website, often plus a start fee
Failed, blocked and non-HTML sitesfreeoften charged as a result row
Fingerprints7,600+, pinned open-source set, named in every runvaries, often undisclosed or an old snapshot
Version numbers and confidence✅some
Evidence for every match (header, script URL, meta tag, DOM element, cookie, DNS record)✅❌
implies / requires / excludes rules (e.g. WooCommerce only with WordPress)✅rarely
Email provider, SPF senders, domain verifications from DNS✅ free❌ or a separate actor
TLS issuer and expiry date✅❌
Social profiles and emails✅some
Flat columns per category (CMS, analytics, hosting…) for CSV/Excel✅ 30 columnssome
Change tracking between scheduled runs (added / removed technologies)✅❌
Free dry run (validate, de-duplicate, maximum cost)✅❌
Bulk input: bare domains, URLs, uploaded files, duplicates removed✅partial

Quick start

  1. Paste websites, one per line (Bulk edit for long lists): example.com, www.example.com or https://example.com/shop all work.
  2. Run. Open the Overview, Marketing & sales stack, Infrastructure or Company & contacts tab, or download all rows as CSV, Excel or JSON.
{
"websites": ["https://wordpress.org/news/", "nextjs.org", "books.toscrape.com"],
"checkDns": true,
"minConfidence": 50
}

From the API, startUrls: [{ "url": "https://a.com" }], urls and domains are accepted too.

Use cases

  • Lead generation: find every Shopify store, or every site on HubSpot, in a list of prospects. Filter the CSV by the ecommerce, crm or marketingAutomation column.
  • Sales intelligence: know a prospect's stack before the call: CMS, analytics, chat, payments, email provider.
  • Competitor monitoring: schedule a weekly run with Track changes and get a changes field when a competitor adds or drops a tool.
  • Security and IT inventory: versions plus CPE identifiers for the web-facing software of many domains, and certificate expiry dates.
  • Market research: RUN_SUMMARY lists the 50 most common technologies across your list.

How it works

  • For each website it fetches the URL you gave, usually the home page, following up to 10 redirects. With no https:// given it tries HTTPS first, then HTTP if HTTPS cannot connect.
  • At the same time it reads the domain's DNS records (MX, TXT, NS, SOA, CNAME). DNS is checked on the host you gave without www..
  • It matches the response headers, cookies, HTML, script URLs, inline scripts and styles, meta tags, DOM elements, visible text, DNS records and the TLS certificate issuer against the fingerprints. Then it applies the fingerprints' implies, requires and excludes rules. Versions come from the matched values; when several are found, the highest is reported.
  • A browser would also see JavaScript globals. Instead, a global counts as present when an inline script assigns it (window.X =, var X =). A small supplement adds the static markers of server-rendered frameworks (for example __NEXT_DATA__ and /_next/static/ for Next.js, /_astro/ for Astro, /_app/immutable/ for SvelteKit). The upstream file is never changed.
  • Hints the fingerprint set marks with confidence 0 are dropped. Minimum confidence (default 50) hides weak single hints.
  • Up to Max concurrency websites (default 10) run in parallel. Each is a different server and gets only one or two requests.
  • If the run is about to time out, it stops starting new websites and still writes the summary. After a platform migration it resumes without re-checking, or re-charging, finished websites.

Statuses (only ok is charged)

statusMeaningCharged
okPage fetched (HTTP < 400, HTML) and analysed✅ $0.0012
blocked401/403/429 or a bot challenge page (Cloudflare, DataDome, Akamai…)free
httpErrorOther HTTP error (404, 500…)free
notHtmlThe URL is a PDF, image, JSON…free
failedDNS error, timeout, TLS error, connection refused, redirect loopfree
dryRunDry run rowfree

Free rows still include whatever the headers, TLS certificate and DNS revealed, for example Cloudflare, the email provider or the hosting.

Output

One dataset row per website. Abridged example (real output from wordpress.org):

{
"url": "https://wordpress.org/news/",
"domain": "wordpress.org",
"status": "ok",
"statusCode": 200,
"title": "WordPress News – The latest news about WordPress and the WordPress community",
"language": "en-US",
"technologyCount": 14,
"technologies": [
{
"name": "WordPress", "version": "7.2", "confidence": 100, "categories": ["CMS", "Blogs"],
"website": "https://wordpress.org", "cpe": "cpe:2.3:a:wordpress:wordpress:*:*:*:*:*:*:*:*",
"evidence": [
"html: <link rel='stylesheet' id='wp-block-navigation-css' href='https://wordpress.org/news/wp-includes/",
"header link: <https://wordpress.org/news/wp-json/>; rel=\"https://api.w.org/\""
],
"impliedBy": null
},
{ "name": "PHP", "version": null, "confidence": 100, "categories": ["Programming languages"], "impliedBy": ["WordPress"] },
{ "name": "Google Tag Manager", "confidence": 100, "evidence": ["html: googletagmanager.com/ns.html?id=GTM-…"] }
],
"cms": ["WordPress 7.2"],
"pageBuilders": ["WordPress Block Editor", "WordPress Site Editor"],
"tagManagers": ["Google Tag Manager"],
"webServers": ["Nginx"],
"programmingLanguages": ["PHP"],
"databases": ["MySQL"],
"mxRecords": ["smtp1-dca.wordpress.org", "smtp2-dca.wordpress.org"],
"spfSenders": ["Help Scout"],
"domainVerifications": ["google"],
"tlsIssuer": "Let's Encrypt",
"tlsExpires": "2026-12-22",
"socialProfiles": { "x": "https://www.x.com/WordPress", "linkedin": "https://www.linkedin.com/company/wordpress" },
"charged": true,
"checkedAt": "2026-10-31T19:57:04Z"
}

A Shopify store from the same test run (www.allbirds.com) came back with ecommerce: ["Shopify"], payments: ["Apple Pay", "PayPal", "Shop Pay"], cdn: ["Cloudflare"], emailProvider: "Microsoft 365" and evidence such as script: https://cdn.shopify.com/… and inline script sets ShopifyAnalytics.

Flat category columns (array of names, with version when known, or null): cms, ecommerce, blogs, pageBuilders, staticSiteGenerators, jsFrameworks, webFrameworks, jsLibraries, uiFrameworks, analytics, tagManagers, advertising, retargeting, marketingAutomation, crm, liveChat, payments, abTesting, cookieConsent, reviews, cdn, hosting, webServers, reverseProxies, programmingLanguages, databases, security, caching, fonts, sslCertificateAuthority. Every technology is in technologies, including categories without a flat column.

DNS fields (with Check DNS): emailProvider, emailProviders, mxRecords, spfSenders, spf, domainVerifications, nameservers.

Other fields: finalUrl, error, description, generator, tlsIssuer, tlsExpires, redirects, socialProfiles, emails, responseTimeMs, changes (with change tracking) and charged.

The RUN_SUMMARY record holds counts by status, charged websites, the 50 most common technologies, skipped inputs and the fingerprint commit used.

Change tracking

Turn on Track changes and schedule the Actor. Each website's technology list is saved in a named key-value store (tech-stack-history by default; it persists between runs). Each ok row then gets:

"changes": { "added": ["Klaviyo"], "removed": ["Mailchimp"], "changed": true, "previousCheckAt": "2026-10-24T06:00:02Z" }

The first check of a website has "firstCheck": true. Use a different History store name for each watch list. Changes compare technologies at or above your minimum confidence, so keep that setting the same between runs.

Input

FieldDefaultDescription
websites–Websites or domains, one per line (also startUrls, urls or domains via API). Up to 100,000 per run.
checkDnstrueRead MX/TXT/NS/SOA/CNAME for the email provider, SPF senders, verifications and DNS-detected technologies.
minConfidence50Hide technologies below this confidence (1–100).
includeEvidencetrueAdd evidence and impliedBy to each technology.
includeContactstrueAdd social profiles and mailto: emails.
trackChangesfalseAdd changes versus the previous run.
historyStoreNametech-stack-historyNamed store used by change tracking.
dryRunfalseValidate and de-duplicate the list and report the maximum cost. Visits nothing and charges nothing.
maxConcurrency10Websites checked in parallel (1–50).
requestTimeoutSecs25Per-website timeout.
userAgentChrome desktopCustom User-Agent.

Pricing

Pay per event: $0.0012 per analysed website ($1.20 per 1,000). No start fee and no monthly rental. Blocked, failed, HTTP-error and non-HTML websites are free, and so are dry runs and DNS lookups. Set a maximum cost per run in the run options: the Actor stops cleanly when it reaches it.

Limitations

  • One page per website. It checks the page you give, usually the home page. Tools used only on other pages (for example a checkout provider) are found only if you give that page's URL.
  • No browser. Technologies that are visible only after JavaScript runs, and add no markers to the HTML, headers or DNS, are not detected. Those are about 900 of the 7,600 fingerprints, mostly ones keyed only on runtime globals; the inline-script heuristic recovers some of them.
  • Sites behind aggressive bot protection may return blocked. Those rows are free and still show what the headers and DNS reveal.
  • Like every fingerprint-based detector, results are evidence-based guesses. Check the evidence field when a match matters.

Fingerprint data and license

Technology fingerprints come from enthec/webappanalyzer, licensed GPL-3.0. They are downloaded unmodified at a pinned commit when the Actor is built, and the license is included in the image (data/LICENSE-webappanalyzer-GPL-3.0.txt). The RUN_SUMMARY record names the commit used. The detection engine, the static-marker supplement and the email-provider mapping are this Actor's own. This Actor is not affiliated with Wappalyzer, BuiltWith or enthec.

FAQ

Is this the same as Wappalyzer? It uses the same open fingerprint format and an actively maintained community fork of that dataset, but it is an independent engine. Wappalyzer's browser extension also sees runtime JavaScript; this Actor trades that for speed and price.

Can I check thousands of domains? Yes: paste them with Bulk edit or send them via the API. In the test run, 6 websites took 2.5 seconds in total at the default concurrency of 10.

Why does a site show blocked? It refused automated requests. You are not charged. Try again later or with a lower concurrency.

Does it store anything in my account? Only the dataset and RUN_SUMMARY for each run, plus the named history store if you turn on change tracking.