<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: MikeL</title>
    <description>The latest articles on DEV Community by MikeL (@detectzestack).</description>
    <link>https://dev.to/detectzestack</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2107035%2Fe0c68bde-32d6-4613-b96c-c6abfa4280b1.png</url>
      <title>DEV Community: MikeL</title>
      <link>https://dev.to/detectzestack</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/detectzestack"/>
    <language>en</language>
    <item>
      <title>How to Detect cdnjs on Any Website (API Guide)</title>
      <dc:creator>MikeL</dc:creator>
      <pubDate>Tue, 30 Jun 2026 14:00:53 +0000</pubDate>
      <link>https://dev.to/detectzestack/how-to-detect-cdnjs-on-any-website-api-guide-5h76</link>
      <guid>https://dev.to/detectzestack/how-to-detect-cdnjs-on-any-website-api-guide-5h76</guid>
      <description>&lt;p&gt;cdnjs is one of the most widely used free public CDNs on the web. It is a community-run, open-source library-delivery service hosted on Cloudflare's network, and it lets a developer drop a single &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag into a page to pull in jQuery, Font Awesome, Lodash, or almost any popular open-source package without hosting a file. That convenience is exactly why “loads assets from cdnjs” is a useful detection signal: it tells you something concrete about how a team builds and ships its front end.&lt;/p&gt;

&lt;p&gt;This guide walks through detecting cdnjs on a website—what it actually is, where it shows up in a page's source, how to spot it manually, and how a single DetectZeStack API call returns cdnjs along with the specific libraries and versions it is delivering. We will start with a one-line check you can run right now.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is cdnjs and Why Detect It
&lt;/h2&gt;

&lt;p&gt;cdnjs (short for “CDN for JavaScript”) is a free, open-source content delivery service that mirrors thousands of popular front-end libraries and serves them from the &lt;code&gt;cdnjs.cloudflare.com&lt;/code&gt; hostname. Where an infrastructure CDN like Cloudflare or Amazon CloudFront proxies a whole site's traffic, cdnjs does something narrower: it hands out versioned copies of &lt;em&gt;other people's&lt;/em&gt; open-source code so a page does not have to bundle and self-host them.&lt;/p&gt;

&lt;p&gt;A confirmed cdnjs reference is a small but specific window into a team's front-end habits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;They lean on public CDNs for dependencies.&lt;/strong&gt; Loading libraries from &lt;code&gt;cdnjs.cloudflare.com&lt;/code&gt; rather than bundling and self-hosting them is a deliberate choice. It often signals a leaner build setup—static sites, server-rendered pages, or templates where a script tag is faster than running a bundler.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It usually arrives with the library it delivers.&lt;/strong&gt; cdnjs rarely travels alone. The same page that references it is almost always loading a detectable library—jQuery, Font Awesome, a charting or animation library—so one detection often hands you a slice of the front-end stack as well.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It hints at a supply-chain posture.&lt;/strong&gt; Teams that pull live third-party scripts from a public CDN have a different dependency surface than teams that vendor everything. For security tooling, software-composition-analysis, or subresource-integrity products, that distinction is the qualifier.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The same detection pipeline applies to any technology DetectZeStack recognizes. We have companion guides for the sibling library-delivery CDN &lt;a href="https://detectzestack.com/blog/find-companies-using-jsdelivr" rel="noopener noreferrer"&gt;jsDelivr&lt;/a&gt; and for &lt;a href="https://detectzestack.com/blog/find-companies-using-google-hosted-libraries" rel="noopener noreferrer"&gt;Google Hosted Libraries&lt;/a&gt;—the fingerprint changes, the workflow stays the same.&lt;/p&gt;

&lt;h2&gt;
  
  
  How cdnjs Shows Up in a Website's Source
&lt;/h2&gt;

&lt;p&gt;cdnjs is a &lt;em&gt;library-delivery&lt;/em&gt; CDN. It exists to serve versioned, open-source assets—a specific build of jQuery, a pinned release of Font Awesome, a particular Lodash version—straight from Cloudflare-hosted mirrors. A company does not put its own domain behind cdnjs; it references cdnjs from inside its pages to fetch other people's code.&lt;/p&gt;

&lt;p&gt;That has a direct consequence for detection. Finding cdnjs on a site does not tell you who hosts the site or how its traffic is proxied. It tells you the page intentionally pulls at least one third-party asset from cdnjs, and it points you at &lt;em&gt;which&lt;/em&gt; asset when that asset is itself fingerprintable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Script tags pointing to cdnjs.cloudflare.com
&lt;/h3&gt;

&lt;p&gt;Every cdnjs reference resolves to the same hostname. In the page source it looks like an ordinary script or stylesheet link:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The constant across all of them is the &lt;code&gt;cdnjs.cloudflare.com&lt;/code&gt; host. That single string is the primary fingerprint: if it appears in a &lt;code&gt;script src&lt;/code&gt; or a &lt;code&gt;link href&lt;/code&gt; in the served HTML, the page references cdnjs. It is also why cdnjs implies Cloudflare—the service is hosted on Cloudflare's network, so a cdnjs match means the page is pulling code from a Cloudflare-hosted origin, distinct from the whole site being proxied through Cloudflare.&lt;/p&gt;

&lt;h3&gt;
  
  
  Library and version fingerprints cdnjs leaves behind
&lt;/h3&gt;

&lt;p&gt;cdnjs URLs are unusually informative because the path is structured: &lt;code&gt;/ajax/libs/&amp;lt;library&amp;gt;/&amp;lt;version&amp;gt;/&amp;lt;file&amp;gt;&lt;/code&gt;. The example above encodes the library (&lt;code&gt;jquery&lt;/code&gt;) and the exact version (&lt;code&gt;3.6.0&lt;/code&gt;) right in the URL. That structure means two things show up in a single page fetch—the delivery method (cdnjs) and the delivered library, frequently with its version parsed straight from the path.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Signal&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;th&gt;What It Tells You&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;cdnjs host reference&lt;/td&gt;
&lt;td&gt;cdnjs.cloudflare.com&lt;/td&gt;
&lt;td&gt;cdnjs confirmed (CDN)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Delivered library + version&lt;/td&gt;
&lt;td&gt;.../ajax/libs/jquery/3.6.0/jquery.min.js&lt;/td&gt;
&lt;td&gt;jQuery confirmed, version parsed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Self-hosted library&lt;/td&gt;
&lt;td&gt;/static/js/jquery.min.js&lt;/td&gt;
&lt;td&gt;Library detected, no cdnjs signal&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No cdnjs reference&lt;/td&gt;
&lt;td&gt;(none in HTML)&lt;/td&gt;
&lt;td&gt;Page does not load assets from cdnjs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Manual Ways to Detect cdnjs (and Their Limits)
&lt;/h2&gt;

&lt;p&gt;Because cdnjs lives in the page body, you can spot the raw signal yourself without any tooling. The fastest check is a single &lt;code&gt;curl&lt;/code&gt; piped into &lt;code&gt;grep&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://example.com | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="s2"&gt;"cdnjs&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="s2"&gt;cloudflare&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="s2"&gt;com"&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt;
cdnjs.cloudflare.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One match is enough to confirm the page references cdnjs. To see exactly &lt;em&gt;what&lt;/em&gt; it is pulling, widen the pattern to capture the full URLs and read the library and version out of each path:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://example.com &lt;span class="se"&gt;\&lt;/span&gt;
| &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-oE&lt;/span&gt; &lt;span class="s2"&gt;"cdnjs&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="s2"&gt;cloudflare&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="s2"&gt;com/ajax/libs/[^&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;']+"&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt;
cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js
cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This works, but it has real limits when you move past one site. The reference only appears if it is present in the server-rendered HTML—a script injected later by client-side JavaScript, or one loaded through a tag manager, may not show up in a plain &lt;code&gt;curl&lt;/code&gt;. You also have to parse each path yourself to turn it into structured data, and running this across hundreds of domains means writing your own concurrency, retry, and timeout handling. That is the gap a detection API closes: it normalizes the same body signal into clean JSON and runs it at scale.&lt;/p&gt;

&lt;h2&gt;
  
  
  Detect cdnjs Programmatically with the DetectZeStack API
&lt;/h2&gt;

&lt;p&gt;When DetectZeStack fetches a page, it scans the HTML for script and link references to &lt;code&gt;cdnjs.cloudflare.com&lt;/code&gt;. A match returns cdnjs under the &lt;strong&gt;CDN&lt;/strong&gt; category at confidence 100, with &lt;code&gt;source: "http"&lt;/code&gt;—because the evidence came directly from the HTTP response body.&lt;/p&gt;

&lt;p&gt;You can try it right now against the public demo endpoint—no API key required. The demo is IP-rate-limited, so use it for spot checks rather than bulk scans:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://detectzestack.com/demo?url=example.com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
| jq &lt;span class="s1"&gt;'.technologies[] | select(.name == "cdnjs")'&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="s2"&gt;"name"&lt;/span&gt;: &lt;span class="s2"&gt;"cdnjs"&lt;/span&gt;,
&lt;span class="s2"&gt;"categories"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"CDN"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;,
&lt;span class="s2"&gt;"confidence"&lt;/span&gt;: 100,
&lt;span class="s2"&gt;"description"&lt;/span&gt;: &lt;span class="s2"&gt;"cdnjs is a free distributed JS library delivery service."&lt;/span&gt;,
&lt;span class="s2"&gt;"website"&lt;/span&gt;: &lt;span class="s2"&gt;"https://cdnjs.com"&lt;/span&gt;,
&lt;span class="s2"&gt;"icon"&lt;/span&gt;: &lt;span class="s2"&gt;"cdnjs.svg"&lt;/span&gt;,
&lt;span class="s2"&gt;"source"&lt;/span&gt;: &lt;span class="s2"&gt;"http"&lt;/span&gt;,
&lt;span class="s2"&gt;"version"&lt;/span&gt;: &lt;span class="s2"&gt;""&lt;/span&gt;,
&lt;span class="s2"&gt;"cpe"&lt;/span&gt;: &lt;span class="s2"&gt;""&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;cdnjs is matched directly off the &lt;code&gt;cdnjs.cloudflare.com&lt;/code&gt; reference in the page and categorized under &lt;code&gt;CDN&lt;/code&gt;. It carries &lt;code&gt;source: "http"&lt;/code&gt; because the evidence came from the HTTP response body, and the &lt;code&gt;version&lt;/code&gt; field is empty—cdnjs itself is a delivery network, not a versioned library, so there is nothing to read a version from. The libraries it delivers are where versions show up.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reading the technologies, version, and categories fields
&lt;/h3&gt;

&lt;p&gt;When you want the full stack for a domain rather than a filtered slice, call &lt;code&gt;/analyze&lt;/code&gt; with your API key. A page that loads jQuery from cdnjs comes back like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://detectzestack.p.rapidapi.com/analyze?url=example.com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-RapidAPI-Key: YOUR_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-RapidAPI-Host: detectzestack.p.rapidapi.com"&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="s2"&gt;"url"&lt;/span&gt;: &lt;span class="s2"&gt;"https://example.com"&lt;/span&gt;,
&lt;span class="s2"&gt;"domain"&lt;/span&gt;: &lt;span class="s2"&gt;"example.com"&lt;/span&gt;,
&lt;span class="s2"&gt;"technologies"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="s2"&gt;"name"&lt;/span&gt;: &lt;span class="s2"&gt;"cdnjs"&lt;/span&gt;,
&lt;span class="s2"&gt;"categories"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"CDN"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;,
&lt;span class="s2"&gt;"confidence"&lt;/span&gt;: 100,
&lt;span class="s2"&gt;"description"&lt;/span&gt;: &lt;span class="s2"&gt;"cdnjs is a free distributed JS library delivery service."&lt;/span&gt;,
&lt;span class="s2"&gt;"website"&lt;/span&gt;: &lt;span class="s2"&gt;"https://cdnjs.com"&lt;/span&gt;,
&lt;span class="s2"&gt;"icon"&lt;/span&gt;: &lt;span class="s2"&gt;"cdnjs.svg"&lt;/span&gt;,
&lt;span class="s2"&gt;"source"&lt;/span&gt;: &lt;span class="s2"&gt;"http"&lt;/span&gt;,
&lt;span class="s2"&gt;"version"&lt;/span&gt;: &lt;span class="s2"&gt;""&lt;/span&gt;,
&lt;span class="s2"&gt;"cpe"&lt;/span&gt;: &lt;span class="s2"&gt;""&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;,
&lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="s2"&gt;"name"&lt;/span&gt;: &lt;span class="s2"&gt;"jQuery"&lt;/span&gt;,
&lt;span class="s2"&gt;"categories"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"JavaScript libraries"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;,
&lt;span class="s2"&gt;"confidence"&lt;/span&gt;: 100,
&lt;span class="s2"&gt;"description"&lt;/span&gt;: &lt;span class="s2"&gt;"jQuery is a JavaScript library designed to simplify HTML DOM tree traversal and manipulation, as well as event handling, CSS animation, and Ajax."&lt;/span&gt;,
&lt;span class="s2"&gt;"website"&lt;/span&gt;: &lt;span class="s2"&gt;"https://jquery.com"&lt;/span&gt;,
&lt;span class="s2"&gt;"icon"&lt;/span&gt;: &lt;span class="s2"&gt;"jQuery.svg"&lt;/span&gt;,
&lt;span class="s2"&gt;"source"&lt;/span&gt;: &lt;span class="s2"&gt;"http"&lt;/span&gt;,
&lt;span class="s2"&gt;"version"&lt;/span&gt;: &lt;span class="s2"&gt;"3.6.0"&lt;/span&gt;,
&lt;span class="s2"&gt;"cpe"&lt;/span&gt;: &lt;span class="s2"&gt;""&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;,
&lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="s2"&gt;"name"&lt;/span&gt;: &lt;span class="s2"&gt;"Cloudflare"&lt;/span&gt;,
&lt;span class="s2"&gt;"categories"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"CDN"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;,
&lt;span class="s2"&gt;"confidence"&lt;/span&gt;: 100,
&lt;span class="s2"&gt;"description"&lt;/span&gt;: &lt;span class="s2"&gt;"Cloudflare is a web-infrastructure and website-security company that provides content-delivery-network services, DDoS mitigation, and ICANN-accredited domain registration services."&lt;/span&gt;,
&lt;span class="s2"&gt;"website"&lt;/span&gt;: &lt;span class="s2"&gt;"https://www.cloudflare.com"&lt;/span&gt;,
&lt;span class="s2"&gt;"icon"&lt;/span&gt;: &lt;span class="s2"&gt;"CloudFlare.svg"&lt;/span&gt;,
&lt;span class="s2"&gt;"source"&lt;/span&gt;: &lt;span class="s2"&gt;"http"&lt;/span&gt;,
&lt;span class="s2"&gt;"version"&lt;/span&gt;: &lt;span class="s2"&gt;""&lt;/span&gt;,
&lt;span class="s2"&gt;"cpe"&lt;/span&gt;: &lt;span class="s2"&gt;""&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;]&lt;/span&gt;,
&lt;span class="s2"&gt;"categories"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="s2"&gt;"CDN"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"cdnjs"&lt;/span&gt;, &lt;span class="s2"&gt;"Cloudflare"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;,
&lt;span class="s2"&gt;"JavaScript libraries"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"jQuery"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;,
&lt;span class="s2"&gt;"meta"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"status_code"&lt;/span&gt;: 200, &lt;span class="s2"&gt;"tech_count"&lt;/span&gt;: 3, &lt;span class="s2"&gt;"scan_depth"&lt;/span&gt;: &lt;span class="s2"&gt;"full"&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;,
&lt;span class="s2"&gt;"cached"&lt;/span&gt;: &lt;span class="nb"&gt;false&lt;/span&gt;,
&lt;span class="s2"&gt;"response_ms"&lt;/span&gt;: 1842
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three entries from one page. cdnjs is the delivery method; jQuery is the thing being delivered, with its version parsed from the script URL; and Cloudflare appears because cdnjs is hosted on Cloudflare's network and its fingerprint implies Cloudflare. The top-level &lt;code&gt;categories&lt;/code&gt; map groups every detection, so you can pull all CDNs with &lt;code&gt;.categories["CDN"]&lt;/code&gt; without iterating the array. The &lt;code&gt;meta&lt;/code&gt; object carries the HTTP &lt;code&gt;status_code&lt;/code&gt;, the &lt;code&gt;tech_count&lt;/code&gt;, and the &lt;code&gt;scan_depth&lt;/code&gt;; &lt;code&gt;response_ms&lt;/code&gt; and &lt;code&gt;cached&lt;/code&gt; sit at the top level.&lt;/p&gt;

&lt;p&gt;One field to watch for list building is &lt;code&gt;meta.scan_depth&lt;/code&gt;. A value of &lt;code&gt;"full"&lt;/code&gt; means the HTTP fetch succeeded and body detection ran. A value of &lt;code&gt;"partial"&lt;/code&gt; means the site blocked or timed out the HTTP request and only DNS and TLS layers completed—and since cdnjs lives in the body, an absent cdnjs entry on a &lt;code&gt;"partial"&lt;/code&gt; scan tells you nothing. Those domains belong in a retry queue, not your rejects file.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The honest limitation: cdnjs detection depends on the HTML actually containing the reference. If a script is injected later by client-side JavaScript that never runs during a server-side fetch, or if the reference sits behind a tag manager, it may not appear in the fetched body. As with any body-fingerprint signal, absence of a detection is an unknown, not proof the site never touches cdnjs.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Detecting cdnjs Across Many Sites at Scale
&lt;/h2&gt;

&lt;p&gt;For list building, &lt;code&gt;POST /analyze/batch&lt;/code&gt; accepts up to 10 URLs per request and analyzes them concurrently. Each entry in the response carries either a full analysis result or an error for domains that could not be fetched:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"https://detectzestack.p.rapidapi.com/analyze/batch"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-RapidAPI-Key: YOUR_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-RapidAPI-Host: detectzestack.p.rapidapi.com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"urls": ["example.com", "getbootstrap.com", "wordpress.org"]}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response wraps one result object per URL, each with the same shape as a single &lt;code&gt;/analyze&lt;/code&gt; response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"results"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"example.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="nl"&gt;"result"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"...full analysis..."&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"getbootstrap.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="nl"&gt;"result"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"...full analysis..."&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"wordpress.org"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nl"&gt;"result"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"...full analysis..."&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"total_ms"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2341&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"successful"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"failed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because each &lt;code&gt;result&lt;/code&gt; matches the single-domain shape, the filtering logic is identical whether you scan one domain or a thousand. Here is a complete, copy-pasteable pipeline using nothing but &lt;code&gt;bash&lt;/code&gt;, &lt;code&gt;curl&lt;/code&gt;, and &lt;code&gt;jq&lt;/code&gt;. It reads &lt;code&gt;domains.txt&lt;/code&gt; (one domain per line), sends batches of 10 to &lt;code&gt;/analyze/batch&lt;/code&gt;, and appends every domain where cdnjs is detected to &lt;code&gt;cdnjs_leads.csv&lt;/code&gt;, recording the tech count alongside it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/usr/bin/env bash&lt;/span&gt;
&lt;span class="c"&gt;# find-cdnjs.sh — filter a domain list down to cdnjs-confirmed sites&lt;/span&gt;
&lt;span class="nv"&gt;KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"YOUR_KEY"&lt;/span&gt;
&lt;span class="nv"&gt;HOST&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"detectzestack.p.rapidapi.com"&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"domain,tech_count"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; cdnjs_leads.csv

&lt;span class="c"&gt;# Process domains.txt in batches of 10 (the /analyze/batch maximum)&lt;/span&gt;
xargs &lt;span class="nt"&gt;-n&lt;/span&gt; 10 &amp;lt; domains.txt | &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="nb"&gt;read&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; batch&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
&lt;/span&gt;&lt;span class="nv"&gt;urls&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'%s\n'&lt;/span&gt; &lt;span class="nv"&gt;$batch&lt;/span&gt; | jq &lt;span class="nt"&gt;-R&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt; | jq &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s1"&gt;'{urls: .}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"https://&lt;/span&gt;&lt;span class="nv"&gt;$HOST&lt;/span&gt;&lt;span class="s2"&gt;/analyze/batch"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-RapidAPI-Key: &lt;/span&gt;&lt;span class="nv"&gt;$KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-RapidAPI-Host: &lt;/span&gt;&lt;span class="nv"&gt;$HOST&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$urls&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; |
jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.results[]
| select(.result != null)
| .result as $r
| select([$r.technologies[].name] | index("cdnjs"))
| [$r.domain, ($r.meta.tech_count | tostring)]
| @csv'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; cdnjs_leads.csv
&lt;span class="k"&gt;done

&lt;/span&gt;&lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; cdnjs_leads.csv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A 1,000-domain list becomes 100 batch calls. The &lt;code&gt;index("cdnjs")&lt;/code&gt; guard keeps a domain whenever cdnjs appears in its technology list, and &lt;code&gt;select(.result != null)&lt;/code&gt; skips domains that failed to resolve (those come back with an &lt;code&gt;error&lt;/code&gt; field instead of a &lt;code&gt;result&lt;/code&gt;). For a deeper treatment of batch throughput, retries, and a production Python scanner, see &lt;a href="https://detectzestack.com/blog/batch-scan-1000-websites" rel="noopener noreferrer"&gt;how to batch scan 1,000 websites&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you want to segment by the library cdnjs is delivering rather than just the delivery method, widen the filter to capture the co-detected technologies—the same &lt;code&gt;technologies&lt;/code&gt; array already carries jQuery, Font Awesome, and whatever else the page pulls in. Our guides on &lt;a href="https://detectzestack.com/blog/how-to-detect-jquery" rel="noopener noreferrer"&gt;detecting jQuery&lt;/a&gt; and the broader &lt;a href="https://detectzestack.com/blog/detect-javascript-framework-website" rel="noopener noreferrer"&gt;JavaScript framework detection&lt;/a&gt; cover those fingerprints in detail.&lt;/p&gt;

&lt;h2&gt;
  
  
  cdnjs vs Other JavaScript CDNs
&lt;/h2&gt;

