SFOLN

Catalogue / Company & lead intelligence

Tech Stack Detector – Website Technologies

sfoln/tech-stack-detector · Lead generation, SEO tools, Developer tools

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.

About

What it does

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.

Price

Price per delivered record

EventPricePer 1,000Charged for
Website tech stack
tech-stack
$0.002$2 / 1,000Charged once per website whose start page answered: detected technologies with categories, versions, confidence and evidence, headline fields (CMS, e-commerce platform, analytics, CDN, hosting, mailbox provider…) and SaaS seen in DNS.

Apify free plan: up to 10 items per run. Paid plans have no per-run cap; set maxTotalChargeUsd to cap spend.

Run

Call it from code, an agent or the Console

curl · synchronous run, rows in the response
curl -X POST "https://api.apify.com/v2/actors/sfoln~tech-stack-detector/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"urls":["apify.com"]}'
mcp.json · hosted Apify MCP server
{
  "mcpServers": {
    "apify": {
      "type": "http",
      "url": "https://mcp.apify.com?tools=sfoln/tech-stack-detector"
    }
  }
}
asynchronous run · for large batches
POST https://api.apify.com/v2/actors/sfoln~tech-stack-detector/runs?maxTotalChargeUsd=1
GET  https://api.apify.com/v2/actor-runs/{runId}            # until status is SUCCEEDED
GET  https://api.apify.com/v2/datasets/{defaultDatasetId}/items?format=json

Authenticate with an Apify API token. MCP clients can instead sign in with OAuth when prompted. Example prompt for an agent: Which CMS, e-commerce platform, analytics tools and e-mail provider do apify.com and wordpress.org use?

Input

Input fields

Enter websites (domains or page URLs). Each website produces one dataset record with its detected technologies.

FieldTypeDefaultMeaning
urls *arrayrequiredWebsites
Domains (apify.com) or page URLs (https://www.apify.com/pricing), one per line. A domain is analysed from its homepage (https://, falling back to http://). Duplicates are removed. Accounts on the Apify free plan can process up to 10 websites per run.
maxPagesinteger1Pages per website
1 = the start page only; 2 = also one more page of the same site (pricing, shop, blog, contact…) to catch technologies that load only there. Range 1–2.
includeDnsSaaSbooleantrueDetect SaaS from DNS
Read TXT verification tokens, MX, SPF, NS and the CNAMEs of common subdomains (help., shop., status., …) to find services that never appear in the HTML: Google Workspace, Microsoft 365, HubSpot, Zendesk, Stripe, SendGrid and more.
categoriesarray—Only these categories
Keep only technologies in these categories, e.g. CMS, Ecommerce, Analytics, Advertising, CDN, Payment processors, Marketing automation (case-insensitive). Empty = every category.
minConfidenceinteger0Minimum confidence
Drop technologies detected with a confidence below this value (0–100; most detections are 100). Range 0–100.
maxItemsinteger1000Max websites
Safety cap on how many websites are processed in this run. Range 1–10000.
concurrencyinteger5Concurrency
How many websites are analysed in parallel (1–10). Range 1–10.
includeRawbooleanfalseInclude raw response data
Attach the response headers of the analysed pages and the DNS records used under raw (larger output).
Example input
{
  "urls": [
    "apify.com"
  ]
}

Output

One record per input item

Records land in the run's dataset; a synchronous call returns them directly. Each has a status (ok is charged; everything else is free) and a charged flag. The run's OUTPUT record totals items and charges.

FieldTypeMeaning
inputstring | objectInput
The website as submitted.
statusstringStatus
ok | not_found | error | skipped_invalid | skipped_budget | skipped_free_plan | skipped_trial | skipped_unmetered e.g. "ok"
chargedbooleanCharged
Whether this record incurred a pay-per-event charge.
chargedEventstringCharged event
Pay-per-event event charged for this record (present only when charged).
chargedCountintegerEvents charged
Events actually charged when the charge came back short of the requested count (present only then; a warning explains it).
sponsoredbooleanSponsored
true when a promotional trial paid for this record instead of you: delivered with charged false and never billed (present only then).
promotionIdstringPromotion
Id of the promotional trial that sponsored this record (present only with sponsored).
trialUnitsAppliedintegerTrial events
Events of this record the trial paid for (present only with sponsored).
retailValueWaivedUsdnumberValue waived (USD)
What those events cost at the listed prices, in USD: what you did not pay (present only with sponsored).
sourcestringSource
website+dns: the site's own pages, its TLS certificate and public DNS.
fetchedAtstringFetched at
ISO timestamp.
errorobjectError
{ code, message, provider?, status? } when status is not ok. Codes: site_blocked (401/403/429/503), page_not_found (404/410), http_error, domain_not_found, invalid_url, network, timeout, tls_error, unexpected_type, too_many_redirects; runtime codes: budget_exhausted, free_plan_limit, unmetered, aborted, charge_failed, record_too_large, invalid_record, dataset_push_failed; promotional-trial codes (status skipped_trial; skipped_free_plan when the free-plan limit of the paid data source is reached or cannot be checked): allowance_exhausted, run_cap, campaign_cap, actor_cap, provider_cap, portfolio_cap, campaign_inactive, window_closed, halted, not_eligible, unknown_cost, ledger_unavailable, invalid_request, free_plan_subsidy_cap.
warningsarrayWarnings
Notes about this record (second page or DNS lookups failed, page cut at 2 MB, detection time budget reached).
domainstring | nullDomain
Registrable domain of the website. e.g. "apify.com"
urlstring | nullURL
Final URL of the analysed start page (after redirects).
httpStatusintegerHTTP status
Status of the start page when it answered with an error (not_found / error records).
titlestring | nullPage title
languagestring | nullLanguage
The page's lang attribute.
technologyCountintegerTechnologies
technologyNamesarrayTechnology names
Most specific category first, then by confidence.
byCategoryobjectBy category
Category name → technology names, e.g. { "CMS": ["WordPress"], "Analytics": ["Google Analytics"] }.
cmsstring | nullCMS
ecommercePlatformstring | nullE-commerce platform
analyticsarrayAnalytics
tagManagersarrayTag managers
advertisingarrayAdvertising and retargeting
marketingAutomationarrayMarketing automation
crmarrayCRM
liveChatarrayLive chat
paymentProcessorsarrayPayment processors
emailProviderstring | nullMailbox provider
From the MX records (Google Workspace, Microsoft 365, …).
emailSendersarrayE-mail senders
Services allowed to send the domain's mail (SPF includes).
hostingarrayHosting / PaaS / IaaS
cdnarrayCDN
webServerstring | nullWeb server
javascriptFrameworksarrayJavaScript frameworks
programmingLanguagesarrayProgramming languages
saasVerifiedByDnsarraySaaS seen in DNS
Technologies found in DNS records (verification tokens, MX, SPF, NS, CNAME).
technologiesarrayTechnologies
[{ name, slug, categories[], version, confidence (0–100), evidence[] (header, cookie, meta, scriptSrc, script, html, text, css, url, dom, cert, dns-txt, dns-spf, dns-mx, dns-ns, dns-soa, dns-cname, implied), website, impliedBy? }]
pagesAnalyzedintegerPages analysed
pagesarrayPages
[{ url, status }] of the analysed pages.
dnsCheckedbooleanDNS checked
certificateIssuerstring | nullTLS certificate issuer
rawobjectRaw
With includeRaw: { pages: [{ url, status, headers }], dns: { txt, mx, ns, cname } }.
Example record
{
  "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"
}

FAQ

Questions

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.

Machine-readable

This page for agents