Wappalyzer Alternative — Tech Stack Detector & BuiltWith API
NexGenData · @nexgendata
Tech stack lookup by URL: Wappalyzer & BuiltWith Alternative, a NexGenData tool, returns the technologies a website uses, grouped by category from the website's own pages.
About
Wappalyzer Alternative — Tech Stack Detector & BuiltWith API
Tech stack lookup by URL: Wappalyzer & BuiltWith Alternative, a NexGenData tool, returns the technologies a website uses, grouped by category from the website's own pages.
A Wappalyzer alternative and tech stack detector you can call as an API: give it website URLs, get back the technologies each site runs.
Point it at a domain, get the technology stack back. A curated catalog of 251 named technology fingerprints (CMS, analytics, frameworks, payment, hosting, ad-tech — the ones that matter for lead qualification and competitive research), each with the evidence that matched, a version where the site exposes one, and a confidence score. Bulk input, one row per domain analysed — built as a drop-in for teams whose Wappalyzer/BuiltWith plan lapsed.
Developer drop-in: a direct Wappalyzer/BuiltWith replacement for detecting a site's tech stack in code.
📊 Sample Output
url | status_code | tech_count | final_url | tech_names | category_list |
|---|---|---|---|---|---|
| https://stripe.com | 200 | 11 | https://stripe.com | Content Security Policy, Google Analytics 4, HSTS, Next.js, Nginx, No… | JavaScript Frameworks, Web Servers, Analytics, Databases, Miscellaneo… |
| https://shopify.com | 200 | 3 | https://www.shopify.com/ | Cloudflare, HSTS, HTTP/3 | CDN, Miscellaneous, Security |
Real rows from a real run (2026-09-24), unedited apart from masked emails/phones and shortened long text; fields the source does not publish are empty.
⚙️ Sample inputs
This is the pre-filled input; it returns rows on the current build. Paste it into the input form, or send it through the API, CLI or a schedule:
{
"urls": [
"https://stripe.com",
"https://shopify.com"
],
"include_confidence": true,
"include_versions": true,
"timeout_seconds": 15
}
🔧 Input reference
| Field | Type | Default | What it does |
|---|---|---|---|
urls | ['array', 'string'] | ["https://stripe.com", "https://shopify.com"] | One or more website URLs to detect tech stack on. Accepts bare hosts ('example.com') or full URLs ('https://example.com/path') — scheme is auto-added if missing. Also accepted und… |
categories_filter | array | [] | Optional: only return technologies whose category is in this list. Examples: 'CMS', 'Analytics', 'CDN', 'Ecommerce', 'JavaScript Frameworks', 'Payment Processors'. Leave empty to… |
include_confidence | boolean | true | When true, each detected technology includes a 0–100 confidence score. Header matches score 100, script-src matches 90, HTML-body matches 85, implied-only techs score 60. |
include_versions | boolean | true | When true, attempts to parse semantic version numbers out of matched headers, script URLs, and HTML. Example: '/[email protected]/' ⇒ version '18.2.0'. Version is null when no reliable… |
timeout_seconds | integer | 15 | Per-URL HTTP request timeout. Range 3–60. Increase for slow sites or if you are analyzing heavy pages that need longer download time. |
startUrls | array | [] | Alias of urls. Accepts plain URL strings or {url: ...} dict items. |
domains | array | [] | Alias of urls. Bare hostnames work too — scheme is auto-added. |
websites | array | [] | Alias of urls. |
targetUrls | array | [] | Alias of urls. |
url | string | "" | Alternative — a single URL when you only need one. Comma-separated values are auto-split. |
🧾 JSON sample record
One real record from a real run (emails/phones masked, long text shortened):
{
"url": "https://stripe.com",
"status_code": 200,
"tech_count": 11,
"categories": {
"JavaScript Frameworks": [
"Next.js",
"React"
],
"Web Servers": [
"Nginx"
],
"Analytics": [
"Google Analytics 4"
],
"Databases": [
"Supabase"
],
"Miscellaneous": [
"Open Graph",
"Schema.org",
"Twitter Card"
],
"Security": [
"Content Security Policy",
"HSTS"
],
"Programming Languages": [
"Node.js"
]
},
"technologies": [
{
"name": "Content Security Policy",
"category": "Security",
"evidence": "header: content-security-policy",
"version": null,
"confidence": 100
},
{
"name": "Google Analytics 4",
"category": "Analytics",
"evidence": "html: \"accounting-alphaNextToNumber\":\"¤ #,##0.00;(¤ #,##0.",
"version": null,
"confidence": 85
},
{
"name": "HSTS",
"category": "Security",
"evidence": "header: strict-transport-security",
"version": null,
"confidence": 100
},
{
"name": "Next.js",
"category": "JavaScript Frameworks",
"evidence": "script: https://b.stripecdn.com/mkt-ssr-statics/assets/_next/static/chunks/polyfills-42372ed130431b0a.js",
"version": null,
"confidence": 90
},
{
"name": "Nginx",
"category": "Web Servers",
"evidence": "header: server",
"version": null,
"confidence": 100
},
{
"name": "Node.js",
"category": "Programming Languages",
"evidence": "implied by Next.js",
"version": null,
"confidence": 60
},
{
"name": "Open Graph",
"category": "Miscellaneous",
"evidence": "html: p;h=180\"/><meta property=\"og:title\" content=\"Stripe | Finan",
"version": null,
"confidence": 85
},
{
"name": "React",
"category": "JavaScript Frameworks",
"evidence": "implied by Next.js",
"version": null,
"confidence": 60
},
"…"
],
"scan_time_ms": 3585,
"final_url": "https://stripe.com",
"tech_names": "Content Security Policy, Google Analytics 4, HSTS, Next.js, Nginx, Node.js, Open Graph, React, Schema.org, Supabase, Twitter Card",
"category_list": "JavaScript Frameworks, Web Servers, Analytics, Databases, Miscellaneous, Security, Programming Languages"
}
📊 What you get
Clean JSON output (9 fields):
url— Urlstatus_code— Status codetech_count— Tech countcategories— Categoriestechnologies— Technologiesscan_time_ms— Scan time msfinal_url— Final urltech_names— Tech names
🤖 Use with AI agents
Point Claude, the OpenAI Agents SDK, an n8n flow or any MCP-aware client at it.
Sample agent prompt:
Run Tech Stack Detector on my input and return the structured results.
Run it on a schedule
A website's tech stack does not change often, so a monthly run over your domain list is enough for most lead qualification. Run it weekly if you are watching specific competitors for a switch, such as a new CMS, analytics tool or payment provider. Between runs the same sites come back with updated technologies, tech_names and tech_count, so you can spot tools that were added or removed. The actor has no built-in change-only mode, so compare runs by url to see what changed. Send each run's results onward with a webhook, Google Sheets, Zapier, Make or the Bytewells API.
FAQ
Why use this instead of Wappalyzer or BuiltWith?
It is not connected to either product. It is a separate detector you can call in bulk without a subscription or a separate API key, and you pay per site analysed. You give it a list of URLs and get one clean JSON row per site, with technologies grouped by category, the evidence that matched, a version where the site exposes one, and a confidence score. It works from its own catalog of 251 named technologies, so it will not recognise every tool those products know.
What does a typical run cost?
One flat monthly price, with a free trial; there is no per-row charge. Bytewells bills compute separately from your prepaid credit, by memory and run time.
How do I find out what CMS or framework a website uses?
Put the site in urls (a bare host such as example.com works). The result shows each technology under its category, such as CMS, JavaScript Frameworks or Analytics. To return only certain categories, list them in categories_filter, for example CMS and Ecommerce.
How does it detect technologies, and how sure is each match?
It checks the site's response headers, the HTML and the script URLs it loads. With include_confidence on, each technology gets a 0 to 100 score: header matches score 100, script matches 90, HTML matches 85, and technologies implied by another one (such as React implied by Next.js) score 60. Versions appear only when the site exposes them; otherwise version is empty.
Can I check tech stacks for a big list of websites at once?
Yes. Pass many URLs in urls and you get one row per site. Slow or heavy sites may need a longer timeout_seconds (range 3 to 60, default 15).
Does it show a site's tech history or who uses a given technology?
No. It reports what each site you give it runs at the time of the run. It does not search for all sites using a technology and does not keep a history; schedule it and keep each run's results if you want one.
How it is billed on Bytewells
One flat monthly price for this actor, with a free trial to start. There is no charge per row, per result or per run from us.
Compute is billed separately by Bytewells from your prepaid credit, by memory and run time (per second). If a run uses the platform's proxy, Bytewells adds that traffic to the same run's compute bill.
Run it from the API
Bytewells speaks the same API as Apify, so curl or apify-client work with the Bytewells address and your Bytewells API key.
curl -X POST "https://bytewells.com/api/v2/acts/nexgendata~wappalyzer-replacement/runs" \
-H "Authorization: Bearer YOUR_BYTEWELLS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"urls": ["https://stripe.com", "https://shopify.com"], "categories_filter": [], "include_confidence": true, "include_versions": true, "timeout_seconds": 15, "startUrls": [], "domains": [], "websites": [], "targetUrls": [], "url": ""}'
# when the run has finished, read its rows:
curl -H "Authorization: Bearer YOUR_BYTEWELLS_API_KEY" \
"https://bytewells.com/api/v2/actor-runs/RUN_ID/dataset/items"
from apify_client import ApifyClient
client = ApifyClient("YOUR_BYTEWELLS_API_KEY", api_url="https://bytewells.com/api")
run = client.actor("nexgendata/wappalyzer-replacement").call(run_input={'urls': ['https://stripe.com', 'https://shopify.com'], 'categories_filter': [], 'include_confidence': True, 'include_versions': True, 'timeout_seconds': 15, 'startUrls': [], 'domains': [], 'websites': [], 'targetUrls': [], 'url': ''})
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
print(row)
Contact
Questions, a source that changed, or a field you need: [email protected]
Input
Preview of the input form. Rent the Actor to fill it in and start runs from the console.
Fields
urlsWebsites to run the tech stack detector on (Wappalyzer alternative input). One or more website URLs to detect tech stack on. Accepts bare hosts ('example.com') or full URLs ('https://example.com/path') — scheme is auto-added if missing. Also accepted under aliases: startUrls, domains, websites, targetUrls. Single string inputs and comma/newline-separated strings are auto-coerced to a list.
categories_filterOptional: only return technologies whose category is in this list. Examples: 'CMS', 'Analytics', 'CDN', 'Ecommerce', 'JavaScript Frameworks', 'Payment Processors'. Leave empty to return all categories.
include_confidenceWhen true, each detected technology includes a 0–100 confidence score. Header matches score 100, script-src matches 90, HTML-body matches 85, implied-only techs score 60.
include_versionsWhen true, attempts to parse semantic version numbers out of matched headers, script URLs, and HTML. Example: '/[email protected]/' ⇒ version '18.2.0'. Version is null when no reliable signal is present.
timeout_secondsPer-URL HTTP request timeout. Range 3–60. Increase for slow sites or if you are analyzing heavy pages that need longer download time.
startUrlsAlias of urls. Accepts plain URL strings or {url: ...} dict items.
domainsAlias of urls. Bare hostnames work too — scheme is auto-added.
websitesAlias of urls.
targetUrlsAlias of urls.
urlAlternative — a single URL when you only need one. Comma-separated values are auto-split.
API
Bytewells speaks the Apify API. Existing integrations keep working: point apify-client at https://bytewells.com/api and use your Bytewells API token (Console → Settings → API access). The Actor ID is nexgendata/wappalyzer-replacement (or nexgendata~wappalyzer-replacement in URLs).
JavaScript · apify-client
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({
token: process.env.BYTEWELLS_TOKEN,
baseUrl: 'https://bytewells.com/api',
});
const input = {
"urls": [
"https://stripe.com",
"https://shopify.com"
],
"categories_filter": [],
"include_confidence": true,
"include_versions": true,
"timeout_seconds": 15,
"startUrls": [],
"domains": [],
"websites": [],
"targetUrls": [],
"url": ""
};
const run = await client.actor('nexgendata/wappalyzer-replacement').call(input);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);Python · apify-client
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ["BYTEWELLS_TOKEN"], api_url="https://bytewells.com/api")
run_input = {
"urls": [
"https://stripe.com",
"https://shopify.com"
],
"categories_filter": [],
"include_confidence": True,
"include_versions": True,
"timeout_seconds": 15,
"startUrls": [],
"domains": [],
"websites": [],
"targetUrls": [],
"url": ""
}
run = client.actor("nexgendata/wappalyzer-replacement").call(run_input=run_input)
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(items)HTTP · curl
curl -X POST "https://bytewells.com/api/v2/acts/nexgendata~wappalyzer-replacement/runs" \
-H "Authorization: Bearer $BYTEWELLS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"urls":["https://stripe.com","https://shopify.com"],"categories_filter":[],"include_confidence":true,"include_versions":true,"timeout_seconds":15,"startUrls":[],"domains":[],"websites":[],"targetUrls":[],"url":""}'Runs are billed as compute from your credit balance. Paid Actors need an active rental or trial; otherwise the API answers 402 rental-required.
Related
More Actors from the same publisher.
Lead Enrichment — Enrich Leads with Emails, Phones & Tech
NexGenData · @nexgendata
Lead Enrichment is a NexGenData tool that returns emails, phone numbers, social profiles and tech stack per company from each company's own website.
BusinessMarketingLead generation$19/mo1-day free trialPR Newswire Scraper — Press Releases by Company, Topic & Date
NexGenData · @nexgendata
PR Newswire Scraper is a NexGenData tool that returns press releases with headline, date, category and stock tickers from PR Newswire.
BusinessMarketingLead generation$49/mo3-day free trialDelaware Corporations Search — DE Entity Data API
NexGenData · @nexgendata
Delaware Corporations Search is a NexGenData tool that returns one row per Delaware entity from the Delaware Division of Corporations registry with entity name, file number, formation date, entity kind and type, residency, and registered agent name, address and phone.
BusinessLead generation$79/mo1-day free trialASX Announcements Scraper — Australian Company Disclosures
NexGenData · @nexgendata
ASX Announcements Scraper is a NexGenData tool that returns company announcements with ticker, headline, type and source PDF link from the Australian Securities Exchange.
$29/mo3-day free trialBilibili Video Search by Keyword · B站视频搜索 (No Login)
NexGenData · @nexgendata
Bilibili Video Search is a NexGenData tool that returns videos with BV-id, title, uploader, plays, likes and danmaku from Bilibili keyword search.
$19/mo1-day free trialLinkedIn Jobs Scraper — No Login, by Keyword & Location
NexGenData · @nexgendata
LinkedIn Jobs Scraper is a NexGenData tool that returns job listings with title, company, salary and posting date from public LinkedIn job pages.
$29/mo3-day free trial