&lt;p&gt;“CDN” is an overloaded word, and it helps to be precise about where cdnjs sits. There are two very different things both called CDNs:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Examples&lt;/th&gt;
&lt;th&gt;Detected From&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Infrastructure CDN&lt;/td&gt;
&lt;td&gt;Cloudflare, Fastly, Amazon CloudFront, Akamai&lt;/td&gt;
&lt;td&gt;DNS CNAME, response headers, TLS certificate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Library-delivery CDN&lt;/td&gt;
&lt;td&gt;cdnjs, jsDelivr, unpkg, Google Hosted Libraries&lt;/td&gt;
&lt;td&gt;Script &amp;amp; link references in the page HTML&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;An infrastructure CDN proxies the whole site, so it shows up in the site's DNS, headers, and certificate—the layer covered in &lt;a href="https://detectzestack.com/blog/detect-cdn-hosting-provider" rel="noopener noreferrer"&gt;how to detect a website's CDN and hosting provider&lt;/a&gt; and, for one specific provider, &lt;a href="https://detectzestack.com/blog/find-companies-using-amazon-cloudfront" rel="noopener noreferrer"&gt;finding companies using Amazon CloudFront&lt;/a&gt;. cdnjs sits in the other column: it is detected purely from references inside the served HTML, alongside its peers jsDelivr (&lt;code&gt;cdn.jsdelivr.net&lt;/code&gt;), unpkg (&lt;code&gt;unpkg.com&lt;/code&gt;), and Google Hosted Libraries (&lt;code&gt;ajax.googleapis.com&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;cdnjs is closest to jsDelivr—both serve open-source libraries from a public mirror—with one wrinkle: cdnjs is hosted on Cloudflare, so its detection implies Cloudflare, while jsDelivr is independent. The flip side of both is the self-hosted case. A team that runs a bundler and ships its libraries from its own domain will load, say, jQuery from &lt;code&gt;/static/js/jquery.min.js&lt;/code&gt;—no cdnjs reference at all. The library is still detectable on its own fingerprint, but the delivery signal is absent. A missing cdnjs detection does not mean the site avoids jQuery; it means the site does not &lt;em&gt;fetch jQuery from cdnjs&lt;/em&gt;. Keep that distinction in mind when you read negatives.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get Your API Key and Start Detecting cdnjs
&lt;/h2&gt;

&lt;p&gt;The free tier includes 100 requests per month with no credit card—enough to validate the pipeline on a sample of your domain list before scaling up. Sign-up is instant through RapidAPI:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Get a key at &lt;a href="https://rapidapi.com/mlugoapx/api/detectzestack" rel="noopener noreferrer"&gt;rapidapi.com/mlugoapx/api/detectzestack&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Spot-check a domain you know: &lt;code&gt;curl -s "https://detectzestack.com/demo?url=yourdomain.com" | jq '.technologies[].name'&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Run the batch script above against your first 100 domains.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Detecting cdnjs comes down to reading one thing well: a &lt;code&gt;cdnjs.cloudflare.com&lt;/code&gt; reference in the page HTML. Because cdnjs is a library-delivery CDN rather than an infrastructure one, it is detected from the body, not from DNS or headers—and the real prize is usually the library it carries, whose name and version are encoded right in the URL path and returned alongside it. A single &lt;code&gt;/analyze&lt;/code&gt; call answers the one-domain question; &lt;code&gt;/analyze/batch&lt;/code&gt; turns a raw domain list into a cdnjs-confirmed list; and &lt;code&gt;meta.scan_depth&lt;/code&gt; tells you which negatives are real and which are unknowns worth a retry. Swap the &lt;code&gt;jq&lt;/code&gt; filter and the same pipeline segments by front-end library, infrastructure CDN, or backend runtime instead.&lt;/p&gt;

&lt;h3&gt;
  
  
  Related Reading
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/find-companies-using-jsdelivr" rel="noopener noreferrer"&gt;Find Companies Using jsDelivr&lt;/a&gt; — The sibling library-delivery CDN (cdn.jsdelivr.net), detected from the page HTML the same way&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/find-companies-using-google-hosted-libraries" rel="noopener noreferrer"&gt;Find Companies Using Google Hosted Libraries&lt;/a&gt; — The other major library-delivery CDN (ajax.googleapis.com), with the delivered library and version encoded in the URL path&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/detect-cdn-hosting-provider" rel="noopener noreferrer"&gt;How to Detect the CDN and Hosting Provider of Any Website&lt;/a&gt; — The infrastructure-CDN layer that sits in front of a site, detected via DNS, headers, and TLS&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/how-to-detect-jquery" rel="noopener noreferrer"&gt;How to Detect jQuery on a Website&lt;/a&gt; — One of the most common libraries delivered over cdnjs, and its own fingerprints&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/find-companies-using-amazon-cloudfront" rel="noopener noreferrer"&gt;Find Companies Using Amazon CloudFront&lt;/a&gt; — An infrastructure CDN detected from headers, DNS, and TLS instead of the page body&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/batch-scan-1000-websites" rel="noopener noreferrer"&gt;How to Batch Scan 1,000 Websites for Tech Stack Data&lt;/a&gt; — Deep dive on /analyze/batch throughput, retries, and a Python scanner&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/lead-enrichment-pipeline-with-tech-detection" rel="noopener noreferrer"&gt;Lead Enrichment Pipeline with Tech Detection&lt;/a&gt; — Turning raw detections into scored, routable leads&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>techstack</category>
      <category>webdev</category>
      <category>api</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Find Companies Using jsDelivr: Technographic API Guide</title>
      <dc:creator>MikeL</dc:creator>
      <pubDate>Mon, 22 Jun 2026 14:00:54 +0000</pubDate>
      <link>https://dev.to/detectzestack/find-companies-using-jsdelivr-technographic-api-guide-48aa</link>
      <guid>https://dev.to/detectzestack/find-companies-using-jsdelivr-technographic-api-guide-48aa</guid>
      <description>&lt;p&gt;jsDelivr is one of the most widely used free public CDNs on the web. It serves open-source files directly from the npm registry and GitHub repositories, which means a developer can drop a single &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag into a page and pull in Bootstrap, Chart.js, a jQuery plugin, or almost any published package without hosting a thing themselves. That convenience is exactly what makes “uses jsDelivr” an interesting technographic signal: it tells you something about how a team builds and ships front-end code.&lt;/p&gt;

&lt;p&gt;This guide explains what jsDelivr usage actually reveals about a company, why it is detected differently from an infrastructure CDN like Cloudflare, and how to turn a raw domain list into a jsDelivr-confirmed lead list with the DetectZeStack API—starting with a single curl command you can run right now.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Find Companies Using jsDelivr?
&lt;/h2&gt;

&lt;p&gt;Technographic data—what technology a company runs—is frequently a stronger qualifier than firmographics alone. A confirmed jsDelivr reference is a small but specific window into a team's front-end habits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;They lean on public CDNs for dependencies.&lt;/strong&gt; Loading libraries from &lt;code&gt;cdn.jsdelivr.net&lt;/code&gt; rather than bundling and self-hosting them is a deliberate choice. It often signals a leaner build setup—static sites, server-rendered pages, or templates where pulling a script tag is faster than running a bundler.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It usually comes bundled with the library it delivers.&lt;/strong&gt; jsDelivr rarely travels alone. The same page that references it is almost always loading a detectable library—Bootstrap, Chart.js, a charting or carousel plugin—so one detection often hands you the front-end stack as well.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It hints at a security and supply-chain posture.&lt;/strong&gt; Teams that pull live third-party scripts from a public CDN have a different dependency surface than teams that vendor everything. For security tooling, SCA, or subresource-integrity products, that distinction is the qualifier.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The same pipeline applies to any detectable technology. We have companion guides for &lt;a href="https://detectzestack.com/blog/find-companies-using-node-js" rel="noopener noreferrer"&gt;finding companies using Node.js&lt;/a&gt; and the broader topic of &lt;a href="https://detectzestack.com/blog/detect-cdn-hosting-provider" rel="noopener noreferrer"&gt;detecting a site's CDN and hosting provider&lt;/a&gt;—the filter changes, the workflow stays the same.&lt;/p&gt;

&lt;h2&gt;
  
  
  What jsDelivr Tells You About a Tech Stack
&lt;/h2&gt;

&lt;p&gt;jsDelivr is a &lt;em&gt;library-delivery&lt;/em&gt; CDN. It exists to serve versioned, open-source assets—a specific build of Bootstrap, a pinned release of Chart.js, a Vue component—straight from npm or GitHub. A company does not put its own domain behind jsDelivr; it references jsDelivr from inside its pages to fetch other people's code.&lt;/p&gt;

&lt;p&gt;That has a direct consequence for what a detection means. Finding jsDelivr on a site does not tell you who hosts the site or how its traffic is proxied. It tells you the page intentionally pulls at least one third-party asset from a public CDN, and it points you at &lt;em&gt;which&lt;/em&gt; asset when that asset is itself fingerprintable.&lt;/p&gt;

&lt;h3&gt;
  
  
  jsDelivr vs Self-Hosted Libraries and Other CDNs
&lt;/h3&gt;

&lt;p&gt;It is worth being precise about where jsDelivr sits, because “CDN” is an overloaded word. There are two very different things both called CDNs:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Examples&lt;/th&gt;
&lt;th&gt;Detected From&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Infrastructure CDN&lt;/td&gt;
&lt;td&gt;Cloudflare, Fastly, CloudFront, Akamai&lt;/td&gt;
&lt;td&gt;DNS CNAME, response headers, TLS certificate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Library-delivery CDN&lt;/td&gt;
&lt;td&gt;jsDelivr, cdnjs, unpkg, Google Hosted Libraries&lt;/td&gt;
&lt;td&gt;Script &amp;amp; link references in the page HTML&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;An infrastructure CDN proxies the whole site, so it shows up in the site's DNS, headers, and certificate—the layer covered in &lt;a href="https://detectzestack.com/blog/detect-cdn-hosting-provider" rel="noopener noreferrer"&gt;how to detect a website's CDN and hosting provider&lt;/a&gt;. jsDelivr leaves none of those marks, because it never touches the site's own domain. It appears only as a reference inside the served HTML, alongside its peers cdnjs (&lt;code&gt;cdnjs.cloudflare.com&lt;/code&gt;), unpkg (&lt;code&gt;unpkg.com&lt;/code&gt;), and Google Hosted Libraries (&lt;code&gt;ajax.googleapis.com&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;The flip side is the self-hosted case. A team that runs a bundler and ships its libraries from its own domain will load, say, Bootstrap from &lt;code&gt;/static/js/bootstrap.min.js&lt;/code&gt;—no jsDelivr reference at all. The library is still detectable on its own fingerprint, but the delivery signal is absent. In other words: a missing jsDelivr detection does not mean the site avoids Bootstrap; it means the site does not &lt;em&gt;fetch Bootstrap from jsDelivr&lt;/em&gt;. Keep that distinction in mind when you read negatives.&lt;/p&gt;

&lt;h2&gt;
  
  
  How DetectZeStack Detects jsDelivr
&lt;/h2&gt;

&lt;p&gt;Because jsDelivr lives in the page body, detection is a body-fingerprint match, not a DNS or header lookup. When DetectZeStack fetches a page, it scans the HTML for script and link references to &lt;code&gt;cdn.jsdelivr.net&lt;/code&gt;. A match returns jsDelivr under the &lt;strong&gt;CDN&lt;/strong&gt; category, at confidence 100, with &lt;code&gt;source: "http"&lt;/code&gt;—because the evidence came directly from the HTTP response body.&lt;/p&gt;

&lt;p&gt;You can spot the same raw signal yourself with a single command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://example.com | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="s2"&gt;"cdn&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="s2"&gt;jsdelivr&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="s2"&gt;net"&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt;
cdn.jsdelivr.net
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One match is enough to confirm the page references jsDelivr. The value the API adds is what comes &lt;em&gt;with&lt;/em&gt; it: many of the libraries delivered over jsDelivr have their own fingerprints, so a single scan typically returns jsDelivr plus whatever it is delivering. A page that loads Chart.js from a &lt;code&gt;cdn.jsdelivr.net&lt;/code&gt; path, for example, comes back with both jsDelivr (under CDN) and Chart.js as separate entries—often with a version parsed straight from the URL.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Signal&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;th&gt;What It Tells You&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;jsDelivr script source&lt;/td&gt;
&lt;td&gt;cdn.jsdelivr.net&lt;/td&gt;
&lt;td&gt;jsDelivr confirmed (CDN)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Delivered library&lt;/td&gt;
&lt;td&gt;.../npm/chart.js@4/dist/chart.js&lt;/td&gt;
&lt;td&gt;Chart.js confirmed, version parsed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Self-hosted library&lt;/td&gt;
&lt;td&gt;/static/js/bootstrap.min.js&lt;/td&gt;
&lt;td&gt;Library detected, no jsDelivr signal&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No jsDelivr reference&lt;/td&gt;
&lt;td&gt;(none in HTML)&lt;/td&gt;
&lt;td&gt;Site does not load assets from jsDelivr&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;The honest limitation: jsDelivr detection depends on the HTML actually containing the reference. If a script is injected later by client-side JavaScript that never runs during a server-side fetch, or if the reference sits behind a tag manager, it may not appear in the fetched body. As with any body-fingerprint signal, absence of a detection is an unknown, not proof the site never touches jsDelivr.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  API Example: Detecting jsDelivr With a Single Call
&lt;/h2&gt;

&lt;p&gt;You can try detection right now against the public demo endpoint—no API key required. The demo is IP-rate-limited, so use it for spot checks rather than bulk scans:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://detectzestack.com/demo?url=example.com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
| jq &lt;span class="s1"&gt;'.technologies[] | select(.name == "jsDelivr")'&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="s2"&gt;"name"&lt;/span&gt;: &lt;span class="s2"&gt;"jsDelivr"&lt;/span&gt;,
&lt;span class="s2"&gt;"categories"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"CDN"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;,
&lt;span class="s2"&gt;"confidence"&lt;/span&gt;: 100,
&lt;span class="s2"&gt;"description"&lt;/span&gt;: &lt;span class="s2"&gt;"JSDelivr is a free public CDN for open-source projects. It can serve web files directly from the npm registry and GitHub repositories without any configuration."&lt;/span&gt;,
&lt;span class="s2"&gt;"website"&lt;/span&gt;: &lt;span class="s2"&gt;"https://www.jsdelivr.com/"&lt;/span&gt;,
&lt;span class="s2"&gt;"icon"&lt;/span&gt;: &lt;span class="s2"&gt;"jsdelivr-icon.svg"&lt;/span&gt;,
&lt;span class="s2"&gt;"source"&lt;/span&gt;: &lt;span class="s2"&gt;"http"&lt;/span&gt;,
&lt;span class="s2"&gt;"version"&lt;/span&gt;: &lt;span class="s2"&gt;""&lt;/span&gt;,
&lt;span class="s2"&gt;"cpe"&lt;/span&gt;: &lt;span class="s2"&gt;""&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;jsDelivr is matched directly off the &lt;code&gt;cdn.jsdelivr.net&lt;/code&gt; reference in the page and categorized under &lt;code&gt;CDN&lt;/code&gt;. It carries &lt;code&gt;source: "http"&lt;/code&gt; because the evidence came from the HTTP response body, and the &lt;code&gt;version&lt;/code&gt; field is empty—jsDelivr itself is a delivery network, not a versioned library, so there is nothing to read a version from. The libraries it delivers are where versions show up.&lt;/p&gt;

&lt;p&gt;When you want the full stack for a domain rather than a filtered slice, call &lt;code&gt;/analyze&lt;/code&gt; with your API key. The complete response is shaped like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://detectzestack.p.rapidapi.com/analyze?url=example.com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-RapidAPI-Key: YOUR_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-RapidAPI-Host: detectzestack.p.rapidapi.com"&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="s2"&gt;"url"&lt;/span&gt;: &lt;span class="s2"&gt;"https://example.com"&lt;/span&gt;,
&lt;span class="s2"&gt;"domain"&lt;/span&gt;: &lt;span class="s2"&gt;"example.com"&lt;/span&gt;,
&lt;span class="s2"&gt;"technologies"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="s2"&gt;"name"&lt;/span&gt;: &lt;span class="s2"&gt;"jsDelivr"&lt;/span&gt;,
&lt;span class="s2"&gt;"categories"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"CDN"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;,
&lt;span class="s2"&gt;"confidence"&lt;/span&gt;: 100,
&lt;span class="s2"&gt;"description"&lt;/span&gt;: &lt;span class="s2"&gt;"JSDelivr is a free public CDN for open-source projects. It can serve web files directly from the npm registry and GitHub repositories without any configuration."&lt;/span&gt;,
&lt;span class="s2"&gt;"website"&lt;/span&gt;: &lt;span class="s2"&gt;"https://www.jsdelivr.com/"&lt;/span&gt;,
&lt;span class="s2"&gt;"icon"&lt;/span&gt;: &lt;span class="s2"&gt;"jsdelivr-icon.svg"&lt;/span&gt;,
&lt;span class="s2"&gt;"source"&lt;/span&gt;: &lt;span class="s2"&gt;"http"&lt;/span&gt;,
&lt;span class="s2"&gt;"version"&lt;/span&gt;: &lt;span class="s2"&gt;""&lt;/span&gt;,
&lt;span class="s2"&gt;"cpe"&lt;/span&gt;: &lt;span class="s2"&gt;""&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;,
&lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="s2"&gt;"name"&lt;/span&gt;: &lt;span class="s2"&gt;"Chart.js"&lt;/span&gt;,
&lt;span class="s2"&gt;"categories"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"JavaScript graphics"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;,
&lt;span class="s2"&gt;"confidence"&lt;/span&gt;: 100,
&lt;span class="s2"&gt;"description"&lt;/span&gt;: &lt;span class="s2"&gt;"Chart.js is a free, open-source JavaScript library for data visualization."&lt;/span&gt;,
&lt;span class="s2"&gt;"website"&lt;/span&gt;: &lt;span class="s2"&gt;"https://www.chartjs.org"&lt;/span&gt;,
&lt;span class="s2"&gt;"icon"&lt;/span&gt;: &lt;span class="s2"&gt;"Chart.js.svg"&lt;/span&gt;,
&lt;span class="s2"&gt;"source"&lt;/span&gt;: &lt;span class="s2"&gt;"http"&lt;/span&gt;,
&lt;span class="s2"&gt;"version"&lt;/span&gt;: &lt;span class="s2"&gt;"4.4.1"&lt;/span&gt;,
&lt;span class="s2"&gt;"cpe"&lt;/span&gt;: &lt;span class="s2"&gt;""&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;]&lt;/span&gt;,
&lt;span class="s2"&gt;"categories"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="s2"&gt;"CDN"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"jsDelivr"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;,
&lt;span class="s2"&gt;"JavaScript graphics"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Chart.js"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;,
&lt;span class="s2"&gt;"meta"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"status_code"&lt;/span&gt;: 200, &lt;span class="s2"&gt;"tech_count"&lt;/span&gt;: 2, &lt;span class="s2"&gt;"scan_depth"&lt;/span&gt;: &lt;span class="s2"&gt;"full"&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;,
&lt;span class="s2"&gt;"cached"&lt;/span&gt;: &lt;span class="nb"&gt;false&lt;/span&gt;,
&lt;span class="s2"&gt;"response_ms"&lt;/span&gt;: 1842
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two entries from one page: jsDelivr as the delivery method and Chart.js as the thing being delivered, with its version parsed from the script URL. The top-level &lt;code&gt;categories&lt;/code&gt; map groups every detection so you can pull all CDNs with &lt;code&gt;.categories["CDN"]&lt;/code&gt; without iterating the array. The &lt;code&gt;meta&lt;/code&gt; object carries the HTTP &lt;code&gt;status_code&lt;/code&gt;, the &lt;code&gt;tech_count&lt;/code&gt;, and the &lt;code&gt;scan_depth&lt;/code&gt;; &lt;code&gt;response_ms&lt;/code&gt; and &lt;code&gt;cached&lt;/code&gt; sit at the top level.&lt;/p&gt;

&lt;p&gt;One field to watch for list building is &lt;code&gt;meta.scan_depth&lt;/code&gt;. A value of &lt;code&gt;"full"&lt;/code&gt; means the HTTP fetch succeeded and body detection ran. A value of &lt;code&gt;"partial"&lt;/code&gt; means the site blocked or timed out the HTTP request and only DNS and TLS layers completed—and since jsDelivr lives in the body, an absent jsDelivr entry on a &lt;code&gt;"partial"&lt;/code&gt; scan tells you nothing. Those domains belong in a retry queue, not your rejects file.&lt;/p&gt;

&lt;h3&gt;
  
  
  Building a List of Companies Using jsDelivr at Scale
&lt;/h3&gt;

&lt;p&gt;For list building, &lt;code&gt;POST /analyze/batch&lt;/code&gt; accepts up to 10 URLs per request and analyzes them concurrently. Each entry in the response carries either a full analysis result or an error for domains that could not be fetched:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"https://detectzestack.p.rapidapi.com/analyze/batch"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-RapidAPI-Key: YOUR_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-RapidAPI-Host: detectzestack.p.rapidapi.com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"urls": ["example.com", "getbootstrap.com", "wordpress.org"]}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response wraps one result object per URL, each with the same shape as a single &lt;code&gt;/analyze&lt;/code&gt; response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"results"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"example.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="nl"&gt;"result"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"...full analysis..."&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"getbootstrap.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="nl"&gt;"result"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"...full analysis..."&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"wordpress.org"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nl"&gt;"result"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"...full analysis..."&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"total_ms"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2341&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"successful"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"failed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because each &lt;code&gt;result&lt;/code&gt; matches the single-domain shape, the filtering logic is identical whether you scan one domain or a thousand. Here is a complete, copy-pasteable pipeline using nothing but &lt;code&gt;bash&lt;/code&gt;, &lt;code&gt;curl&lt;/code&gt;, and &lt;code&gt;jq&lt;/code&gt;. It reads &lt;code&gt;domains.txt&lt;/code&gt; (one domain per line), sends batches of 10 to &lt;code&gt;/analyze/batch&lt;/code&gt;, and appends every domain where jsDelivr is detected to &lt;code&gt;jsdelivr_leads.csv&lt;/code&gt;, recording the tech count alongside it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/usr/bin/env bash&lt;/span&gt;
&lt;span class="c"&gt;# find-jsdelivr.sh — filter a domain list down to jsDelivr-confirmed leads&lt;/span&gt;
&lt;span class="nv"&gt;KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"YOUR_KEY"&lt;/span&gt;
&lt;span class="nv"&gt;HOST&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"detectzestack.p.rapidapi.com"&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"domain,tech_count"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; jsdelivr_leads.csv

&lt;span class="c"&gt;# Process domains.txt in batches of 10 (the /analyze/batch maximum)&lt;/span&gt;
xargs &lt;span class="nt"&gt;-n&lt;/span&gt; 10 &amp;lt; domains.txt | &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="nb"&gt;read&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; batch&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
&lt;/span&gt;&lt;span class="nv"&gt;urls&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'%s\n'&lt;/span&gt; &lt;span class="nv"&gt;$batch&lt;/span&gt; | jq &lt;span class="nt"&gt;-R&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt; | jq &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s1"&gt;'{urls: .}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"https://&lt;/span&gt;&lt;span class="nv"&gt;$HOST&lt;/span&gt;&lt;span class="s2"&gt;/analyze/batch"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-RapidAPI-Key: &lt;/span&gt;&lt;span class="nv"&gt;$KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-RapidAPI-Host: &lt;/span&gt;&lt;span class="nv"&gt;$HOST&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$urls&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; |
jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.results[]
| select(.result != null)
| .result as $r
| select([$r.technologies[].name] | index("jsDelivr"))
| [$r.domain, ($r.meta.tech_count | tostring)]
| @csv'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; jsdelivr_leads.csv
&lt;span class="k"&gt;done

&lt;/span&gt;&lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; jsdelivr_leads.csv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A 1,000-domain list becomes 100 batch calls. The &lt;code&gt;index("jsDelivr")&lt;/code&gt; guard keeps a domain whenever jsDelivr appears in its technology list, and &lt;code&gt;select(.result != null)&lt;/code&gt; skips domains that failed to resolve (those come back with an &lt;code&gt;error&lt;/code&gt; field instead of a &lt;code&gt;result&lt;/code&gt;). For a deeper treatment of batch throughput, retries, and a production Python scanner, see &lt;a href="https://detectzestack.com/blog/batch-scan-1000-websites" rel="noopener noreferrer"&gt;how to batch scan 1,000 websites&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you want to segment by the library jsDelivr is delivering rather than just the delivery method, widen the filter to capture the co-detected technologies—the same &lt;code&gt;technologies&lt;/code&gt; array already carries Chart.js, Bootstrap, jQuery, and whatever else the page pulls in. Our guides on &lt;a href="https://detectzestack.com/blog/how-to-detect-jquery" rel="noopener noreferrer"&gt;detecting jQuery&lt;/a&gt; and the broader &lt;a href="https://detectzestack.com/blog/detect-javascript-framework-website" rel="noopener noreferrer"&gt;JavaScript framework detection&lt;/a&gt; cover those fingerprints in detail.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use Cases: Sales, Competitive Intelligence, and Security
&lt;/h2&gt;

&lt;p&gt;A jsDelivr-confirmed list is rarely the end goal on its own—it is the entry point to a more specific segment. Three common ways teams use it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sales and prospecting.&lt;/strong&gt; Pair the jsDelivr flag with the library it delivers. A list of sites pulling a specific charting or UI library from jsDelivr is a precise audience if you sell a competing or complementary front-end product. The delivery method narrows the list; the delivered library qualifies it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Competitive intelligence.&lt;/strong&gt; Scanning a market segment for public-CDN usage tells you how teams in that space build. A cohort that leans heavily on jsDelivr and cdnjs is shipping differently than one that bundles and self-hosts everything—useful context when you are studying how an entire market makes front-end decisions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security and supply-chain mapping.&lt;/strong&gt; Every live third-party script is part of a site's dependency surface. Security teams use technographic scans to inventory which external CDNs a domain pulls executable code from, which feeds subresource-integrity audits and third-party-risk reviews. The CDN category is exactly the layer they need to enumerate.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Two practical enrichment moves once the list is built: cross-reference the infrastructure CDN to separate “loads libraries from jsDelivr” from “proxied through Cloudflare”—they are independent signals and a site commonly has both—and score by &lt;code&gt;meta.tech_count&lt;/code&gt;, a rough proxy for how built-out a company's front end is. Feeding those signals into a scoring model is covered in our &lt;a href="https://detectzestack.com/blog/lead-enrichment-pipeline-with-tech-detection" rel="noopener noreferrer"&gt;lead enrichment pipeline guide&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get Started With the DetectZeStack API
&lt;/h2&gt;

&lt;p&gt;The free tier includes 100 requests per month with no credit card—enough to validate the pipeline on a sample of your prospect list before scaling up. Sign-up is instant through RapidAPI:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Get a key at &lt;a href="https://rapidapi.com/mlugoapx/api/detectzestack" rel="noopener noreferrer"&gt;rapidapi.com/mlugoapx/api/detectzestack&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Spot-check a domain you know: &lt;code&gt;curl -s "https://detectzestack.com/demo?url=yourdomain.com" | jq '.technologies[].name'&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Run the batch script above against your first 100 domains.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Finding companies using jsDelivr comes down to reading one thing well: a &lt;code&gt;cdn.jsdelivr.net&lt;/code&gt; reference in the page HTML. Because jsDelivr is a library-delivery CDN rather than an infrastructure one, it is detected from the body, not from DNS or headers—and the real prize is usually the library it carries, which a single scan returns alongside it. A single &lt;code&gt;/analyze&lt;/code&gt; call answers the one-domain question; &lt;code&gt;/analyze/batch&lt;/code&gt; turns a raw domain list into a jsDelivr-confirmed lead list; and &lt;code&gt;meta.scan_depth&lt;/code&gt; tells you which negatives are real and which are unknowns worth a retry. Swap the &lt;code&gt;jq&lt;/code&gt; filter and the same pipeline segments by infrastructure CDN, front-end library, or backend runtime instead.&lt;/p&gt;

&lt;h3&gt;
  
  
  Related Reading
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/detect-cdn-hosting-provider" rel="noopener noreferrer"&gt;How to Detect the CDN and Hosting Provider of Any Website&lt;/a&gt; — The infrastructure-CDN layer that sits in front of a site, detected via DNS, headers, and TLS&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/find-companies-using-node-js" rel="noopener noreferrer"&gt;Find Companies Using Node.js&lt;/a&gt; — The same batch workflow filtered for a backend runtime&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/how-to-detect-jquery" rel="noopener noreferrer"&gt;How to Detect jQuery on a Website&lt;/a&gt; — One of the most common libraries delivered over jsDelivr, and its own fingerprints&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/detect-javascript-framework-website" rel="noopener noreferrer"&gt;How to Detect the JavaScript Framework of a Website&lt;/a&gt; — Segmenting by the front-end library jsDelivr is delivering&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/batch-scan-1000-websites" rel="noopener noreferrer"&gt;How to Batch Scan 1,000 Websites for Tech Stack Data&lt;/a&gt; — Deep dive on /analyze/batch throughput, retries, and a Python scanner&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/lead-enrichment-pipeline-with-tech-detection" rel="noopener noreferrer"&gt;Lead Enrichment Pipeline with Tech Detection&lt;/a&gt; — Turning raw detections into scored, routable leads&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>techstack</category>
      <category>webdev</category>
      <category>api</category>
    </item>
    <item>
      <title>How to Find Companies Using MySQL: API Guide for 2026</title>
      <dc:creator>MikeL</dc:creator>
      <pubDate>Sun, 14 Jun 2026 14:01:17 +0000</pubDate>
      <link>https://dev.to/detectzestack/how-to-find-companies-using-mysql-api-guide-for-2026-59p7</link>
      <guid>https://dev.to/detectzestack/how-to-find-companies-using-mysql-api-guide-for-2026-59p7</guid>
      <description>&lt;p&gt;MySQL has been the default database of the web for two decades. It sits underneath WordPress, Magento, PrestaShop, and a long tail of forums, wikis, and self-hosted tools—which means a list of companies using MySQL is really a list of companies running real, database-backed applications. If you sell database tooling, managed hosting, backup services, migration consulting, or performance monitoring, that list is your pipeline.&lt;/p&gt;

&lt;p&gt;There is a catch, and most guides skip it: &lt;strong&gt;you cannot detect MySQL directly from outside a website.&lt;/strong&gt; The database never talks to the browser. This guide explains how MySQL detection actually works (inference through the application layer), how reliable those inferences are, and how to turn a raw domain list into a MySQL-confirmed prospect list with the DetectZeStack API—single checks, batch scans, and side-by-side comparison included.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Build a List of Companies Using MySQL
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Who Uses MySQL Lists: Sales, DevRel, Security, and Migration Vendors
&lt;/h3&gt;

&lt;p&gt;MySQL technographics serve a wider set of buyers than most technology filters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Database and infrastructure vendors.&lt;/strong&gt; Managed MySQL hosting, backup-as-a-service, replication tooling, query performance monitors—every one of these products has “runs MySQL” as its first qualifying question. A confirmed detection replaces a discovery call.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Migration and consulting shops.&lt;/strong&gt; Teams selling PostgreSQL migrations, cloud database moves, or version-upgrade services need to find MySQL estates before they can pitch replacing or modernizing them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DevRel and developer marketing.&lt;/strong&gt; If your product integrates with MySQL—an ORM, a CDC pipeline, a caching layer—the companies already running it are the audience for your content and outreach.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security teams.&lt;/strong&gt; MySQL detections come with a CPE identifier (&lt;code&gt;cpe:2.3:a:mysql:mysql&lt;/code&gt;), which plugs directly into vulnerability workflows. An external scan of your vendors’ domains tells you which ones run MySQL-backed platforms worth asking about in a security review. Our &lt;a href="https://detectzestack.com/blog/cpe-identifiers-explained-for-security-teams" rel="noopener noreferrer"&gt;CPE guide for security teams&lt;/a&gt; covers that pipeline end to end.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The workflow below is the same one we documented for &lt;a href="https://detectzestack.com/blog/find-companies-using-nginx" rel="noopener noreferrer"&gt;finding companies using Nginx&lt;/a&gt; and &lt;a href="https://detectzestack.com/blog/find-companies-using-stripe-technographic-prospecting" rel="noopener noreferrer"&gt;finding companies using Stripe&lt;/a&gt;—only the filter changes. What makes the MySQL version interesting is &lt;em&gt;how&lt;/em&gt; the detection happens.&lt;/p&gt;

&lt;h2&gt;
  
  
  How MySQL Detection Works (and Its Limits)
&lt;/h2&gt;

&lt;p&gt;A web server announces itself in the &lt;code&gt;Server&lt;/code&gt; header. A JavaScript framework leaves fingerprints all over the HTML. MySQL does neither—it listens on port 3306 behind a firewall and speaks only to the application. There is no header, cookie, or script tag that says “MySQL.”&lt;/p&gt;

&lt;p&gt;So external detection works by &lt;strong&gt;implication&lt;/strong&gt;. The fingerprint database knows that certain applications are built on MySQL. When one of those applications is detected through its own (very visible) fingerprints, MySQL is added to the result as an implied technology. Detect WordPress, and you have detected MySQL, because WordPress does not run without it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Indirect Signals: CMS and Ecommerce Platform Implications
&lt;/h3&gt;

&lt;p&gt;Dozens of detectable platforms carry a MySQL implication. The ones you will encounter most in real scans:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;What It Means for Your List&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;WordPress&lt;/td&gt;
&lt;td&gt;CMS / Blogs&lt;/td&gt;
&lt;td&gt;The single biggest MySQL signal on the web—every WordPress site is a MySQL (or MariaDB) site&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Magento&lt;/td&gt;
&lt;td&gt;Ecommerce&lt;/td&gt;
&lt;td&gt;Larger ecommerce operations with real database load—prime targets for performance tooling&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PrestaShop&lt;/td&gt;
&lt;td&gt;Ecommerce&lt;/td&gt;
&lt;td&gt;SMB ecommerce, heavily represented in Europe&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenCart&lt;/td&gt;
&lt;td&gt;Ecommerce&lt;/td&gt;
&lt;td&gt;Self-hosted SMB stores, often on shared or VPS hosting&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Shopware&lt;/td&gt;
&lt;td&gt;Ecommerce&lt;/td&gt;
&lt;td&gt;Mid-market ecommerce, strong in the DACH region&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Flarum / Invision Power Board&lt;/td&gt;
&lt;td&gt;Forums&lt;/td&gt;
&lt;td&gt;Community-run infrastructure with long-lived databases&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;BookStack / MantisBT / Piwigo&lt;/td&gt;
&lt;td&gt;Self-hosted tools&lt;/td&gt;
&lt;td&gt;Teams that self-host internal tooling—a strong “runs own infrastructure” signal&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Two honest caveats before you build a pipeline on this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;MySQL vs MariaDB is invisible from outside.&lt;/strong&gt; WordPress and most of the platforms above run equally well on MariaDB, a drop-in replacement. External detection cannot tell which fork is actually installed—treat the detection as “MySQL-compatible database” when precision matters.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not every MySQL-implying platform is in the chain.&lt;/strong&gt; Notably, Drupal supports several databases and therefore does &lt;em&gt;not&lt;/em&gt; imply MySQL in the fingerprint data, even though many Drupal sites do run it. The implication list is deliberately conservative: it only includes platforms where MySQL is a hard requirement.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why Server-Side Databases Are Harder to Detect Than Frontend Tech
&lt;/h3&gt;

&lt;p&gt;This inference model has an asymmetry you need to internalize before trusting your lead list:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Positives are strong.&lt;/strong&gt; If the API reports MySQL, a MySQL-requiring platform was detected at full confidence. The implication is definitional, not statistical—there is no such thing as a WordPress site without a MySQL-compatible database behind it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Negatives are unknowns.&lt;/strong&gt; A custom Laravel app, a Rails monolith, or a Django site can all run MySQL without exposing any platform fingerprint that implies it. No detection does &lt;em&gt;not&lt;/em&gt; mean no MySQL—it means no visible evidence. Score these domains as “unknown,” not “disqualified.”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the database equivalent of the CDN-masking problem we covered in the &lt;a href="https://detectzestack.com/blog/find-companies-using-nginx" rel="noopener noreferrer"&gt;Nginx guide&lt;/a&gt;: external scanning gives you high-precision positives and ambiguous negatives. Good pipelines keep the two piles separate.&lt;/p&gt;

&lt;h2&gt;
  
  
  Find MySQL-Backed Sites with the DetectZeStack API
&lt;/h2&gt;

&lt;p&gt;The API runs the full detection pass—HTTP fingerprints, DNS records, and TLS certificates—in one call, resolves the implication chains, and returns structured JSON. You can try it right now against the public demo endpoint, no API key required (it is IP-rate-limited, so use it for spot checks, not bulk scans):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://detectzestack.com/demo?url=wordpress.org"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
| jq &lt;span class="s1"&gt;'.technologies[] | select(.name == "MySQL")'&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="s2"&gt;"name"&lt;/span&gt;: &lt;span class="s2"&gt;"MySQL"&lt;/span&gt;,
&lt;span class="s2"&gt;"categories"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Databases"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;,
&lt;span class="s2"&gt;"confidence"&lt;/span&gt;: 100,
&lt;span class="s2"&gt;"description"&lt;/span&gt;: &lt;span class="s2"&gt;"MySQL is an open-source relational database management system."&lt;/span&gt;,
&lt;span class="s2"&gt;"website"&lt;/span&gt;: &lt;span class="s2"&gt;"https://mysql.com"&lt;/span&gt;,
&lt;span class="s2"&gt;"icon"&lt;/span&gt;: &lt;span class="s2"&gt;"MySQL.svg"&lt;/span&gt;,
&lt;span class="s2"&gt;"cpe"&lt;/span&gt;: &lt;span class="s2"&gt;"cpe:2.3:a:mysql:mysql:*:*:*:*:*:*:*:*"&lt;/span&gt;,
&lt;span class="s2"&gt;"source"&lt;/span&gt;: &lt;span class="s2"&gt;"http"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is a real response. MySQL appears under the &lt;code&gt;Databases&lt;/code&gt; category at confidence 100—the implying platform (WordPress, in this case) was an HTTP-layer match, and the implication inherits its confidence. The &lt;code&gt;cpe&lt;/code&gt; field is ready for vulnerability tooling. Note there is no &lt;code&gt;version&lt;/code&gt; field: an implied database carries no version information, because the version lives server-side where no scanner can see it.&lt;/p&gt;

&lt;p&gt;The top-level &lt;code&gt;categories&lt;/code&gt; map gives you a shortcut—you can check for any database without iterating the technologies array:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://detectzestack.com/demo?url=wordpress.org"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
| jq &lt;span class="s1"&gt;'.categories["Databases"]'&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;
&lt;span class="s2"&gt;"MySQL"&lt;/span&gt;
&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Single Domain Check with /analyze
&lt;/h3&gt;

&lt;p&gt;With an API key, &lt;code&gt;/analyze&lt;/code&gt; is the authenticated equivalent—same response shape, your own rate limits, and results cached for repeat lookups:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://detectzestack.p.rapidapi.com/analyze?url=example-store.com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-RapidAPI-Key: YOUR_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-RapidAPI-Host: detectzestack.p.rapidapi.com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
| jq &lt;span class="s1"&gt;'{domain, mysql: (.categories["Databases"] // [] | contains(["MySQL"])), via: .categories["CMS"], tech_count: .meta.tech_count}'&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="s2"&gt;"domain"&lt;/span&gt;: &lt;span class="s2"&gt;"example-store.com"&lt;/span&gt;,
&lt;span class="s2"&gt;"mysql"&lt;/span&gt;: &lt;span class="nb"&gt;true&lt;/span&gt;,
&lt;span class="s2"&gt;"via"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"WordPress"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;,
&lt;span class="s2"&gt;"tech_count"&lt;/span&gt;: 14
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When all you need is the boolean, the &lt;code&gt;/check&lt;/code&gt; endpoint is the cheapest call—pass the domain and &lt;code&gt;tech=mysql&lt;/code&gt; (the parameter is case-insensitive):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://detectzestack.p.rapidapi.com/check?url=wordpress.org&amp;amp;tech=mysql"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-RapidAPI-Key: YOUR_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-RapidAPI-Host: detectzestack.p.rapidapi.com"&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="s2"&gt;"domain"&lt;/span&gt;: &lt;span class="s2"&gt;"wordpress.org"&lt;/span&gt;,
&lt;span class="s2"&gt;"technology"&lt;/span&gt;: &lt;span class="s2"&gt;"MySQL"&lt;/span&gt;,
&lt;span class="s2"&gt;"detected"&lt;/span&gt;: &lt;span class="nb"&gt;true&lt;/span&gt;,
&lt;span class="s2"&gt;"confidence"&lt;/span&gt;: 100,
&lt;span class="s2"&gt;"version"&lt;/span&gt;: &lt;span class="s2"&gt;""&lt;/span&gt;,
&lt;span class="s2"&gt;"categories"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Databases"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;,
&lt;span class="s2"&gt;"response_ms"&lt;/span&gt;: 1204,
&lt;span class="s2"&gt;"cached"&lt;/span&gt;: &lt;span class="nb"&gt;false&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Scaling Up with POST /analyze/batch
&lt;/h3&gt;

&lt;p&gt;For list building, &lt;code&gt;POST /analyze/batch&lt;/code&gt; accepts up to 10 URLs per request and analyzes them concurrently. Here is a complete pipeline using &lt;code&gt;bash&lt;/code&gt;, &lt;code&gt;curl&lt;/code&gt;, and &lt;code&gt;jq&lt;/code&gt; that reads &lt;code&gt;domains.txt&lt;/code&gt; (one domain per line) and writes every MySQL-confirmed domain to &lt;code&gt;mysql_leads.csv&lt;/code&gt;, annotated with the platform that implied the database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/usr/bin/env bash&lt;/span&gt;
&lt;span class="c"&gt;# find-mysql.sh — filter a domain list down to MySQL-confirmed leads&lt;/span&gt;
&lt;span class="nv"&gt;KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"YOUR_KEY"&lt;/span&gt;
&lt;span class="nv"&gt;HOST&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"detectzestack.p.rapidapi.com"&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"domain,platform,tech_count"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; mysql_leads.csv

&lt;span class="c"&gt;# Process domains.txt in batches of 10 (the /analyze/batch maximum)&lt;/span&gt;
xargs &lt;span class="nt"&gt;-n&lt;/span&gt; 10 &amp;lt; domains.txt | &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="nb"&gt;read&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; batch&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
&lt;/span&gt;&lt;span class="nv"&gt;urls&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'%s\n'&lt;/span&gt; &lt;span class="nv"&gt;$batch&lt;/span&gt; | jq &lt;span class="nt"&gt;-R&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt; | jq &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s1"&gt;'{urls: .}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"https://&lt;/span&gt;&lt;span class="nv"&gt;$HOST&lt;/span&gt;&lt;span class="s2"&gt;/analyze/batch"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-RapidAPI-Key: &lt;/span&gt;&lt;span class="nv"&gt;$KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-RapidAPI-Host: &lt;/span&gt;&lt;span class="nv"&gt;$HOST&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$urls&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; |
jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.results[]
| select(.result != null)
| select(.result.categories["Databases"] // [] | contains(["MySQL"]))
| [.result.domain,
((.result.categories["CMS"] // .result.categories["Ecommerce"] // ["unknown"])[0]),
(.result.meta.tech_count | tostring)]
| @csv'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; mysql_leads.csv
&lt;span class="k"&gt;done

&lt;/span&gt;&lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; mysql_leads.csv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A 1,000-domain list becomes 100 batch calls. Domains that fail to resolve or time out appear in &lt;code&gt;results[]&lt;/code&gt; with an &lt;code&gt;error&lt;/code&gt; field instead of a &lt;code&gt;result&lt;/code&gt;, and the &lt;code&gt;select(.result != null)&lt;/code&gt; guard skips them cleanly. One more filter worth adding for data quality: check &lt;code&gt;meta.scan_depth&lt;/code&gt;. A value of &lt;code&gt;"partial"&lt;/code&gt; means the HTTP fetch failed and only DNS and TLS layers ran—since MySQL implications come from HTTP-layer platform detection, a partial scan can never find MySQL, and those domains belong in a retry queue rather than your rejects file. For throughput, retries, and a production Python version of this scanner, see &lt;a href="https://detectzestack.com/blog/batch-scan-1000-websites" rel="noopener noreferrer"&gt;how to batch scan 1,000 websites&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building a Prospect List: From Detection to Outreach
&lt;/h2&gt;

&lt;p&gt;The CSV above is a lead list, but the &lt;code&gt;platform&lt;/code&gt; column is what makes it routable. A MySQL detection via Magento and one via WordPress describe very different companies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;WordPress + MySQL&lt;/strong&gt; — could be anything from a hobby blog to an enterprise content site. Qualify further on &lt;code&gt;tech_count&lt;/code&gt; and the rest of the stack: a site also running a tag manager, a CRM widget, and a CDN is a business; fifteen plugins and shared hosting is not your enterprise buyer. Our guide to &lt;a href="https://detectzestack.com/blog/check-if-website-uses-wordpress" rel="noopener noreferrer"&gt;checking if a website uses WordPress&lt;/a&gt; covers reading those secondary signals.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Magento / Shopware + MySQL&lt;/strong&gt; — transactional databases under real load. These companies feel query latency in revenue and are the natural audience for performance and reliability tooling.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Self-hosted tools (BookStack, MantisBT) + MySQL&lt;/strong&gt; — engineering-led teams that run their own infrastructure and can actually install what you sell.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Comparing Two Prospects with POST /compare
&lt;/h3&gt;

&lt;p&gt;When you are deciding which of two accounts to work first, &lt;code&gt;POST /compare&lt;/code&gt; analyzes 2–10 domains in one call and computes the shared and unique technologies across them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"https://detectzestack.p.rapidapi.com/compare"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-RapidAPI-Key: YOUR_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-RapidAPI-Host: detectzestack.p.rapidapi.com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"urls": ["prospect-a.com", "prospect-b.com"]}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
| jq &lt;span class="s1"&gt;'{shared, unique_a: .domains[0].unique, unique_b: .domains[1].unique}'&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="s2"&gt;"shared"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"WordPress"&lt;/span&gt;, &lt;span class="s2"&gt;"MySQL"&lt;/span&gt;, &lt;span class="s2"&gt;"PHP"&lt;/span&gt;, &lt;span class="s2"&gt;"Nginx"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;,
&lt;span class="s2"&gt;"unique_a"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"WooCommerce"&lt;/span&gt;, &lt;span class="s2"&gt;"Cloudflare"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;,
&lt;span class="s2"&gt;"unique_b"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"HubSpot"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both prospects run WordPress on MySQL, but prospect A added ecommerce (WooCommerce)—its database is taking orders, not just serving pages. If you sell backup or performance tooling, A goes to the top of the queue. The full response also carries each domain’s complete &lt;code&gt;technologies&lt;/code&gt; array, so one compare call doubles as two enrichment calls. Feeding these signals into a scoring model is covered in our &lt;a href="https://detectzestack.com/blog/lead-enrichment-pipeline-with-tech-detection" rel="noopener noreferrer"&gt;lead enrichment pipeline guide&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  MySQL Detection vs Other Technographic Tools
&lt;/h2&gt;

&lt;p&gt;Every external technographic tool—ours included—detects databases the same way, because there is only one way: implication through the application layer. The differences that actually matter when you evaluate tools for a MySQL pipeline:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Live scans vs stored indexes.&lt;/strong&gt; Directory-style tools answer from a crawl that may be months old; a site that migrated off Magento last quarter still shows as a MySQL lead. DetectZeStack scans the domain at request time, so the detection reflects today’s stack. (Results are cached briefly for repeat lookups—the &lt;code&gt;cached&lt;/code&gt; field in every response tells you which you got.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Structured output.&lt;/strong&gt; A boolean from &lt;code&gt;/check&lt;/code&gt;, a filterable &lt;code&gt;categories&lt;/code&gt; map from &lt;code&gt;/analyze&lt;/code&gt;, and CPE identifiers on every detection that has one—built for scripts rather than screenshots.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost at list-building volume.&lt;/strong&gt; Enterprise technographic platforms price for sales teams buying exports. If what you need is “run my own domain list through a detector,” API pricing is an order of magnitude cheaper—we did the math in our &lt;a href="https://detectzestack.com/blog/technographic-data-pricing" rel="noopener noreferrer"&gt;technographic data pricing breakdown&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion and Next Steps
&lt;/h2&gt;

&lt;p&gt;Finding companies using MySQL means accepting how database detection really works: there is no direct fingerprint, only implication through platforms like WordPress, Magento, PrestaShop, and OpenCart that cannot run without it. That gives you high-precision positives (the implication is definitional), negatives that are really unknowns (custom apps hide their database), and one structural blind spot (MySQL vs MariaDB is indistinguishable from outside).&lt;/p&gt;

&lt;p&gt;The pipeline itself is three calls: &lt;code&gt;/demo&lt;/code&gt; or &lt;code&gt;/check&lt;/code&gt; to validate the approach on domains you know, &lt;code&gt;/analyze/batch&lt;/code&gt; to turn a raw domain list into a platform-annotated MySQL lead list, and &lt;code&gt;/compare&lt;/code&gt; to rank the prospects you are about to work. The free tier’s 100 requests per month are enough to validate the pipeline on a sample of your list before scaling up.&lt;/p&gt;

&lt;h3&gt;
  
  
  Related Reading
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/find-companies-using-nginx" rel="noopener noreferrer"&gt;How to Find Companies Using Nginx&lt;/a&gt; — The same prospecting pipeline at the web-server layer, where detection is direct&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/find-companies-using-wordpress" rel="noopener noreferrer"&gt;How to Find Companies Using WordPress&lt;/a&gt; — The platform behind most MySQL detections, as its own prospecting filter&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/find-companies-using-stripe-technographic-prospecting" rel="noopener noreferrer"&gt;Find Companies Using Stripe: Technographic Prospecting&lt;/a&gt; — Payment-stack targeting with the same batch workflow&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/check-if-website-uses-wordpress" rel="noopener noreferrer"&gt;How to Check if a Website Uses WordPress&lt;/a&gt; — Reading the platform signals that imply the database&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/batch-scan-1000-websites" rel="noopener noreferrer"&gt;How to Batch Scan 1,000 Websites for Tech Stack Data&lt;/a&gt; — Deep dive on /analyze/batch throughput, retries, and a Python scanner&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/cpe-identifiers-explained-for-security-teams" rel="noopener noreferrer"&gt;CPE Identifiers Explained for Security Teams&lt;/a&gt; — Mapping detected technologies to vulnerability data&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>techstack</category>
      <category>webdev</category>
      <category>api</category>
    </item>
    <item>
      <title>DNS Lookup API: MX, NS, SPF, DMARC via REST (2026)</title>
      <dc:creator>MikeL</dc:creator>
      <pubDate>Sat, 06 Jun 2026 14:01:20 +0000</pubDate>
      <link>https://dev.to/detectzestack/dns-lookup-api-mx-ns-spf-dmarc-via-rest-2026-28fe</link>
      <guid>https://dev.to/detectzestack/dns-lookup-api-mx-ns-spf-dmarc-via-rest-2026-28fe</guid>
      <description>&lt;p&gt;Most engineers default to &lt;code&gt;dig&lt;/code&gt; when they need to look at a domain's DNS. It's fast, it's local, and it's correct. But the moment you need DNS records inside a script, a webhook handler, a CI pipeline, a Slack bot, or a lead-enrichment job, parsing &lt;code&gt;dig&lt;/code&gt;'s text output becomes a chore. A DNS lookup API gives you the same answers as structured JSON: one HTTP call, one parser, every record type in one shot.&lt;/p&gt;

&lt;p&gt;This post walks through what a DNS lookup API does, which records the DetectZeStack &lt;code&gt;GET /dns&lt;/code&gt; endpoint returns, how the email-security grading on top of those records works, and where it beats the shell-out-to-dig pattern. Every example uses the real API; none of the field names are invented.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a DNS Lookup API Does (and Why You Need One)
&lt;/h2&gt;

&lt;p&gt;DNS is the connective tissue of the public internet. Every domain answers questions about itself through DNS: where its web servers live (A, AAAA), where its mail goes (MX), who can sign for it (NS, SOA), what the apex is aliased to (CNAME), and what arbitrary metadata the owner has chosen to publish (TXT — including SPF, DMARC, Google Search Console verification, and dozens of other conventions).&lt;/p&gt;

&lt;p&gt;A DNS lookup API exists because the data is useful in places where running &lt;code&gt;dig&lt;/code&gt; isn't practical:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A serverless function that needs to know a prospect's email provider before deciding which outreach template to send&lt;/li&gt;
&lt;li&gt;A change-monitoring job that polls a domain every week and posts to Slack when its nameservers move&lt;/li&gt;
&lt;li&gt;A CRM enrichment hook that wants the &lt;code&gt;email_security_grade&lt;/code&gt; for a domain at lead-creation time&lt;/li&gt;
&lt;li&gt;An M&amp;amp;A diligence dashboard that audits 200 portfolio companies' SPF and DMARC posture nightly&lt;/li&gt;
&lt;li&gt;A browser-side tool that can't make raw DNS queries because the browser only speaks HTTP&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In all of those, you don't want to package &lt;code&gt;dig&lt;/code&gt; as a dependency, parse its text output, handle stderr, and figure out which selectors to probe for DKIM. You want JSON.&lt;/p&gt;

&lt;h2&gt;
  
  
  Records You Can Query: A, AAAA, MX, NS, TXT, SOA, CNAME, PTR
&lt;/h2&gt;

&lt;p&gt;The DetectZeStack &lt;code&gt;GET /dns&lt;/code&gt; endpoint resolves all of the standard public DNS record types in a single call. The response is a JSON object with one field per record type:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;a&lt;/td&gt;
&lt;td&gt;IPv4 address records (list of strings)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;aaaa&lt;/td&gt;
&lt;td&gt;IPv6 address records (list of strings)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;cname&lt;/td&gt;
&lt;td&gt;Canonical name (string; empty when not present at the queried label)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mx&lt;/td&gt;
&lt;td&gt;Mail exchange records as {host, priority} objects&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ns&lt;/td&gt;
&lt;td&gt;Authoritative nameservers (list of strings)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;txt&lt;/td&gt;
&lt;td&gt;All TXT records (list of strings, including SPF and verification tokens)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;soa&lt;/td&gt;
&lt;td&gt;Start-of-authority record with primary_ns, admin_email, serial, refresh, retry, expire, min_ttl&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ptr&lt;/td&gt;
&lt;td&gt;Reverse DNS for the first A record (list of strings)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;email_provider&lt;/td&gt;
&lt;td&gt;Identified email provider from MX records (Google Workspace, Microsoft 365, Zoho, Proton, Fastmail, etc.)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;dns_provider&lt;/td&gt;
&lt;td&gt;Identified DNS provider from NS records (Cloudflare, Route 53, Google Cloud DNS, GoDaddy, etc.)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;query_ms&lt;/td&gt;
&lt;td&gt;Total DNS resolution time in milliseconds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;response_ms&lt;/td&gt;
&lt;td&gt;End-to-end API response time in milliseconds (top-level)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The endpoint sets a 5-second hard cap on a single lookup. If a record type can't be resolved (typical for AAAA on IPv4-only domains, or PTR when no rDNS is published), the field is returned as an empty array rather than as an error — you get all the records that exist in one call instead of having to retry for each missing type.&lt;/p&gt;

&lt;h2&gt;
  
  
  Email Security Records: SPF, DMARC, DKIM
&lt;/h2&gt;

&lt;p&gt;SPF and DMARC are plain TXT records. DKIM is a TXT record at a &lt;code&gt;&amp;lt;selector&amp;gt;._domainkey.&amp;lt;domain&amp;gt;&lt;/code&gt; label. If you only ask DNS for them, you get raw strings — &lt;code&gt;v=spf1 include:_spf.google.com ~all&lt;/code&gt;, &lt;code&gt;v=DMARC1; p=reject; rua=mailto:dmarc@...&lt;/code&gt; — and then you have to parse them yourself.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;/dns&lt;/code&gt; endpoint parses them for you and adds them as separate top-level fields:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;spf&lt;/code&gt; — the parsed SPF record with &lt;code&gt;record&lt;/code&gt;, &lt;code&gt;exists&lt;/code&gt;, &lt;code&gt;mechanism&lt;/code&gt; (&lt;code&gt;-all&lt;/code&gt; / &lt;code&gt;~all&lt;/code&gt; / &lt;code&gt;?all&lt;/code&gt; / &lt;code&gt;+all&lt;/code&gt;), &lt;code&gt;includes&lt;/code&gt; (list of include domains), a letter &lt;code&gt;grade&lt;/code&gt;, and a list of &lt;code&gt;issues&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;dmarc&lt;/code&gt; — the parsed DMARC record with &lt;code&gt;record&lt;/code&gt;, &lt;code&gt;exists&lt;/code&gt;, &lt;code&gt;policy&lt;/code&gt; (&lt;code&gt;reject&lt;/code&gt; / &lt;code&gt;quarantine&lt;/code&gt; / &lt;code&gt;none&lt;/code&gt;), &lt;code&gt;subdomain_policy&lt;/code&gt;, aggregate reporting URI (&lt;code&gt;rua&lt;/code&gt;), forensic URI (&lt;code&gt;ruf&lt;/code&gt;), &lt;code&gt;grade&lt;/code&gt;, and &lt;code&gt;issues&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;dkim&lt;/code&gt; — the DKIM probe result: which selector was tested (&lt;code&gt;selector_tested&lt;/code&gt;), whether a record &lt;code&gt;exists&lt;/code&gt;, a &lt;code&gt;grade&lt;/code&gt;, and any &lt;code&gt;issues&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How DetectZeStack Grades Email Security
&lt;/h3&gt;

&lt;p&gt;Each protocol gets an A–F letter grade, and an overall &lt;code&gt;email_security_grade&lt;/code&gt; is computed from the three. The logic, briefly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SPF&lt;/strong&gt; — An A requires &lt;code&gt;-all&lt;/code&gt; (hardfail) and fewer than 10 DNS-lookup includes (RFC 7208 caps SPF at 10 lookups). &lt;code&gt;~all&lt;/code&gt; (softfail) scores a B. Missing or &lt;code&gt;+all&lt;/code&gt; is an F.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DMARC&lt;/strong&gt; — &lt;code&gt;p=reject&lt;/code&gt; with &lt;code&gt;rua&lt;/code&gt; reporting earns an A. &lt;code&gt;p=quarantine&lt;/code&gt; is a B. &lt;code&gt;p=none&lt;/code&gt; (monitor-only) is a C. No record is an F.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DKIM&lt;/strong&gt; — The API probes 8 common selectors: &lt;code&gt;google&lt;/code&gt;, &lt;code&gt;default&lt;/code&gt;, &lt;code&gt;selector1&lt;/code&gt;, &lt;code&gt;selector2&lt;/code&gt;, &lt;code&gt;k1&lt;/code&gt;, &lt;code&gt;mandrill&lt;/code&gt;, &lt;code&gt;mailchimp&lt;/code&gt;, &lt;code&gt;smtp&lt;/code&gt;. If any selector returns a valid record, DKIM grades A. None found grades F.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The composite &lt;code&gt;email_security_grade&lt;/code&gt; is dragged down by the weakest of the three. A single F on any one of SPF, DMARC, or DKIM stops the overall grade from being an A. The &lt;code&gt;email_security_summary&lt;/code&gt; field is a human-readable sentence you can drop straight into a Slack message or a CRM note.&lt;/p&gt;

&lt;p&gt;If you want the full breakdown of SPF/DMARC/DKIM checks beyond what's in this post, see &lt;a href="https://detectzestack.com/blog/dns-intelligence-api-spf-dkim-dmarc" rel="noopener noreferrer"&gt;DNS Intelligence API: SPF, DKIM &amp;amp; DMARC Check&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  DNS Lookup API vs Running &lt;code&gt;dig&lt;/code&gt; Yourself
&lt;/h2&gt;

&lt;p&gt;Both approaches resolve the same records. The difference is everything that surrounds the resolution:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Capability&lt;/th&gt;
&lt;th&gt;dig / nslookup&lt;/th&gt;
&lt;th&gt;DetectZeStack /dns&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;One record type per command&lt;/td&gt;
&lt;td&gt;Yes — dig MX, dig TXT, dig NS separately&lt;/td&gt;
&lt;td&gt;All record types in one call&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Output format&lt;/td&gt;
&lt;td&gt;Text (zone-file style)&lt;/td&gt;
&lt;td&gt;JSON&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Email-provider identification&lt;/td&gt;
&lt;td&gt;Read MX records, classify by hand&lt;/td&gt;
&lt;td&gt;Automatic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DNS-provider identification&lt;/td&gt;
&lt;td&gt;Read NS records, classify by hand&lt;/td&gt;
&lt;td&gt;Automatic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SPF parsing &amp;amp; grading&lt;/td&gt;
&lt;td&gt;Manual (read TXT, interpret)&lt;/td&gt;
&lt;td&gt;Built in&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DMARC parsing &amp;amp; grading&lt;/td&gt;
&lt;td&gt;Manual (dig _dmarc. TXT)&lt;/td&gt;
&lt;td&gt;Built in&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DKIM probing&lt;/td&gt;
&lt;td&gt;Guess selectors, query each&lt;/td&gt;
&lt;td&gt;8 common selectors probed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Works from browser / serverless&lt;/td&gt;
&lt;td&gt;No (needs OS DNS client)&lt;/td&gt;
&lt;td&gt;Yes (just HTTP)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Batch automation&lt;/td&gt;
&lt;td&gt;Bash + xargs + parsing&lt;/td&gt;
&lt;td&gt;Plain HTTP requests in any language&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;dig&lt;/code&gt; is the right tool when you're sitting at a terminal debugging one domain. The API is the right tool when the answer needs to flow into another system — a Slack alert, a Postgres row, a Notion page, a CRM enrichment field, a CI assertion.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using the DetectZeStack /dns Endpoint (curl example)
&lt;/h2&gt;

&lt;p&gt;Grab a free RapidAPI key from &lt;a href="https://rapidapi.com/mlugoapx/api/detectzestack" rel="noopener noreferrer"&gt;the DetectZeStack listing&lt;/a&gt; (no credit card required, 100 requests per month on the free plan), then call &lt;code&gt;/dns&lt;/code&gt; with a &lt;code&gt;domain&lt;/code&gt; query parameter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://detectzestack.p.rapidapi.com/dns?domain=stripe.com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-rapidapi-key: YOUR_API_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-rapidapi-host: detectzestack.p.rapidapi.com"&lt;/span&gt; | python3 &lt;span class="nt"&gt;-m&lt;/span&gt; json.tool
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you just want to see the shape of the response without an API key, the public &lt;code&gt;/demo&lt;/code&gt; endpoint returns the same kind of structured data for the tech-detection side of the API (no key required). You can use it as a smoke test before wiring up your real key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://detectzestack.com/demo?url=https://stripe.com"&lt;/span&gt; | python3 &lt;span class="nt"&gt;-m&lt;/span&gt; json.tool
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That call returns the technology-detection response shape:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://stripe.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"domain"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"stripe.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"technologies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"React"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"categories"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"JavaScript frameworks"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"React is an open-source JavaScript library for building user interfaces."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"website"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://reactjs.org"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"icon"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"React.svg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"cpe"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Cloudflare"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"categories"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"CDN"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Cloudflare is a global CDN and DDoS-mitigation network."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"website"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://www.cloudflare.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"icon"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"CloudFlare.svg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"cpe"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"categories"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"JavaScript frameworks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"React"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"CDN"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Cloudflare"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"meta"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"status_code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"tech_count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"scan_depth"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"full"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"cached"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"response_ms"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1842&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use &lt;code&gt;/demo&lt;/code&gt; to confirm the auth-free flow works, then point at &lt;code&gt;/dns&lt;/code&gt; with your key for the DNS-specific records.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sample JSON Response
&lt;/h3&gt;

&lt;p&gt;A realistic &lt;code&gt;/dns&lt;/code&gt; response looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"domain"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"stripe.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"a"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"185.166.143.26"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"185.166.143.18"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"aaaa"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"cname"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"mx"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"host"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"aspmx.l.google.com."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"priority"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"host"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"alt1.aspmx.l.google.com."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"priority"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"host"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"alt2.aspmx.l.google.com."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"priority"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"ns"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;"ns-cloud-a1.googledomains.com."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;"ns-cloud-a2.googledomains.com."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;"ns-cloud-a3.googledomains.com."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;"ns-cloud-a4.googledomains.com."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"txt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;"v=spf1 include:_spf.google.com include:servers.mcsv.net ~all"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;"google-site-verification=..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;"MS=ms..."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"soa"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"primary_ns"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ns-cloud-a1.googledomains.com."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"admin_email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cloud-dns-hostmaster.google.com."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"serial"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"refresh"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;21600&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"retry"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3600&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"expire"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1209600&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"min_ttl"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"ptr"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"185-166-143-26.example.ptr."&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"email_provider"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Google Workspace"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"dns_provider"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Google Cloud DNS"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"spf"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"record"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"v=spf1 include:_spf.google.com include:servers.mcsv.net ~all"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"exists"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"mechanism"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"~all"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"includes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"_spf.google.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"servers.mcsv.net"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"grade"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"B"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"issues"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Uses ~all (softfail) instead of -all (hardfail)"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"dmarc"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"record"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"v=DMARC1; p=reject; rua=mailto:dmarc@stripe.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"exists"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"policy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"reject"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"subdomain_policy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"rua"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mailto:dmarc@stripe.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"ruf"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"grade"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"A"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"issues"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"dkim"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"selector_tested"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"google"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"exists"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"grade"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"A"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"issues"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"email_security_grade"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"A"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"email_security_summary"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Strong email security posture. SPF, DMARC, and DKIM are all configured."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"query_ms"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;142&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"response_ms"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;168&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;One request, full DNS picture. Every record type, parsed email-auth records, identified providers, and a composite security grade — in a single JSON document.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Common Use Cases: Migration, Deliverability, Lead Enrichment, Monitoring
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Pre-migration audit
&lt;/h3&gt;

&lt;p&gt;Before pointing a domain at a new email host or DNS provider, dump the current state so the rollback path is documented:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://detectzestack.p.rapidapi.com/dns?domain=acme.com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-rapidapi-key: &lt;/span&gt;&lt;span class="nv"&gt;$RAPIDAPI_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-rapidapi-host: detectzestack.p.rapidapi.com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
| jq &lt;span class="s1"&gt;'{
ns,
mx,
spf: .spf.record,
dmarc: .dmarc.record,
email_provider,
dns_provider
}'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; pre-migration.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the same call after the cutover and &lt;code&gt;diff&lt;/code&gt; the two snapshots. If &lt;code&gt;email_provider&lt;/code&gt; stays the same when you expected it to change, you know propagation hasn't completed.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Deliverability triage
&lt;/h3&gt;

&lt;p&gt;When a sales team reports "our emails are going to spam", the first three things to check are SPF, DMARC, and DKIM. One curl call surfaces all three plus a grade:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://detectzestack.p.rapidapi.com/dns?domain=&lt;/span&gt;&lt;span class="nv"&gt;$DOMAIN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-rapidapi-key: &lt;/span&gt;&lt;span class="nv"&gt;$RAPIDAPI_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-rapidapi-host: detectzestack.p.rapidapi.com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
| jq &lt;span class="s1"&gt;'{grade: .email_security_grade, summary: .email_security_summary,
spf: .spf.grade, dmarc: .dmarc.policy, dkim: .dkim.exists}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Lead enrichment
&lt;/h3&gt;

&lt;p&gt;For B2B sales, the email provider and DNS provider tell you a lot about company size and IT sophistication. A small business on GoDaddy DNS with no DMARC is a very different conversation from an enterprise on Cloudflare with &lt;code&gt;p=reject&lt;/code&gt;. Hook the &lt;code&gt;/dns&lt;/code&gt; call into the new-lead webhook in your CRM and write &lt;code&gt;email_provider&lt;/code&gt;, &lt;code&gt;dns_provider&lt;/code&gt;, and &lt;code&gt;email_security_grade&lt;/code&gt; onto the lead record. For the broader pipeline pattern, see &lt;a href="https://detectzestack.com/blog/lead-enrichment-pipeline-with-tech-detection" rel="noopener noreferrer"&gt;Lead Enrichment Pipeline with Tech Detection&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Infrastructure-change monitoring
&lt;/h3&gt;

&lt;p&gt;Run a daily cron that compares today's MX, NS, and SPF to yesterday's. Any diff triggers a Slack alert. This is how you catch "marketing changed our ESP and broke SPF" before customer support catches it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# /opt/scripts/dns-watch.sh — daily cron, 0 8 * * *&lt;/span&gt;
&lt;span class="nv"&gt;DOMAIN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"yourdomain.com"&lt;/span&gt;
&lt;span class="nv"&gt;OUT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/var/log/dns-watch/&lt;/span&gt;&lt;span class="nv"&gt;$DOMAIN&lt;/span&gt;&lt;span class="s2"&gt;.json"&lt;/span&gt;
&lt;span class="nv"&gt;PREV&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;OUT&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.prev"&lt;/span&gt;

&lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$OUT&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;mv&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$OUT&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PREV&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://detectzestack.p.rapidapi.com/dns?domain=&lt;/span&gt;&lt;span class="nv"&gt;$DOMAIN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-rapidapi-key: &lt;/span&gt;&lt;span class="nv"&gt;$RAPIDAPI_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-rapidapi-host: detectzestack.p.rapidapi.com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
| jq &lt;span class="s1"&gt;'{mx, ns, spf: .spf.record, dmarc: .dmarc.record, grade: .email_security_grade}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$OUT&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PREV&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; diff &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PREV&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$OUT&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /dev/null&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
&lt;/span&gt;&lt;span class="nv"&gt;DIFF&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;diff &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PREV&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$OUT&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-40&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SLACK_WEBHOOK&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"{&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;DNS change detected for &lt;/span&gt;&lt;span class="nv"&gt;$DOMAIN&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\n\`\`\`&lt;/span&gt;&lt;span class="nv"&gt;$DIFF&lt;/span&gt;&lt;span class="se"&gt;\`\`\`\"&lt;/span&gt;&lt;span class="s2"&gt;}"&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;DNS isn't only an email signal — CDN and hosting providers also leak through. For that angle see &lt;a href="https://detectzestack.com/blog/detect-cdn-hosting-provider" rel="noopener noreferrer"&gt;Detect CDN &amp;amp; Hosting Provider&lt;/a&gt; and &lt;a href="https://detectzestack.com/blog/dns-based-technology-detection" rel="noopener noreferrer"&gt;DNS-Based Technology Detection&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pricing and Rate Limits
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Plan&lt;/th&gt;
&lt;th&gt;Requests/Month&lt;/th&gt;
&lt;th&gt;Price&lt;/th&gt;
&lt;th&gt;Typical fit&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Basic (free)&lt;/td&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;td&gt;$0/mo&lt;/td&gt;
&lt;td&gt;Personal audits, weekly checks on a few domains&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pro&lt;/td&gt;
&lt;td&gt;1,000&lt;/td&gt;
&lt;td&gt;$9/mo&lt;/td&gt;
&lt;td&gt;Small MSP, daily monitoring of 20–30 domains&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ultra&lt;/td&gt;
&lt;td&gt;10,000&lt;/td&gt;
&lt;td&gt;$29/mo&lt;/td&gt;
&lt;td&gt;Lead enrichment at modest volume, agency portfolios&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mega&lt;/td&gt;
&lt;td&gt;50,000&lt;/td&gt;
&lt;td&gt;$79/mo&lt;/td&gt;
&lt;td&gt;Vendor-risk programs, large-scale CRM enrichment&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Quota is shared across endpoints: &lt;code&gt;/dns&lt;/code&gt;, &lt;code&gt;/analyze&lt;/code&gt;, &lt;code&gt;/certificate/check&lt;/code&gt;, and &lt;code&gt;/security&lt;/code&gt; all draw from the same monthly bucket. A daily check on 3 domains is ~90 requests/month — comfortably inside the free tier.&lt;/p&gt;

&lt;p&gt;For SSL alongside DNS monitoring, pair this with &lt;a href="https://detectzestack.com/blog/ssl-certificate-check-api-devops" rel="noopener noreferrer"&gt;the SSL Certificate Check API&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started in 60 Seconds
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Sign up at &lt;a href="https://rapidapi.com/mlugoapx/api/detectzestack" rel="noopener noreferrer"&gt;rapidapi.com/mlugoapx/api/detectzestack&lt;/a&gt; and copy your &lt;code&gt;x-rapidapi-key&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Run the curl example above with a domain you control.&lt;/li&gt;
&lt;li&gt;Read &lt;code&gt;email_security_grade&lt;/code&gt; first — if it's not an A, the rest of the response tells you exactly which protocol pulled it down.&lt;/li&gt;
&lt;li&gt;If you only want a smoke test with no signup, hit &lt;code&gt;https://detectzestack.com/demo?url=https://example.com&lt;/code&gt; — same response shape (for tech detection), no key needed.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Related Reading
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/dns-intelligence-api-spf-dkim-dmarc" rel="noopener noreferrer"&gt;DNS Intelligence API: SPF, DKIM &amp;amp; DMARC Check&lt;/a&gt; — Deep dive on how the email-security grading works&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/dns-based-technology-detection" rel="noopener noreferrer"&gt;DNS-Based Technology Detection&lt;/a&gt; — How DNS records expose CDNs, hosting providers, and infrastructure&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/detect-cdn-hosting-provider" rel="noopener noreferrer"&gt;Detect CDN &amp;amp; Hosting Provider&lt;/a&gt; — CDN identification via DNS + HTTP signals&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/ssl-certificate-check-api-devops" rel="noopener noreferrer"&gt;SSL Certificate Check API for DevOps Teams&lt;/a&gt; — Cert expiry, chain, and TLS posture as a sibling endpoint&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/ssl-monitoring-api" rel="noopener noreferrer"&gt;SSL Monitoring API: Cert Expiry, Issuer &amp;amp; Chain&lt;/a&gt; — Cron + Slack alerting patterns&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/lead-enrichment-pipeline-with-tech-detection" rel="noopener noreferrer"&gt;Lead Enrichment Pipeline with Tech Detection&lt;/a&gt; — Wiring DNS + tech signals into a CRM&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>techstack</category>
      <category>webdev</category>
      <category>api</category>
    </item>
    <item>
      <title>StackShare Alternative: Programmatic Tech Stack Research API</title>
      <dc:creator>MikeL</dc:creator>
      <pubDate>Sun, 17 May 2026 14:01:11 +0000</pubDate>
      <link>https://dev.to/detectzestack/stackshare-alternative-programmatic-tech-stack-research-api-2dc0</link>
      <guid>https://dev.to/detectzestack/stackshare-alternative-programmatic-tech-stack-research-api-2dc0</guid>
      <description>&lt;p&gt;StackShare was the place engineers went to peek at another company’s stack. You typed in a name, got a profile page, and saw the libraries and services that engineering team had decided to publicly share. For a long time it was the closest thing to a public registry of who was running what.&lt;/p&gt;

&lt;p&gt;It still has profile pages. What it doesn’t have, in any practical sense, is a programmatic API you can hit from a CRM workflow, a research notebook, or a sales-ops pipeline. The public StackShare API was deprecated, third-party access went quiet, and the experience now is “browse a UI” rather than “loop over a list of domains.” If your job-to-be-done is “tell my software what stack a company is running,” StackShare isn’t the right shape for it anymore.&lt;/p&gt;

&lt;p&gt;This guide covers why people end up looking for a StackShare alternative, what a programmatic tech stack research API actually needs to do, and how the tradeoffs shake out across the realistic options. The example at the end is a working &lt;code&gt;curl&lt;/code&gt; against a free endpoint — you can run it in 30 seconds and decide for yourself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Look for a StackShare Alternative
&lt;/h2&gt;

&lt;p&gt;Three concrete reasons surface again and again:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No accessible public API.&lt;/strong&gt; StackShare’s API access has effectively wound down for general developer use. You can browse profiles in a browser, but stitching that data into a workflow means scraping a UI — brittle, slow, and against the terms most public sites set. For a research workflow or a CRM enrichment job, that’s a non-starter.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Crowdsourced data goes stale.&lt;/strong&gt; Profiles on StackShare are filled in by engineers at the company, often once, often years ago. A team that filed their stack in 2021 might be on a completely different setup now — new framework, different CDN, replaced analytics, dropped feature flags. The profile doesn’t know.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Coverage is patchy.&lt;/strong&gt; Big-name SaaS companies have profiles. The mid-market SaaS company you’re prospecting into often does not. For sales research and lead enrichment workflows, the long tail is where the value is — and that’s where StackShare thins out the most.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If any of those bites you, what you actually want is a tech detection API: something you give a domain to, and it tells you, right now, what that domain is running. The next sections walk through what StackShare offers, where the gap is, and how a programmatic alternative covers it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What StackShare Offers (and What’s Missing)
&lt;/h2&gt;

&lt;p&gt;StackShare’s product is a community wiki for tech stacks. Engineers create a profile for their company, list the tools and services they use, and tag categories. The site aggregates those entries into directories — “everyone using Postgres,” “all sites running Stripe,” and so on — and surfaces popularity trends and comparisons between similar tools.&lt;/p&gt;

&lt;p&gt;That model has real strengths:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Editorial framing.&lt;/strong&gt; Profiles include a why, not just a what. Why a team picked PostgreSQL over MySQL, why they switched analytics tools. That context is rare in any other source.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Categories of tools detection alone misses.&lt;/strong&gt; Internal tools, project management software, CI/CD platforms, design tools — things that don’t leave a fingerprint on the public website. A self-reported profile knows the team uses Linear and GitHub Actions; a website scanner does not.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Discovery and trends.&lt;/strong&gt; “What are all the alternatives to Segment?” is a question StackShare is genuinely good at, because the data is structured around tools rather than companies.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The API Gap
&lt;/h3&gt;

&lt;p&gt;What StackShare doesn’t do well in 2026 is programmatic access. The public API that existed in earlier years isn’t generally available now, and there’s no documented self-serve replacement aimed at developers who want to enrich a list of 5,000 domains. So the data exists, but it sits behind a UI you have to click through. For workflows where automation is the whole point, that’s the missing piece.&lt;/p&gt;

&lt;p&gt;The other gap is freshness. Detection from an actual scan tells you what a website is doing today. A profile that was last updated in 2022 tells you what an engineer remembered to type in three years ago. For competitive intelligence, lead enrichment, and stack monitoring, you need today.&lt;/p&gt;

&lt;h2&gt;
  
  
  DetectZeStack as a Programmatic StackShare Alternative
&lt;/h2&gt;

&lt;p&gt;DetectZeStack is a focused REST API for live tech stack detection. Give it a domain, get back the technologies running on the public-facing site — JavaScript frameworks, CMS, analytics, CDN, hosting, payment processors, marketing tools, web server, security headers, and more. There’s no community wiki, no profile editing, no UI to curate. The product is the API.&lt;/p&gt;

&lt;p&gt;The free tier on RapidAPI is 100 requests/month with no credit card. Paid tiers scale linearly: $9/mo for 1,000 requests, $29/mo for 10,000, $79/mo for 50,000. API access is on every tier — the free tier and the top tier hit the exact same endpoints with the exact same response shape.&lt;/p&gt;

&lt;h3&gt;
  
  
  Live Detection vs Crowdsourced Profiles
&lt;/h3&gt;

&lt;p&gt;Every &lt;code&gt;/analyze&lt;/code&gt; call performs a real scan against the target domain. There’s no static profile to go stale, no cached community entry. If a company switched their CDN from Fastly to Cloudflare last week, the next scan reflects that. If they swapped React for Svelte, the next scan reflects that.&lt;/p&gt;

&lt;p&gt;That comes with a tradeoff worth being honest about: detection only sees what’s on the public site. Internal tools, build pipelines, communication apps, ticket trackers — none of those leave fingerprints on a marketing page. A self-reported profile catches them; a scan does not. If your research depends on knowing the internal tools side, detection alone won’t replace it. If your research is “what does this company’s public stack look like, programmatically, at scale,” detection wins clearly.&lt;/p&gt;

&lt;h3&gt;
  
  
  DNS, SSL, and Security Signals StackShare Doesn’t Cover
&lt;/h3&gt;

&lt;p&gt;DetectZeStack runs three detection layers on every scan, and each detected technology carries a &lt;code&gt;source&lt;/code&gt; field of &lt;code&gt;http&lt;/code&gt;, &lt;code&gt;dns&lt;/code&gt;, or &lt;code&gt;tls&lt;/code&gt; so you can tell which layer surfaced it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;HTTP fingerprinting&lt;/strong&gt; against the open-source Wappalyzer signature database (7,500+ patterns) for frameworks, CMS, analytics, ad tech, marketing automation, server software, and much more. This is the same signature corpus that powers &lt;a href="https://detectzestack.com/blog/wappalyzer-open-source-alternatives" rel="noopener noreferrer"&gt;several open-source detection tools&lt;/a&gt;, kept current with regular updates.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DNS analysis&lt;/strong&gt; on CNAME and NS records to identify CDNs and hosting providers that don’t advertise themselves in HTTP headers. &lt;a href="https://detectzestack.com/blog/detect-cdn-hosting-provider" rel="noopener noreferrer"&gt;CDN and hosting detection via DNS&lt;/a&gt; catches Cloudflare in proxy mode, CloudFront, Fastly, Vercel, Netlify, and Akamai even when the upstream &lt;code&gt;Server&lt;/code&gt; header is generic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TLS inspection&lt;/strong&gt; for certificate authority, HSTS configuration, and TLS-level signals. Useful when an upstream blocks the HTTP fetch but DNS and TLS still produce a partial picture.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of that exists on a StackShare profile, because none of it is the kind of thing an engineer types into a wiki. It only shows up when you actually scan the domain.&lt;/p&gt;

&lt;h2&gt;
  
  
  API Example: Pulling a Company’s Tech Stack in One Call
&lt;/h2&gt;

&lt;p&gt;The fastest way to compare a profile-based tool to a detection API is to run the same domain through the API and look at the JSON. The DetectZeStack &lt;code&gt;/demo&lt;/code&gt; endpoint requires no authentication, so you can do this with one &lt;code&gt;curl&lt;/code&gt; right now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://detectzestack.com/demo?url=stripe.com"&lt;/span&gt; | jq
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Response (trimmed for length):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://stripe.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"domain"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"stripe.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"technologies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"React"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"categories"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"JavaScript frameworks"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"React is an open-source JavaScript library for building user interfaces."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"website"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://reactjs.org"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"icon"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"React.svg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"cpe"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Cloudflare"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"categories"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"CDN"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Cloudflare is a web-infrastructure and website-security company."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"website"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://www.cloudflare.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"icon"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Cloudflare.svg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dns"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"cpe"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Stripe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"categories"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Payment processors"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Stripe is an online payment processing platform for internet businesses."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"website"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://stripe.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"icon"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Stripe.svg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"cpe"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"categories"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"CDN"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Cloudflare"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"JavaScript frameworks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"React"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"Payment processors"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Stripe"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"meta"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"status_code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"tech_count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"scan_depth"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"full"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"cached"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"response_ms"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1842&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A few things worth pointing out about the response shape:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;technologies&lt;/code&gt; is the full list. Each entry has a &lt;code&gt;confidence&lt;/code&gt; score (0–100) and a &lt;code&gt;source&lt;/code&gt; field indicating which detection layer surfaced it. Filter on &lt;code&gt;source: "dns"&lt;/code&gt; when you only want infrastructure signals.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;categories&lt;/code&gt; is a convenience map keyed by category name. Want every payment processor regardless of detection method? Read &lt;code&gt;categories["Payment processors"]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;meta.scan_depth&lt;/code&gt; is &lt;code&gt;"full"&lt;/code&gt; when all three layers ran cleanly. &lt;code&gt;"partial"&lt;/code&gt; means HTTP was blocked but DNS and TLS still produced results.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cached&lt;/code&gt; and &lt;code&gt;response_ms&lt;/code&gt; sit at the top level, not inside &lt;code&gt;meta&lt;/code&gt;. First-time scans typically take 1.5–3 seconds; cached scans return in 5–50ms.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cpe&lt;/code&gt; is populated for technologies that have a CPE 2.3 identifier in the signature database. Feed those straight into NVD for vulnerability lookups — the kind of &lt;a href="https://detectzestack.com/blog/detect-vulnerable-technologies-with-cpe" rel="noopener noreferrer"&gt;CVE pipeline&lt;/a&gt; StackShare profiles can’t support.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once you have an API key, the authenticated endpoint behaves identically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://detectzestack.p.rapidapi.com/analyze?url=stripe.com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-RapidAPI-Key: YOUR_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-RapidAPI-Host: detectzestack.p.rapidapi.com"&lt;/span&gt; | jq
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a research workflow that processes a list of domains, the batch endpoint accepts up to 10 URLs in one request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-sX&lt;/span&gt; POST &lt;span class="s2"&gt;"https://detectzestack.p.rapidapi.com/analyze/batch"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-RapidAPI-Key: YOUR_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-RapidAPI-Host: detectzestack.p.rapidapi.com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"urls": ["stripe.com", "shopify.com", "vercel.com"]}'&lt;/span&gt; | jq
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you’re scanning thousands of domains, chunk into batches of 10 and run them concurrently from a worker pool. &lt;a href="https://detectzestack.com/blog/batch-scan-1000-websites" rel="noopener noreferrer"&gt;Scanning a thousand domains in one job&lt;/a&gt; covers the rate-limit math and a worker-pool pattern that holds up under real load.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comparing Two Companies’ Stacks Programmatically
&lt;/h2&gt;

&lt;p&gt;One of the most common StackShare workflows is “show me the difference between these two companies’ stacks.” DetectZeStack exposes that as a single endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-sX&lt;/span&gt; POST &lt;span class="s2"&gt;"https://detectzestack.p.rapidapi.com/compare"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-RapidAPI-Key: YOUR_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-RapidAPI-Host: detectzestack.p.rapidapi.com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"urls": ["stripe.com", "square.com"]}'&lt;/span&gt; | jq
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response groups detected technologies into the ones both domains share, the ones unique to each, and the categorical breakdown. That makes it straightforward to power a “how does our stack compare to a competitor’s” tile in a dashboard, or to scan a target list of competitors weekly and alert when the diff changes. &lt;a href="https://detectzestack.com/blog/competitor-website-technology-analysis" rel="noopener noreferrer"&gt;Competitor website technology analysis&lt;/a&gt; walks through the full pattern.&lt;/p&gt;

&lt;p&gt;For change tracking specifically — the “they used to run X, now they run Y” question — the &lt;code&gt;/changes&lt;/code&gt; endpoint returns a feed of detected technology changes from the moment you start scanning a domain regularly. &lt;a href="https://detectzestack.com/blog/track-website-tech-changes-api" rel="noopener noreferrer"&gt;Tracking website tech changes via API&lt;/a&gt; covers wiring that into a webhook or a daily digest.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use Cases: Sales Research, Competitive Intel, and Lead Enrichment
&lt;/h2&gt;

&lt;p&gt;The reasons teams move from “StackShare profiles in a browser” to “detection API in a script” are mostly the same three workflows, in some combination:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sales research and prospecting.&lt;/strong&gt; Filter your TAM by what they’re actually running. “Show me every domain in my account list using HubSpot” is a one-liner against the API and a manual click-through against profiles. &lt;a href="https://detectzestack.com/blog/find-companies-using-stripe-technographic-prospecting" rel="noopener noreferrer"&gt;Technographic prospecting&lt;/a&gt; covers the pattern in detail.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CRM enrichment.&lt;/strong&gt; Fire a webhook on every new account in your CRM, hit &lt;code&gt;/analyze&lt;/code&gt;, write the technologies back as fields. The hard part is wiring the data flow; the detection itself is one HTTP call. &lt;a href="https://detectzestack.com/blog/tech-stack-enrichment-for-sales-teams" rel="noopener noreferrer"&gt;Tech stack enrichment for sales teams&lt;/a&gt; walks through the integration patterns.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Competitive intelligence.&lt;/strong&gt; Daily scan of a watchlist of competitor domains, surface diffs over time, alert when something material changes. The detection API gives you the raw signal; &lt;a href="https://detectzestack.com/blog/track-website-tech-changes-api" rel="noopener noreferrer"&gt;a change-tracking pipeline&lt;/a&gt; makes it actionable.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of those workflows fit well into a profile-page model. They all assume the data is structured, queryable, and current.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When self-reported still wins: If your research depends on internal tools (project management, CI/CD, communication, design), self-reported profiles are still the better source. A scan can’t see Linear or Notion. The right answer is often both — detection for the public stack, profiles or surveys for the internal layer.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Pricing and Getting Started
&lt;/h2&gt;

&lt;p&gt;Detection-API pricing for tech stack research is published, predictable, and an order of magnitude lower than enterprise sales-intel tools. DetectZeStack’s tiers on RapidAPI:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tier&lt;/th&gt;
&lt;th&gt;Price&lt;/th&gt;
&lt;th&gt;Requests / Month&lt;/th&gt;
&lt;th&gt;Best For&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Basic&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;td&gt;Trying it, side projects&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pro&lt;/td&gt;
&lt;td&gt;$9&lt;/td&gt;
&lt;td&gt;1,000&lt;/td&gt;
&lt;td&gt;Indie tools, small enrichment jobs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ultra&lt;/td&gt;
&lt;td&gt;$29&lt;/td&gt;
&lt;td&gt;10,000&lt;/td&gt;
&lt;td&gt;CRM enrichment, dashboards&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mega&lt;/td&gt;
&lt;td&gt;$79&lt;/td&gt;
&lt;td&gt;50,000&lt;/td&gt;
&lt;td&gt;Large account lists, scheduled re-scans&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For comparison, full sales-intelligence platforms that bundle detection with contact databases and firmographic data start in the four-figure-per-month range and require a sales call. &lt;a href="https://detectzestack.com/blog/technographic-data-pricing" rel="noopener noreferrer"&gt;Technographic data pricing&lt;/a&gt; covers why that gap exists across the whole category — the contact data dominates the price, not the detection.&lt;/p&gt;

&lt;p&gt;Getting started is one step: sign up on RapidAPI, copy your key, and call &lt;code&gt;/analyze&lt;/code&gt;. There’s no procurement process, no annual commit. If you’re still deciding, run the &lt;code&gt;/demo&lt;/code&gt; curl above against three or four of the domains you actually care about. The response shape is identical to &lt;code&gt;/analyze&lt;/code&gt; — that single call will tell you whether the detection breadth covers your real workflow before you commit to anything.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;StackShare is still useful for browsing curated, editorial profiles of well-known engineering teams. What it isn’t, in 2026, is a programmatic source of truth you can plug into automation. For tech stack research that has to scale — CRM enrichment, prospecting, competitive monitoring, change tracking — a live detection API is the right shape.&lt;/p&gt;

&lt;p&gt;If you’re evaluating options for that job, the broader landscape is in the &lt;a href="https://detectzestack.com/blog/best-tech-stack-detection-apis-2026" rel="noopener noreferrer"&gt;2026 detection API roundup&lt;/a&gt;. The &lt;a href="https://detectzestack.com/blog/free-builtwith-alternatives-2026" rel="noopener noreferrer"&gt;free BuiltWith alternatives&lt;/a&gt; guide covers the zero-cost end. And the &lt;a href="https://detectzestack.com/blog/detect-any-website-tech-stack-with-single-api-call" rel="noopener noreferrer"&gt;single API call walkthrough&lt;/a&gt; shows the integration patterns most teams settle on once they decide.&lt;/p&gt;

&lt;h3&gt;
  
  
  Related Reading
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/competitor-website-technology-analysis" rel="noopener noreferrer"&gt;Competitor Website Technology Analysis&lt;/a&gt; — Building a competitive-intel pipeline on detection data&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/find-companies-using-stripe-technographic-prospecting" rel="noopener noreferrer"&gt;Find Companies Using Stripe (Technographic Prospecting)&lt;/a&gt; — Technology-based prospecting workflow&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/tech-stack-enrichment-for-sales-teams" rel="noopener noreferrer"&gt;Tech Stack Enrichment for Sales Teams&lt;/a&gt; — Wiring detection into your CRM&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/best-tech-stack-detection-apis-2026" rel="noopener noreferrer"&gt;Best Tech Stack Detection APIs (2026)&lt;/a&gt; — Full landscape across price tiers&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/detect-any-website-tech-stack-with-single-api-call" rel="noopener noreferrer"&gt;Detect Any Website’s Tech Stack With a Single API Call&lt;/a&gt; — End-to-end integration walkthrough&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/similartech-alternative" rel="noopener noreferrer"&gt;SimilarTech Alternative&lt;/a&gt; — Comparison against another sales-intel platform&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/free-builtwith-alternatives-2026" rel="noopener noreferrer"&gt;Free BuiltWith Alternatives (2026)&lt;/a&gt; — Zero-cost detection options&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/track-website-tech-changes-api" rel="noopener noreferrer"&gt;Track Website Tech Changes via API&lt;/a&gt; — Building a change-detection pipeline&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/technographic-data-pricing" rel="noopener noreferrer"&gt;Technographic Data Pricing&lt;/a&gt; — Why detection API costs vary by 10x&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/detect-cdn-hosting-provider" rel="noopener noreferrer"&gt;Detect CDN and Hosting Provider&lt;/a&gt; — DNS-layer detection that profile pages miss&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>techstack</category>
      <category>webdev</category>
      <category>api</category>
    </item>
    <item>
      <title>Set Up Webhook Tech Stack Changes Alerts via API</title>
      <dc:creator>MikeL</dc:creator>
      <pubDate>Sun, 10 May 2026 14:00:36 +0000</pubDate>
      <link>https://dev.to/detectzestack/set-up-webhook-tech-stack-changes-alerts-via-api-4fh9</link>
      <guid>https://dev.to/detectzestack/set-up-webhook-tech-stack-changes-alerts-via-api-4fh9</guid>
      <description>&lt;p&gt;Polling an API on a timer to check whether a website changed its tech stack is wasteful. You burn requests checking domains that have not changed, and you miss changes that happen between your polling intervals. Webhooks solve both problems: DetectZeStack monitors domains on a schedule and pushes notifications to your server only when something actually changes.&lt;/p&gt;

&lt;p&gt;This guide walks through the full webhook lifecycle: creating a subscription, enabling scheduled monitoring, verifying HMAC-signed payloads, and building a working Slack integration that alerts your team when a competitor switches frameworks, adds a CDN, or drops their analytics provider.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Monitor Websites for Tech Stack Changes
&lt;/h2&gt;

&lt;p&gt;Technology stack changes are leading indicators. A company adding Stripe is about to launch payments. A competitor switching from Heroku to AWS is preparing to scale. A client removing their Content-Security-Policy header just created a security vulnerability nobody noticed.&lt;/p&gt;

&lt;p&gt;Manual checking does not scale. If you are tracking 20 competitor domains, logging in weekly to scan each one is a full hour of repetitive work. And you will miss changes that happen mid-week.&lt;/p&gt;

&lt;p&gt;Webhook alerts flip the model: instead of you checking DetectZeStack, DetectZeStack checks the domains and tells you when something changes. Zero wasted effort, zero missed changes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use Cases for Webhook Tech Stack Changes Alerts
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Competitive intelligence&lt;/strong&gt; — get notified when a competitor adds Intercom, switches from React to Next.js, or deploys behind Cloudflare&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security monitoring&lt;/strong&gt; — alert when a managed client removes security headers, drops their WAF, or changes SSL configuration&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sales signals&lt;/strong&gt; — identify prospects adding payment processors, marketing automation, or analytics tools that indicate buying intent&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Investment due diligence&lt;/strong&gt; — track portfolio company infrastructure decisions in real time rather than waiting for quarterly updates&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agency client oversight&lt;/strong&gt; — catch unauthorized changes to client websites before they become incidents&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How DetectZeStack Webhook Alerts Work
&lt;/h2&gt;

&lt;p&gt;The webhook system has three components:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Subscription&lt;/strong&gt; — you register a domain + callback URL pair via &lt;code&gt;POST /webhooks&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitoring&lt;/strong&gt; — you enable daily or weekly scanning via &lt;code&gt;PATCH /webhooks/{id}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Delivery&lt;/strong&gt; — when changes are detected, DetectZeStack POSTs a signed payload to your URL&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  The Webhook Lifecycle
&lt;/h3&gt;

&lt;p&gt;Every time a monitored domain is scanned, DetectZeStack diffs the new snapshot against the previous one. If technologies were added, removed, or changed version, a &lt;code&gt;tech_stack.changed&lt;/code&gt; event is sent to all active subscribers for that domain. If nothing changed, no notification is sent — your endpoint stays quiet.&lt;/p&gt;

&lt;p&gt;Every scan (whether changes were found or not) also fires a &lt;code&gt;tech_stack.analyzed&lt;/code&gt; event with the full technology list. This is useful if you want to log every scan result to your own database regardless of whether anything changed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1 — Create a Webhook Subscription
&lt;/h2&gt;

&lt;p&gt;Register a webhook by POSTing the domain you want to monitor and the URL where you want to receive notifications:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"https://detectzestack.p.rapidapi.com/webhooks"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-rapidapi-key: YOUR_API_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-rapidapi-host: detectzestack.p.rapidapi.com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
"domain": "competitor.com",
"webhook_url": "https://your-server.com/hooks/techstack"
}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"domain"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"competitor.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"webhook_url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://your-server.com/hooks/techstack"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"hmac_secret"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;hmac_secret&lt;/code&gt; is returned exactly once at creation time. Store it securely — it cannot be retrieved again. You will use it to verify that incoming webhook deliveries actually came from DetectZeStack.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Webhook URLs must use HTTPS. HTTP endpoints are rejected to prevent credentials from being transmitted in plaintext. The URL must also resolve to a public IP address (no localhost or private ranges).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Webhook Limits by Plan
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Plan&lt;/th&gt;
&lt;th&gt;Price&lt;/th&gt;
&lt;th&gt;Webhook Subscriptions&lt;/th&gt;
&lt;th&gt;Monitoring&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Basic (free)&lt;/td&gt;
&lt;td&gt;$0/mo&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Not available&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pro&lt;/td&gt;
&lt;td&gt;$9/mo&lt;/td&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;Daily / Weekly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ultra&lt;/td&gt;
&lt;td&gt;$29/mo&lt;/td&gt;
&lt;td&gt;50&lt;/td&gt;
&lt;td&gt;Daily / Weekly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mega&lt;/td&gt;
&lt;td&gt;$79/mo&lt;/td&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;td&gt;Daily / Weekly&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Free tier users can create webhook subscriptions and receive notifications when they manually trigger scans via the API. Scheduled monitoring (automatic daily or weekly scans) requires a paid tier.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2 — Enable Scheduled Monitoring
&lt;/h2&gt;

&lt;p&gt;Creating a webhook subscription does not automatically start monitoring. To have DetectZeStack scan the domain on a schedule, update the subscription with a monitoring interval:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; PATCH &lt;span class="s2"&gt;"https://detectzestack.p.rapidapi.com/webhooks/42"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-rapidapi-key: YOUR_API_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-rapidapi-host: detectzestack.p.rapidapi.com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"monitor_interval": "daily"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"updated"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"monitor_interval"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"daily"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Daily vs Weekly Monitoring Intervals
&lt;/h3&gt;

&lt;p&gt;Choose the interval based on how time-sensitive the information is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Daily&lt;/strong&gt; — best for security monitoring, active competitive tracking, or client oversight where you need to catch changes within 24 hours&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Weekly&lt;/strong&gt; — sufficient for investment monitoring, long-term trend tracking, or low-priority domains where day-level granularity is unnecessary&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To disable monitoring without deleting the webhook, set &lt;code&gt;monitor_interval&lt;/code&gt; to an empty string (&lt;code&gt;""&lt;/code&gt;). The subscription remains active for manual triggers but no automatic scans occur.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3 — Receive and Verify Webhook Payloads
&lt;/h2&gt;

&lt;p&gt;When changes are detected, DetectZeStack sends an HTTP POST to your registered URL. The request includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Content-Type: application/json&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;X-Webhook-Event: tech_stack.analyzed&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;X-Webhook-Signature: sha256=&amp;lt;hex-encoded HMAC&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  HMAC Signature Verification
&lt;/h3&gt;

&lt;p&gt;Every delivery is signed with your webhook's HMAC secret using SHA-256. To verify:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Read the raw request body (do not parse JSON first)&lt;/li&gt;
&lt;li&gt;Compute HMAC-SHA256 of the raw body using your stored &lt;code&gt;hmac_secret&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Compare the computed signature against the value in &lt;code&gt;X-Webhook-Signature&lt;/code&gt; (after stripping the &lt;code&gt;sha256=&lt;/code&gt; prefix)&lt;/li&gt;
&lt;li&gt;Use constant-time comparison to prevent timing attacks&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Python verification example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;hmac&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;hashlib&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;verify_signature&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payload_body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;signature_header&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Verify the HMAC-SHA256 signature from DetectZeStack webhook.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;signature_header&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startswith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sha256=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;

&lt;span class="n"&gt;expected_sig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;signature_header&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;:]&lt;/span&gt;  &lt;span class="c1"&gt;# strip "sha256=" prefix
&lt;/span&gt;&lt;span class="n"&gt;computed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hmac&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;span class="n"&gt;payload_body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;hashlib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sha256&lt;/span&gt;
&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;hexdigest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;hmac&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compare_digest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;computed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expected_sig&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Payload Structure
&lt;/h3&gt;

&lt;p&gt;The webhook payload contains the full scan result along with metadata:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"event"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tech_stack.analyzed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"domain"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"competitor.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"technologies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"React"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"categories"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"JavaScript frameworks"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"18.2.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Cloudflare"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"categories"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"CDN"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Next.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"categories"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"JavaScript frameworks"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"14.1.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Google Analytics"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"categories"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Analytics"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"meta"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"scan_time_ms"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1842&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"detection_count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-04-20T10:30:00Z"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the scan detected changes compared to the previous snapshot, the payload additionally includes technology change events in the &lt;code&gt;/changes&lt;/code&gt; feed that you can query separately for structured diffs (added, removed, version_changed).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Delivery retries: If your endpoint returns a non-2xx status code, DetectZeStack retries up to 3 times with exponential backoff (2 seconds, then 4 seconds). After 3 failures, the delivery is abandoned for that event.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Step 4 — Query the Change Feed for Context
&lt;/h2&gt;

&lt;p&gt;Webhook payloads tell you the current state. To see exactly what changed (what was added or removed), query the &lt;code&gt;/changes&lt;/code&gt; endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://detectzestack.p.rapidapi.com/changes?domain=competitor.com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-rapidapi-key: YOUR_API_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-rapidapi-host: detectzestack.p.rapidapi.com"&lt;/span&gt; | python3 &lt;span class="nt"&gt;-m&lt;/span&gt; json.tool
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"changes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4821&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"domain"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"competitor.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"technology"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Cloudflare"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"change_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"added"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"category"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"CDN"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"created_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-04-20T10:30:00Z"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4822&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"domain"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"competitor.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"technology"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Akamai"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"change_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"removed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"category"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"CDN"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"created_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-04-20T10:30:00Z"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"history_days"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"tier"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"pro"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Combining webhooks with the change feed gives you the full picture: the webhook tells you &lt;em&gt;something changed&lt;/em&gt;, and the change feed tells you &lt;em&gt;exactly what&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Managing Your Webhooks
&lt;/h2&gt;

&lt;h3&gt;
  
  
  List Active Webhooks
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://detectzestack.p.rapidapi.com/webhooks"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-rapidapi-key: YOUR_API_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-rapidapi-host: detectzestack.p.rapidapi.com"&lt;/span&gt; | python3 &lt;span class="nt"&gt;-m&lt;/span&gt; json.tool
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"webhooks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"domain"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"competitor.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"webhook_url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://your-server.com/hooks/techstack"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"monitor_interval"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"daily"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"created_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-04-20T09:00:00Z"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Update or Delete a Webhook
&lt;/h3&gt;

&lt;p&gt;Change the monitoring interval:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; PATCH &lt;span class="s2"&gt;"https://detectzestack.p.rapidapi.com/webhooks/42"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-rapidapi-key: YOUR_API_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-rapidapi-host: detectzestack.p.rapidapi.com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"monitor_interval": "weekly"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Delete a subscription entirely:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; DELETE &lt;span class="s2"&gt;"https://detectzestack.p.rapidapi.com/webhooks/42"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-rapidapi-key: YOUR_API_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-rapidapi-host: detectzestack.p.rapidapi.com"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Deleting a webhook stops all monitoring and future deliveries for that subscription immediately.&lt;/p&gt;

&lt;h2&gt;
  
  
  Full Python Example — Slack Alerts on Tech Stack Changes
&lt;/h2&gt;

&lt;p&gt;Here is a complete Flask application that receives DetectZeStack webhooks, verifies the signature, queries the change feed for context, and posts a formatted message to Slack:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;hmac&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;hashlib&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;flask&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;jsonify&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;WEBHOOK_SECRET&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;your_hmac_secret_from_creation&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;RAPIDAPI_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YOUR_API_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;SLACK_WEBHOOK&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://hooks.slack.com/services/YOUR/WEBHOOK/URL&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="nd"&gt;@app.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/hooks/techstack&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;POST&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;handle_webhook&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;span class="c1"&gt;# Step 1: Verify signature
&lt;/span&gt;&lt;span class="n"&gt;signature&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;X-Webhook-Signature&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nf"&gt;verify_signature&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;WEBHOOK_SECRET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;jsonify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;error&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;invalid signature&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="mi"&gt;401&lt;/span&gt;

&lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="n"&gt;domain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;domain&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;# Step 2: Query the change feed for structured diffs
&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;x-rapidapi-key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;RAPIDAPI_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;x-rapidapi-host&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;detectzestack.p.rapidapi.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://detectzestack.p.rapidapi.com/changes?domain=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;changes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;changes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;count&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;jsonify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;no changes&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;

&lt;span class="c1"&gt;# Step 3: Format and send Slack message
&lt;/span&gt;&lt;span class="n"&gt;lines&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;changes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;changes&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
&lt;span class="n"&gt;prefix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;added&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;+&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;removed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;version_changed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;~&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;symbol&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;prefix&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;change_type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;symbol&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;] &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;technology&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; (&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;category&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;previous_version&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;new_version&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;previous_version&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; -&amp;gt; &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;new_version&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;lines&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;*Tech stack change detected on &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;:*&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;```
&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;endraw&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;
&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lines&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;  &lt;span class="c1"&gt;# limit to 10 changes
&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;
{% raw %}
```&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SLACK_WEBHOOK&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;jsonify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ok&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;verify_signature&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payload_body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;signature_header&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;signature_header&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startswith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sha256=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;
&lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;signature_header&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;:]&lt;/span&gt;
&lt;span class="n"&gt;computed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hmac&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;payload_body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hashlib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sha256&lt;/span&gt;
&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;hexdigest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;hmac&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compare_digest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;computed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Deploy this behind HTTPS (using nginx, Caddy, or a platform like Railway) and register the public URL as your webhook endpoint. The entire pipeline — detection, notification, and alerting — runs automatically without any polling or cron jobs on your side.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It: Scan a Domain with the Demo Endpoint
&lt;/h2&gt;

&lt;p&gt;Before setting up webhooks, verify what DetectZeStack detects for a given domain using the free demo endpoint (no API key required):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://detectzestack.com/demo?url=https://stripe.com"&lt;/span&gt; | python3 &lt;span class="nt"&gt;-m&lt;/span&gt; json.tool
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This returns the full technology list for stripe.com — the same data structure that webhook payloads use. Use this to validate that the domains you plan to monitor produce useful detection results before investing in webhook setup.&lt;/p&gt;

&lt;h2&gt;
  
  
  Webhook Limits and Tier Comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Free&lt;/th&gt;
&lt;th&gt;Pro ($9/mo)&lt;/th&gt;
&lt;th&gt;Ultra ($29/mo)&lt;/th&gt;
&lt;th&gt;Mega ($79/mo)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Webhook subscriptions&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;50&lt;/td&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scheduled monitoring&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Daily / Weekly&lt;/td&gt;
&lt;td&gt;Daily / Weekly&lt;/td&gt;
&lt;td&gt;Daily / Weekly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Change history depth&lt;/td&gt;
&lt;td&gt;7 days&lt;/td&gt;
&lt;td&gt;30 days&lt;/td&gt;
&lt;td&gt;90 days&lt;/td&gt;
&lt;td&gt;365 days&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API requests/month&lt;/td&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;td&gt;1,000&lt;/td&gt;
&lt;td&gt;10,000&lt;/td&gt;
&lt;td&gt;50,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HMAC-signed payloads&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Retry on failure&lt;/td&gt;
&lt;td&gt;3 attempts&lt;/td&gt;
&lt;td&gt;3 attempts&lt;/td&gt;
&lt;td&gt;3 attempts&lt;/td&gt;
&lt;td&gt;3 attempts&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;All plans include HMAC signature verification and automatic retry with exponential backoff. The difference between tiers is how many domains you can monitor simultaneously and whether scheduled (automatic) monitoring is available.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get Started with Webhook Tech Stack Changes Alerts
&lt;/h2&gt;

&lt;p&gt;Setting up webhook-based tech stack monitoring takes about five minutes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Get your API key from RapidAPI (free tier includes 5 webhook subscriptions)&lt;/li&gt;
&lt;li&gt;Create a subscription with &lt;code&gt;POST /webhooks&lt;/code&gt; for each domain you want to monitor&lt;/li&gt;
&lt;li&gt;Enable scheduled monitoring with &lt;code&gt;PATCH /webhooks/{id}&lt;/code&gt; (paid tiers)&lt;/li&gt;
&lt;li&gt;Implement signature verification in your webhook handler&lt;/li&gt;
&lt;li&gt;Route notifications to Slack, PagerDuty, email, or your own dashboard&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No polling. No cron jobs. No wasted API requests checking domains that have not changed. DetectZeStack handles the scanning, diffing, and notification delivery — you just receive the alerts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Related Reading
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/track-website-tech-changes-api" rel="noopener noreferrer"&gt;Track Website Tech Changes Over Time via API&lt;/a&gt; — Full guide to /changes, /history, and /webhooks endpoints&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/automate-security-audits-api" rel="noopener noreferrer"&gt;Automate Security Audits with the DetectZeStack API&lt;/a&gt; — Combine webhooks with security header monitoring&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/batch-scan-1000-websites" rel="noopener noreferrer"&gt;How to Batch Scan 1,000 Websites for Tech Stack Data&lt;/a&gt; — Bulk scanning for initial baseline before enabling webhook monitoring&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/competitor-website-technology-analysis" rel="noopener noreferrer"&gt;Competitor Website Technology Analysis&lt;/a&gt; — Use tech stack data for competitive intelligence&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/monitor" rel="noopener noreferrer"&gt;Technology Change Monitor&lt;/a&gt; — Interactive dashboard for tracking tech stack changes&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>techstack</category>
      <category>webdev</category>
      <category>api</category>
    </item>
    <item>
      <title>WhatRuns Alternative API: 4 Options for Programmatic Detection</title>
      <dc:creator>MikeL</dc:creator>
      <pubDate>Fri, 01 May 2026 14:01:10 +0000</pubDate>
      <link>https://dev.to/detectzestack/whatruns-alternative-api-4-options-for-programmatic-detection-8bp</link>
      <guid>https://dev.to/detectzestack/whatruns-alternative-api-4-options-for-programmatic-detection-8bp</guid>
      <description>&lt;p&gt;If you opened this page, you probably went looking for “WhatRuns API” or “WhatRuns API key,” hit a dead end, and started searching for an alternative. That’s the right move—&lt;a href="https://detectzestack.com/blog/whatruns-api-key-alternative" rel="noopener noreferrer"&gt;WhatRuns has no public API&lt;/a&gt;, no key, and no documentation. It is a browser extension, full stop.&lt;/p&gt;

&lt;p&gt;The good news is that the use cases people associate with WhatRuns—identifying JavaScript frameworks, spotting CMS platforms, mapping hosting and CDN providers, enriching lead lists—are well covered by APIs you can hit with &lt;code&gt;curl&lt;/code&gt; in a few seconds. This guide walks through four practical WhatRuns alternative API options, the trade-offs between them, and a working example you can copy and run today.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why WhatRuns Has No Public API
&lt;/h2&gt;

&lt;p&gt;WhatRuns’ founder shipped the extension as a free product several years ago and effectively walked away from active development. The extension still works as a manual lookup tool, but the team never published a REST endpoint, never released SDKs, and never documented an authentication flow. The detection logic runs inside the browser, reads page-level signals, and reports back to a private backend the extension uses for its own UI—not for third-party consumption.&lt;/p&gt;

&lt;p&gt;The result: any workflow that needs automated, repeatable tech detection has to look elsewhere. Browser extensions also can’t see the infrastructure layer. They can’t resolve DNS, inspect TLS certificates, or check IP ranges, which means a CDN like CloudFront or Fastly that doesn’t advertise itself in HTTP headers is invisible. &lt;a href="https://detectzestack.com/blog/dns-tls-detection-vs-browser-extensions" rel="noopener noreferrer"&gt;A purpose-built API can see all four layers&lt;/a&gt;, which matters once you start scanning anything beyond a marketing site.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to Look for in a WhatRuns Alternative API
&lt;/h2&gt;

&lt;p&gt;Not every detection API solves the same problem. Before picking one, decide what you actually need. Three dimensions matter most.&lt;/p&gt;

&lt;h3&gt;
  
  
  Coverage Across JS, CMS, Hosting, and DNS
&lt;/h3&gt;

&lt;p&gt;WhatRuns is strongest at JavaScript framework and front-end library detection—it surfaces React, Vue, Next.js, jQuery, Tailwind, analytics scripts, and chat widgets reliably. A direct replacement should cover the same categories, plus the infrastructure signals the extension misses. At a minimum, look for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;JavaScript frameworks and libraries&lt;/strong&gt; — &lt;a href="https://detectzestack.com/blog/how-to-detect-react-website" rel="noopener noreferrer"&gt;React&lt;/a&gt;, Vue, Angular, Next.js, Svelte, jQuery, Tailwind CSS, and so on.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CMS and e-commerce platforms&lt;/strong&gt; — WordPress, Shopify, Webflow, HubSpot CMS, Drupal, Magento, Squarespace.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Analytics and marketing tools&lt;/strong&gt; — Google Analytics, Segment, Mixpanel, Amplitude, HubSpot, Intercom.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hosting and CDN&lt;/strong&gt; — Cloudflare, CloudFront, Fastly, Vercel, Netlify, Akamai. &lt;a href="https://detectzestack.com/blog/detect-cdn-hosting-provider" rel="noopener noreferrer"&gt;DNS-level detection&lt;/a&gt; is what separates the API class from the extension class.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security and TLS&lt;/strong&gt; — HSTS, certificate authority, SSL/TLS configuration.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Pricing That Scales With Usage
&lt;/h3&gt;

&lt;p&gt;If you’re scanning ten domains a month, a free tier on RapidAPI is fine. If you’re enriching a 50,000-row CRM export, the per-domain cost dominates. The cheapest providers settle around $9–$29/month for a few thousand requests. The expensive end—BuiltWith’s premium tier—starts at $295/month and is priced for enterprise sales intelligence rather than ad-hoc detection. &lt;a href="https://detectzestack.com/blog/technographic-data-pricing" rel="noopener noreferrer"&gt;Technographic data pricing&lt;/a&gt; varies by an order of magnitude, so check the rate limits and price-per-call before committing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Response Latency and Cache Behavior
&lt;/h3&gt;

&lt;p&gt;A first-time scan of an unfamiliar domain usually costs 1.5–3 seconds because the API has to make an outbound HTTP request, parse the response, run DNS lookups, and complete a TLS handshake. Subsequent scans of the same domain should be near-instant if the provider caches results. Cached responses on DetectZeStack typically return in 5–50ms, which matters when you’re fanning out across hundreds of domains in a job.&lt;/p&gt;

&lt;h2&gt;
  
  
  Four WhatRuns Alternative APIs Compared
&lt;/h2&gt;

&lt;p&gt;Here are the four credible options, ordered roughly from easiest-to-start to most-effort-to-run.&lt;/p&gt;

&lt;h3&gt;
  
  
  DetectZeStack
&lt;/h3&gt;

&lt;p&gt;DetectZeStack is a REST API for tech stack detection that combines HTTP fingerprinting (using the Wappalyzer signature database with 7,300+ patterns), DNS CNAME and NS analysis, and TLS certificate inspection. The free tier is 100 requests/month on RapidAPI with no credit card. Paid tiers start at $9/month for 1,000 requests and scale to 50,000 requests at $79/month.&lt;/p&gt;

&lt;p&gt;Endpoints worth knowing about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;GET /analyze&lt;/code&gt; — single URL, full detection across HTTP, DNS, and TLS.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GET /demo&lt;/code&gt; — same response shape as &lt;code&gt;/analyze&lt;/code&gt;, no API key needed, useful for trying it out.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;POST /analyze/batch&lt;/code&gt; — up to 10 URLs per request for parallel scans.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;POST /compare&lt;/code&gt; — diff two domains to see which technologies are unique to each.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GET /certificate&lt;/code&gt; — TLS certificate details (issuer, expiry, SANs).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GET /dns&lt;/code&gt; — raw DNS records (A, AAAA, CNAME, MX, NS, TXT).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Strengths: free tier, no credit card, DNS-layer detection that browser extensions can’t do, version numbers and CPE identifiers when available for vulnerability mapping. Honest weaknesses: smaller historical dataset than BuiltWith’s, no built-in lead-list export.&lt;/p&gt;

&lt;h3&gt;
  
  
  BuiltWith API
&lt;/h3&gt;

&lt;p&gt;BuiltWith is the long-running incumbent. Their detection covers a similar range of categories and includes deep historical data that goes back years—useful if you want to know when a domain switched from Magento to Shopify. The catch is pricing: the entry-level “Basic” API plan starts at $295/month, with higher tiers running into the low four figures. If your use case is sales intelligence on a known list of accounts, the historical depth can pay for itself. For ad-hoc developer use, it’s usually overkill. &lt;a href="https://detectzestack.com/blog/builtwith-vs-whatruns" rel="noopener noreferrer"&gt;BuiltWith versus WhatRuns&lt;/a&gt; covers the deeper comparison.&lt;/p&gt;

&lt;h3&gt;
  
  
  Wappalyzer API
&lt;/h3&gt;

&lt;p&gt;Wappalyzer publishes its detection signatures as open source (MIT license) and runs a paid hosted API on top of them. Pricing starts at around $250/month for the “Lookup” plan with monthly request quotas. The signature database is the same one that powers DetectZeStack and many other tools, so detection breadth is comparable. Wappalyzer’s differentiator is the bundled lead-generation tooling (filtered lists of sites by technology, exportable to CSV).&lt;/p&gt;

&lt;h3&gt;
  
  
  Self-Hosted wappalyzergo
&lt;/h3&gt;

&lt;p&gt;If you have engineering capacity and want zero per-call cost, you can run detection in-process. &lt;code&gt;wappalyzergo&lt;/code&gt; is a Go library that ports the Wappalyzer detection logic and ships the same signature JSON. You write a few lines of Go to fetch a URL, hand the response to the library, and read out the technologies. There’s no rate limit, no monthly bill, and no third-party dependency in the request path.&lt;/p&gt;

&lt;p&gt;The trade-offs are real, though. You need to maintain the deployment, update the signature file periodically, build outbound fetch logic with proper SSRF protection, and handle DNS and TLS detection separately because &lt;code&gt;wappalyzergo&lt;/code&gt; only handles HTTP-layer detection. &lt;a href="https://detectzestack.com/blog/wappalyzer-open-source-alternatives" rel="noopener noreferrer"&gt;A deeper walkthrough of the open-source path&lt;/a&gt; covers what to expect in production. This is the right answer when you’re scanning millions of domains and the API bills would be prohibitive; it’s the wrong answer for most teams who just want a result back from one HTTP call.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Option&lt;/th&gt;
&lt;th&gt;Free Tier&lt;/th&gt;
&lt;th&gt;Entry Price&lt;/th&gt;
&lt;th&gt;DNS / TLS Detection&lt;/th&gt;
&lt;th&gt;Hosted&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;DetectZeStack&lt;/td&gt;
&lt;td&gt;100 req/mo&lt;/td&gt;
&lt;td&gt;$9/mo (1k req)&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;BuiltWith API&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;$295/mo&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Wappalyzer API&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;$250/mo&lt;/td&gt;
&lt;td&gt;Partial&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;wappalyzergo (self-hosted)&lt;/td&gt;
&lt;td&gt;Free (your infra)&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;td&gt;Build it yourself&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Calling the DetectZeStack API: A Working Example
&lt;/h2&gt;

&lt;p&gt;The fastest way to see whether a detection API meets your needs is to fire one request at it. The DetectZeStack &lt;code&gt;/demo&lt;/code&gt; endpoint requires no authentication, so you can test the response shape before signing up for anything.&lt;/p&gt;

&lt;h3&gt;
  
  
  Single-URL Detection With /analyze
&lt;/h3&gt;

&lt;p&gt;Try &lt;code&gt;/demo&lt;/code&gt; first. Same response shape as &lt;code&gt;/analyze&lt;/code&gt;, no key needed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://detectzestack.com/demo?url=stripe.com"&lt;/span&gt; | jq
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Response (trimmed):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://stripe.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"domain"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"stripe.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"technologies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Amazon S3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"categories"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"CDN"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Amazon S3 or Amazon Simple Storage Service is a service offered by AWS that provides object storage through a web service interface."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"website"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://aws.amazon.com/s3/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"icon"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Amazon S3.svg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"cpe"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Nginx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"categories"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Web servers"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Reverse proxies"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Nginx is a web server that can also be used as a reverse proxy, load balancer, mail proxy and HTTP cache."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"website"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://nginx.org/en"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"icon"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Nginx.svg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"cpe"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cpe:2.3:a:f5:nginx:*:*:*:*:*:*:*:*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"DigiCert"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"categories"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"SSL/TLS certificate authority"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tls"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"categories"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"CDN"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Amazon S3"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"PaaS"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Amazon Web Services"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"Reverse proxies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Nginx"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"SSL/TLS certificate authority"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"DigiCert"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"Security"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"HSTS"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"Web servers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Nginx"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"meta"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"status_code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"tech_count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"scan_depth"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"full"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"cached"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"response_ms"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1842&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A few things worth noting in the response:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;technologies&lt;/code&gt; is the full list with confidence scores and source labels. The &lt;code&gt;source&lt;/code&gt; field shows how the technology was detected: &lt;code&gt;http&lt;/code&gt; for header or HTML pattern matches, &lt;code&gt;dns&lt;/code&gt; for CNAME/NS matches, and &lt;code&gt;tls&lt;/code&gt; for certificate-based detection.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;categories&lt;/code&gt; is a convenience map for “give me everything in CDN” or “give me everything in JavaScript frameworks.”&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;meta.scan_depth&lt;/code&gt; is &lt;code&gt;"full"&lt;/code&gt; when all three layers ran, &lt;code&gt;"partial"&lt;/code&gt; when the upstream blocked HTTP requests but DNS or TLS still produced results.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cached&lt;/code&gt; and &lt;code&gt;response_ms&lt;/code&gt; sit at the top level, not inside &lt;code&gt;meta&lt;/code&gt;. Cached responses typically return in 5–50ms.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cpe&lt;/code&gt; is populated when a CPE 2.3 identifier exists for the technology, which is what you feed into NVD for &lt;a href="https://detectzestack.com/blog/detect-vulnerable-technologies-with-cpe" rel="noopener noreferrer"&gt;vulnerability lookups&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once you have an API key, the same call against the authenticated endpoint looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://detectzestack.p.rapidapi.com/analyze?url=stripe.com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-RapidAPI-Key: YOUR_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-RapidAPI-Host: detectzestack.p.rapidapi.com"&lt;/span&gt; | jq
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Bulk Scans With /analyze/batch
&lt;/h3&gt;

&lt;p&gt;For workflows that need to scan a list of domains, &lt;code&gt;POST /analyze/batch&lt;/code&gt; handles up to 10 URLs per request and runs the fetches in parallel server-side. That removes the round-trip overhead of issuing ten separate calls.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-sX&lt;/span&gt; POST &lt;span class="s2"&gt;"https://detectzestack.p.rapidapi.com/analyze/batch"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-RapidAPI-Key: YOUR_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-RapidAPI-Host: detectzestack.p.rapidapi.com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"urls": ["stripe.com", "shopify.com", "vercel.com"]}'&lt;/span&gt; | jq
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response is a &lt;code&gt;results&lt;/code&gt; array with one entry per input URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"results"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"stripe.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nl"&gt;"result"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"domain"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"stripe.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"technologies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"categories"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"meta"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"cached"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"response_ms"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1842&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"shopify.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"result"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"domain"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"shopify.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"technologies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"categories"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"meta"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"cached"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nl"&gt;"response_ms"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"vercel.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nl"&gt;"result"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"domain"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"vercel.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"technologies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"categories"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"meta"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"cached"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"response_ms"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1654&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"total_ms"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1873&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"successful"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"failed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If a single URL in the batch fails (for example, an unreachable domain), the corresponding entry will have an &lt;code&gt;error&lt;/code&gt; field instead of a &lt;code&gt;result&lt;/code&gt; field. The successful items still come through, so a partial failure doesn’t blow up the whole job. For larger lists, chunk into batches of 10 and run them concurrently from your worker pool. &lt;a href="https://detectzestack.com/blog/batch-scan-1000-websites" rel="noopener noreferrer"&gt;Scanning a thousand domains&lt;/a&gt; covers the rate-limit math in detail.&lt;/p&gt;

&lt;h2&gt;
  
  
  Migrating From the WhatRuns Extension to an API Workflow
&lt;/h2&gt;

&lt;p&gt;If you’ve been using WhatRuns by hand—clicking the icon on each page you visit—moving to an API is mostly a rewiring exercise. The shape of the data is similar; what changes is the integration point. A few practical migration tips:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Map your existing categories.&lt;/strong&gt; WhatRuns groups results into “Frameworks,” “Analytics,” “CMS,” “Web Server,” etc. DetectZeStack uses Wappalyzer’s category names, which are similar but not identical. The &lt;code&gt;categories&lt;/code&gt; object in the response is your lookup table.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trust confidence scores.&lt;/strong&gt; WhatRuns shows a single technology name with no confidence indicator. APIs return a 0–100 score per detection. For batch jobs, filtering at &lt;code&gt;confidence &amp;gt;= 80&lt;/code&gt; usually removes most false positives without sacrificing real matches.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pull DNS and TLS results explicitly.&lt;/strong&gt; If you specifically need CDN or hosting provider, don’t rely on the HTTP detection alone—Cloudflare in proxy mode or CloudFront without identifying headers will only show up via DNS or TLS signals. Filter &lt;code&gt;technologies&lt;/code&gt; by &lt;code&gt;source: "dns"&lt;/code&gt; or &lt;code&gt;source: "tls"&lt;/code&gt; when you want infrastructure signals only.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cache aggressively.&lt;/strong&gt; The API caches responses, but if you’re running daily enrichment over a static account list, store the results in your own warehouse and only refresh weekly. The &lt;code&gt;cached&lt;/code&gt; field tells you whether the response came from cache.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Track changes over time.&lt;/strong&gt; The big upside of moving to an API is that you can record results and diff them. &lt;a href="https://detectzestack.com/blog/track-website-tech-changes-api" rel="noopener noreferrer"&gt;Tracking technology changes&lt;/a&gt; over time is something WhatRuns simply can’t do because it has no concept of history.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Picking the right tier: If you’re scanning 10–100 domains a month, the free tier covers it. If you’re enriching a CRM with thousands of accounts, the $29/month tier (10,000 requests) is usually the sweet spot. The $79/month tier (50,000 requests) makes sense when you’re running scheduled re-scans across a large account list.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Get Started With a Free API Key
&lt;/h2&gt;

&lt;p&gt;WhatRuns won’t ever ship an API—the project is dormant. But the workflows people associate with WhatRuns translate directly to a detection API, and once you make the switch you get capabilities the extension was structurally incapable of: DNS-layer detection, TLS inspection, batch scans, change tracking, and version-level metadata for vulnerability work.&lt;/p&gt;

&lt;p&gt;If you want to try the closest behavioral match before committing, run the &lt;code&gt;/demo&lt;/code&gt; curl above. It returns the same response shape as the authenticated &lt;code&gt;/analyze&lt;/code&gt; endpoint, costs nothing, and will tell you in one round-trip whether the detection breadth is enough for your use case. For deeper comparisons, see &lt;a href="https://detectzestack.com/blog/detectzestack-vs-whatruns" rel="noopener noreferrer"&gt;DetectZeStack vs WhatRuns&lt;/a&gt; and the broader &lt;a href="https://detectzestack.com/blog/best-tech-stack-detection-apis-2026" rel="noopener noreferrer"&gt;2026 detection API landscape&lt;/a&gt;. To see the full single-call workflow end-to-end, the &lt;a href="https://detectzestack.com/blog/detect-any-website-tech-stack-with-single-api-call" rel="noopener noreferrer"&gt;single API call walkthrough&lt;/a&gt; covers the integration patterns most teams settle on.&lt;/p&gt;

&lt;h3&gt;
  
  
  Related Reading
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/whatruns-api-key-alternative" rel="noopener noreferrer"&gt;WhatRuns API Key — There Isn’t One. Here’s the Free Alternative&lt;/a&gt; — Why no key exists and the closest replacement&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/detectzestack-vs-whatruns" rel="noopener noreferrer"&gt;DetectZeStack vs WhatRuns&lt;/a&gt; — Side-by-side comparison of detection layers and use cases&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/builtwith-vs-whatruns" rel="noopener noreferrer"&gt;BuiltWith vs WhatRuns&lt;/a&gt; — Historical depth vs lightweight extension trade-off&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/best-tech-stack-detection-apis-2026" rel="noopener noreferrer"&gt;Best Tech Stack Detection APIs (2026)&lt;/a&gt; — Full landscape of detection APIs across price tiers&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/detect-any-website-tech-stack-with-single-api-call" rel="noopener noreferrer"&gt;Detect Any Website’s Tech Stack With a Single API Call&lt;/a&gt; — End-to-end integration walkthrough&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/dns-tls-detection-vs-browser-extensions" rel="noopener noreferrer"&gt;DNS + TLS Detection vs Browser Extensions&lt;/a&gt; — What infrastructure signals extensions miss&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/wappalyzer-open-source-alternatives" rel="noopener noreferrer"&gt;Wappalyzer Open-Source Alternatives&lt;/a&gt; — Self-hosted detection with wappalyzergo&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/batch-scan-1000-websites" rel="noopener noreferrer"&gt;Batch Scan 1000 Websites&lt;/a&gt; — Rate-limit math and worker pool patterns&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/track-website-tech-changes-api" rel="noopener noreferrer"&gt;Track Website Tech Changes via API&lt;/a&gt; — Building a change-detection pipeline&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/technographic-data-pricing" rel="noopener noreferrer"&gt;Technographic Data Pricing&lt;/a&gt; — Why detection API costs vary by 10x&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>techstack</category>
      <category>webdev</category>
      <category>api</category>
    </item>
    <item>
      <title>Ecommerce Tech Stack Analysis: Shopify vs WooCommerce</title>
      <dc:creator>MikeL</dc:creator>
      <pubDate>Thu, 23 Apr 2026 14:01:03 +0000</pubDate>
      <link>https://dev.to/detectzestack/ecommerce-tech-stack-analysis-shopify-vs-woocommerce-hck</link>
      <guid>https://dev.to/detectzestack/ecommerce-tech-stack-analysis-shopify-vs-woocommerce-hck</guid>
      <description>&lt;p&gt;Every ecommerce store is built on layers of technology: a platform, a payment processor, a CDN, analytics tools, marketing integrations, and often a JavaScript framework powering the storefront. Understanding what those layers are—and how they differ between competitors—is valuable for sales teams qualifying leads, agencies scoping migration projects, and researchers mapping market trends.&lt;/p&gt;

&lt;p&gt;This guide breaks down the typical tech stacks behind Shopify and WooCommerce stores, explains how to identify custom-built ecommerce platforms, and shows how to automate the analysis using the DetectZeStack API. If you have worked through our &lt;a href="https://detectzestack.com/blog/shopify-vs-woocommerce-detection" rel="noopener noreferrer"&gt;Shopify vs WooCommerce detection&lt;/a&gt; guide, this post goes deeper: beyond just identifying the platform, we analyze the full stack surrounding it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Ecommerce Tech Stack Analysis Matters
&lt;/h2&gt;

&lt;p&gt;Knowing that a store runs on Shopify tells you one thing. Knowing that it also uses Stripe for payments, Cloudflare for its CDN, Klaviyo for email, and Google Analytics 4 for tracking tells you far more. Here are the practical use cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sales prospecting&lt;/strong&gt; — A WooCommerce store without a dedicated hosting provider is a prospect for managed WordPress hosting. A Shopify store still using Google Analytics Universal (instead of GA4) may need an analytics migration partner. &lt;a href="https://detectzestack.com/blog/find-companies-using-stripe-technographic-prospecting" rel="noopener noreferrer"&gt;Technographic prospecting&lt;/a&gt; turns technology signals into qualified leads.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Competitive intelligence&lt;/strong&gt; — Map every competitor in a niche to see which payment processors dominate, which CDNs are most common, and whether the market is consolidating around Shopify or staying on WooCommerce. See our &lt;a href="https://detectzestack.com/blog/competitor-website-technology-analysis" rel="noopener noreferrer"&gt;competitor tech analysis guide&lt;/a&gt; for the full methodology.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Migration planning&lt;/strong&gt; — Agencies migrating stores from WooCommerce to Shopify (or vice versa) need to inventory every plugin, integration, and third-party script before quoting a project. Missing a critical integration means scope creep.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security auditing&lt;/strong&gt; — Outdated jQuery versions, exposed PHP headers, and missing security headers are all signals that a technology detection scan can surface. WooCommerce stores in particular inherit the security posture of their hosting environment.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What a Typical Shopify Tech Stack Looks Like
&lt;/h2&gt;

&lt;p&gt;Shopify is a hosted platform, which means the core infrastructure is managed by Shopify itself. But the technology stack of a Shopify store extends well beyond the platform. Here is what a scan of a typical Shopify store reveals:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Platform:&lt;/strong&gt; Shopify (detected via DNS CNAME to &lt;code&gt;shops.myshopify.com&lt;/code&gt; and &lt;code&gt;cdn.shopify.com&lt;/code&gt; script references)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CDN:&lt;/strong&gt; Shopify CDN for assets, often with Cloudflare or Fastly in front for the storefront domain&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Payment:&lt;/strong&gt; Stripe (Shopify Payments is built on Stripe), detected via &lt;code&gt;js.stripe.com&lt;/code&gt; script inclusion&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Analytics:&lt;/strong&gt; Google Analytics, often alongside Shopify’s built-in analytics&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JavaScript:&lt;/strong&gt; jQuery (still common in Shopify themes), React (for Hydrogen/headless storefronts)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Marketing:&lt;/strong&gt; Meta Pixel, Google Tag Manager, Klaviyo&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Payment, CDN, and Analytics on Shopify
&lt;/h3&gt;

&lt;p&gt;Shopify Payments—used by the majority of Shopify stores—is powered by Stripe under the hood. When you scan a Shopify store, you will often see both “Shopify” and “Stripe” in the results. The Stripe detection comes from the &lt;code&gt;js.stripe.com/v3&lt;/code&gt; script tag that Shopify injects into checkout pages.&lt;/p&gt;

&lt;p&gt;For CDN, Shopify serves static assets (images, CSS, JavaScript) from &lt;code&gt;cdn.shopify.com&lt;/code&gt;, which is its own CDN infrastructure. However, many Shopify merchants also use Cloudflare as a reverse proxy in front of their custom domain. In DNS terms, you will see the custom domain CNAME pointing to &lt;code&gt;shops.myshopify.com&lt;/code&gt;, but the nameservers may be Cloudflare’s &lt;code&gt;*.ns.cloudflare.com&lt;/code&gt;. DetectZeStack catches both signals: the Shopify CNAME via DNS detection and the Cloudflare nameservers via NS record inspection.&lt;/p&gt;

&lt;p&gt;Google Analytics is present on the vast majority of Shopify stores. Detection is straightforward: the &lt;code&gt;gtag.js&lt;/code&gt; script or the &lt;code&gt;G-&lt;/code&gt; measurement ID in the page source. Many stores also load Google Tag Manager, which acts as a container for additional tracking scripts.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a Typical WooCommerce Tech Stack Looks Like
&lt;/h2&gt;

&lt;p&gt;WooCommerce is a WordPress plugin, so every WooCommerce store is also a WordPress site. This means the tech stack is more varied than Shopify’s because the store owner (or their hosting provider) makes every infrastructure decision.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Platform:&lt;/strong&gt; WordPress + WooCommerce (detected via &lt;code&gt;/wp-content/&lt;/code&gt; paths, &lt;code&gt;X-Powered-By: PHP&lt;/code&gt; header, and WooCommerce-specific meta tags)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hosting:&lt;/strong&gt; Varies widely—from shared hosting to managed WordPress hosts to cloud infrastructure on AWS or DigitalOcean&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CDN:&lt;/strong&gt; Cloudflare (most common), CloudFront, or a WordPress-specific CDN&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Payment:&lt;/strong&gt; Stripe, PayPal, or both—installed as WooCommerce payment gateway plugins&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Analytics:&lt;/strong&gt; Google Analytics (via plugin), sometimes with additional tools like Hotjar or Microsoft Clarity&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JavaScript:&lt;/strong&gt; jQuery (WordPress ships it by default), sometimes React (for Gutenberg blocks)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security:&lt;/strong&gt; Wordfence or Sucuri (common WordPress security plugins), Let’s Encrypt TLS certificates&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Hosting, Plugins, and Performance Layers
&lt;/h3&gt;

&lt;p&gt;The biggest difference between Shopify and WooCommerce stacks is infrastructure ownership. Shopify handles hosting, scaling, and CDN automatically. WooCommerce store owners must choose and configure each layer themselves.&lt;/p&gt;

&lt;p&gt;This means WooCommerce stores show far more variety in their tech stacks. A scan might reveal Cloudflare CDN on one store, CloudFront on another, and no CDN at all on a third. You can &lt;a href="https://detectzestack.com/blog/detect-cdn-hosting-provider" rel="noopener noreferrer"&gt;detect the CDN and hosting provider&lt;/a&gt; using DNS CNAME records and HTTP headers, which DetectZeStack checks automatically.&lt;/p&gt;

&lt;p&gt;For payment detection, WooCommerce stores typically load Stripe.js or PayPal’s SDK directly on the checkout page. These are detected through HTML script tag analysis. Because WooCommerce is open-source, stores sometimes use less common payment gateways that are harder to detect—but the major processors (Stripe, PayPal, Square) all have well-known JavaScript fingerprints.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Detection tip: If you want to confirm WooCommerce specifically (not just WordPress), check for WordPress detection signals first, then look for WooCommerce-specific indicators: the woocommerce body class, /wp-json/wc/ REST API routes, or wc- prefixed cookies.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Custom-Built Ecommerce Stacks and How to Identify Them
&lt;/h2&gt;

&lt;p&gt;Not every online store runs on Shopify or WooCommerce. Large retailers, marketplaces, and niche platforms often build custom ecommerce systems or use platforms like Magento, BigCommerce, or Salesforce Commerce Cloud.&lt;/p&gt;

&lt;p&gt;Custom-built stores are identifiable by what is &lt;em&gt;absent&lt;/em&gt; from a scan: no Shopify DNS signatures, no WordPress/WooCommerce fingerprints, no known platform patterns. What you will find instead are the surrounding technologies: the CDN, the JavaScript framework powering the frontend (often React or Next.js—see our &lt;a href="https://detectzestack.com/blog/how-to-detect-nextjs-website" rel="noopener noreferrer"&gt;Next.js detection guide&lt;/a&gt;), the payment processor, and the analytics tools.&lt;/p&gt;

&lt;p&gt;BigCommerce stores are detectable via DNS: they CNAME to &lt;code&gt;*.mybigcommerce.com&lt;/code&gt;. Magento stores leave HTTP header fingerprints and distinctive HTML patterns. For platforms without strong fingerprints, the surrounding technologies often tell the story. A site running Next.js on Vercel with Stripe checkout and Algolia search is almost certainly a headless commerce implementation, even if the specific backend platform is opaque.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;th&gt;Primary Detection Signal&lt;/th&gt;
&lt;th&gt;Common Companion Technologies&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Shopify&lt;/td&gt;
&lt;td&gt;CNAME: shops.myshopify.com&lt;/td&gt;
&lt;td&gt;Stripe, Cloudflare, Google Analytics, jQuery&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WooCommerce&lt;/td&gt;
&lt;td&gt;/wp-content/, X-Powered-By: PHP&lt;/td&gt;
&lt;td&gt;WordPress, Stripe, PayPal, Cloudflare, jQuery&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;BigCommerce&lt;/td&gt;
&lt;td&gt;CNAME: *.mybigcommerce.com&lt;/td&gt;
&lt;td&gt;Cloudflare, Google Analytics, Stripe&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Magento&lt;/td&gt;
&lt;td&gt;Mage cookies, /static/frontend/ paths&lt;/td&gt;
&lt;td&gt;PHP, MySQL, Varnish, Fastly, PayPal&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Custom / Headless&lt;/td&gt;
&lt;td&gt;No known platform fingerprint&lt;/td&gt;
&lt;td&gt;React, Next.js, Vercel, Stripe, Algolia&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  How to Analyze Any Ecommerce Tech Stack with the DetectZeStack API
&lt;/h2&gt;

&lt;p&gt;Manual inspection with &lt;code&gt;dig&lt;/code&gt;, &lt;code&gt;curl&lt;/code&gt;, and browser dev tools works for one-off checks, but it does not scale. The DetectZeStack API combines DNS resolution, HTTP header analysis, HTML fingerprinting, and TLS certificate inspection into a single request.&lt;/p&gt;

&lt;h3&gt;
  
  
  Single-Store Analysis with GET /analyze
&lt;/h3&gt;

&lt;p&gt;To analyze one store, use the free demo endpoint (no API key required, rate-limited to 20 requests per hour):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://detectzestack.com/demo?url=allbirds.com"&lt;/span&gt; | jq &lt;span class="s1"&gt;'.technologies[] | {name, categories, confidence}'&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="s2"&gt;"name"&lt;/span&gt;: &lt;span class="s2"&gt;"Shopify"&lt;/span&gt;,
&lt;span class="s2"&gt;"categories"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Ecommerce"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;,
&lt;span class="s2"&gt;"confidence"&lt;/span&gt;: 100
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="s2"&gt;"name"&lt;/span&gt;: &lt;span class="s2"&gt;"Cloudflare"&lt;/span&gt;,
&lt;span class="s2"&gt;"categories"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"CDN"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;,
&lt;span class="s2"&gt;"confidence"&lt;/span&gt;: 80
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="s2"&gt;"name"&lt;/span&gt;: &lt;span class="s2"&gt;"Google Analytics"&lt;/span&gt;,
&lt;span class="s2"&gt;"categories"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Analytics"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;,
&lt;span class="s2"&gt;"confidence"&lt;/span&gt;: 100
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="s2"&gt;"name"&lt;/span&gt;: &lt;span class="s2"&gt;"Stripe"&lt;/span&gt;,
&lt;span class="s2"&gt;"categories"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Payment processors"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;,
&lt;span class="s2"&gt;"confidence"&lt;/span&gt;: 100
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For production use with higher rate limits, use the authenticated &lt;code&gt;GET /analyze&lt;/code&gt; endpoint via RapidAPI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://detectzestack.p.rapidapi.com/analyze?url=allbirds.com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-RapidAPI-Key: YOUR_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-RapidAPI-Host: detectzestack.p.rapidapi.com"&lt;/span&gt; | jq &lt;span class="s1"&gt;'.technologies'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response includes every detected technology with its name, categories, and confidence score. Confidence reflects the detection method: 100% for direct HTTP/HTML matches, 80% for DNS CNAME matches, 70% for TLS certificate matches.&lt;/p&gt;

&lt;h3&gt;
  
  
  Comparing Two Stores Side by Side with POST /compare
&lt;/h3&gt;

&lt;p&gt;To compare a Shopify store against a WooCommerce store, use the &lt;code&gt;POST /compare&lt;/code&gt; endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"https://detectzestack.p.rapidapi.com/compare"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-RapidAPI-Key: YOUR_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-RapidAPI-Host: detectzestack.p.rapidapi.com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"urls": ["allbirds.com", "underarmour.com"]}'&lt;/span&gt; | jq &lt;span class="s1"&gt;'.'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The comparison response shows which technologies are shared between the two stores and which are unique to each. This is useful for competitive analysis: if a competitor uses a tool you do not, it may be worth investigating. If two stores in the same market use completely different stacks, that tells you there is no consensus on the “right” approach—an insight that matters for agencies advising clients.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Technologies to Watch in Ecommerce Stacks
&lt;/h2&gt;

&lt;p&gt;When analyzing ecommerce tech stacks, certain technologies carry more strategic weight than others. Here is what to pay attention to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Payment processor&lt;/strong&gt; — Stripe vs PayPal vs native platform payments. Stripe dominance in a market segment signals developer-oriented stores. PayPal presence often indicates a more traditional retail audience.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CDN choice&lt;/strong&gt; — Cloudflare is the most common CDN across both Shopify and WooCommerce stores. CloudFront indicates AWS infrastructure. No CDN at all on a WooCommerce store is a red flag for performance. See our &lt;a href="https://detectzestack.com/blog/detect-cdn-hosting-provider" rel="noopener noreferrer"&gt;CDN detection guide&lt;/a&gt; for the technical details.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Analytics tools&lt;/strong&gt; — Google Analytics is nearly universal, but the presence of additional tools like Hotjar (session recording), Mixpanel (product analytics), or Segment (data pipeline) indicates a more sophisticated operation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JavaScript framework&lt;/strong&gt; — jQuery is still the default on most Shopify themes and WordPress sites. React or Vue.js in a store’s stack often means a headless architecture or a custom-built storefront. You can &lt;a href="https://detectzestack.com/blog/detect-javascript-framework-website" rel="noopener noreferrer"&gt;detect JavaScript frameworks&lt;/a&gt; through HTML fingerprints and JavaScript global variables.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security posture&lt;/strong&gt; — The TLS certificate issuer, the presence of security headers, and the server software version all provide signals. Shopify handles this automatically. WooCommerce stores vary widely, making security posture a useful differentiator.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Scaling Ecommerce Tech Stack Analysis to Hundreds of Sites
&lt;/h2&gt;

&lt;p&gt;Analyzing one or two competitors is useful. Analyzing every store in a market segment is transformative. The &lt;code&gt;POST /analyze/batch&lt;/code&gt; endpoint accepts up to 10 URLs per request, letting you scan at scale:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"https://detectzestack.p.rapidapi.com/analyze/batch"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-RapidAPI-Key: YOUR_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-RapidAPI-Host: detectzestack.p.rapidapi.com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"urls": ["store1.com", "store2.com", "store3.com"]}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a detailed walkthrough of scanning hundreds or thousands of domains—including a Python script with rate limiting and CSV output—see &lt;a href="https://detectzestack.com/blog/batch-scan-1000-websites" rel="noopener noreferrer"&gt;How to Batch Scan 1,000 Websites for Tech Stack Data&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;At scale, patterns emerge that are invisible at the single-store level. You might discover that 70% of stores in a niche use Shopify, that Stripe is the payment processor for 85% of them, or that stores using Cloudflare CDN have measurably faster response times. This kind of data powers market research reports, competitive strategy, and sales targeting.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tip: Combine batch scanning with the GET /check endpoint to filter results. For example, after scanning 500 ecommerce domains, use /check?url=store.com&amp;amp;tech=Stripe to quickly verify which stores use Stripe without re-scanning the full tech stack.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Ecommerce tech stack analysis goes beyond knowing whether a store uses Shopify or WooCommerce. The full picture—payment processors, CDNs, analytics tools, JavaScript frameworks, and security posture—reveals actionable intelligence for sales, competitive research, and migration planning.&lt;/p&gt;

&lt;p&gt;Shopify stores share a common infrastructure foundation but vary in their third-party integrations. WooCommerce stores vary at every layer, from hosting to CDN to payment gateway. Custom-built stores are identifiable by their surrounding technologies even when the platform itself leaves no fingerprint.&lt;/p&gt;

&lt;p&gt;The DetectZeStack API lets you automate this analysis across one store or thousands, returning structured data that you can filter, compare, and integrate into your workflows.&lt;/p&gt;

&lt;h3&gt;
  
  
  Related Reading
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/shopify-vs-woocommerce-detection" rel="noopener noreferrer"&gt;Shopify vs WooCommerce: How to Tell Which Platform a Site Uses&lt;/a&gt; — DNS fingerprints, HTML patterns, and cookie signatures for platform identification&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/find-companies-using-stripe-technographic-prospecting" rel="noopener noreferrer"&gt;Find Companies Using Stripe: Technographic Prospecting&lt;/a&gt; — Turn payment processor detection into qualified sales leads&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/batch-scan-1000-websites" rel="noopener noreferrer"&gt;How to Batch Scan 1,000 Websites for Tech Stack Data&lt;/a&gt; — Python script, curl examples, and optimization tips for scanning at scale&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/competitor-website-technology-analysis" rel="noopener noreferrer"&gt;Website Tech Lookup for Competitor Analysis&lt;/a&gt; — Full methodology for competitive technology intelligence&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/detect-cdn-hosting-provider" rel="noopener noreferrer"&gt;How to Detect CDN and Hosting Providers&lt;/a&gt; — DNS, headers, TLS, and IP range methods for infrastructure detection&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/detect-javascript-framework-website" rel="noopener noreferrer"&gt;Detect What JavaScript Framework a Website Uses&lt;/a&gt; — Identify React, Vue, Next.js, and other frontend technologies&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/check-if-website-uses-wordpress" rel="noopener noreferrer"&gt;Check If a Website Uses WordPress&lt;/a&gt; — Essential for WooCommerce detection since WooCommerce runs on WordPress&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/how-to-detect-shopify" rel="noopener noreferrer"&gt;How to Detect if a Website Uses Shopify&lt;/a&gt; — Five detection methods for Shopify stores specifically&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>techstack</category>
      <category>webdev</category>
      <category>api</category>
    </item>
    <item>
      <title>How to Detect if a Website Uses React: 4 Proven Methods</title>
      <dc:creator>MikeL</dc:creator>
      <pubDate>Wed, 15 Apr 2026 22:11:22 +0000</pubDate>
      <link>https://dev.to/detectzestack/how-to-detect-if-a-website-uses-react-4-proven-methods-3f73</link>
      <guid>https://dev.to/detectzestack/how-to-detect-if-a-website-uses-react-4-proven-methods-3f73</guid>
      <description>&lt;p&gt;React powers a massive share of the modern web. From single-page apps to server-rendered sites built with Next.js, React’s footprint is everywhere—but not always obvious. A well-built React site can look indistinguishable from any other website in the browser. There’s no “Built with React” badge in the footer.&lt;/p&gt;

&lt;p&gt;Whether you’re evaluating a competitor’s technology choices, auditing a site for known React vulnerabilities, qualifying leads based on their tech stack, or simply curious about how a product is built, you need reliable detection methods. This guide covers four approaches, from quick manual checks to fully automated API-based detection.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Detect React on a Website
&lt;/h2&gt;

&lt;p&gt;Knowing whether a site runs React is more than trivia. Here are the practical reasons people look for this information:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Competitive intelligence:&lt;/strong&gt; Understanding what frameworks your competitors chose—and whether they use plain React, Next.js, or Gatsby—reveals their engineering priorities. A Next.js site signals investment in SEO and performance. A client-side React SPA suggests a different set of trade-offs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security auditing:&lt;/strong&gt; React versions have known CVEs. Detecting an outdated React version on a target site is a concrete security finding. The same applies to Next.js, which has had its own set of vulnerabilities.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sales prospecting:&lt;/strong&gt; If you sell developer tools, monitoring services, or React-specific products, knowing which companies use React determines whether your outreach is relevant. This is the same logic behind &lt;a href="https://detectzestack.com/blog/find-companies-using-stripe-technographic-prospecting" rel="noopener noreferrer"&gt;finding companies that use Stripe&lt;/a&gt; for payment-related prospecting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Migration planning:&lt;/strong&gt; Before migrating from Angular to React, or upgrading from React 17 to React 18, you need to know exactly what’s running in production—not what the internal documentation says.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hiring context:&lt;/strong&gt; Researching a company’s tech stack before an interview helps you understand what you’ll be working with and what questions to expect.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Method 1 — Browser DevTools Console
&lt;/h2&gt;

&lt;p&gt;The fastest way to check if a website uses React is through the browser’s DevTools console. React leaves several fingerprints in the DOM and in JavaScript globals that you can query directly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Check for React Global Objects
&lt;/h3&gt;

&lt;p&gt;Open Chrome DevTools (press &lt;code&gt;F12&lt;/code&gt; or &lt;code&gt;Cmd+Option+I&lt;/code&gt; on macOS), switch to the Console tab, and run these checks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Check for the React DevTools hook (present on most React sites)&lt;/span&gt;
&lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;__REACT_DEVTOOLS_GLOBAL_HOOK__&lt;/span&gt;

&lt;span class="c1"&gt;// Check for React Fiber on the root element&lt;/span&gt;
&lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)?.&lt;/span&gt;&lt;span class="nx"&gt;_reactRootContainer&lt;/span&gt;

&lt;span class="c1"&gt;// Check for the data-reactroot attribute (React 15-16 pattern)&lt;/span&gt;
&lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[data-reactroot]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// Check for Next.js (built on React)&lt;/span&gt;
&lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;__next&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If any of these return &lt;code&gt;true&lt;/code&gt;, the site is running React. The &lt;code&gt;__REACT_DEVTOOLS_GLOBAL_HOOK__&lt;/code&gt; check is the most reliable for modern React apps because React itself injects this hook during initialization, regardless of whether React DevTools is installed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Inspect the DOM for React Fiber Attributes
&lt;/h3&gt;

&lt;p&gt;React’s reconciler (Fiber) attaches internal properties to DOM nodes. In the Elements panel, select any element inside the React app and look at its properties in the Console:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;// Select an element, &lt;span class="k"&gt;then &lt;/span&gt;run:
&lt;span class="nv"&gt;$0&lt;/span&gt;.__reactFiber&lt;span class="nv"&gt;$ &lt;/span&gt;  // React 18+
&lt;span class="nv"&gt;$0&lt;/span&gt;.__reactInternalInstance&lt;span class="nv"&gt;$ &lt;/span&gt;  // React 16-17
&lt;span class="nv"&gt;$0&lt;/span&gt;._reactInternalFiber   // Older React versions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These properties are prefixed with a random hash (e.g., &lt;code&gt;__reactFiber$abc123&lt;/code&gt;), so you may need to type the prefix and let autocomplete show the full property name. If any of these properties exist on DOM nodes, React is managing that part of the page.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Partial React usage: Some sites use React for only part of the page—a checkout widget, a search bar, or a dashboard embedded in a server-rendered page. In these cases, the React root may not be the top-level #root div. Check multiple elements if the top-level checks return false.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Method 2 — View Page Source Clues
&lt;/h2&gt;

&lt;p&gt;Viewing the HTML source (&lt;code&gt;Ctrl+U&lt;/code&gt; or &lt;code&gt;Cmd+Option+U&lt;/code&gt;) reveals patterns that indicate React, even before JavaScript executes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Script Tags and Bundle Filenames
&lt;/h3&gt;

&lt;p&gt;React apps typically load bundled JavaScript files. Look for these patterns in the source:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;react.production.min.js&lt;/code&gt; or &lt;code&gt;react-dom.production.min.js&lt;/code&gt; — Direct React library references, common on CDN-loaded setups.&lt;/li&gt;
&lt;li&gt;Webpack chunk filenames like &lt;code&gt;main.abc123.js&lt;/code&gt; or &lt;code&gt;static/js/bundle.js&lt;/code&gt; — While not React-specific, these are the default output of Create React App.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/__next/&lt;/code&gt; prefixed asset paths — A definitive Next.js marker. All static assets in Next.js are served from &lt;code&gt;/_next/static/&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For client-side rendered React apps, the HTML source is often minimal—just a &lt;code&gt;&amp;lt;div id="root"&amp;gt;&amp;lt;/div&amp;gt;&lt;/code&gt; and script tags. This “empty shell” pattern is itself a strong signal of a client-side React SPA, though other frameworks like Vue and Angular can produce similar output.&lt;/p&gt;

&lt;h3&gt;
  
  
  Server-Side Rendered React and Next.js Markers
&lt;/h3&gt;

&lt;p&gt;Server-rendered React sites (using Next.js, Remix, or custom SSR) include the full HTML content in the source. The distinguishing markers are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;div id="__next"&amp;gt;&lt;/code&gt; — The root element for Next.js applications.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;script id="__NEXT_DATA__" type="application/json"&amp;gt;&lt;/code&gt; — Contains the serialized page props, build ID, and routing data. This is the single most reliable indicator of Next.js.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;data-reactroot&lt;/code&gt; attribute on the root element — Added by &lt;code&gt;ReactDOMServer.renderToString()&lt;/code&gt; in React 15-16.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;data-nhead&lt;/code&gt; or &lt;code&gt;data-react-helmet&lt;/code&gt; attributes — Present when using helmet-style head management in React SSR.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- Next.js fingerprint in page source --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"__next"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!-- Full server-rendered HTML here --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"__NEXT_DATA__"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"application/json"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;props&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pageProps&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:{}},&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;page&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;buildId&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;abc123&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Method 3 — Browser Extensions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  React Developer Tools Extension
&lt;/h3&gt;

&lt;p&gt;The official React Developer Tools extension (available for Chrome and Firefox) is the most definitive manual check. When you visit a React-powered site, the extension icon lights up—blue for production builds, red for development builds. It also adds “Components” and “Profiler” tabs to DevTools, letting you inspect the React component tree directly.&lt;/p&gt;

&lt;p&gt;The extension works by detecting the &lt;code&gt;__REACT_DEVTOOLS_GLOBAL_HOOK__&lt;/code&gt; that React attaches during initialization. If React is present anywhere on the page—even in a small embedded widget—the extension will detect it.&lt;/p&gt;

&lt;p&gt;The limitation: you have to visit each site individually. This is fine for one-off checks but impractical if you need to scan hundreds of sites.&lt;/p&gt;

&lt;h3&gt;
  
  
  DetectZeStack Chrome Extension
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://chromewebstore.google.com/detail/detectzestack/mgecmlacndohfjfooobaebjkhekpjdod" rel="noopener noreferrer"&gt;DetectZeStack Chrome extension&lt;/a&gt; detects not just React but the entire technology stack—frameworks, CDNs, analytics tools, hosting providers, and more—all from a single toolbar click. Unlike React DevTools, which only identifies React, DetectZeStack shows the full picture: whether the site also uses Next.js, what &lt;a href="https://detectzestack.com/blog/detect-cdn-hosting-provider" rel="noopener noreferrer"&gt;CDN or hosting provider&lt;/a&gt; serves it, what analytics and marketing tools are loaded, and more.&lt;/p&gt;

&lt;h2&gt;
  
  
  Method 4 — DetectZeStack API (Programmatic Detection)
&lt;/h2&gt;

&lt;p&gt;Manual methods work for spot checks. When you need to detect React across tens, hundreds, or thousands of sites—for lead qualification, competitive analysis, or security scanning—you need an API.&lt;/p&gt;

&lt;h3&gt;
  
  
  Single-URL Analysis with curl
&lt;/h3&gt;

&lt;p&gt;The DetectZeStack API detects React and 7,300+ other technologies in a single request. Here is a quick check using the free demo endpoint (no API key required):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://detectzestack.com/demo?url=netflix.com"&lt;/span&gt; | jq &lt;span class="s1"&gt;'.technologies[] | select(.name == "React" or .name == "Next.js")'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For production use with higher limits, use the RapidAPI endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://detectzestack.p.rapidapi.com/analyze?url=netflix.com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-RapidAPI-Key: YOUR_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-RapidAPI-Host: detectzestack.p.rapidapi.com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
| jq &lt;span class="s1"&gt;'.technologies[] | select(.categories[] | contains("JavaScript frameworks"))'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Reading the API Response
&lt;/h3&gt;

&lt;p&gt;The API returns a JSON object with all detected technologies. Here is what a React detection looks like in the response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://netflix.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"domain"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"netflix.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"scan_depth"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"full"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"technologies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"React"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"categories"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"JavaScript frameworks"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"18.2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"website"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://reactjs.org"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"cpe"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cpe:2.3:a:facebook:react:18.2:*:*:*:*:*:*:*"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Next.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"categories"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"JavaScript frameworks"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"website"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://nextjs.org"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Key fields to look at:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;name&lt;/code&gt; — The technology name. React and Next.js are reported separately, so you can distinguish between the two.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;confidence&lt;/code&gt; — How certain the detection is (0-100). A confidence of 100 means the fingerprint matched unambiguously.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;version&lt;/code&gt; — When detectable, the specific React version. Useful for security auditing—you can cross-reference this against known CVEs.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cpe&lt;/code&gt; — The &lt;a href="https://detectzestack.com/blog/cpe-identifiers-explained-for-security-teams" rel="noopener noreferrer"&gt;CPE identifier&lt;/a&gt; for the technology, letting you look up vulnerabilities in the NVD directly.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;categories&lt;/code&gt; — React appears under “JavaScript frameworks.” This lets you filter the response to only show front-end frameworks.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Batch Detection Across Multiple Sites
&lt;/h3&gt;

&lt;p&gt;To scan a list of domains for React usage, loop through them with curl or use a script. Here is a quick bash one-liner:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="k"&gt;for &lt;/span&gt;domain &lt;span class="k"&gt;in &lt;/span&gt;netflix.com airbnb.com stripe.com&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$domain&lt;/span&gt;&lt;span class="s2"&gt;: "&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://detectzestack.p.rapidapi.com/analyze?url=&lt;/span&gt;&lt;span class="nv"&gt;$domain&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-RapidAPI-Key: YOUR_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-RapidAPI-Host: detectzestack.p.rapidapi.com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
| jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'[.technologies[] | select(.name == "React" or .name == "Next.js") | .name] | if length == 0 then "not detected" else join(", ") end'&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For larger-scale scanning, see the &lt;a href="https://detectzestack.com/blog/website-technology-detection-python-tutorial" rel="noopener noreferrer"&gt;Python tutorial&lt;/a&gt; which covers batch scanning with rate limiting and CSV export.&lt;/p&gt;

&lt;h2&gt;
  
  
  React vs Next.js — What the Detection Tells You
&lt;/h2&gt;

&lt;p&gt;Every Next.js site uses React, but not every React site uses Next.js. Understanding the distinction matters for competitive analysis and technical assessment:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Signal&lt;/th&gt;
&lt;th&gt;Plain React (CRA/Vite)&lt;/th&gt;
&lt;th&gt;Next.js&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Root element&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Page data&lt;/td&gt;
&lt;td&gt;None in source&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;NEXT_DATA&lt;/strong&gt; script tag&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Asset paths&lt;/td&gt;
&lt;td&gt;/static/js/main.*.js&lt;/td&gt;
&lt;td&gt;/_next/static/chunks/*.js&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTTP headers&lt;/td&gt;
&lt;td&gt;None specific&lt;/td&gt;
&lt;td&gt;X-Nextjs-Cache (on ISR pages)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SSR&lt;/td&gt;
&lt;td&gt;Possible but manual&lt;/td&gt;
&lt;td&gt;Built-in (SSR/SSG/ISR)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rendering pattern&lt;/td&gt;
&lt;td&gt;Client-side (empty shell)&lt;/td&gt;
&lt;td&gt;Server-rendered HTML&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;When the DetectZeStack API reports both “React” and “Next.js,” it means the site uses Next.js as the framework layer on top of React. If only “React” is reported, the site uses React directly—possibly with Create React App, Vite, Gatsby, Remix, or a custom setup.&lt;/p&gt;

&lt;p&gt;Other React-based frameworks you may see detected alongside React include Gatsby (which uses React for its component model and adds a static site generation layer) and Remix (which, like Next.js, adds server-side rendering to React). For a broader overview of detecting all JavaScript frameworks, see &lt;a href="https://detectzestack.com/blog/detect-javascript-framework-website" rel="noopener noreferrer"&gt;How to Detect What JavaScript Framework a Website Uses&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why this matters for sales: A company running Next.js has likely invested in performance and SEO—they may be interested in monitoring and analytics tools. A company running a client-side React SPA may be more interested in performance optimization and bundle analysis tools. The framework choice signals the team’s priorities. For more on using tech detection for outreach, see Tech Stack Enrichment for Sales Teams.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Get Started with Programmatic React Detection
&lt;/h2&gt;

&lt;p&gt;Manual checks are fine for occasional curiosity. For anything systematic—lead qualification, competitive research, security scanning, or portfolio analysis—an API is the only practical approach.&lt;/p&gt;

&lt;p&gt;The DetectZeStack API gives you React detection plus 7,300+ other technology fingerprints in a single call. Every request also includes DNS-based infrastructure detection, TLS certificate analysis, and CPE identifiers for vulnerability lookups—layers that no browser-based method can match.&lt;/p&gt;

&lt;p&gt;The free tier includes 100 requests per month with no credit card required. That is enough to scan your competitor list, audit a client portfolio, or build a proof-of-concept integration.&lt;/p&gt;

&lt;h3&gt;
  
  
  Related Reading
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/detect-javascript-framework-website" rel="noopener noreferrer"&gt;Detect What JavaScript Framework a Website Uses&lt;/a&gt; — React, Vue, Angular, Next.js, and Svelte detection compared&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/detect-any-website-tech-stack-with-single-api-call" rel="noopener noreferrer"&gt;Detect Any Website's Tech Stack with a Single API Call&lt;/a&gt; — Overview of all four detection layers&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/website-technology-checker-api" rel="noopener noreferrer"&gt;Website Technology Checker API&lt;/a&gt; — Full endpoint reference and integration guide&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/cpe-identifiers-explained-for-security-teams" rel="noopener noreferrer"&gt;CPE Identifiers Explained for Security Teams&lt;/a&gt; — Cross-reference detected React versions with known CVEs&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/find-companies-using-stripe-technographic-prospecting" rel="noopener noreferrer"&gt;Find Companies Using Stripe&lt;/a&gt; — Technographic prospecting with the same API&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/website-technology-detection-python-tutorial" rel="noopener noreferrer"&gt;Website Technology Detection: Python Tutorial&lt;/a&gt; — Batch scanning with Python and CSV export&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/check-if-website-uses-wordpress" rel="noopener noreferrer"&gt;Check If a Website Uses WordPress&lt;/a&gt; — CMS detection guide&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/detect-cdn-hosting-provider" rel="noopener noreferrer"&gt;How to Detect CDN and Hosting Provider&lt;/a&gt; — Infrastructure-layer detection&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/how-to-detect-nextjs-website" rel="noopener noreferrer"&gt;How to Detect if a Website Uses Next.js&lt;/a&gt; — Next.js-specific detection with Pages Router vs App Router fingerprints&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/how-to-detect-vue-website" rel="noopener noreferrer"&gt;How to Detect if a Website Uses Vue.js&lt;/a&gt; — Vue and Nuxt detection from console checks to API automation&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/how-to-detect-tailwind-css" rel="noopener noreferrer"&gt;How to Detect Tailwind CSS on Any Website&lt;/a&gt; — 5 methods to identify Tailwind from DOM inspection to API automation&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>techstack</category>
      <category>webdev</category>
      <category>api</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to Detect if a Website Uses Intercom: 5 Methods</title>
      <dc:creator>MikeL</dc:creator>
      <pubDate>Wed, 15 Apr 2026 20:42:00 +0000</pubDate>
      <link>https://dev.to/detectzestack/how-to-detect-if-a-website-uses-intercom-5-methods-3o4k</link>
      <guid>https://dev.to/detectzestack/how-to-detect-if-a-website-uses-intercom-5-methods-3o4k</guid>
      <description>&lt;p&gt;Intercom is one of the most popular customer messaging platforms on the web. Companies use it for live chat, in-app messaging, help centers, and product tours—making it a key indicator of how a business handles customer communication. From the outside, the familiar chat bubble in the bottom-right corner is a strong hint, but it is not always visible: some sites customize or delay-load the widget, and others use Intercom only for backend messaging without a visible launcher.&lt;/p&gt;

&lt;p&gt;Whether you are qualifying sales leads, analyzing a competitor’s support stack, auditing third-party scripts for security, or planning a migration off Intercom, reliably detecting it matters. This guide covers five methods: from quick manual checks to a fully programmatic API approach that works at scale.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Detect Intercom on a Website
&lt;/h2&gt;

&lt;p&gt;Intercom is more than a chat widget. Detecting it on a website tells you several things about the business behind it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Budget signal.&lt;/strong&gt; Intercom pricing starts around $39/month for very small teams and scales to $139/month or more for growth-stage companies. Businesses running Intercom have allocated budget for customer communication tooling—they are not using a free contact form.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Customer engagement maturity.&lt;/strong&gt; Intercom implies a proactive approach to customer support and engagement. Sites running Intercom typically have a support team, defined response SLAs, and automated workflows. This is useful context for sales prospecting: these are companies that invest in customer experience.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Third-party script inventory.&lt;/strong&gt; For security teams, knowing that Intercom’s JavaScript is loaded on a site matters. The Intercom messenger injects iframes, loads external scripts from &lt;code&gt;intercomcdn.com&lt;/code&gt;, and sets persistent cookies. Any third-party script with that level of page access is worth tracking in a vendor audit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Migration planning.&lt;/strong&gt; If you are evaluating a move from Intercom to Zendesk, Drift, Crisp, or another platform, the first step is understanding exactly which Intercom features are in use: just the messenger widget, or also articles, product tours, and automated messages. The detection methods below help you inventory the integration depth.&lt;/p&gt;

&lt;h2&gt;
  
  
  Method 1 — Check the Page Source for Intercom Scripts
&lt;/h2&gt;

&lt;p&gt;The simplest way to detect Intercom is to view the page source and search for its script signatures. In any browser, press &lt;code&gt;Ctrl+U&lt;/code&gt; (or &lt;code&gt;Cmd+Option+U&lt;/code&gt; on macOS) to view source, then search for these strings:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;widget.intercom.io&lt;/code&gt; — the Intercom messenger widget stylesheet&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;intercomcdn.com&lt;/code&gt; — Intercom’s CDN for JavaScript assets&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;api.intercom.io&lt;/code&gt; — the Intercom API endpoint for messenger initialization&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;intercom&lt;/code&gt; in inline script blocks — the &lt;code&gt;window.intercomSettings&lt;/code&gt; configuration object&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What to Look For in the HTML
&lt;/h3&gt;

&lt;p&gt;The standard Intercom installation embeds a JavaScript snippet that configures and boots the messenger. It typically looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;intercomSettings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="na"&gt;api_base&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://api-iam.intercom.io&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="na"&gt;app_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;abc123de&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;w&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;ic&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;w&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Intercom&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;ic&lt;/span&gt;&lt;span class="o"&gt;===&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;function&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
&lt;span class="nf"&gt;ic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;reattach_activator&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="nf"&gt;ic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;update&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;w&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;intercomSettings&lt;/span&gt;&lt;span class="p"&gt;);}&lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;c&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;);};&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;q&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;q&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);};&lt;/span&gt;&lt;span class="nx"&gt;w&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Intercom&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;l&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;script&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text/javascript&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://widget.intercom.io/widget/abc123de&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementsByTagName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;script&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parentNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;insertBefore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);};&lt;/span&gt;&lt;span class="nf"&gt;l&lt;/span&gt;&lt;span class="p"&gt;();}})();&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;app_id&lt;/code&gt; value (&lt;code&gt;abc123de&lt;/code&gt; in this example) identifies the Intercom workspace. Every Intercom account has a unique app ID, which appears in both the &lt;code&gt;intercomSettings&lt;/code&gt; object and the widget script URL.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Script Pattern&lt;/th&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;What It Means&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;widget.intercom.io/widget/{app_id}&lt;/td&gt;
&lt;td&gt;Messenger widget&lt;/td&gt;
&lt;td&gt;Live chat and in-app messaging active&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;static.intercomcdn.com&lt;/td&gt;
&lt;td&gt;CDN assets&lt;/td&gt;
&lt;td&gt;Intercom JavaScript bundle loaded&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;api.intercom.io&lt;/td&gt;
&lt;td&gt;API endpoint&lt;/td&gt;
&lt;td&gt;Messenger communicating with Intercom backend&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;window.intercomSettings&lt;/td&gt;
&lt;td&gt;Config object&lt;/td&gt;
&lt;td&gt;Intercom initialized with workspace settings&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Limitation: Viewing page source only shows scripts in the initial HTML. If Intercom is loaded after cookie consent or on specific pages only (e.g., the app dashboard but not the marketing site), it will not appear in the source of every page. Method 3 catches these cases by checking what the browser actually rendered.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Method 2 — Inspect Cookies and Local Storage
&lt;/h2&gt;

&lt;p&gt;Intercom sets distinctive cookies and local storage entries that persist even if the messenger widget is not visible on the current page. Open Chrome DevTools (&lt;code&gt;F12&lt;/code&gt;), go to &lt;strong&gt;Application &amp;gt; Cookies&lt;/strong&gt;, and look for these patterns:&lt;/p&gt;

&lt;h3&gt;
  
  
  Intercom Cookies
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Cookie Name Pattern&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;th&gt;Lifetime&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;intercom-session-{app_id}&lt;/td&gt;
&lt;td&gt;Session tracking for the messenger&lt;/td&gt;
&lt;td&gt;1 week&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;intercom-id-{app_id}&lt;/td&gt;
&lt;td&gt;Anonymous visitor identity&lt;/td&gt;
&lt;td&gt;9 months&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;intercom-device-id-{app_id}&lt;/td&gt;
&lt;td&gt;Device fingerprint for cross-session tracking&lt;/td&gt;
&lt;td&gt;9 months&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;{app_id}&lt;/code&gt; in the cookie name matches the workspace ID from the script installation. If you see any cookie starting with &lt;code&gt;intercom-&lt;/code&gt;, that site runs Intercom.&lt;/p&gt;

&lt;h3&gt;
  
  
  Local Storage Entries
&lt;/h3&gt;

&lt;p&gt;Intercom also writes to &lt;code&gt;localStorage&lt;/code&gt;. In DevTools, go to &lt;strong&gt;Application &amp;gt; Local Storage&lt;/strong&gt; and look for keys starting with &lt;code&gt;intercom.&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;intercom.intercom-state-{app_id}&lt;/code&gt; — messenger state (open/closed, unread count)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;intercom.intercom-id&lt;/code&gt; — visitor identity token&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Local storage entries persist across browser sessions and are a reliable indicator even when the Intercom widget has not fully loaded on the current page.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: Cookies and local storage are set by client-side JavaScript, not by the server. A simple curl request will not trigger them. For cookie-based detection, you need to visit the site in a browser or headless browser that executes JavaScript.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Method 3 — Look for the Intercom Messenger Widget in the DOM
&lt;/h2&gt;

&lt;p&gt;Once Intercom loads, it injects specific DOM elements into the page. These are reliable fingerprints because they use fixed IDs and attribute patterns that Intercom has maintained across versions.&lt;/p&gt;

&lt;p&gt;Open Chrome DevTools (&lt;code&gt;F12&lt;/code&gt;), go to the &lt;strong&gt;Console&lt;/strong&gt; tab, and run these checks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Check for the Intercom messenger iframe&lt;/span&gt;
&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;iframe#intercom-frame&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// Returns the iframe element if Intercom is loaded, null otherwise&lt;/span&gt;

&lt;span class="c1"&gt;// Check for the Intercom widget stylesheet&lt;/span&gt;
&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;link[href*="widget.intercom.io"]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// Returns the link element if present&lt;/span&gt;

&lt;span class="c1"&gt;// Check for the Intercom launcher (the chat bubble)&lt;/span&gt;
&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.intercom-launcher&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// Returns the launcher button element&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If any of these return an element (not &lt;code&gt;null&lt;/code&gt;), Intercom is active on the page.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;DOM Selector&lt;/th&gt;
&lt;th&gt;Element&lt;/th&gt;
&lt;th&gt;What It Confirms&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;iframe#intercom-frame&lt;/td&gt;
&lt;td&gt;Messenger iframe&lt;/td&gt;
&lt;td&gt;Intercom messenger widget is loaded and rendered&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;link[href*="widget.intercom.io"]&lt;/td&gt;
&lt;td&gt;Widget stylesheet&lt;/td&gt;
&lt;td&gt;Intercom CSS has been injected into the page&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;.intercom-launcher&lt;/td&gt;
&lt;td&gt;Chat bubble&lt;/td&gt;
&lt;td&gt;The visible launcher button is present&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;#intercom-container&lt;/td&gt;
&lt;td&gt;Widget container&lt;/td&gt;
&lt;td&gt;The messenger container div exists in the DOM&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;DOM inspection catches Intercom even when it is loaded dynamically after page load, behind a cookie consent banner, or via a tag manager like &lt;a href="https://detectzestack.com/blog/how-to-detect-google-analytics" rel="noopener noreferrer"&gt;Google Tag Manager&lt;/a&gt;. It is more reliable than source inspection for single-page applications where the initial HTML is minimal.&lt;/p&gt;

&lt;h2&gt;
  
  
  Method 4 — Check the JavaScript Global Object
&lt;/h2&gt;

&lt;p&gt;Intercom exposes a global &lt;code&gt;window.Intercom&lt;/code&gt; function that serves as its public API. This is one of the most reliable detection methods because Intercom requires this global to function—it cannot operate without it.&lt;/p&gt;

&lt;p&gt;In the browser console:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Check if the Intercom global exists&lt;/span&gt;
&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Intercom&lt;/span&gt;
&lt;span class="c1"&gt;// Returns "function" if Intercom is loaded, "undefined" otherwise&lt;/span&gt;

&lt;span class="c1"&gt;// Get the Intercom app ID from the booted instance&lt;/span&gt;
&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Intercom&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;booted&lt;/span&gt;
&lt;span class="c1"&gt;// Returns true if the messenger has been initialized&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;window.Intercom&lt;/code&gt; function is used by the site’s own code to control the messenger: showing/hiding it, passing user data, triggering messages. Because it is part of Intercom’s public API contract, it is stable across versions and not likely to change.&lt;/p&gt;

&lt;p&gt;You can also extract configuration details:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// If intercomSettings is available, read the app ID&lt;/span&gt;
&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;intercomSettings&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;intercomSettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;app_id&lt;/span&gt;
&lt;span class="c1"&gt;// Returns the workspace app ID (e.g., "abc123de")&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Tip: Methods 3 and 4 (DOM and JavaScript global) require visiting the page in a browser. For automated detection across many domains, Method 5 (the API approach) handles this by performing full HTTP analysis server-side, including JavaScript fingerprinting.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Method 5 — Use the DetectZeStack API for Programmatic Detection
&lt;/h2&gt;

&lt;p&gt;When you need to detect Intercom across hundreds or thousands of domains—for lead qualification, market research, or vendor auditing—manual methods do not scale. The DetectZeStack API detects Intercom via HTTP fingerprinting in a single request, alongside 7,300+ other technologies.&lt;/p&gt;

&lt;h3&gt;
  
  
  Single URL Analysis with curl
&lt;/h3&gt;

&lt;p&gt;Try it without signing up. The &lt;code&gt;/demo&lt;/code&gt; endpoint is rate-limited to 20 requests per hour per IP, but requires no authentication:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://detectzestack.com/demo?url=intercom.com"&lt;/span&gt; | jq &lt;span class="s1"&gt;'.'&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="s2"&gt;"url"&lt;/span&gt;: &lt;span class="s2"&gt;"https://intercom.com"&lt;/span&gt;,
&lt;span class="s2"&gt;"domain"&lt;/span&gt;: &lt;span class="s2"&gt;"intercom.com"&lt;/span&gt;,
&lt;span class="s2"&gt;"technologies"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="s2"&gt;"name"&lt;/span&gt;: &lt;span class="s2"&gt;"Intercom"&lt;/span&gt;,
&lt;span class="s2"&gt;"categories"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Live chat"&lt;/span&gt;, &lt;span class="s2"&gt;"Customer engagement"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;,
&lt;span class="s2"&gt;"confidence"&lt;/span&gt;: 100,
&lt;span class="s2"&gt;"source"&lt;/span&gt;: &lt;span class="s2"&gt;"http"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;,
&lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="s2"&gt;"name"&lt;/span&gt;: &lt;span class="s2"&gt;"React"&lt;/span&gt;,
&lt;span class="s2"&gt;"categories"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"JavaScript frameworks"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;,
&lt;span class="s2"&gt;"confidence"&lt;/span&gt;: 100,
&lt;span class="s2"&gt;"source"&lt;/span&gt;: &lt;span class="s2"&gt;"http"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;,
...
&lt;span class="o"&gt;]&lt;/span&gt;,
&lt;span class="s2"&gt;"categories"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="s2"&gt;"Live chat"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Intercom"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;,
&lt;span class="s2"&gt;"Customer engagement"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Intercom"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;,
&lt;span class="s2"&gt;"JavaScript frameworks"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"React"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;,
...
&lt;span class="o"&gt;}&lt;/span&gt;,
&lt;span class="s2"&gt;"meta"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="s2"&gt;"status_code"&lt;/span&gt;: 200,
&lt;span class="s2"&gt;"tech_count"&lt;/span&gt;: 18,
&lt;span class="s2"&gt;"scan_depth"&lt;/span&gt;: &lt;span class="s2"&gt;"full"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;,
&lt;span class="s2"&gt;"cached"&lt;/span&gt;: &lt;span class="nb"&gt;false&lt;/span&gt;,
&lt;span class="s2"&gt;"response_ms"&lt;/span&gt;: 920
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice the &lt;code&gt;source: "http"&lt;/code&gt; field on Intercom—the API detected it through HTTP fingerprinting, matching script patterns like &lt;code&gt;widget.intercom.io&lt;/code&gt; and DOM elements like &lt;code&gt;iframe#intercom-frame&lt;/code&gt;. This is the automated equivalent of Methods 1 through 4 combined.&lt;/p&gt;

&lt;h3&gt;
  
  
  Batch Detection Across Multiple Sites
&lt;/h3&gt;

&lt;p&gt;For production use, the &lt;code&gt;/analyze&lt;/code&gt; endpoint supports higher rate limits and is available through RapidAPI. To scan multiple domains, use the &lt;code&gt;/analyze/batch&lt;/code&gt; endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"https://detectzestack.p.rapidapi.com/analyze/batch"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-RapidAPI-Key: YOUR_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-RapidAPI-Host: detectzestack.p.rapidapi.com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"urls": ["intercom.com", "drift.com", "zendesk.com"]}'&lt;/span&gt; | jq &lt;span class="s1"&gt;'.'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The batch endpoint accepts up to 10 URLs per request and returns results for each domain. This is ideal for building a spreadsheet of which prospects use Intercom versus competing live chat platforms like Drift, Zendesk, Crisp, or LiveChat.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reading the API Response
&lt;/h3&gt;

&lt;p&gt;The response structure makes it straightforward to filter for Intercom and related customer engagement technologies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check if Intercom is present on a site&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://detectzestack.com/demo?url=example.com"&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
jq &lt;span class="s1"&gt;'.technologies[] | select(.name == "Intercom")'&lt;/span&gt;

&lt;span class="c"&gt;# Find all live chat tools on a site&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://detectzestack.com/demo?url=example.com"&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
jq &lt;span class="s1"&gt;'.categories["Live chat"]'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;categories&lt;/code&gt; object groups technologies by function. Intercom appears under “Live chat” and “Customer engagement”. You can use this to find all customer communication tools on a site at once—Intercom alongside tools like Zendesk, Drift, Freshdesk, or HubSpot.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Use Cases for Intercom Detection
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Competitive Intelligence for Sales Teams
&lt;/h3&gt;

&lt;p&gt;If you sell customer support software, CRM tools, or competing messaging platforms, knowing which companies use Intercom is directly actionable. Intercom customers have already committed to a customer messaging strategy and have budget allocated for it. They are qualified prospects for any product that integrates with or replaces Intercom.&lt;/p&gt;

&lt;p&gt;Combine Intercom detection with other &lt;a href="https://detectzestack.com/blog/tech-stack-enrichment-for-sales-teams" rel="noopener noreferrer"&gt;tech stack signals&lt;/a&gt; to build richer prospect profiles. A company running Intercom alongside &lt;a href="https://detectzestack.com/blog/how-to-detect-hubspot" rel="noopener noreferrer"&gt;HubSpot&lt;/a&gt; likely has a mature marketing and support stack. A company using Intercom with &lt;a href="https://detectzestack.com/blog/find-companies-using-stripe-technographic-prospecting" rel="noopener noreferrer"&gt;Stripe&lt;/a&gt; has an online payment flow and is likely a SaaS or e-commerce business. These combinations tell you more than any single technology detection. For a deeper look at using technographic data in sales, see &lt;a href="https://detectzestack.com/blog/sales-teams-competitive-intelligence" rel="noopener noreferrer"&gt;Sales Teams: Competitive Intelligence with Tech Stack Data&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Security Auditing Third-Party Scripts
&lt;/h3&gt;

&lt;p&gt;Intercom’s messenger loads external JavaScript, injects iframes, sets persistent cookies, and writes to local storage. For security-conscious organizations, tracking which third-party scripts have this level of access is essential for vendor auditing and compliance.&lt;/p&gt;

&lt;p&gt;Use the DetectZeStack API to inventory all third-party scripts on your domains. Intercom is one of many live chat and analytics tools that inject client-side code—knowing exactly which ones are present helps you assess your attack surface and maintain an accurate vendor register.&lt;/p&gt;

&lt;h3&gt;
  
  
  Migration Planning
&lt;/h3&gt;

&lt;p&gt;If you are considering a switch from Intercom to another platform (or the reverse), the detection methods above tell you exactly which Intercom components are in use. A site that only loads the messenger widget is a simpler migration than one using Intercom Articles (help center), Product Tours, and automated messaging workflows.&lt;/p&gt;

&lt;p&gt;The API response categorizes Intercom under “Live chat” and “Customer engagement.” If the API also detects “Intercom Articles” (a separate technology entry), you know the help center is in use too—that is a larger migration scope.&lt;/p&gt;

&lt;h2&gt;
  
  
  Intercom Detection at Scale
&lt;/h2&gt;

&lt;p&gt;Here is a practical Python script to scan a list of domains and flag which ones use Intercom:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;csv&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;

&lt;span class="n"&gt;API_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://detectzestack.p.rapidapi.com/analyze&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;HEADERS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;X-RapidAPI-Key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YOUR_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;X-RapidAPI-Host&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;detectzestack.p.rapidapi.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;domains&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;intercom.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;drift.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;zendesk.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;crisp.chat&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;intercom_audit.csv&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;w&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;newline&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="n"&gt;writer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;csv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;writer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writerow&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;domain&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;has_intercom&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;categories&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;other_live_chat&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;domain&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;domains&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;API_URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;HEADERS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;url&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;intercom&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;technologies&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Intercom&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;live_chat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;categories&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{}).&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Live chat&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;
&lt;span class="n"&gt;other_chat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;live_chat&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Intercom&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;intercom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="n"&gt;tech&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;intercom&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;writer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writerow&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
&lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;, &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tech&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;categories&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[])),&lt;/span&gt;
&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;, &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;other_chat&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;other_chat&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;
&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: Intercom detected&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="n"&gt;writer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writerow&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;, &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;live_chat&lt;/span&gt;&lt;span class="p"&gt;)])&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: no Intercom&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# respect rate limits
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This produces a CSV with each domain, whether Intercom was found, its categories, and any competing live chat tools detected on the same site. For a more complete tutorial covering batch endpoints and error handling, see &lt;a href="https://detectzestack.com/blog/website-technology-detection-python-tutorial" rel="noopener noreferrer"&gt;Detect Any Website’s Tech Stack with Python&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion and Next Steps
&lt;/h2&gt;

&lt;p&gt;Detecting Intercom manually works for one-off checks: view the source for &lt;code&gt;widget.intercom.io&lt;/code&gt;, check cookies for &lt;code&gt;intercom-session-&lt;/code&gt; prefixes, look for &lt;code&gt;iframe#intercom-frame&lt;/code&gt; in the DOM, or test &lt;code&gt;window.Intercom&lt;/code&gt; in the console. Each method catches a different aspect of the integration.&lt;/p&gt;

&lt;p&gt;For anything beyond a handful of sites—building prospect lists, monitoring competitor stacks, or auditing vendor dependencies—the DetectZeStack API automates all detection methods in a single request. One call returns Intercom, &lt;a href="https://detectzestack.com/blog/how-to-detect-hubspot" rel="noopener noreferrer"&gt;HubSpot&lt;/a&gt;, &lt;a href="https://detectzestack.com/blog/how-to-detect-google-analytics" rel="noopener noreferrer"&gt;Google Analytics&lt;/a&gt;, and every other technology on the site, with structured JSON output that feeds directly into your pipeline.&lt;/p&gt;

&lt;h3&gt;
  
  
  Related Reading
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/how-to-detect-hubspot" rel="noopener noreferrer"&gt;How to Detect if a Website Uses HubSpot&lt;/a&gt; — 4 methods from page source to API detection&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/tech-stack-enrichment-for-sales-teams" rel="noopener noreferrer"&gt;Tech Stack Enrichment for Sales Teams&lt;/a&gt; — Why technographic data matters more than firmographics&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/sales-teams-competitive-intelligence" rel="noopener noreferrer"&gt;Sales Teams: Competitive Intelligence&lt;/a&gt; — Using tech stack data for competitive positioning&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/detect-any-website-tech-stack-with-single-api-call" rel="noopener noreferrer"&gt;Detect Any Website’s Tech Stack with a Single API Call&lt;/a&gt; — Overview of all four detection layers&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/dns-based-technology-detection" rel="noopener noreferrer"&gt;DNS-Based Technology Detection&lt;/a&gt; — How CNAME records reveal hosting and marketing platforms&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>techstack</category>
      <category>webdev</category>
      <category>api</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>I Built an API That Detects 7,200+ Technologies — Here's How It Works</title>
      <dc:creator>MikeL</dc:creator>
      <pubDate>Tue, 10 Mar 2026 02:49:22 +0000</pubDate>
      <link>https://dev.to/detectzestack/i-built-an-api-that-detects-7200-technologies-heres-how-it-works-7hd</link>
      <guid>https://dev.to/detectzestack/i-built-an-api-that-detects-7200-technologies-heres-how-it-works-7hd</guid>
      <description>&lt;p&gt;You visit a website. Within seconds, you want to know: what's it built with? What CDN? What framework? What analytics?&lt;/p&gt;

&lt;p&gt;I needed this for a project — bulk tech stack detection across thousands of domains. Wappalyzer's browser extension is great for one-off lookups, but I needed an API that could handle volume, return structured data, and catch things the browser extension misses.&lt;/p&gt;

&lt;p&gt;So I built &lt;a href="https://detectzestack.com" rel="noopener noreferrer"&gt;DetectZeStack&lt;/a&gt;, a tech stack detection API in Go. It scans 7,200+ technologies using four detection layers. Here's how it works under the hood.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem With Single-Layer Detection
&lt;/h2&gt;

&lt;p&gt;Most tech detection tools rely on one method: matching patterns in HTML, headers, and JavaScript. That's what Wappalyzer does, and it's genuinely good at it.&lt;/p&gt;

&lt;p&gt;But it misses things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;DNS-level infrastructure&lt;/strong&gt; (CDNs, hosting providers identified by CNAME records)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TLS certificate issuers&lt;/strong&gt; (tells you who provides their SSL — Cloudflare, AWS, Let's Encrypt)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Infrastructure headers&lt;/strong&gt; that aren't in the fingerprint database&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A site behind Cloudflare with a React frontend might only show "React" with single-layer detection. You'd miss the CDN, the certificate authority, and the hosting provider.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Four Detection Layers
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Layer 1: Wappalyzer Fingerprinting (7,200+ signatures)
&lt;/h3&gt;

&lt;p&gt;The foundation. I use &lt;a href="https://github.com/projectdiscovery/wappalyzergo" rel="noopener noreferrer"&gt;wappalyzergo&lt;/a&gt;, which ports Wappalyzer's fingerprint database to Go. It analyzes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTML content (meta tags, script sources, DOM patterns)&lt;/li&gt;
&lt;li&gt;HTTP response headers (Server, X-Powered-By, etc.)&lt;/li&gt;
&lt;li&gt;JavaScript variables and objects&lt;/li&gt;
&lt;li&gt;Cookie names and patterns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This alone catches most frontend frameworks, CMS platforms, analytics tools, and e-commerce platforms.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 2: DNS CNAME/NS Fingerprinting (111 signatures)
&lt;/h3&gt;

&lt;p&gt;Here's where it gets interesting. When you resolve a domain's DNS, the CNAME chain reveals infrastructure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;stripe.com → stripe.com.cdn.cloudflare.net → ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That CNAME tells you Cloudflare is involved, even if the HTTP headers are scrubbed clean.&lt;/p&gt;

&lt;p&gt;I maintain 111 DNS signatures mapping CNAME patterns to technologies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;*.cloudfront.net&lt;/code&gt; → Amazon CloudFront&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;*.fastly.net&lt;/code&gt; → Fastly&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;*.netlify.app&lt;/code&gt; → Netlify&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;*.vercel-dns.com&lt;/code&gt; → Vercel&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;*.herokuapp.com&lt;/code&gt; → Heroku&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The DNS lookup runs &lt;strong&gt;in parallel&lt;/strong&gt; with the HTTP fetch, so it adds zero latency. If DNS times out (2-second cap), the scan still returns HTTP-based results.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 3: TLS Certificate Analysis
&lt;/h3&gt;

&lt;p&gt;Every HTTPS connection includes a TLS handshake with the server's certificate. The certificate issuer reveals the SSL/TLS provider:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Certificate Issuer&lt;/th&gt;
&lt;th&gt;Technology&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Cloudflare, Inc.&lt;/td&gt;
&lt;td&gt;Cloudflare SSL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Amazon&lt;/td&gt;
&lt;td&gt;AWS Certificate Manager&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Let's Encrypt&lt;/td&gt;
&lt;td&gt;Let's Encrypt&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Google Trust Services&lt;/td&gt;
&lt;td&gt;Google Cloud&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DigiCert Inc&lt;/td&gt;
&lt;td&gt;DigiCert&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This is essentially free — the cert info is already in the TLS handshake, no extra request needed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 4: Custom Header Matching
&lt;/h3&gt;

&lt;p&gt;Some infrastructure providers add unique headers that aren't in Wappalyzer's database:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;X-Railway-Request-Id&lt;/code&gt; → Railway (PaaS)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;X-Amz-Cf-Pop&lt;/code&gt; → Amazon CloudFront (edge location)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;X-Nf-Request-Id&lt;/code&gt; → Netlify&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These fill gaps where standard fingerprinting falls short.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deduplication
&lt;/h2&gt;

&lt;p&gt;When multiple layers detect the same technology, the API deduplicates by name. If Wappalyzer detects "Cloudflare" from headers AND DNS detects "Cloudflare" from CNAME, you get one entry — not two.&lt;/p&gt;

&lt;p&gt;Higher-confidence detections take priority. Wappalyzer's pattern match at 100% confidence beats a DNS-only detection at 80%.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the Output Looks Like
&lt;/h2&gt;

&lt;p&gt;Here's a real scan of &lt;code&gt;stripe.com&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="s2"&gt;"https://detectzestack.com/demo?url=stripe.com"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://stripe.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"domain"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"stripe.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"technologies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Amazon S3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"categories"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"CDN"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Amazon S3 or Amazon Simple Storage Service..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"website"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://aws.amazon.com/s3/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"icon"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Amazon S3.svg"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Amazon Web Services"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"categories"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"PaaS"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"website"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://aws.amazon.com/"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"DigiCert"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"categories"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"SSL/TLS certificate authority"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"HSTS"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"categories"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Security"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Nginx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"categories"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Web servers"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Reverse proxies"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"cpe"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cpe:2.3:a:f5:nginx:*:*:*:*:*:*:*:*"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"categories"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"CDN"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Amazon S3"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"PaaS"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Amazon Web Services"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Security"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"HSTS"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"SSL/TLS certificate authority"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"DigiCert"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Web servers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Nginx"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"meta"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"status_code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"tech_count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"scan_depth"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"full"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice the DigiCert entry with 70% confidence — that came from TLS certificate analysis (Layer 3), not HTML fingerprinting.&lt;/p&gt;

&lt;p&gt;And here's &lt;code&gt;github.com&lt;/code&gt;, which returns 8 technologies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="s2"&gt;"https://detectzestack.com/demo?url=github.com"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"technologies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Amazon S3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"categories"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"CDN"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Amazon Web Services"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"categories"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"PaaS"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"C3.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"categories"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"JavaScript libraries"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Contentful"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"categories"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"CMS"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"GitHub Pages"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"categories"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"PaaS"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"HSTS"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"categories"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Security"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"React"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"categories"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"JavaScript frameworks"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Sectigo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"categories"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"SSL/TLS certificate authority"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Contentful (CMS), C3.js (charting), React (frontend), Sectigo (TLS) — all from a single API call.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture Decisions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Why Go?&lt;/strong&gt; Concurrency is first-class. The DNS lookup, HTTP fetch, and TLS extraction all run in parallel goroutines. A typical scan completes in 1-2 seconds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why not just wrap the Wappalyzer npm package?&lt;/strong&gt; Performance and deployability. The Go binary is a single executable, ~15MB, runs on a $3/month Fly.io instance. No Node.js runtime, no headless browser, no Puppeteer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why SQLite for storage?&lt;/strong&gt; The API caches scan results to avoid hammering target sites. SQLite is perfect for this — single-file database, zero configuration, handles thousands of concurrent reads. It runs alongside the API process on the same machine.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why not headless browser rendering?&lt;/strong&gt; Some JavaScript-heavy sites would benefit from it, but it would 10x the infrastructure cost and response time. Wappalyzer's static analysis catches the vast majority of technologies. If you need rendered-page analysis, tools like Wappalyzer's browser extension are the right choice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;/demo&lt;/code&gt; endpoint is free, no signup needed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Try it right now&lt;/span&gt;
curl &lt;span class="s2"&gt;"https://detectzestack.com/demo?url=your-site.com"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For production use (higher rate limits, change tracking, history), it's on &lt;a href="https://rapidapi.com/mlugoapx/api/detectzestack" rel="noopener noreferrer"&gt;RapidAPI with a free tier&lt;/a&gt; — 100 requests/month, no credit card.&lt;/p&gt;

&lt;p&gt;There are also alternatives worth considering: Wappalyzer's npm package if you want to self-host detection, and BuiltWith if you need historical data going back years. DetectZeStack's differentiator is the multi-layer detection approach and the structured API response with confidence scores.&lt;/p&gt;




&lt;p&gt;If you're building anything that needs tech stack data — competitive analysis, security auditing, lead enrichment — I'd love to hear about your use case. Drop a comment or find me on &lt;a href="https://x.com/DetectZeStack" rel="noopener noreferrer"&gt;Twitter/X&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>showdev</category>
      <category>go</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Build a Website Tech Stack Scanner in Python (Under 50 Lines)</title>
      <dc:creator>MikeL</dc:creator>
      <pubDate>Sun, 08 Mar 2026 01:31:49 +0000</pubDate>
      <link>https://dev.to/detectzestack/build-a-website-tech-stack-scanner-in-python-under-50-lines-273i</link>
      <guid>https://dev.to/detectzestack/build-a-website-tech-stack-scanner-in-python-under-50-lines-273i</guid>
      <description>&lt;p&gt;Ever wonder what tech stack a website is running? Maybe you're scoping out a competitor, enriching leads, or checking for outdated frameworks with known vulnerabilities.&lt;/p&gt;

&lt;p&gt;Here's a Python script that does it in under 50 lines. It calls a tech detection API, parses the response, and gives you a clean report.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Full Script
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;

&lt;span class="n"&gt;API_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://detectzestack.p.rapidapi.com/analyze&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;HEADERS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;X-RapidAPI-Key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YOUR_API_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;X-RapidAPI-Host&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;detectzestack.p.rapidapi.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;scan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;API_URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;HEADERS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;url&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;raise_for_status&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;report&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;  &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;domain&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;  (HTTP &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;status_code&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;  Scanned in &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;detection_time_ms&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;ms&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Group by category
&lt;/span&gt;    &lt;span class="n"&gt;by_cat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;tech&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;technologies&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
        &lt;span class="n"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tech&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;category&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;by_cat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setdefault&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[]).&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tech&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;techs&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;by_cat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;()):&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;  &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;techs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;ver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; v&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;version&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;version&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;
            &lt;span class="n"&gt;src&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;source&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;]&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
            &lt;span class="n"&gt;cpe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;      CPE: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;cpe&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cpe&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;    - &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}{&lt;/span&gt;&lt;span class="n"&gt;ver&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="si"&gt;}{&lt;/span&gt;&lt;span class="n"&gt;cpe&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;  Total: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;technologies&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; technologies detected&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;urls&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:]&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stripe.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;urls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;report&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;scan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save this as &lt;code&gt;scan.py&lt;/code&gt; and run it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python scan.py stripe.com github.com shopify.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Sample Output
&lt;/h2&gt;

&lt;p&gt;Here's what you get for &lt;code&gt;stripe.com&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;==================================================
  stripe.com  (HTTP 200)
  Scanned in 847ms
==================================================

  CDN:
    - Cloudflare [dns]

  JavaScript frameworks:
    - React [wappalyzer]

  Web servers:
    - Nginx v1.25.3 [wappalyzer]
      CPE: cpe:2.3:a:f5:nginx:1.25.3:*:*:*:*:*:*:*

  Analytics:
    - Google Analytics [wappalyzer]

  SSL/TLS certificate authorities:
    - Let's Encrypt [tls]

  Total: 5 technologies detected
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What's Happening Under the Hood
&lt;/h2&gt;

&lt;p&gt;The API uses four detection layers:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. HTTP Header Fingerprinting&lt;/strong&gt;&lt;br&gt;
Headers like &lt;code&gt;Server: nginx/1.25.3&lt;/code&gt; and &lt;code&gt;X-Powered-By: Express&lt;/code&gt; reveal the web server and framework. Fast, but many production sites strip these.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. HTML/DOM Pattern Matching&lt;/strong&gt;&lt;br&gt;
The API scans page source for known patterns: &lt;code&gt;&amp;lt;meta name="generator" content="WordPress"&amp;gt;&lt;/code&gt;, script URLs containing &lt;code&gt;react.production.min.js&lt;/code&gt;, CSS class patterns like Tailwind's utilities. This is the core engine — over 7,200 technology signatures via &lt;a href="https://github.com/projectdiscovery/wappalyzergo" rel="noopener noreferrer"&gt;wappalyzergo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. DNS CNAME Analysis&lt;/strong&gt;&lt;br&gt;
A DNS lookup reveals infrastructure that HTTP can't see. &lt;code&gt;example.com CNAME d1234.cloudfront.net&lt;/code&gt; → Amazon CloudFront. The API checks against 111 CDN/hosting provider signatures.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. TLS Certificate Inspection&lt;/strong&gt;&lt;br&gt;
The certificate authority correlates with infrastructure: Let's Encrypt → self-hosted, Cloudflare Inc → Cloudflare proxy, Amazon → AWS.&lt;/p&gt;

&lt;p&gt;Each technology in the response includes a &lt;code&gt;source&lt;/code&gt; field (&lt;code&gt;wappalyzer&lt;/code&gt;, &lt;code&gt;dns&lt;/code&gt;, &lt;code&gt;tls&lt;/code&gt;, or &lt;code&gt;headers&lt;/code&gt;) so you know exactly how it was detected.&lt;/p&gt;
&lt;h2&gt;
  
  
  Extending It: Batch Analysis
&lt;/h2&gt;

&lt;p&gt;Need to scan multiple URLs efficiently? The API has a batch endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="n"&gt;urls&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stripe.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;shopify.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;github.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;notion.so&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;vercel.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://detectzestack.p.rapidapi.com/batch&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;X-RapidAPI-Key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YOUR_API_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;X-RapidAPI-Host&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;detectzestack.p.rapidapi.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Content-Type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;application/json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;urls&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;urls&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;results&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="n"&gt;techs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;technologies&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;domain&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;, &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;techs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This sends one HTTP request instead of five.&lt;/p&gt;

&lt;h2&gt;
  
  
  Extending It: Security Scanning with CPE
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;cpe&lt;/code&gt; field in the response maps detected technologies to the &lt;a href="https://nvd.nist.gov/" rel="noopener noreferrer"&gt;NVD (National Vulnerability Database)&lt;/a&gt;. You can cross-reference it to check for known CVEs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;tech&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;technologies&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;tech&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cpe&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;  &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tech&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; → &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tech&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;cpe&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c1"&gt;# Query NVD: https://services.nvd.nist.gov/rest/json/cves/2.0?cpeName={cpe}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is useful for security audits and compliance checks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting an API Key
&lt;/h2&gt;

&lt;p&gt;The API is on &lt;a href="https://rapidapi.com/mlugoapx/api/detectzestack" rel="noopener noreferrer"&gt;RapidAPI&lt;/a&gt;. The free tier gives you 100 requests/month — no credit card required. Enough to build and test with.&lt;/p&gt;

&lt;p&gt;Paid plans start at $9/month for 1,000 requests if you need more volume.&lt;/p&gt;




&lt;p&gt;What are you building with tech detection? Competitive analysis dashboards? Lead enrichment pipelines? Security scanners? Drop a comment — I'd love to hear your use case.&lt;/p&gt;

</description>
      <category>python</category>
      <category>tutorial</category>
      <category>webdev</category>
      <category>api</category>
    </item>
  </channel>
</rss>
