<?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>Find Companies Using Java: Detection Signals and API</title>
      <dc:creator>MikeL</dc:creator>
      <pubDate>Thu, 24 Sep 2026 14:00:28 +0000</pubDate>
      <link>https://dev.to/detectzestack/find-companies-using-java-detection-signals-and-api-2594</link>
      <guid>https://dev.to/detectzestack/find-companies-using-java-detection-signals-and-api-2594</guid>
      <description>&lt;p&gt;Java runs a large share of enterprise web backends: banks, retailers, airlines, telecoms, and most of the big content management platforms. If you sell Java tooling, application security, JVM monitoring, or migration services, a list of companies using Java is a list of prospects. The problem is that Java is not in the page. It runs on the server, and the HTML it produces looks like any other HTML.&lt;/p&gt;

&lt;p&gt;This guide covers the signals that do leak out of a Java backend, exactly which of them DetectZeStack matches (and which it does not), and how to turn a domain list into a Java prospect list with a few API calls. The API responses and headers quoted below came from real requests made while writing this post.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Finding Companies Using Java Is Harder Than Front-End Tech
&lt;/h2&gt;

&lt;p&gt;Front-end libraries announce themselves. A site that uses jQuery has a &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag pointing at a jQuery file, and anyone can read it. A site that uses Java has a JVM somewhere behind its load balancer, and the only trace in the response is whatever the application server, framework, or CMS happens to add to it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Java Runs on the Server, So Detection Relies on Indirect Signals
&lt;/h3&gt;

&lt;p&gt;Every Java detection is an inference from a side effect: a session cookie the servlet container sets, a header the application server stamps on responses, or a product that is known to be built on Java. That makes Java detection different in two ways. First, the signal is often in the headers, not the HTML. Second, it can disappear without the backend changing at all, because a proxy in front of the application stripped it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Signals That a Website Runs on Java
&lt;/h2&gt;

&lt;p&gt;These are the signals worth knowing, in rough order of how often you will see them. The table at the end of this section shows which ones DetectZeStack's HTTP scan actually matches.&lt;/p&gt;

&lt;h3&gt;
  
  
  JSESSIONID Session Cookies
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;JSESSIONID&lt;/code&gt; is the default session cookie name in the Java Servlet specification, so Tomcat, Jetty, WildFly, WebLogic, WebSphere and most other servlet containers use it unless the application renames it. It is the single most common Java signal. You can check for it with one command:&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="nt"&gt;-o&lt;/span&gt; /dev/null &lt;span class="nt"&gt;-D&lt;/span&gt; - https://confluence.atlassian.com | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s1"&gt;'^set-cookie: jsessionid'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When we ran it, Atlassian's Confluence site answered with &lt;code&gt;set-cookie: JSESSIONID=AE599AB7...; Path=/; Secure; HttpOnly&lt;/code&gt;. Confluence is a Java application, and the cookie gives it away even though the &lt;code&gt;Server&lt;/code&gt; header just says &lt;code&gt;AtlassianEdge&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Server and X-Powered-By Headers (Apache Tomcat, Jetty, JBoss/WildFly, Servlet/JSP)
&lt;/h3&gt;

&lt;p&gt;Application servers that are not hidden behind a proxy often identify themselves:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Server: Apache-Coyote/1.1&lt;/code&gt; is Tomcat's HTTP connector.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Server: Jetty(9.4.51.v20230217)&lt;/code&gt; is Eclipse Jetty, with a version.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;X-Powered-By: Servlet/3.0 JSP/2.2&lt;/code&gt; is added by several Java EE servers and names the spec versions.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;X-Powered-By: JBoss-7.1&lt;/code&gt; and &lt;code&gt;X-Powered-By: Undertow/1&lt;/code&gt; come from JBoss and WildFly.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;X-Application-Context&lt;/code&gt; is a header older Spring Boot versions added by default.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Check them with &lt;code&gt;curl -sI https://example.com&lt;/code&gt; and read the &lt;code&gt;server&lt;/code&gt; and &lt;code&gt;x-powered-by&lt;/code&gt; lines.&lt;/p&gt;

&lt;h3&gt;
  
  
  URL Patterns (.jsp, .do, .action, ;jsessionid=)
&lt;/h3&gt;

&lt;p&gt;Java web apps have recognizable URL habits. JavaServer Pages end in &lt;code&gt;.jsp&lt;/code&gt;. Apache Struts 1 maps actions to &lt;code&gt;.do&lt;/code&gt; and Struts 2 to &lt;code&gt;.action&lt;/code&gt;. When a servlet container cannot set a cookie, it rewrites links to carry the session in the path, as in &lt;code&gt;/cart;jsessionid=ABC123&lt;/code&gt;. These are good hints when you look at a site by hand, but they are weak on their own, because any server can be configured to serve a path ending in &lt;code&gt;.do&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Framework Traces (Spring, Struts, JSF)
&lt;/h3&gt;

&lt;p&gt;Frameworks leave their own marks. JavaServer Faces pages include a hidden form field named &lt;code&gt;javax.faces.ViewState&lt;/code&gt; (or &lt;code&gt;jakarta.faces.ViewState&lt;/code&gt; in newer versions). Spring shows up through the &lt;code&gt;X-Application-Context&lt;/code&gt; header mentioned above. Vaadin apps load a &lt;code&gt;vaadinBootstrap.js&lt;/code&gt; script. And a lot of Java reaches the web through products built on it: Adobe Experience Manager, Liferay, Magnolia CMS, Atlassian Confluence and Jira all run on the JVM.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Doesn't Count as Java: JavaScript Is Unrelated
&lt;/h3&gt;

&lt;p&gt;JavaScript and Java share four letters and nothing else. A site running React, Angular, or jQuery tells you about its front end, not its backend. When you filter scan results, match on the exact name &lt;code&gt;Java&lt;/code&gt; in the &lt;code&gt;Programming languages&lt;/code&gt; category. A substring match on "java" will also catch &lt;code&gt;JavaScript libraries&lt;/code&gt; and &lt;code&gt;JavaScript frameworks&lt;/code&gt; and flood your list with false positives.&lt;/p&gt;

&lt;h3&gt;
  
  
  Which Signals DetectZeStack Matches
&lt;/h3&gt;

&lt;p&gt;DetectZeStack's HTTP detection uses the open-source Wappalyzer fingerprint set. It fetches the page, reads the headers, cookies and HTML, and does not run JavaScript. We ran each signal above through the same fingerprint library the API uses:&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;Reported as&lt;/th&gt;
&lt;th&gt;Also adds Java?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;JSESSIONID cookie&lt;/td&gt;
&lt;td&gt;Java&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Server: Apache-Coyote&lt;/td&gt;
&lt;td&gt;Apache Tomcat&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;X-Powered-By: Tomcat-9.0.83&lt;/td&gt;
&lt;td&gt;Apache Tomcat 9.0.83&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Server: Jetty(9.4.51...)&lt;/td&gt;
&lt;td&gt;Jetty 9.4.51&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;X-Powered-By: Servlet/3.0 JSP/2.2&lt;/td&gt;
&lt;td&gt;Java Servlet 3.0, JavaServer Pages 2.2&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;X-Application-Context&lt;/td&gt;
&lt;td&gt;Spring&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Adobe Experience Manager paths (/etc.clientlibs/)&lt;/td&gt;
&lt;td&gt;Adobe Experience Manager&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;X-Powered-By: JBoss-7.1&lt;/td&gt;
&lt;td&gt;JBoss Application Server 7.1&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;X-Powered-By: Undertow / Server: WildFly&lt;/td&gt;
&lt;td&gt;not detected&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;javax.faces.ViewState hidden field&lt;/td&gt;
&lt;td&gt;not detected&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;.jsp / .do links, ;jsessionid= in URLs&lt;/td&gt;
&lt;td&gt;not detected&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Three things stand out. Java is usually reported as an &lt;em&gt;implied&lt;/em&gt; technology: when the scan finds Tomcat, Jetty, Spring, GlassFish, Resin, Vaadin, Liferay, Magnolia CMS or Adobe Experience Manager, it adds a &lt;code&gt;Java&lt;/code&gt; entry next to it. JBoss is the exception: its fingerprint does not imply Java, so check for &lt;code&gt;JBoss Application Server&lt;/code&gt; separately. And the URL-pattern and JSF ViewState signals are manual checks only. JavaServer Faces is still detected when a server sends &lt;code&gt;X-Powered-By: JSF/2.2&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Limits of Detecting Java from the Outside
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Reverse Proxies, CDNs, and Stripped Headers Hide the Backend
&lt;/h3&gt;

&lt;p&gt;The best illustration is Tomcat's own website. A scan of &lt;code&gt;tomcat.apache.org&lt;/code&gt; returns Apache HTTP Server, HSTS, Let's Encrypt and Varnish, and no Java, because the project site is static pages served by Apache httpd. The server you see is whatever sits at the edge.&lt;/p&gt;

&lt;p&gt;The same thing happens on the commercial side, where Java backends almost always sit behind Akamai, Cloudflare, Fastly, or an Nginx reverse proxy. The edge replaces the &lt;code&gt;Server&lt;/code&gt; header, and home pages often come from a cache that never sets a session cookie. The data shows it. As of the September 24, 2026 snapshot of DetectZeStack's index, 134 domains had Java recorded. 101 of those got there through Adobe Experience Manager, 2 through Spring, and 1 through Jetty. Apache Tomcat, the most widely deployed Java server, appeared on zero indexed domains, because its &lt;code&gt;Apache-Coyote&lt;/code&gt; header rarely survives the trip through a CDN.&lt;/p&gt;

&lt;p&gt;Detection can also change between scans. American Airlines' &lt;code&gt;www.aa.com&lt;/code&gt; is in the index with Java, but a scan while writing this post returned only Akamai, Akamai Bot Manager and HSTS. Bot protection and cache state change what a scanner receives. Treat a Java hit as strong evidence, and treat a miss as "nothing visible this time."&lt;/p&gt;

&lt;h2&gt;
  
  
  API Example: Detect Java with DetectZeStack
&lt;/h2&gt;

&lt;p&gt;Start with the public &lt;code&gt;/demo&lt;/code&gt; endpoint. It needs no API key and is rate-limited by IP:&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://www.homedepot.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;h3&gt;
  
  
  Full Stack Scan with GET /analyze
&lt;/h3&gt;

&lt;p&gt;For production use, call &lt;code&gt;/analyze&lt;/code&gt; with your RapidAPI key. This is the response for Home Depot, trimmed to the Java-related entries, with the &lt;code&gt;categories&lt;/code&gt; map and &lt;code&gt;meta&lt;/code&gt; block left intact. We had just scanned the site, so it came back from cache with &lt;code&gt;"cached": true&lt;/code&gt; and a &lt;code&gt;response_ms&lt;/code&gt; of 0. A fresh scan takes a few seconds:&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/analyze?url=https://www.homedepot.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;/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://www.homedepot.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;"www.homedepot.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;"Java"&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;"Programming languages"&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;"Java is a class-based, object-oriented programming language that is designed to have as few implementation dependencies as possible."&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://java.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;"Java.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:oracle:jre:*:*:*:*:*:*:*:*"&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="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;"Spring"&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 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://spring.io/"&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;"Spring.png"&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="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;"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;"Caching"&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;"Varnish"&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;"Programming languages"&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;"Java"&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="s2"&gt;"Akamai Bot Manager"&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 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;"Spring"&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;9&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;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;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;How to read it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Spring&lt;/code&gt; was matched from the &lt;code&gt;X-Application-Context&lt;/code&gt; header, the only Spring rule in the fingerprint set. &lt;code&gt;Java&lt;/code&gt; was added because Spring implies it.&lt;/li&gt;
&lt;li&gt;The stack in front of it is Akamai, Varnish, and Nginx. Java is detected here despite the proxies because the Spring header made it through all three.&lt;/li&gt;
&lt;li&gt;React sits in &lt;code&gt;JavaScript frameworks&lt;/code&gt;. That is the front end, and it is unrelated to the Java entry.&lt;/li&gt;
&lt;li&gt;Empty fields are left out. Neither entry has a &lt;code&gt;version&lt;/code&gt;, and &lt;code&gt;Spring&lt;/code&gt; has no &lt;code&gt;cpe&lt;/code&gt;, so those keys are missing. In &lt;code&gt;jq&lt;/code&gt;, use &lt;code&gt;.version // ""&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Other sites show the other routes to a Java entry. &lt;code&gt;www.cisco.com&lt;/code&gt; returns &lt;code&gt;Adobe Experience Manager&lt;/code&gt; plus &lt;code&gt;Java&lt;/code&gt;. &lt;code&gt;bitbucket.org&lt;/code&gt; returns &lt;code&gt;Magnolia CMS&lt;/code&gt; plus &lt;code&gt;Java&lt;/code&gt;, matched from its &lt;code&gt;x-magnolia-registration&lt;/code&gt; header. &lt;code&gt;confluence.atlassian.com&lt;/code&gt; returns &lt;code&gt;Java&lt;/code&gt; alone, from the JSESSIONID cookie.&lt;/p&gt;

&lt;h3&gt;
  
  
  Yes/No Check with GET /check?tech=Java
&lt;/h3&gt;

&lt;p&gt;If you only need a yes or no, &lt;code&gt;/check&lt;/code&gt; takes a &lt;code&gt;tech&lt;/code&gt; parameter and returns a flat object with &lt;code&gt;detected&lt;/code&gt;, &lt;code&gt;confidence&lt;/code&gt;, &lt;code&gt;version&lt;/code&gt;, and &lt;code&gt;categories&lt;/code&gt;. The name match 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;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://detectzestack.p.rapidapi.com/check?tech=Java&amp;amp;url=https://www.cisco.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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because JBoss does not imply Java, run a second check with &lt;code&gt;tech=JBoss Application Server&lt;/code&gt; (URL-encoded as &lt;code&gt;JBoss%20Application%20Server&lt;/code&gt;) if JBoss shops matter to you.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scan a Prospect List with POST /analyze/batch
&lt;/h3&gt;

&lt;p&gt;To start from domains already in the index, call &lt;code&gt;/lookup?tech=Java&lt;/code&gt;. It returns matching domains with &lt;code&gt;first_seen&lt;/code&gt; and &lt;code&gt;last_seen&lt;/code&gt; timestamps, and the number of results per page depends on your plan:&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/lookup?tech=Java&amp;amp;limit=50"&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="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.results[].domain'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To check your own list, send up to 10 URLs per request to &lt;code&gt;/analyze/batch&lt;/code&gt;. Each URL counts as one request against your quota. Each item nests its analysis under &lt;code&gt;.result&lt;/code&gt;, or carries an &lt;code&gt;error&lt;/code&gt; string instead:&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="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: &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;
&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": ["https://www.homedepot.com", "https://www.cisco.com", "https://confluence.atlassian.com"]}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
| jq &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'.results[] | {url: .url, java: ([.result.technologies[]? | select(.name == "Java")] | length &amp;gt; 0)}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This Python script scans &lt;code&gt;domains.txt&lt;/code&gt; in chunks of 10 and writes a CSV that records not just whether Java was found but &lt;em&gt;how&lt;/em&gt;, which is what makes the list useful for outreach. "Java via Adobe Experience Manager" and "Java via Spring" are different conversations:&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;csv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;urllib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;

&lt;span class="n"&gt;KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;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;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/batch&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;JAVA_SOURCES&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;Apache Tomcat&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;Jetty&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;JBoss Application Server&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;GlassFish&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;Spring&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;JavaServer Pages&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;JavaServer Faces&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;Java Servlet&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;Resin&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;Vaadin&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;Apache Wicket&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;Adobe Experience Manager&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;Liferay&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;Magnolia CMS&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;Atlassian Confluence&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;Atlassian Jira&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="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strip&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;d&lt;/span&gt; &lt;span class="ow"&gt;in&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;domains.txt&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;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt;
&lt;span class="n"&gt;rows&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;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&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="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;domains&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="n"&gt;chunk&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;d&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;http&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="s"&gt;https://&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;d&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;i&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;
&lt;span class="n"&gt;req&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;urllib&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="nc"&gt;Request&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;data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&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;chunk&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;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;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="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="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;urllib&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="nf"&gt;urlopen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;120&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;resp&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;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load&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="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&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;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="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="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&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;result&lt;/span&gt;&lt;span class="sh"&gt;"&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="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="n"&gt;via&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;JAVA_SOURCES&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;n&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="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Java&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;techs&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;via&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="n"&gt;rows&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="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;item&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;via&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;via&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Java only&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;versions&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="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;n&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;techs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;n&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;for&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;via&lt;/span&gt; &lt;span class="k"&gt;if&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;n&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cdn&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;n&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&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="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CDN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&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;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="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;java_prospects.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;w&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="nc"&gt;DictWriter&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;fieldnames&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;via&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;versions&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;cdn&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeheader&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writerows&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rows&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="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; of &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;domains&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; domains show a Java signal&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;A row labelled &lt;code&gt;Java only&lt;/code&gt; has a &lt;code&gt;Java&lt;/code&gt; entry with none of the named sources next to it. That is almost always the JSESSIONID cookie, which is the one rule that reports Java directly instead of implying it. For lists in the thousands, see &lt;a href="https://detectzestack.com/blog/batch-scan-1000-websites" rel="noopener noreferrer"&gt;Batch Scan 1,000 Websites for Tech Stack&lt;/a&gt; for concurrency, retries, and quota planning.&lt;/p&gt;

&lt;h3&gt;
  
  
  Compare Java and Non-Java Stacks with POST /compare
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;/compare&lt;/code&gt; takes 2 to 10 URLs and returns each domain's technologies, a &lt;code&gt;unique&lt;/code&gt; list per domain, and a top-level &lt;code&gt;shared&lt;/code&gt; list. It is a quick way to see whether a competitor set splits between Java and other backends:&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="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: &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;
&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": ["https://www.homedepot.com", "https://www.lowes.com"]}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
| jq &lt;span class="s1"&gt;'{shared: .shared, unique: [.domains[] | {domain, unique}]}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;Java&lt;/code&gt; is in &lt;code&gt;shared&lt;/code&gt;, every site you compared showed a Java signal. If it appears in one domain's &lt;code&gt;unique&lt;/code&gt; list, only that one did, which may reflect a real difference or just a proxy hiding the other backend.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Java Detection for Lead Lists and Security Audits
&lt;/h2&gt;

&lt;p&gt;For sales, the "via" column above is the segmenting field. Adobe Experience Manager sites are large enterprises with a marketing platform budget. Spring and Tomcat hits point to in-house engineering teams running their own Java services. Liferay and Magnolia point to portal and content teams. Pair any of them with the CDN column and you know what sits between the application and its users. For a complete enrichment flow into a CRM, see &lt;a href="https://detectzestack.com/blog/lead-enrichment-pipeline-with-tech-detection" rel="noopener noreferrer"&gt;Build a Lead Enrichment Pipeline with Tech Detection&lt;/a&gt;. For comparison with other backends, see &lt;a href="https://detectzestack.com/blog/find-companies-using-node-js" rel="noopener noreferrer"&gt;Find Companies Using Node.js&lt;/a&gt; and &lt;a href="https://detectzestack.com/blog/find-companies-using-mysql" rel="noopener noreferrer"&gt;Find Companies Using MySQL&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mapping Detected Versions to CPE Identifiers for Vulnerability Checks
&lt;/h3&gt;

&lt;p&gt;Several Java entries carry a &lt;code&gt;cpe&lt;/code&gt; field: &lt;code&gt;Java&lt;/code&gt; itself (&lt;code&gt;cpe:2.3:a:oracle:jre&lt;/code&gt;), &lt;code&gt;Apache Tomcat&lt;/code&gt;, &lt;code&gt;JBoss Application Server&lt;/code&gt;, &lt;code&gt;GlassFish&lt;/code&gt;, &lt;code&gt;Liferay&lt;/code&gt;, &lt;code&gt;Magnolia CMS&lt;/code&gt;, and &lt;code&gt;Adobe Experience Manager&lt;/code&gt;. DetectZeStack's &lt;code&gt;/vulnerability&lt;/code&gt; endpoint looks up CVEs only for technologies that have &lt;em&gt;both&lt;/em&gt; a CPE and a detected version. The &lt;code&gt;Java&lt;/code&gt; entry never has a version, since no HTTP signal reveals the JRE release, so it is never checked. A Tomcat version from &lt;code&gt;X-Powered-By: Tomcat-9.0.83&lt;/code&gt;, or a JBoss or Liferay version from their headers, is checked:&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/vulnerability?url=https://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: &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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In practice, a Java server that publishes its exact version in a header is also a server whose headers were never hardened, which is a finding on its own. &lt;a href="https://detectzestack.com/blog/detect-vulnerable-technologies-with-cpe" rel="noopener noreferrer"&gt;Detect Vulnerable Technologies with CPE&lt;/a&gt; explains how the CPE matching works and how to read the results.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How can I tell if a website runs on Java?
&lt;/h3&gt;

&lt;p&gt;Run &lt;code&gt;curl -sI&lt;/code&gt; against the site and look for a &lt;code&gt;JSESSIONID&lt;/code&gt; cookie, a &lt;code&gt;Server&lt;/code&gt; header starting with &lt;code&gt;Apache-Coyote&lt;/code&gt; or &lt;code&gt;Jetty&lt;/code&gt;, or an &lt;code&gt;X-Powered-By&lt;/code&gt; header naming Servlet, JSP, JSF, or Tomcat. &lt;code&gt;.jsp&lt;/code&gt; or &lt;code&gt;.do&lt;/code&gt; URLs are further hints.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I find a list of companies using Java?
&lt;/h3&gt;

&lt;p&gt;Use &lt;code&gt;/lookup?tech=Java&lt;/code&gt; for domains already in the index, then check your own list 10 URLs at a time with &lt;code&gt;POST /analyze/batch&lt;/code&gt;, keeping results with an entry named &lt;code&gt;Java&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is JavaScript the same as Java for tech detection?
&lt;/h3&gt;

&lt;p&gt;No. Java appears under &lt;code&gt;Programming languages&lt;/code&gt;. JavaScript libraries and frameworks are front-end code and say nothing about the backend.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why does a Java website not show Java in the scan?
&lt;/h3&gt;

&lt;p&gt;A CDN or reverse proxy usually replaced the headers and served a cached page with no session cookie. A missing entry means no Java signal was visible, not that the backend is something else.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion: Get Your Free API Key on RapidAPI
&lt;/h2&gt;

&lt;p&gt;Finding companies using Java comes down to catching the side effects of a Java backend: the JSESSIONID cookie, application server headers, the Spring header, and Java-based products like Adobe Experience Manager and Liferay. DetectZeStack matches those and adds a &lt;code&gt;Java&lt;/code&gt; entry whenever one of them implies it. It does not match URL patterns or JSF form fields, and it cannot see through a proxy that strips everything, so treat hits as strong evidence and misses as unknown.&lt;/p&gt;

&lt;p&gt;The workflow: one &lt;code&gt;/demo&lt;/code&gt; call to see the response shape, &lt;code&gt;/lookup?tech=Java&lt;/code&gt; for indexed domains, &lt;code&gt;/analyze/batch&lt;/code&gt; for your own list, and the script above to record how each Java signal was found. Each scan also returns the CDN, CMS, and front-end stack from the same request.&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-node-js" rel="noopener noreferrer"&gt;Find Companies Using Node.js&lt;/a&gt; — the other common server-side runtime, and the signals it leaves&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/find-companies-using-nginx" rel="noopener noreferrer"&gt;Find Companies Using Nginx&lt;/a&gt; — the reverse proxy that often sits in front of Java backends&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/find-companies-using-mysql" rel="noopener noreferrer"&gt;Find Companies Using MySQL&lt;/a&gt; — another backend technology you can only infer from indirect signals&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/detect-vulnerable-technologies-with-cpe" rel="noopener noreferrer"&gt;Detect Vulnerable Technologies with CPE&lt;/a&gt; — how detected versions become CVE lookups&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/batch-scan-1000-websites" rel="noopener noreferrer"&gt;Batch Scan 1,000 Websites for Tech Stack&lt;/a&gt; — concurrency, retries, and quota planning for large lists&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/lead-enrichment-pipeline-with-tech-detection" rel="noopener noreferrer"&gt;Build a Lead Enrichment Pipeline with Tech Detection&lt;/a&gt; — turning scan results into CRM-ready leads&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>techstack</category>
      <category>webdev</category>
      <category>api</category>
    </item>
    <item>
      <title>Find Companies Using Contentful CMS via API (2026 Guide)</title>
      <dc:creator>MikeL</dc:creator>
      <pubDate>Wed, 16 Sep 2026 14:01:10 +0000</pubDate>
      <link>https://dev.to/detectzestack/find-companies-using-contentful-cms-via-api-2026-guide-3f58</link>
      <guid>https://dev.to/detectzestack/find-companies-using-contentful-cms-via-api-2026-guide-3f58</guid>
      <description>&lt;p&gt;Contentful is the headless CMS that shows up underneath a specific kind of company: one that decided its marketing site needed its own front-end team. It is not a starter-plan product and it is not something a freelancer installs on a Friday. Finding the companies running it gives you a segment that has already paid for a content platform, already staffed a front end, and already committed to a build pipeline — which is exactly the profile that buys developer tooling, personalization, search, localization, and migration services.&lt;/p&gt;

&lt;p&gt;The catch is that Contentful is genuinely harder to detect than WordPress, and for a structural reason rather than an accidental one. This post covers why, which fingerprints survive a static build, and how to turn those into a list of companies using Contentful through the DetectZeStack API. Every response and every number below was captured on the day this post was written.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Companies Using Contentful Are a Distinct Prospect Segment
&lt;/h2&gt;

&lt;p&gt;A CMS detection is usually a weak signal because the population is enormous and undifferentiated. Contentful is the opposite. Adopting it means a team explicitly chose to separate content from presentation, which implies three things you can sell against:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;There is a front-end team.&lt;/strong&gt; Contentful returns JSON, not pages. Somebody has to build the rendering layer, which means an in-house or agency front-end practice exists and has a budget.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;There is a build pipeline.&lt;/strong&gt; Content changes trigger rebuilds or revalidation. That means CI, a hosting platform, preview environments, and all the tooling those drag along.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The site is not the product.&lt;/strong&gt; Contentful usually sits under a marketing or docs site in front of a real product. The buyer you want is often in growth or marketing engineering, not IT.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Across the DetectZeStack scan corpus as of September 16, 2026, 106 domains carry a Contentful detection. That population skews hard toward B2B SaaS and consumer tech: dovetail.com, temporal.io, &lt;a href="http://www.samsara.com" rel="noopener noreferrer"&gt;www.samsara.com&lt;/a&gt;, &lt;a href="http://www.onepeloton.com" rel="noopener noreferrer"&gt;www.onepeloton.com&lt;/a&gt;, &lt;a href="http://www.docusign.com" rel="noopener noreferrer"&gt;www.docusign.com&lt;/a&gt;, waymo.com, and &lt;a href="http://www.atlassian.com" rel="noopener noreferrer"&gt;www.atlassian.com&lt;/a&gt; are all in it. That is a narrow, high-value list — not the long tail you get from a WordPress query.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Contentful Is Harder to Detect Than WordPress
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Headless means no generator meta tag and no CMS-rendered HTML
&lt;/h3&gt;

&lt;p&gt;WordPress detection is easy because WordPress renders the page. It stamps &lt;code&gt;&amp;lt;meta name="generator" content="WordPress 6.x"&amp;gt;&lt;/code&gt; into the head, serves assets from &lt;code&gt;/wp-content/&lt;/code&gt;, and exposes &lt;code&gt;/wp-json/&lt;/code&gt;. Every one of those is the CMS talking about itself in its own output.&lt;/p&gt;

&lt;p&gt;Contentful never renders anything. Its Content Delivery API returns JSON; a framework consumes that JSON and produces the HTML. By the time a page reaches a browser, the markup was generated by Next.js, Gatsby, Nuxt, or a hand-rolled renderer — and those frameworks stamp &lt;em&gt;themselves&lt;/em&gt;, not the CMS. There is no generator tag, no admin path, no CMS-owned URL prefix. If you are building a detector from first principles, this is the point where the WordPress playbook stops working. Our broader guide to &lt;a href="https://detectzestack.com/blog/detect-what-cms-website-uses" rel="noopener noreferrer"&gt;detecting what CMS a website uses&lt;/a&gt; walks through that split in more detail.&lt;/p&gt;

&lt;h3&gt;
  
  
  The signals that do survive the build: ctfassets.net and the Contentful API host
&lt;/h3&gt;

&lt;p&gt;One thing cannot be compiled away. Images, videos, and downloads uploaded to Contentful are served from Contentful's own asset CDN, and those absolute URLs end up in the rendered HTML because that is the whole point of a hosted asset pipeline. The fingerprint is the asset hostname:&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;Where it appears&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Image assets&lt;/td&gt;
&lt;td&gt;images.ctfassets.net&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Video assets&lt;/td&gt;
&lt;td&gt;videos.ctfassets.net&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Generic assets&lt;/td&gt;
&lt;td&gt;assets.ctfassets.net&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Downloads&lt;/td&gt;
&lt;td&gt;downloads.ctfassets.net&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Response header&lt;/td&gt;
&lt;td&gt;x-contentful-request-id&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;You can confirm the asset signal on any site with one line, no API key and no browser:&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;-sL&lt;/span&gt; https://temporal.io &lt;span class="se"&gt;\&lt;/span&gt;
| &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-aoE&lt;/span&gt; &lt;span class="s1"&gt;'[a-z0-9.-]+\.(ctfassets\.net|contentful\.com)'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
| &lt;span class="nb"&gt;sort&lt;/span&gt; | &lt;span class="nb"&gt;uniq&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-rn&lt;/span&gt;
230 images.ctfassets.net
2 videos.ctfassets.net
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;230 image references on a single page. That is not an edge case — it is what a Contentful-backed marketing site looks like from the outside, and it is why the signal is reliable despite being indirect. A lower-volume site still trips it; dovetail.com shows four of each on its homepage.&lt;/p&gt;

&lt;p&gt;The header signal, &lt;code&gt;x-contentful-request-id&lt;/code&gt;, is a different thing and worth understanding so you do not go looking for it in the wrong place. It is set by Contentful's own API hosts, not by customer websites:&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;-sI&lt;/span&gt; &lt;span class="s2"&gt;"https://cdn.contentful.com/spaces/foo/entries"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; contentful
server: Contentful
x-contentful-request-id: 0679d4f1-a3c1-403b-b078-6a0806ae1efb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A customer's marketing site proxies nothing, so that header will not be on its response. It fires when you scan a Contentful API endpoint directly. In practice, essentially every real-world detection comes from the asset hostname.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The asset host has to be in the rendered HTML to count. A site that proxies Contentful images through its own domain — Next.js image optimization pointed at a custom loader, or a Cloudflare Worker rewriting asset URLs — strips the fingerprint entirely. Those sites run Contentful and will come back negative. This is the main false-negative source, and there is no HTTP-layer workaround for it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  The frontend stack sitting in front of Contentful
&lt;/h3&gt;

&lt;p&gt;Because Contentful cannot render, every Contentful detection arrives with a rendering framework attached — and that co-detection is where the qualification value lives. Counting distinct domains across the 106 Contentful sites in the corpus:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Co-detected technology&lt;/th&gt;
&lt;th&gt;Domains&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Amazon Web Services&lt;/td&gt;
&lt;td&gt;54&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;React&lt;/td&gt;
&lt;td&gt;52&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Webpack&lt;/td&gt;
&lt;td&gt;46&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Next.js&lt;/td&gt;
&lt;td&gt;32&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cloudflare&lt;/td&gt;
&lt;td&gt;28&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vercel&lt;/td&gt;
&lt;td&gt;24&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gatsby&lt;/td&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Netlify&lt;/td&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vue.js&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Nuxt.js&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Roughly half of Contentful sites in the corpus run React, and &lt;a href="https://detectzestack.com/blog/find-companies-using-next-js" rel="noopener noreferrer"&gt;Next.js&lt;/a&gt; alone covers 32 of 106. Gatsby is still present on 15, which is a meaningful sub-segment in its own right given Gatsby's trajectory — those are modernization conversations waiting to happen. On the hosting side, &lt;a href="https://detectzestack.com/blog/how-to-detect-vercel" rel="noopener noreferrer"&gt;Vercel&lt;/a&gt; and Netlify together account for 36 of the 106, while AWS shows up on 54.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check One Domain for Contentful Free (GET /demo)
&lt;/h2&gt;

&lt;p&gt;The public &lt;code&gt;/demo&lt;/code&gt; endpoint runs the full detector against any URL with no authentication and no signup, rate limited to 20 requests per hour per IP:&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=temporal.io"&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;The real response, captured September 16, 2026:&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://temporal.io"&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;"temporal.io"&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;"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="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;"Contentful is an API-first content management platform to create, manage and publish content on any digital channel."&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.contentful.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;"Contentful.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="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="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;"HTTP Strict Transport Security (HSTS) informs browsers that the site should only be accessed using HTTPS."&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.rfc-editor.org/rfc/rfc6797#section-6.1"&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="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;"Let's Encrypt"&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;"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;"Vercel"&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;"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;"Vercel is a cloud platform for static frontends and serverless functions."&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://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;"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;"vercel.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="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;"CMS"&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;"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;"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;"Vercel"&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;"Let's Encrypt"&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="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;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;"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;1901&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;Three fields to read carefully. &lt;code&gt;source: "http"&lt;/code&gt; means the Contentful match came from the HTML body rather than DNS or TLS — which is why &lt;code&gt;meta.scan_depth&lt;/code&gt; must be &lt;code&gt;"full"&lt;/code&gt; for a Contentful result to mean anything. A &lt;code&gt;"partial"&lt;/code&gt; scan means the HTTP fetch was blocked or timed out and only the DNS and TLS layers ran, so the absence of Contentful in a partial result is &lt;em&gt;unknown&lt;/em&gt;, not negative. And &lt;code&gt;cached&lt;/code&gt; and &lt;code&gt;response_ms&lt;/code&gt; are top-level fields, not part of &lt;code&gt;meta&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  API Examples: Detecting Contentful Four Ways
&lt;/h2&gt;

&lt;h3&gt;
  
  
  GET /check?tech=Contentful — a yes/no answer with confidence
&lt;/h3&gt;

&lt;p&gt;When you want a boolean rather than the whole stack, &lt;code&gt;/check&lt;/code&gt; runs the same scan and returns a compact object. The technology name is matched case-insensitively:&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=dovetail.com&amp;amp;tech=Contentful"&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;"dovetail.com"&lt;/span&gt;,
&lt;span class="s2"&gt;"technology"&lt;/span&gt;: &lt;span class="s2"&gt;"Contentful"&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;"CMS"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;,
&lt;span class="s2"&gt;"response_ms"&lt;/span&gt;: 4744,
&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;p&gt;&lt;code&gt;confidence: 100&lt;/code&gt; is what an unambiguous hostname fingerprint earns. &lt;code&gt;version&lt;/code&gt; is empty and always will be — Contentful is hosted SaaS, so there is no customer-visible release number to report, and the hostname pattern captures no digits. Filter on &lt;code&gt;name&lt;/code&gt; or &lt;code&gt;detected&lt;/code&gt;, never on &lt;code&gt;version&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  GET /lookup?tech=Contentful — domains already known to run Contentful
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;/lookup&lt;/code&gt; is a reverse index over DetectZeStack's prior scans, not a crawl of the open web. Treat it as a way to seed a list rather than to enumerate every Contentful site that exists. Results paginate with &lt;code&gt;limit&lt;/code&gt; and &lt;code&gt;offset&lt;/code&gt;, clamped per tier: 2 rows on the free tier, 50 on Pro, 200 on Ultra, 800 on Mega.&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/lookup?tech=Contentful&amp;amp;limit=50"&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;"technology"&lt;/span&gt;: &lt;span class="s2"&gt;"Contentful"&lt;/span&gt;,
&lt;span class="s2"&gt;"total"&lt;/span&gt;: 106,
&lt;span class="s2"&gt;"limit"&lt;/span&gt;: 2,
&lt;span class="s2"&gt;"offset"&lt;/span&gt;: 0,
&lt;span class="s2"&gt;"results"&lt;/span&gt;: &lt;span class="o"&gt;[&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;"dovetail.com"&lt;/span&gt;,
&lt;span class="s2"&gt;"category"&lt;/span&gt;: &lt;span class="s2"&gt;"CMS"&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;"first_seen"&lt;/span&gt;: &lt;span class="s2"&gt;"2026-05-11T04:09:35Z"&lt;/span&gt;,
&lt;span class="s2"&gt;"last_seen"&lt;/span&gt;: &lt;span class="s2"&gt;"2026-09-16T13:02:44Z"&lt;/span&gt;
&lt;span class="o"&gt;}&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;"www.onepeloton.com"&lt;/span&gt;,
&lt;span class="s2"&gt;"category"&lt;/span&gt;: &lt;span class="s2"&gt;"CMS"&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;"first_seen"&lt;/span&gt;: &lt;span class="s2"&gt;"2026-05-27T13:39:21Z"&lt;/span&gt;,
&lt;span class="s2"&gt;"last_seen"&lt;/span&gt;: &lt;span class="s2"&gt;"2026-09-15T18:02:31Z"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;]&lt;/span&gt;,
&lt;span class="s2"&gt;"response_ms"&lt;/span&gt;: 11
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That call was made on a free-tier key, which is why &lt;code&gt;limit&lt;/code&gt; comes back as &lt;code&gt;2&lt;/code&gt; even though the request asked for 50 — the tier ceiling overrides your parameter silently. &lt;code&gt;total&lt;/code&gt; is &lt;em&gt;not&lt;/em&gt; clamped, so you can always see how large the segment is before deciding whether the tier is worth upgrading.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;first_seen&lt;/code&gt; and &lt;code&gt;last_seen&lt;/code&gt; pair is the most underused field in the response. dovetail.com first seen in May and last seen today has run Contentful continuously across every scan in between — a stable signal. A wide gap between the two means the detection is stale and worth re-scanning before the domain goes on an outreach list.&lt;/p&gt;

&lt;h3&gt;
  
  
  POST /analyze/batch — scan up to 10 prospect domains per request
&lt;/h3&gt;

&lt;p&gt;For domains you bring yourself, &lt;code&gt;/analyze/batch&lt;/code&gt; takes up to 10 URLs per request and scans them concurrently. Each item in &lt;code&gt;results&lt;/code&gt; carries either a &lt;code&gt;result&lt;/code&gt; object with the single-domain shape or an &lt;code&gt;error&lt;/code&gt; string. This call mixes two Contentful sites with one that is not:&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": ["dovetail.com", "www.samsara.com", "getbootstrap.com"]}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
| jq &lt;span class="s1"&gt;'{successful, failed, total_ms,
rows: [.results[] | {url,
contentful: ([.result.technologies[]? | select(.name == "Contentful")] | length &amp;gt; 0),
cms: .result.categories["CMS"],
depth: .result.meta.scan_depth,
count: .result.meta.tech_count}]}'&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="s2"&gt;"successful"&lt;/span&gt;: 3,
&lt;span class="s2"&gt;"failed"&lt;/span&gt;: 0,
&lt;span class="s2"&gt;"total_ms"&lt;/span&gt;: 3590,
&lt;span class="s2"&gt;"rows"&lt;/span&gt;: &lt;span class="o"&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;"dovetail.com"&lt;/span&gt;,    &lt;span class="s2"&gt;"contentful"&lt;/span&gt;: &lt;span class="nb"&gt;true&lt;/span&gt;,  &lt;span class="s2"&gt;"cms"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Contentful"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;, &lt;span class="s2"&gt;"depth"&lt;/span&gt;: &lt;span class="s2"&gt;"full"&lt;/span&gt;, &lt;span class="s2"&gt;"count"&lt;/span&gt;: 12 &lt;span class="o"&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;"www.samsara.com"&lt;/span&gt;, &lt;span class="s2"&gt;"contentful"&lt;/span&gt;: &lt;span class="nb"&gt;true&lt;/span&gt;,  &lt;span class="s2"&gt;"cms"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Contentful"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;, &lt;span class="s2"&gt;"depth"&lt;/span&gt;: &lt;span class="s2"&gt;"full"&lt;/span&gt;, &lt;span class="s2"&gt;"count"&lt;/span&gt;: 8  &lt;span class="o"&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;"getbootstrap.com"&lt;/span&gt;,&lt;span class="s2"&gt;"contentful"&lt;/span&gt;: &lt;span class="nb"&gt;false&lt;/span&gt;, &lt;span class="s2"&gt;"cms"&lt;/span&gt;: null,           &lt;span class="s2"&gt;"depth"&lt;/span&gt;: &lt;span class="s2"&gt;"full"&lt;/span&gt;, &lt;span class="s2"&gt;"count"&lt;/span&gt;: 11 &lt;span class="o"&gt;}&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;getbootstrap.com is a deliberate negative: it has no &lt;code&gt;CMS&lt;/code&gt; category at all. Note that a null category is not the same as a miss, and a partial scan is not the same as a negative — the filter has to check the exact name and the scan depth together.&lt;/p&gt;

&lt;h3&gt;
  
  
  POST /compare — diff a Contentful site against a WordPress competitor
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;/compare&lt;/code&gt; takes 2 to 10 URLs and returns what they share and what each one has alone. Running a headless site against a traditional one makes the architectural split obvious in a single response:&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": ["dovetail.com", "techcrunch.com"]}'&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;"HSTS"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;,
&lt;span class="s2"&gt;"domains"&lt;/span&gt;: &lt;span class="o"&gt;[&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;"dovetail.com"&lt;/span&gt;,
&lt;span class="s2"&gt;"unique"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Netlify"&lt;/span&gt;, &lt;span class="s2"&gt;"Next.js"&lt;/span&gt;, &lt;span class="s2"&gt;"Node.js"&lt;/span&gt;, &lt;span class="s2"&gt;"Algolia"&lt;/span&gt;, &lt;span class="s2"&gt;"Linkedin Ads"&lt;/span&gt;,
&lt;span class="s2"&gt;"React"&lt;/span&gt;, &lt;span class="s2"&gt;"Webpack"&lt;/span&gt;, &lt;span class="s2"&gt;"Amazon CloudFront"&lt;/span&gt;, &lt;span class="s2"&gt;"Amazon S3"&lt;/span&gt;,
&lt;span class="s2"&gt;"Amazon Web Services"&lt;/span&gt;, &lt;span class="s2"&gt;"Contentful"&lt;/span&gt;&lt;span class="o"&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;"domain"&lt;/span&gt;: &lt;span class="s2"&gt;"techcrunch.com"&lt;/span&gt;,
&lt;span class="s2"&gt;"unique"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Yoast SEO Premium"&lt;/span&gt;, &lt;span class="s2"&gt;"reCAPTCHA"&lt;/span&gt;, &lt;span class="s2"&gt;"Google Tag Manager"&lt;/span&gt;,
&lt;span class="s2"&gt;"Let's Encrypt"&lt;/span&gt;, &lt;span class="s2"&gt;"MySQL"&lt;/span&gt;, &lt;span class="s2"&gt;"WordPress"&lt;/span&gt;, &lt;span class="s2"&gt;"WordPress Block Editor"&lt;/span&gt;,
&lt;span class="s2"&gt;"WordPress Site Editor"&lt;/span&gt;, &lt;span class="s2"&gt;"WordPress VIP"&lt;/span&gt;, &lt;span class="s2"&gt;"Nginx"&lt;/span&gt;, &lt;span class="s2"&gt;"PHP"&lt;/span&gt;,
&lt;span class="s2"&gt;"Sailthru"&lt;/span&gt;, &lt;span class="s2"&gt;"Yoast SEO"&lt;/span&gt;&lt;span class="o"&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;"total_ms"&lt;/span&gt;: 2547
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One shared technology out of 25. That is the headless split rendered as data: Contentful plus a JavaScript build chain plus a CDN on one side, WordPress plus PHP plus MySQL plus Nginx on the other. If you sell into one of those worlds, this response tells you in one call which conversation you are having.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building a Contentful Prospect List End to End
&lt;/h2&gt;

&lt;p&gt;A raw list of Contentful domains is a starting point, not a segment. The value comes from what else is in the same response — and because &lt;code&gt;/analyze&lt;/code&gt; returns the entire stack in one call, you already have it without a second lookup.&lt;/p&gt;

&lt;p&gt;Two real hits from the batch above sort into completely different buckets. dovetail.com comes back with &lt;code&gt;JavaScript frameworks: ["Next.js", "React"]&lt;/code&gt;, &lt;code&gt;PaaS: ["Amazon Web Services", "Netlify"]&lt;/code&gt;, &lt;code&gt;Search engines: ["Algolia"]&lt;/code&gt;, &lt;code&gt;Advertising: ["Linkedin Ads"]&lt;/code&gt;, and 12 technologies total — a mature Jamstack build with a search vendor and paid acquisition already in place. &lt;a href="http://www.samsara.com" rel="noopener noreferrer"&gt;www.samsara.com&lt;/a&gt; comes back with &lt;code&gt;JavaScript frameworks: ["Nuxt.js", "Vue.js"]&lt;/code&gt;, &lt;code&gt;A/B Testing: ["Intellimize"]&lt;/code&gt;, &lt;code&gt;CDN: ["Amazon CloudFront"]&lt;/code&gt;, and 8 technologies — a Vue shop on AWS running personalization, with no search vendor detected.&lt;/p&gt;

&lt;p&gt;Same CMS, opposite pitches. If you sell site search, dovetail already bought and samsara has not. If you sell React component libraries, the Vue site is disqualified before anyone writes an email. If you sell experimentation tooling, samsara has already proven it will pay for that category. Filtering Contentful hits on the co-detected framework and vendor set splits the list along exactly the line your product cares about.&lt;/p&gt;

&lt;p&gt;Here is the whole thing as a shell pipeline. It reads &lt;code&gt;domains.txt&lt;/code&gt; one domain per line, sends batches of 10, writes one CSV row per Contentful hit with the co-detected framework and hosting, and pushes failures and partial scans into a retry file instead of silently counting them as negatives:&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-contentful.sh - build a Contentful prospect list from domains.txt&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;"requested,resolved,frameworks,hosting,tech_count"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; contentful.csv
: &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; contentful_retry.txt

&lt;span class="c"&gt;# 10 URLs per request is 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;
&lt;span class="nv"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;=&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;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$resp&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)
| . as $item
| $item.result as $r
| select([$r.technologies[].name] | index("Contentful"))
| [
$item.url,
$r.domain,
(($r.categories["JavaScript frameworks"] // []) | join(";")),
(($r.categories["PaaS"] // []) | join(";")),
($r.meta.tech_count | tostring)
] | @csv'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; contentful.csv

&lt;span class="c"&gt;# Fetch errors and DNS-only scans are unknown, not negative&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$resp&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(.error != null or .result.meta.scan_depth == "partial")
| .url'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; contentful_retry.txt

&lt;span class="nb"&gt;sleep &lt;/span&gt;1
&lt;span class="k"&gt;done

&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Contentful hits: &lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; &amp;lt; contentful.csv&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="k"&gt;))&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A 1,000-domain list is 100 batch calls. Throughput, retries, and a Python version of this loop are covered in &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;. For wiring the resulting rows into a CRM alongside firmographic data, see &lt;a href="https://detectzestack.com/blog/lead-enrichment-pipeline-with-tech-detection" rel="noopener noreferrer"&gt;building a lead enrichment pipeline with tech detection&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tracking Migrations Onto and Off Contentful
&lt;/h2&gt;

&lt;p&gt;A company mid-replatform is worth more than a company that settled three years ago, and the timing signal is in the change feed. &lt;code&gt;GET /changes?domain=example.com&lt;/code&gt; returns technologies added and removed between consecutive scans of a domain, with history depth gated by tier: 7 days on Basic, 30 on Pro, 90 on Ultra, 365 on Mega. &lt;code&gt;GET /history?domain=example.com&amp;amp;include_changes=true&lt;/code&gt; gives you the same movement attached to the underlying snapshots.&lt;/p&gt;

&lt;p&gt;One honest warning before you build alerting on this. Over the change history for Contentful in the corpus, there are 33 &lt;code&gt;added&lt;/code&gt; events and 35 &lt;code&gt;removed&lt;/code&gt; events — and they are not 68 migrations. &lt;a href="http://www.atlassian.com" rel="noopener noreferrer"&gt;www.atlassian.com&lt;/a&gt; alone accounts for 13 adds and 13 removes, and &lt;a href="http://www.chegg.com" rel="noopener noreferrer"&gt;www.chegg.com&lt;/a&gt; for 9 and 9. Those domains are flapping, not replatforming: their homepage sometimes renders with a &lt;code&gt;ctfassets.net&lt;/code&gt; asset and sometimes does not, depending on which A/B or personalization variant the scanner happened to receive.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A single removed event is noise. A sustained absence is a migration. Before you treat a Contentful removal as a replatform, require the technology to be missing from several consecutive full scans, and check whether the same domain has flapped before. A domain with a one-directional change and no history of alternating events — monzo.com added it once, bombas.com removed it once — is the shape you actually want to alert on.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you want this pushed to you rather than polled, &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 the monitoring side, including the alerting patterns that filter out exactly this kind of flapping.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rate Limits, Caching, and What a Contentful Sweep Costs
&lt;/h2&gt;

&lt;p&gt;Scan results are cached per domain, and a cache hit is what makes a repeat sweep cheap. In the &lt;code&gt;/check&lt;/code&gt; response above, &lt;code&gt;cached: false&lt;/code&gt; with &lt;code&gt;response_ms: 4744&lt;/code&gt; is a cold fetch of a heavy marketing page; a warm repeat of the same domain returns in single-digit milliseconds. That matters for list hygiene: re-running last quarter's 1,000-domain sweep is dramatically faster than the first pass, because most of those domains are already warm.&lt;/p&gt;

&lt;p&gt;Three cost notes worth planning around:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Batch requests are still per-URL against your quota.&lt;/strong&gt; A 10-URL &lt;code&gt;/analyze/batch&lt;/code&gt; call is convenient, not free — budget 1,000 domains as 1,000 requests, not 100.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;/lookup&lt;/code&gt; is one request regardless of result count.&lt;/strong&gt; Pulling 200 known Contentful domains on Ultra costs one request. If your goal is a seed list rather than verification of specific accounts, start here.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;/demo&lt;/code&gt; costs nothing but is capped at 20 requests per hour per IP.&lt;/strong&gt; Use it to build and debug your &lt;code&gt;jq&lt;/code&gt; filter against the exact response shape before you spend a single paid request.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Accuracy Notes and Known Limits
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Proxied assets are invisible.&lt;/strong&gt; Covered above, and it is the single largest false-negative source. A site that rewrites Contentful asset URLs onto its own domain leaves no HTTP-layer trace of the CMS at all.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A &lt;code&gt;partial&lt;/code&gt; scan cannot see Contentful.&lt;/strong&gt; The fingerprint lives in the HTML body. If &lt;code&gt;meta.scan_depth&lt;/code&gt; is &lt;code&gt;"partial"&lt;/code&gt;, only DNS and TLS signals are present and the result is "unknown." Treating it as "no" quietly deletes real prospects from your list, which is why the script above routes partials to a retry file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Only the URL you give it is scanned.&lt;/strong&gt; A company whose homepage is a hand-built hero but whose &lt;code&gt;/blog&lt;/code&gt; or &lt;code&gt;/resources&lt;/code&gt; section is Contentful-backed will come back negative on the apex domain. For Contentful specifically this is a common shape — headless CMSes are frequently adopted section by section. If your list matters, scan two or three representative paths per domain.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Contentful's own marketing site may rate-limit you.&lt;/strong&gt; A scan of contentful.com returned &lt;code&gt;"status_code": 429&lt;/code&gt; and only two technologies. A non-200 status code in &lt;code&gt;meta&lt;/code&gt; is a signal that the body you got was an error page, not the real site — check it before recording the result.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get Your API Key and Start Finding Contentful Sites
&lt;/h2&gt;

&lt;p&gt;Start with &lt;code&gt;/demo&lt;/code&gt; — no key, no signup, and it returns the exact response shape shown above, so you can build your filter before spending a request. When you are ready to scan a list, the free tier on RapidAPI is 100 requests per month with no credit card. Paid plans start at $9/month for 1,000 requests and scale to 50,000. Every tier uses the same endpoints and the same response shape, so the pipeline you write against the free tier runs unchanged when you scale it up.&lt;/p&gt;

&lt;p&gt;The same call that finds Contentful also names the rendering framework, the hosting platform, the CDN, the search vendor, the analytics tags, and every other library on the page. One quota, one response, the whole stack.&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-what-cms-website-uses" rel="noopener noreferrer"&gt;How to Detect What CMS a Website Uses&lt;/a&gt; — the traditional-CMS playbook Contentful breaks, and why&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/find-companies-using-next-js" rel="noopener noreferrer"&gt;Find Companies Using Next.js&lt;/a&gt; — the framework on 32 of the 106 Contentful domains in the corpus&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/how-to-detect-vercel" rel="noopener noreferrer"&gt;How to Detect Vercel Hosting&lt;/a&gt; — the platform most often sitting under a Contentful front end&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; — catching replatforms without alerting on flapping detections&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 detections into CRM-ready rows&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/batch-scan-1000-websites" rel="noopener noreferrer"&gt;Batch Scan 1,000 Websites for Tech Stack&lt;/a&gt; — concurrency, retries, and quota patterns&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>techstack</category>
      <category>webdev</category>
      <category>api</category>
    </item>
    <item>
      <title>Find Companies Using Akamai Bot Manager (API Guide)</title>
      <dc:creator>MikeL</dc:creator>
      <pubDate>Tue, 08 Sep 2026 14:01:12 +0000</pubDate>
      <link>https://dev.to/detectzestack/find-companies-using-akamai-bot-manager-api-guide-fn3</link>
      <guid>https://dev.to/detectzestack/find-companies-using-akamai-bot-manager-api-guide-fn3</guid>
      <description>&lt;p&gt;A list of companies running Akamai Bot Manager is one of the better-qualified prospect lists you can build from public signals. Bot Manager is not a starter product. It is a paid module bolted onto an Akamai delivery contract, and organizations buy it because scraping, credential stuffing, or inventory hoarding is actively costing them money. Every domain on that list has a security budget, an incident that justified the spend, and a team that already thinks about automated traffic.&lt;/p&gt;

&lt;p&gt;The good news for anyone building the list is that Bot Manager is loud. It writes its own session cookies on the way out, which means a single unauthenticated HTTP request reveals it. This guide covers what the module is, the exact cookie names that fingerprint it, the Akamai edge signals underneath, how to check one domain by hand, how to check hundreds through the DetectZeStack API, and what to do when the bot protection blocks the scan itself. Every response below came from a live scan run while writing this post.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Build a List of Companies Using Akamai Bot Manager
&lt;/h2&gt;

&lt;p&gt;Three groups get different value from the same list.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sales and partnerships.&lt;/strong&gt; Bot Manager sits alongside fraud tooling, identity verification, inventory protection, and API security. If you sell into any of those categories, an Akamai Bot Manager deployment tells you the buyer has already been through a procurement cycle for exactly this problem. That is a warmer starting point than firmographics, because it is evidence of behavior rather than a guess from headcount and industry code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Competitive intelligence.&lt;/strong&gt; If you sell bot mitigation, the list is your displacement target. If you sell something adjacent, it tells you which accounts are already committed to the Akamai edge, which shapes how you position an integration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Engineering and data teams.&lt;/strong&gt; If you scrape, crawl, or run automated integration tests against third-party sites, knowing in advance which targets run Bot Manager changes your architecture. The right response is usually to seek an official API or a data partnership rather than to spend engineering time on a fight you are not meant to win.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Akamai Bot Manager Is and Where It Sits in the Stack
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Bot Manager Is a Module on the Akamai Edge, Not a Separate Vendor
&lt;/h3&gt;

&lt;p&gt;Akamai’s core business is content delivery: a global edge network that terminates TLS close to the user, caches what it can, and forwards the rest to the origin. Bot Manager is a policy layer that runs on that same edge. When it is enabled on a property, every request is scored before it reaches the origin, and the edge decides whether to serve, challenge, delay, or deny it.&lt;/p&gt;

&lt;p&gt;Two consequences follow, and both matter for detection. First, Bot Manager can only exist on a domain that already goes through Akamai, so a Bot Manager hit is also an Akamai hit. Second, the module maintains per-session state to do its scoring, and that state travels in cookies. Those cookies are the fingerprint.&lt;/p&gt;

&lt;p&gt;The same architecture applies to Akamai’s other security add-ons. Akamai Web Application Protector, the WAF and DDoS module, is a separate product on the same edge with its own signals, and the two frequently ship together on the same property.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Signals That Reveal Akamai Bot Manager
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Bot Manager Cookies: ak_bmsc, bm_sz, and bm_sv
&lt;/h3&gt;

&lt;p&gt;DetectZeStack fingerprints Akamai Bot Manager on three &lt;code&gt;Set-Cookie&lt;/code&gt; names, and any one of them is enough:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Cookie&lt;/th&gt;
&lt;th&gt;What it carries&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;bm_sz&lt;/td&gt;
&lt;td&gt;The session identifier the bot scoring engine keys on&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ak_bmsc&lt;/td&gt;
&lt;td&gt;The Bot Manager session context for the visitor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;bm_sv&lt;/td&gt;
&lt;td&gt;Set by the Bot Manager verification flow&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Akamai edge responses often carry more than these three. During testing, &lt;code&gt;www.lowes.com&lt;/code&gt; and &lt;code&gt;www.delta.com&lt;/code&gt; both returned &lt;code&gt;_abck&lt;/code&gt; and &lt;code&gt;bm_so&lt;/code&gt; alongside &lt;code&gt;bm_sz&lt;/code&gt;, and several Akamai properties set &lt;code&gt;akavpau_*&lt;/code&gt; and &lt;code&gt;akaalb_*&lt;/code&gt; cookies. Those are genuine Akamai artifacts, but they are not part of the three-cookie fingerprint, so a domain that sets &lt;code&gt;_abck&lt;/code&gt; and nothing else is not reported as Akamai Bot Manager. If you are building your own detector rather than calling an API, decide deliberately whether you want the narrow, high-precision set or the wider, noisier one.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why the cookie layer is the right layer here: Bot Manager has no dedicated response header and no dedicated hostname. Akamai sells it as a policy on an existing property, so the only thing that changes on the wire when a customer switches it on is the session state the edge starts writing. Anything that reads Set-Cookie sees it on the first request, with no login, no JavaScript execution, and no headless browser.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  The Akamai Edge Signals Underneath It
&lt;/h3&gt;

&lt;p&gt;Bot Manager rides on Akamai delivery, and the delivery layer has its own signals across DNS and HTTP. DetectZeStack matches Akamai CNAME suffixes at the DNS layer — &lt;code&gt;.akamaiedge.net&lt;/code&gt;, &lt;code&gt;.akamai.net&lt;/code&gt;, &lt;code&gt;.edgekey.net&lt;/code&gt;, &lt;code&gt;.edgesuite.net&lt;/code&gt;, &lt;code&gt;.akamaized.net&lt;/code&gt;, and &lt;code&gt;.akamaihd.net&lt;/code&gt; — and Akamai-specific response headers at the HTTP layer, principally &lt;code&gt;x-akamai-transformed&lt;/code&gt;. Four of the retail and travel domains checked for this post resolve through the same suffix:&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;d &lt;span class="k"&gt;in &lt;/span&gt;www.macys.com www.lowes.com www.delta.com www.homedepot.com&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
&lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'%-22s %s\n'&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$d&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;dig +short &lt;span class="nv"&gt;$d&lt;/span&gt; CNAME&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;done
&lt;/span&gt;www.macys.com          www.macys.com.edgekey.net.
www.lowes.com          wwwlowes.com.edgekey.net.
www.delta.com          www.delta.com.edgekey.net.
www.homedepot.com      www.homedepot.com.edgekey.net.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Bot Manager fingerprint also carries an implication: Akamai Bot Manager implies Akamai, so &lt;strong&gt;Akamai&lt;/strong&gt; appears under &lt;strong&gt;CDN&lt;/strong&gt; in the response even on a scan where no separate Akamai pattern matched. When both layers fire, the merge deduplicates by technology name and the HTTP entry wins, which is why &lt;code&gt;Akamai&lt;/code&gt; usually comes back with &lt;code&gt;source: "http"&lt;/code&gt; rather than &lt;code&gt;"dns"&lt;/code&gt;. One name that is &lt;em&gt;not&lt;/em&gt; a fingerprint is worth calling out: &lt;code&gt;Server: AkamaiGHost&lt;/code&gt; appears on many Akamai error and challenge responses, but it is not in the pattern database, so do not expect it to produce a detection on its own. The full DNS and header method for the delivery layer is covered in &lt;a href="https://detectzestack.com/blog/find-companies-using-akamai" rel="noopener noreferrer"&gt;find companies using Akamai&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check One Domain by Hand With curl
&lt;/h2&gt;

&lt;p&gt;For a single domain, one request answers the question. Use &lt;code&gt;-D -&lt;/code&gt; to dump headers and &lt;code&gt;-o /dev/null&lt;/code&gt; to discard the body, then filter for the three cookie names:&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;-D&lt;/span&gt; - &lt;span class="nt"&gt;-o&lt;/span&gt; /dev/null &lt;span class="s2"&gt;"https://www.delta.com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
| &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-oiE&lt;/span&gt; &lt;span class="s2"&gt;"set-cookie: (ak_bmsc|bm_sz|bm_sv)"&lt;/span&gt; 
set-cookie: bm_sz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Any output at all is a positive. To see the surrounding Akamai context in the same call, widen the filter to the delivery headers:&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;-D&lt;/span&gt; - &lt;span class="nt"&gt;-o&lt;/span&gt; /dev/null &lt;span class="s2"&gt;"https://www.lowes.com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
| &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-iE&lt;/span&gt; &lt;span class="s2"&gt;"^(x-akamai-transformed|server):"&lt;/span&gt;
x-akamai-transformed: 9 367 0 &lt;span class="nv"&gt;pmb&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;mRUM,2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This works, and it stops working the moment your list has more than a couple of dozen rows. You are managing timeouts, redirect chains, sites that reject a bare &lt;code&gt;HEAD&lt;/code&gt;, and the parsing of everything else on the page that decides whether the lead is worth a call. That last part is the real limitation: &lt;code&gt;grep&lt;/code&gt; gives you one bit, and prospecting needs the whole stack.&lt;/p&gt;

&lt;h2&gt;
  
  
  Detect Akamai Bot Manager With the DetectZeStack API
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The /demo Endpoint, No API Key Required
&lt;/h3&gt;

&lt;p&gt;The public &lt;code&gt;/demo&lt;/code&gt; endpoint takes a &lt;code&gt;url&lt;/code&gt; query parameter, needs no API key, is limited to 20 requests per hour per IP, and returns exactly the same JSON shape as the authenticated endpoint. Here is the live response for &lt;code&gt;www.lowes.com&lt;/code&gt;, trimmed to the entries that matter for this post:&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=www.lowes.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://www.lowes.com"&lt;/span&gt;,
&lt;span class="s2"&gt;"domain"&lt;/span&gt;: &lt;span class="s2"&gt;"www.lowes.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;"Akamai"&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;"Akamai is global content delivery network (CDN) services provider for media and software delivery, and cloud security solutions."&lt;/span&gt;,
&lt;span class="s2"&gt;"website"&lt;/span&gt;: &lt;span class="s2"&gt;"https://akamai.com"&lt;/span&gt;,
&lt;span class="s2"&gt;"icon"&lt;/span&gt;: &lt;span class="s2"&gt;"Akamai.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="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;"Akamai Bot Manager"&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;"Security"&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;"Akamai Bot Manager detect bots using device fingerprinting bot signatures."&lt;/span&gt;,
&lt;span class="s2"&gt;"website"&lt;/span&gt;: &lt;span class="s2"&gt;"https://www.akamai.com/us/en/products/security/bot-manager.jsp"&lt;/span&gt;,
&lt;span class="s2"&gt;"icon"&lt;/span&gt;: &lt;span class="s2"&gt;"Akamai.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="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;"Adobe Experience Manager"&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;"CMS"&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;"name"&lt;/span&gt;: &lt;span class="s2"&gt;"Sectigo"&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;"SSL/TLS certificate authority"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;,
&lt;span class="s2"&gt;"confidence"&lt;/span&gt;: 70,
&lt;span class="s2"&gt;"source"&lt;/span&gt;: &lt;span class="s2"&gt;"tls"&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;"Akamai"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;,
&lt;span class="s2"&gt;"CMS"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Adobe Experience Manager"&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="s2"&gt;"SSL/TLS certificate authority"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Sectigo"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;,
&lt;span class="s2"&gt;"Security"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"HSTS"&lt;/span&gt;, &lt;span class="s2"&gt;"Blue Triangle"&lt;/span&gt;, &lt;span class="s2"&gt;"Akamai Bot Manager"&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;: 13,
&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;: 2900
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Read the &lt;code&gt;categories&lt;/code&gt; object rather than scanning the array: &lt;code&gt;categories.Security&lt;/code&gt; is where Bot Manager lands, and it is a list, so test for membership rather than equality. The full scan returned 13 technologies including Adobe Experience Manager as the CMS and React on the front end — the context that turns a detection into a qualified lead. The &lt;code&gt;description&lt;/code&gt;, &lt;code&gt;website&lt;/code&gt;, and &lt;code&gt;icon&lt;/code&gt; fields are trimmed on three entries above to keep the listing short; the API always returns them when the fingerprint database has them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Single Domain: GET /analyze With Your API Key
&lt;/h3&gt;

&lt;p&gt;For production use, call &lt;code&gt;/analyze&lt;/code&gt; with your key. The response shape is identical to &lt;code&gt;/demo&lt;/code&gt;, so the same &lt;code&gt;jq&lt;/code&gt; filters work on both. This pulls out just the fields a prospecting pipeline needs:&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=www.delta.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, security: .categories.Security, cdn: .categories.CDN,
tech_count: .meta.tech_count, depth: .meta.scan_depth, cached, response_ms}'&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;"www.delta.com"&lt;/span&gt;,
&lt;span class="s2"&gt;"security"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Akamai Bot Manager"&lt;/span&gt;, &lt;span class="s2"&gt;"HSTS"&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;"Amazon S3"&lt;/span&gt;, &lt;span class="s2"&gt;"Akamai"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;,
&lt;span class="s2"&gt;"tech_count"&lt;/span&gt;: 7,
&lt;span class="s2"&gt;"depth"&lt;/span&gt;: &lt;span class="s2"&gt;"full"&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;: 388
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Delta is a good illustration of why the CDN field is a list. Amazon S3 appears next to Akamai because assets load from an S3 bucket while the HTML is served through the Akamai edge, and Amazon Web Services shows up separately under PaaS in the full response. A stack is rarely one vendor.&lt;/p&gt;

&lt;p&gt;Two fields to read on every result. &lt;code&gt;meta.scan_depth&lt;/code&gt; is &lt;code&gt;"full"&lt;/code&gt; when headers and body were fetched and &lt;code&gt;"partial"&lt;/code&gt; when only DNS resolved; a partial scan never saw a &lt;code&gt;Set-Cookie&lt;/code&gt; header, so the absence of Akamai Bot Manager on a partial scan means unknown, not no. &lt;code&gt;cached&lt;/code&gt; tells you whether the result came from DetectZeStack’s cache, and &lt;code&gt;response_ms&lt;/code&gt; is the wall-clock time for the call.&lt;/p&gt;

&lt;h3&gt;
  
  
  Yes or No: GET /check?url=...&amp;amp;tech=Akamai%20Bot%20Manager
&lt;/h3&gt;

&lt;p&gt;When a boolean is all you need, &lt;code&gt;/check&lt;/code&gt; returns a much smaller object. The technology name is matched case-insensitively and must be URL-encoded because it contains spaces:&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=www.delta.com&amp;amp;tech=Akamai%20Bot%20Manager"&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;"www.delta.com"&lt;/span&gt;,
&lt;span class="s2"&gt;"technology"&lt;/span&gt;: &lt;span class="s2"&gt;"Akamai Bot Manager"&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;"Security"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;,
&lt;span class="s2"&gt;"response_ms"&lt;/span&gt;: 0,
&lt;span class="s2"&gt;"cached"&lt;/span&gt;: &lt;span class="nb"&gt;true&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;technology&lt;/code&gt; field echoes the canonical name from the database on a match, so &lt;code&gt;tech=akamai%20bot%20manager&lt;/code&gt; in lowercase comes back as &lt;code&gt;"Akamai Bot Manager"&lt;/code&gt;. A miss returns &lt;code&gt;"detected": false&lt;/code&gt; with confidence 0 and an empty categories array. The &lt;code&gt;response_ms: 0&lt;/code&gt; above is a cache hit from the &lt;code&gt;/analyze&lt;/code&gt; call a moment earlier.&lt;/p&gt;

&lt;h2&gt;
  
  
  When the Bot Manager Blocks the Scan: Reading a 403 Result
&lt;/h2&gt;

&lt;p&gt;Bot Manager sometimes decides a scanner is a bot, which is the entire point of the product. A challenged request comes back as HTTP 403 with a &lt;code&gt;Server: AkamaiGHost&lt;/code&gt; header and a challenge page instead of the real site. That is not a failed scan — the block is itself a strong signal. Here is what &lt;code&gt;www.macys.com&lt;/code&gt; returned:&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=www.macys.com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
| jq &lt;span class="s1"&gt;'{categories, meta}'&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;"Akamai"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;,
&lt;span class="s2"&gt;"SSL/TLS certificate authority"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Sectigo"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;,
&lt;span class="s2"&gt;"Security"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Akamai Bot Manager"&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;: 403,
&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="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The challenge response still carried the Bot Manager cookies, so both Akamai entries were reported. What is missing is everything else: no CMS, no framework, no analytics, because no application HTML was ever served. Handle this pattern explicitly in a prospecting pipeline. A &lt;code&gt;status_code&lt;/code&gt; of 403 with a &lt;code&gt;tech_count&lt;/code&gt; in the low single digits and Akamai Bot Manager present is a high-conviction lead with a thin profile, not a dead row. Sort those into their own bucket and enrich them from a different source rather than discarding them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Screen a Prospect List at Scale With POST /analyze/batch
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;POST /analyze/batch&lt;/code&gt; accepts up to 10 URLs per request and scans them concurrently. Each item in &lt;code&gt;results&lt;/code&gt; carries either a &lt;code&gt;result&lt;/code&gt; object in the single-domain shape or an &lt;code&gt;error&lt;/code&gt; string. The script below reads &lt;code&gt;domains.txt&lt;/code&gt;, one domain per line, sends batches of 10, and writes one CSV row per domain: whether Bot Manager was found, the full security list, the CDN list, the HTTP status, and the technology count. Partial scans go to a retry file instead of being recorded as negatives, and blocked domains go to their own file:&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-akamai-bot-manager.sh - build a Bot Manager prospect list&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,bot_manager,security,cdn,status,tech_count"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; akamai_bm.csv
: &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; akamai_bm_retry.txt
: &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; akamai_bm_blocked.txt

&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;
&lt;span class="nv"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;=&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;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# One row per fully scanned domain&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$resp&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 and .result.meta.scan_depth == "full")
| .result as $r
| [
$r.domain,
((($r.categories.Security // []) | index("Akamai Bot Manager")) != null),
(($r.categories.Security // []) | join(";")),
(($r.categories.CDN // []) | join(";")),
($r.meta.status_code | tostring),
($r.meta.tech_count | tostring)
] | @csv'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; akamai_bm.csv

&lt;span class="c"&gt;# Challenged: Bot Manager present but the page never rendered&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$resp&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.meta.status_code == 403)
| .result.domain'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; akamai_bm_blocked.txt

&lt;span class="c"&gt;# Unknown: DNS only, so no Set-Cookie header was ever seen&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$resp&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 and .result.meta.scan_depth == "partial")
| .result.domain'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; akamai_bm_retry.txt
&lt;span class="k"&gt;done

&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"scanned:     &lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; &amp;lt; akamai_bm.csv&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="k"&gt;))&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"bot manager: &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="nt"&gt;-F&lt;/span&gt;, &lt;span class="s1"&gt;'NR&amp;gt;1 &amp;amp;&amp;amp; $2=="true"'&lt;/span&gt; akamai_bm.csv | &lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"challenged:  &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; &amp;lt; akamai_bm_blocked.txt&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"retries:     &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; &amp;lt; akamai_bm_retry.txt&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A 1,000-domain list is 100 batch calls. Throughput, retry policy, and a production Python version of this loop are covered in &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;
  
  
  Reverse Lookup: Domains Already Known to Run Bot Manager
&lt;/h2&gt;

&lt;p&gt;If you do not have a domain list to start from, &lt;code&gt;GET /lookup&lt;/code&gt; works the other way around. It searches the domains DetectZeStack has already scanned and returns the ones where a given technology was recorded:&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/lookup?tech=Akamai%20Bot%20Manager&amp;amp;limit=5"&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;"technology"&lt;/span&gt;: &lt;span class="s2"&gt;"Akamai Bot Manager"&lt;/span&gt;,
&lt;span class="s2"&gt;"total"&lt;/span&gt;: 173,
&lt;span class="s2"&gt;"results"&lt;/span&gt;: &lt;span class="o"&gt;[&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;"www.ajio.com"&lt;/span&gt;,
&lt;span class="s2"&gt;"category"&lt;/span&gt;: &lt;span class="s2"&gt;"Security"&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;"first_seen"&lt;/span&gt;: &lt;span class="s2"&gt;"2026-05-15T10:03:40Z"&lt;/span&gt;,
&lt;span class="s2"&gt;"last_seen"&lt;/span&gt;: &lt;span class="s2"&gt;"2026-09-07T18:01:52Z"&lt;/span&gt;
&lt;span class="o"&gt;}&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;"www.ing.com.au"&lt;/span&gt;,
&lt;span class="s2"&gt;"category"&lt;/span&gt;: &lt;span class="s2"&gt;"Security"&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;"first_seen"&lt;/span&gt;: &lt;span class="s2"&gt;"2026-05-11T03:28:59Z"&lt;/span&gt;,
&lt;span class="s2"&gt;"last_seen"&lt;/span&gt;: &lt;span class="s2"&gt;"2026-09-07T18:01:45Z"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;]&lt;/span&gt;,
&lt;span class="s2"&gt;"limit"&lt;/span&gt;: 2,
&lt;span class="s2"&gt;"offset"&lt;/span&gt;: 0,
&lt;span class="s2"&gt;"response_ms"&lt;/span&gt;: 11
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two caveats. &lt;code&gt;total&lt;/code&gt; counts only domains that have been scanned at least once, so it is a floor, not a census of the internet — 173 was the count at the time of writing and it grows as the corpus does. And the number of rows you get back is capped by tier: 2 on free, 50 on the $9 plan, 200 on the $29 plan, and 800 on the $79 plan. The response above was taken on a free key, which is why &lt;code&gt;limit&lt;/code&gt; came back as 2 rather than the requested 5. The &lt;code&gt;first_seen&lt;/code&gt; and &lt;code&gt;last_seen&lt;/code&gt; timestamps are the useful part for anyone tracking adoption over time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comparing Two Sites’ Edge Security Posture With POST /compare
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;POST /compare&lt;/code&gt; takes 2 to 10 URLs and returns each domain’s full technology list plus a &lt;code&gt;shared&lt;/code&gt; array of what they all have in common and a &lt;code&gt;unique&lt;/code&gt; array per domain. It is the fastest way to put a prospect next to a competitor. Two US airlines, scanned live:&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": ["www.delta.com", "www.jetblue.com"]}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
| jq &lt;span class="s1"&gt;'{shared, total_ms,
domains: [.domains[] | {domain, 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;"HSTS"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;,
&lt;span class="s2"&gt;"total_ms"&lt;/span&gt;: 2178,
&lt;span class="s2"&gt;"domains"&lt;/span&gt;: &lt;span class="o"&gt;[&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;"www.delta.com"&lt;/span&gt;,
&lt;span class="s2"&gt;"unique"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Bootstrap"&lt;/span&gt;, &lt;span class="s2"&gt;"DigiCert"&lt;/span&gt;, &lt;span class="s2"&gt;"Akamai"&lt;/span&gt;, &lt;span class="s2"&gt;"Akamai Bot Manager"&lt;/span&gt;,
&lt;span class="s2"&gt;"Amazon S3"&lt;/span&gt;, &lt;span class="s2"&gt;"Amazon Web Services"&lt;/span&gt;&lt;span class="o"&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;"domain"&lt;/span&gt;: &lt;span class="s2"&gt;"www.jetblue.com"&lt;/span&gt;,
&lt;span class="s2"&gt;"unique"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Varnish"&lt;/span&gt;, &lt;span class="s2"&gt;"Fastly"&lt;/span&gt;, &lt;span class="s2"&gt;"Let's Encrypt"&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="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;Two airlines, two entirely different edges. Delta is on Akamai with Bot Manager active; JetBlue is on Fastly with no bot-management module visible from the outside. If you sell bot mitigation, that contrast is the opening line of an email to one of them. The Fastly signals in that second list are broken down in &lt;a href="https://detectzestack.com/blog/find-companies-using-fastly" rel="noopener noreferrer"&gt;find companies using Fastly&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pricing, Rate Limits, and Getting an API Key
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;/demo&lt;/code&gt; endpoint is the fastest way to confirm the response shape against a domain you already know: no signup, 20 requests per hour per IP, full JSON. For lists, audits, or anything you want to run again next quarter, the free RapidAPI plan includes 100 requests per month with no credit card. Paid plans start at $9 per month for 1,000 requests, and every plan includes header, cookie, DNS, and TLS detection on every scan, so Akamai Bot Manager, the Akamai edge underneath it, and the rest of the stack all come back in the same call.&lt;/p&gt;

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

&lt;p&gt;Akamai Bot Manager is detected from three &lt;code&gt;Set-Cookie&lt;/code&gt; names — &lt;code&gt;ak_bmsc&lt;/code&gt;, &lt;code&gt;bm_sz&lt;/code&gt;, and &lt;code&gt;bm_sv&lt;/code&gt; — written by the Akamai edge when the module is active on a property. It lands under the &lt;strong&gt;Security&lt;/strong&gt; category at confidence 100 and pulls &lt;strong&gt;Akamai&lt;/strong&gt; into &lt;strong&gt;CDN&lt;/strong&gt; by implication, and the delivery layer underneath usually confirms it with an &lt;code&gt;edgekey.net&lt;/code&gt; CNAME or an &lt;code&gt;x-akamai-transformed&lt;/code&gt; header. For one domain, a single &lt;code&gt;curl&lt;/code&gt; with a &lt;code&gt;grep&lt;/code&gt; on the cookie names answers the question. For a prospect list, &lt;code&gt;/analyze/batch&lt;/code&gt; returns the whole stack in structured JSON at 10 domains per call, &lt;code&gt;/lookup&lt;/code&gt; works backwards from the technology to the domains, and &lt;code&gt;/compare&lt;/code&gt; puts two stacks side by side. The one rule worth writing into the pipeline: a 403 with Bot Manager present is your best lead, not a failed row.&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-akamai" rel="noopener noreferrer"&gt;Find Companies Using Akamai (Technographic API Guide)&lt;/a&gt; — The delivery layer underneath Bot Manager: the edgekey.net CNAME family and the Akamai response headers&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/how-to-detect-cloudflare-bot-management" rel="noopener noreferrer"&gt;How to Detect Cloudflare Bot Management on Any Site&lt;/a&gt; — The competing module on the competing edge, and the CF-Ray and nameserver signals that reveal it&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 full multi-layer method across Akamai, Cloudflare, CloudFront, Fastly, and more&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/how-to-detect-recaptcha" rel="noopener noreferrer"&gt;How to Detect reCAPTCHA on Any Website&lt;/a&gt; — The other half of the bot-defense picture, detected from the page body rather than the edge&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/dns-tls-detection-vs-browser-extensions" rel="noopener noreferrer"&gt;DNS and TLS Detection vs Browser Extensions&lt;/a&gt; — What a server-side scan sees that a browser extension does not, and vice versa&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>techstack</category>
      <category>webdev</category>
      <category>api</category>
    </item>
    <item>
      <title>Detect Drupal Website: Manual Checks + API Guide (2026)</title>
      <dc:creator>MikeL</dc:creator>
      <pubDate>Mon, 31 Aug 2026 14:00:36 +0000</pubDate>
      <link>https://dev.to/detectzestack/detect-drupal-website-manual-checks-api-guide-2026-5f5e</link>
      <guid>https://dev.to/detectzestack/detect-drupal-website-manual-checks-api-guide-2026-5f5e</guid>
      <description>&lt;p&gt;Drupal is the CMS of governments, universities, media companies, and large enterprises — the segment of the web where WordPress stops and structured content, editorial workflow, and access control begin. That makes "does this site run Drupal?" a question with real money and real risk attached: Drupal shops sell into it, security teams patch it on a deadline, and migration consultants quote against it. The good news is that a default Drupal installation announces itself in several places at once, and even a hardened one usually leaks a signal or two.&lt;/p&gt;

&lt;p&gt;This guide covers both approaches: the manual checks you can run against a single site with &lt;code&gt;curl&lt;/code&gt; and a view-source, and the DetectZeStack API for confirming Drupal programmatically or sweeping a thousand-domain prospect list. Every code example is copy-pasteable and uses fields that actually exist in the API response.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Detect Drupal? Sales, Security, and Migration Use Cases
&lt;/h2&gt;

&lt;p&gt;Three audiences ask this question daily, for different reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sales and agency teams.&lt;/strong&gt; If you sell Drupal development, hosting (Acquia-style managed platforms), module work, or support retainers, your addressable market is precisely "organizations currently running Drupal." A verified technographic list beats guessing from industry alone, and because Drupal skews toward government, education, and enterprise, a Drupal hit also tells you something about deal size and procurement style.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security and asset-inventory teams.&lt;/strong&gt; Drupal has a history of severe, wormable vulnerabilities — "Drupalgeddon" (SA-CORE-2014-005) and "Drupalgeddon 2" (SA-CORE-2018-002) were both exploited at internet scale within days of disclosure. When the next core advisory drops, the first question is "which of our domains, subsidiaries, and vendors run Drupal?" You want that inventory before the advisory, not after.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Migration and replatforming consultants.&lt;/strong&gt; Drupal 7 reached end of life in January 2025, and a long tail of sites still runs it. Identifying Drupal sites — and ideally the major version — is how you find replatforming prospects and scope the work.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All three need the same answer in code: &lt;em&gt;is this site Drupal, and if so, which major version?&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Manual Ways to Detect a Drupal Website
&lt;/h2&gt;

&lt;p&gt;Drupal emits more fingerprints than most CMSes. Here they are in descending order of reliability.&lt;/p&gt;

&lt;h3&gt;
  
  
  Check the X-Generator Header and Meta Generator Tag
&lt;/h3&gt;

&lt;p&gt;Modern Drupal (8 and later) sends an &lt;code&gt;X-Generator&lt;/code&gt; response header on every page by default. One &lt;code&gt;curl -I&lt;/code&gt; answers the question:&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;-sI&lt;/span&gt; https://www.example.gov | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-iE&lt;/span&gt; &lt;span class="s2"&gt;"x-generator|x-drupal"&lt;/span&gt;
x-generator: Drupal 10 &lt;span class="o"&gt;(&lt;/span&gt;https://www.drupal.org&lt;span class="o"&gt;)&lt;/span&gt;
x-drupal-cache: HIT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two signals in one shot:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;X-Generator: Drupal 10 (https://www.drupal.org)&lt;/code&gt; — the clearest Drupal tell on the web. It names the CMS, states the major version, and links to drupal.org. If you see this, you are done.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;X-Drupal-Cache&lt;/code&gt; (and on newer sites &lt;code&gt;X-Drupal-Dynamic-Cache&lt;/code&gt;) — Drupal's internal page-cache headers, reporting &lt;code&gt;HIT&lt;/code&gt; or &lt;code&gt;MISS&lt;/code&gt;. These survive on many sites that strip the generator header, because ops teams rely on them for cache debugging.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is also a stranger, older tell: Drupal's page cache has historically sent &lt;code&gt;Expires: Sun, 19 Nov 1978 05:00:00 GMT&lt;/code&gt; — a deliberately ancient date (Drupal founder Dries Buytaert's birthday) used to mark content as always-stale to intermediaries. Seeing 19 November 1978 in an &lt;code&gt;Expires&lt;/code&gt; header is a strong Drupal hint all by itself.&lt;/p&gt;

&lt;p&gt;The same generator string usually appears in the HTML head as a meta tag, which survives some proxy configurations that strip custom headers:&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://www.example.gov | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-io&lt;/span&gt; &lt;span class="s1"&gt;'&amp;lt;meta name="generator"[^&amp;gt;]*&amp;gt;'&lt;/span&gt;
&amp;lt;meta &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"generator"&lt;/span&gt; &lt;span class="nv"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Drupal 10 (https://www.drupal.org)"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Look for /sites/default/ Asset Paths and Drupal Settings JSON
&lt;/h3&gt;

&lt;p&gt;When headers and meta tags have been sanitized, the page body still betrays Drupal's very distinctive file layout. Drupal serves uploaded files, theme assets, and aggregated CSS/JS from &lt;code&gt;/sites/default/files/&lt;/code&gt; (or &lt;code&gt;/sites/all/&lt;/code&gt; on older multisite installs), and no other mainstream CMS uses those paths:&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://www.example.gov | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="s1"&gt;'/sites/\(default\|all\)/[^"]*'&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-5&lt;/span&gt;
/sites/default/files/css/css_AbC123.css
/sites/default/files/js/js_XyZ789.js
/sites/default/files/logo.svg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Drupal 8+ also injects its front-end configuration as a JSON blob with an unmistakable attribute:&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="err"&gt;&amp;lt;script&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;type=&lt;/span&gt;&lt;span class="s2"&gt;"application/json"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;data-drupal-selector=&lt;/span&gt;&lt;span class="s2"&gt;"drupal-settings-json"&lt;/span&gt;&lt;span class="err"&gt;&amp;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;"path"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="nl"&gt;"baseUrl"&lt;/span&gt;&lt;span class="p"&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;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"currentPath"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"node&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="s2"&gt;1"&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="nl"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="nl"&gt;"uid"&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="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Anything containing &lt;code&gt;data-drupal-selector&lt;/code&gt;, a &lt;code&gt;drupalSettings&lt;/code&gt; JSON payload (or the legacy &lt;code&gt;Drupal.settings&lt;/code&gt; object on Drupal 7), or a &lt;code&gt;drupal.js&lt;/code&gt; script reference is a body-level confirmation. Sites running Drupal's JavaScript also expose a global &lt;code&gt;Drupal&lt;/code&gt; object you can check in the browser console.&lt;/p&gt;

&lt;h3&gt;
  
  
  Probe Known Drupal Paths (CHANGELOG.txt, /user/login, /core/)
&lt;/h3&gt;

&lt;p&gt;A third manual technique is to request paths that exist on Drupal and almost nothing else:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/user/login&lt;/code&gt; — Drupal's login route. A themed login form at exactly this path (rather than &lt;code&gt;/wp-login.php&lt;/code&gt; or &lt;code&gt;/admin&lt;/code&gt;) is characteristic of Drupal.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/core/CHANGELOG.txt&lt;/code&gt; and &lt;code&gt;/core/&lt;/code&gt; assets — Drupal 8+ keeps core files under &lt;code&gt;/core/&lt;/code&gt;. On poorly hardened sites, &lt;code&gt;CHANGELOG.txt&lt;/code&gt; is world-readable and states the exact version. On Drupal 7 the file lived at &lt;code&gt;/CHANGELOG.txt&lt;/code&gt; in the web root.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/core/misc/drupal.js&lt;/code&gt; — a core JavaScript file at a predictable path; an HTTP 200 here is a strong signal.
&lt;/li&gt;
&lt;/ul&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;-o&lt;/span&gt; /dev/null &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="s2"&gt;"%{http_code}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; https://www.example.gov/core/misc/drupal.js
200
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A caution: well-run Drupal sites block the txt files precisely because they leak the patch level, and probing paths generates 404 noise in the target's logs. Use path probes as a tiebreaker, not an opener — and only against sites you have a legitimate reason to assess.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Manual Checks Fail on Hardened or Cached Drupal Sites
&lt;/h3&gt;

&lt;p&gt;Each signal above can be individually suppressed. Security-conscious Drupal shops remove the generator header and meta tag (a one-line change or a common hardening module), a CDN or Varnish layer in front of the origin can strip &lt;code&gt;X-Drupal-Cache&lt;/code&gt; and rewrite &lt;code&gt;Expires&lt;/code&gt;, and an aggressive edge cache can serve pages where aggregation has rewritten asset URLs. A single &lt;code&gt;curl&lt;/code&gt; against the home page then comes back clean even though the site is Drupal to the core.&lt;/p&gt;

&lt;p&gt;Reliable detection therefore means checking &lt;em&gt;all&lt;/em&gt; the signals — headers, meta tags, HTML body patterns, script paths, and the JavaScript layer — and combining them, which is exactly what you do not want to hand-script across a list of 1,000 domains. That is the job of an API.&lt;/p&gt;

&lt;h2&gt;
  
  
  Detect Drupal Instantly with the DetectZeStack API
&lt;/h2&gt;

&lt;p&gt;DetectZeStack runs the full fingerprint set in one call: the &lt;code&gt;X-Generator&lt;/code&gt; and &lt;code&gt;X-Drupal-Cache&lt;/code&gt; headers, the 1978 &lt;code&gt;Expires&lt;/code&gt; tell, the meta generator tag, &lt;code&gt;/sites/default/&lt;/code&gt; and &lt;code&gt;/sites/all/&lt;/code&gt; asset paths, &lt;code&gt;drupal.js&lt;/code&gt; script references, and the &lt;code&gt;Drupal&lt;/code&gt; JavaScript global. Any of them firing returns Drupal in the &lt;code&gt;CMS&lt;/code&gt; category — and because Drupal implies PHP, a PHP entry usually rides along in the same response.&lt;/p&gt;

&lt;h3&gt;
  
  
  curl Example with GET /analyze and the JSON Response
&lt;/h3&gt;

&lt;p&gt;You can smoke-test the response shape right now against the public &lt;code&gt;/demo&lt;/code&gt; endpoint, which runs the same detector pipeline with no API key (IP rate-limited):&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://www.drupal.org"&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;The response is a single JSON object. Trimmed to the relevant entries, a Drupal hit 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;"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://www.drupal.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;"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;"drupal.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;"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;"Drupal"&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="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;"Drupal is a free and open-source web content management framework."&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.drupal.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;"Drupal.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;"10"&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:drupal:drupal:*:*:*:*:*:*:*:*"&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;"PHP"&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;"Programming languages"&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;"PHP is a general-purpose scripting language."&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.php.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;"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;"PHP.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;"cpe:2.3:a:php:php:*:*:*:*:*:*:*:*"&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;"CMS"&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;"Drupal"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Programming languages"&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;"PHP"&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;12&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;1764&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 fields worth understanding before you build on them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;version&lt;/code&gt;&lt;/strong&gt; — populated from the generator signal, so it is typically the major version only (&lt;code&gt;"10"&lt;/code&gt;). Drupal deliberately omits the minor and patch level from its generator string, and a site that strips the generator entirely returns an empty string here. Empty means "version not externally visible," not "not Drupal."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;cpe&lt;/code&gt;&lt;/strong&gt; — the CPE identifier security teams map to vulnerability databases. See &lt;a href="https://detectzestack.com/blog/cpe-identifiers-explained-for-security-teams" rel="noopener noreferrer"&gt;CPE identifiers explained&lt;/a&gt; for turning this into CVE matches.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;source&lt;/code&gt;&lt;/strong&gt; — where the signal came from; &lt;code&gt;"http"&lt;/code&gt; for Drupal, since the fingerprints live in the response headers and body.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;response_ms&lt;/code&gt; and &lt;code&gt;cached&lt;/code&gt;&lt;/strong&gt; — top-level fields (not inside &lt;code&gt;meta&lt;/code&gt;) reporting scan duration and cache status. The &lt;code&gt;meta&lt;/code&gt; object carries only &lt;code&gt;status_code&lt;/code&gt;, &lt;code&gt;tech_count&lt;/code&gt;, and &lt;code&gt;scan_depth&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For production, sign up on RapidAPI and call &lt;code&gt;/analyze&lt;/code&gt; with your key — same shape, no demo rate limit:&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/analyze?url=https://www.drupal.org"&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;'.technologies[] | select(.name == "Drupal")'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If Drupal is present, that pipe prints exactly the matching object; if not, &lt;code&gt;jq&lt;/code&gt; prints nothing and exits cleanly — easy to wire into a shell filter. When Drupal is the only technology you care about, the &lt;code&gt;/check&lt;/code&gt; endpoint answers the yes/no question directly with a &lt;code&gt;?tech=&lt;/code&gt; parameter (case-insensitive), so you skip the client-side filtering entirely.&lt;/p&gt;

&lt;h3&gt;
  
  
  Checking Drupal Across 1,000 Domains with POST /analyze/batch
&lt;/h3&gt;

&lt;p&gt;For lists, &lt;code&gt;POST /analyze/batch&lt;/code&gt; scans up to 10 URLs concurrently per call. A 1,000-domain sweep is therefore 100 batch calls — each URL still counts against your quota, but the concurrency and error handling are the API's problem instead of yours:&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="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: &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;
&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": ["www.drupal.org", "www.example.com", "example.gov"]}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response wraps one full &lt;code&gt;/analyze&lt;/code&gt; result per URL, plus per-item errors so one dead domain does not sink the batch:&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;"www.drupal.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 /analyze response..."&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;"bad-domain.example"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"failed to fetch URL"&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;4210&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;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;"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;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;p&gt;Chunking a file of domains into batches of 10 and extracting the Drupal hits is a few lines of shell:&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="nb"&gt;split&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; 10 domains.txt chunk_
&lt;span class="k"&gt;for &lt;/span&gt;f &lt;span class="k"&gt;in &lt;/span&gt;chunk_&lt;span class="k"&gt;*&lt;/span&gt;&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;jq &lt;span class="nt"&gt;-R&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s1"&gt;'split("\n") | map(select(length &amp;gt; 0)) | {urls: .}'&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$f&lt;/span&gt;&lt;span class="s2"&gt;"&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://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: &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;
&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; &lt;span class="se"&gt;\&lt;/span&gt;
| jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.results[] | select(.result.technologies[]?.name == "Drupal") | .url'&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That prints every Drupal domain in the list, one per line — a prospect list or a patch-day inventory, depending on which hat you are wearing. For throughput, quota math, and connection-reuse patterns at larger scale, see &lt;a href="https://detectzestack.com/blog/batch-scan-1000-websites" rel="noopener noreferrer"&gt;Batch Scan 1,000 Websites for Tech Stack&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Drupal Detection Signals Explained (Headers, HTML, DNS)
&lt;/h2&gt;

&lt;p&gt;For reference, here is the full signal set the detector evaluates, with rough reliability:&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;Where&lt;/th&gt;
&lt;th&gt;Reliability&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;X-Generator: Drupal 10 (...)&lt;/td&gt;
&lt;td&gt;HTTP header&lt;/td&gt;
&lt;td&gt;Definitive; includes major version&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;X-Drupal-Cache / X-Drupal-Dynamic-Cache&lt;/td&gt;
&lt;td&gt;HTTP header&lt;/td&gt;
&lt;td&gt;Definitive when present&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Expires: 19 Nov 1978&lt;/td&gt;
&lt;td&gt;HTTP header&lt;/td&gt;
&lt;td&gt;Strong; Drupal's trademark stale date&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;HTML head&lt;/td&gt;
&lt;td&gt;Definitive; includes major version&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;/sites/default/ or /sites/all/ asset paths&lt;/td&gt;
&lt;td&gt;HTML body&lt;/td&gt;
&lt;td&gt;Strong; unique file layout&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;drupal.js script reference&lt;/td&gt;
&lt;td&gt;HTML body&lt;/td&gt;
&lt;td&gt;Strong&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Drupal JavaScript global&lt;/td&gt;
&lt;td&gt;JS runtime&lt;/td&gt;
&lt;td&gt;Strong&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Note what is &lt;em&gt;not&lt;/em&gt; on the list: DNS. Drupal is application code, so &lt;a href="https://detectzestack.com/blog/dns-based-technology-detection" rel="noopener noreferrer"&gt;DNS-layer detection&lt;/a&gt; cannot name it directly — but DNS still adds context. Managed Drupal platforms sit behind recognizable CDN and hosting infrastructure, so the same &lt;code&gt;/analyze&lt;/code&gt; call that confirms Drupal from HTTP signals also reports the CDN and hosting layer from DNS, giving you "Drupal on a managed platform" versus "Drupal on a bare VPS" in one response. That distinction matters for both sales (budget signal) and security (who applies the patches).&lt;/p&gt;

&lt;h2&gt;
  
  
  Comparing Two Sites' Stacks with POST /compare
&lt;/h2&gt;

&lt;p&gt;A common follow-up: you know one target runs Drupal and want to see how a competitor's stack differs, or check which of two university sites carries more legacy. &lt;code&gt;POST /compare&lt;/code&gt; takes 2–10 URLs and returns each site's technologies plus the shared and unique sets:&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="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: &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;
&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": ["www.drupal.org", "wordpress.org"]}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response groups the delta for you:&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;"domains"&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;"www.drupal.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;"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;"drupal.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;"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;"Drupal"&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="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&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="nl"&gt;"unique"&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;"Drupal"&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;"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;"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;"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;"WordPress"&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="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&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="nl"&gt;"unique"&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;"WordPress"&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;"shared"&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;"PHP"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MySQL"&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;3892&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;unique&lt;/code&gt; array on each domain and the top-level &lt;code&gt;shared&lt;/code&gt; array answer the "what does one run that the other does not" question without any client-side set math. For an agency pitching a Drupal-to-anything migration, one &lt;code&gt;/compare&lt;/code&gt; of the prospect against a reference build is a slide in your deck.&lt;/p&gt;

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

&lt;p&gt;Everything above the batch section works with zero setup via the &lt;code&gt;/demo&lt;/code&gt; endpoint. For real volume, get a key on RapidAPI — the free tier includes 100 requests per month, no credit card, and every endpoint shown here: &lt;code&gt;/analyze&lt;/code&gt;, &lt;code&gt;/check&lt;/code&gt;, &lt;code&gt;/analyze/batch&lt;/code&gt;, and &lt;code&gt;/compare&lt;/code&gt;. Paid tiers scale from 1,000 to 50,000 requests per month, and the same key also unlocks certificate checks, historical snapshots, and &lt;a href="https://detectzestack.com/blog/track-website-tech-changes-api" rel="noopener noreferrer"&gt;tech-change tracking&lt;/a&gt; for the Drupal sites you monitor.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Patch-day tip: the Drupal entry's cpe field is the bridge from "we detected Drupal" to "which advisories apply." Store the CPE alongside the domain when you scan, and the next core security release becomes a lookup instead of a fire drill.&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;Detecting Drupal on a single site is usually one command: &lt;code&gt;curl -sI&lt;/code&gt; and look for &lt;code&gt;X-Generator: Drupal&lt;/code&gt;, &lt;code&gt;X-Drupal-Cache&lt;/code&gt;, or the 1978 &lt;code&gt;Expires&lt;/code&gt; date. When headers are stripped, the meta generator tag, &lt;code&gt;/sites/default/&lt;/code&gt; asset paths, the &lt;code&gt;drupalSettings&lt;/code&gt; JSON blob, and predictable core paths like &lt;code&gt;/core/misc/drupal.js&lt;/code&gt; fill the gap. No other CMS shares this exact fingerprint set.&lt;/p&gt;

&lt;p&gt;Detecting it across a portfolio is one API call per site — &lt;code&gt;/analyze&lt;/code&gt; for the full stack, &lt;code&gt;/check&lt;/code&gt; for the yes/no, &lt;code&gt;/analyze/batch&lt;/code&gt; for lists, and &lt;code&gt;/compare&lt;/code&gt; for head-to-head deltas — each returning Drupal in the &lt;code&gt;CMS&lt;/code&gt; category with the major version when the site exposes it and a CPE for security work. The same response hands you the rest of the stack for free: PHP, database, CDN, analytics, all in one quota-counted request.&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-what-cms-website-uses" rel="noopener noreferrer"&gt;Detect What CMS a Website Uses&lt;/a&gt; — the full CMS detection guide: WordPress, Drupal, Joomla, and friends&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; — the same playbook for Drupal's biggest neighbor&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/how-to-detect-laravel-website" rel="noopener noreferrer"&gt;How to Detect if a Website Uses Laravel&lt;/a&gt; — framework detection on the custom-build side of the PHP web&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; — turn the Drupal cpe field into CVE matches&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/batch-scan-1000-websites" rel="noopener noreferrer"&gt;Batch Scan 1,000 Websites for Tech Stack&lt;/a&gt; — concurrency, quota, and connection-reuse patterns for large lists&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;/ul&gt;

</description>
      <category>techstack</category>
      <category>webdev</category>
      <category>api</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Find Companies Using Mailchimp: API Guide (2026)</title>
      <dc:creator>MikeL</dc:creator>
      <pubDate>Sat, 01 Aug 2026 14:01:24 +0000</pubDate>
      <link>https://dev.to/detectzestack/find-companies-using-mailchimp-api-guide-2026-424a</link>
      <guid>https://dev.to/detectzestack/find-companies-using-mailchimp-api-guide-2026-424a</guid>
      <description>&lt;p&gt;Mailchimp is where companies start doing email marketing. That makes "uses Mailchimp" one of the most versatile technographic filters there is: depending on what you sell, the same signal marks a warm prospect for your agency, a graduation candidate for your fancier ESP, or a churn risk for your retention team. This guide shows how Mailchimp is detected from the outside and how to turn that detection into a working prospect list with the DetectZeStack API. Every response shape below comes from the live API, and the worked example is a real site.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Sales Prospecting for Email Marketing Tools and Agencies
&lt;/h3&gt;

&lt;p&gt;A company running Mailchimp has told you three things without saying a word. They have an audience worth emailing. They have decided email marketing is worth doing. And they picked the entry-level generalist to do it with, which usually means no dedicated email team and a marketing operation still small enough for one platform to cover.&lt;/p&gt;

&lt;p&gt;If you run an email marketing agency, that is your ideal client: someone already sold on the channel who lacks the hands to run it well. If you sell templates, deliverability audits, list-cleaning services, landing page builders, or CRM tooling that integrates with Mailchimp, the filter hands you an audience that has pre-qualified itself on budget and intent.&lt;/p&gt;

&lt;h3&gt;
  
  
  Competitive Intelligence for ESP Vendors
&lt;/h3&gt;

&lt;p&gt;For anyone selling a competing email platform, Mailchimp sites are the displacement list. Mailchimp's pricing scales with contact count, and its ecommerce automation is shallower than specialist tools, so growing companies routinely outgrow it. A Mailchimp signup form on a store that also runs an ecommerce platform and an A/B testing tool is a store that has probably outgrown its ESP already: exactly the account a &lt;a href="https://detectzestack.com/blog/find-companies-using-klaviyo" rel="noopener noreferrer"&gt;Klaviyo&lt;/a&gt;-style vendor wants to reach first, before the migration decision gets made. The detection tells you where the accounts are; the surrounding stack tells you which ones are ripe.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Mailchimp Shows Up on a Website
&lt;/h2&gt;

&lt;p&gt;Mailchimp touches a website in two places: the code the site embeds to collect subscribers and track visitors, and the DNS records the domain publishes to send authenticated email. Both are externally visible, and they fail independently, which is why checking both catches companies a single-signal check would miss.&lt;/p&gt;

&lt;h3&gt;
  
  
  Signup Form Embeds and chimpstatic/list-manage Scripts
&lt;/h3&gt;

&lt;p&gt;The classic integration is the embedded signup form. Mailchimp generates a block of HTML the site owner pastes in, and its markup is unmistakable: a form with the &lt;code&gt;mc-embedded-subscribe-form&lt;/code&gt; identifier that posts to the site's &lt;code&gt;list-manage.com&lt;/code&gt; subdomain, usually accompanied by a stylesheet from &lt;code&gt;cdn-images.mailchimp.com&lt;/code&gt; and the &lt;code&gt;mc-validate.js&lt;/code&gt; validation script:&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="c"&gt;&amp;lt;!-- Begin Mailchimp Signup Form --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"//cdn-images.mailchimp.com/embedcode/classic-061523.css"&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;type=&lt;/span&gt;&lt;span class="s"&gt;"text/css"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;action=&lt;/span&gt;&lt;span class="s"&gt;"https://example.us1.list-manage.com/subscribe/post?u=...&amp;amp;amp;id=..."&lt;/span&gt;
&lt;span class="na"&gt;method=&lt;/span&gt;&lt;span class="s"&gt;"post"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"mc-embedded-subscribe-form"&lt;/span&gt;
&lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"mc-embedded-subscribe-form"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
...
&lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second common integration is the connected-site script, which Mailchimp uses for pop-up forms and visitor tracking. It loads from Mailchimp's &lt;code&gt;chimpstatic.com&lt;/code&gt; asset domain as an &lt;code&gt;mcjs-connected&lt;/code&gt; bundle. DetectZeStack keys on all of these signals: the &lt;code&gt;chimpstatic.com/mcjs-connected&lt;/code&gt; script source, the &lt;code&gt;cdn-images.mailchimp.com&lt;/code&gt; stylesheet, the &lt;code&gt;mc-validate.js&lt;/code&gt; script, and the signup form markup itself. There is no reason for any of them to appear on a page except a live Mailchimp integration, so a match returns a &lt;code&gt;confidence&lt;/code&gt; of &lt;code&gt;100&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;On WordPress, the integration is often a plugin rather than pasted embed code, and the API distinguishes the variants:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Detected as&lt;/th&gt;
&lt;th&gt;What it means&lt;/th&gt;
&lt;th&gt;Signal&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;MailChimp&lt;/td&gt;
&lt;td&gt;Core platform: signup forms, pop-ups, visitor tracking&lt;/td&gt;
&lt;td&gt;chimpstatic.com script, embed form markup, mc-validate.js&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MailChimp for WordPress&lt;/td&gt;
&lt;td&gt;The mc4wp plugin wiring WordPress forms into Mailchimp lists&lt;/td&gt;
&lt;td&gt;Assets under /wp-content/plugins/mailchimp-for-wp/&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MailChimp for WooCommerce&lt;/td&gt;
&lt;td&gt;Store purchase data syncing into Mailchimp automations&lt;/td&gt;
&lt;td&gt;Assets under /wp-content/plugins/mailchimp-for-woocommerce/&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The plugin detections imply the core platform, so a site running MailChimp for WooCommerce also reports MailChimp itself. The distinction is useful qualification data: a store syncing WooCommerce purchase data into Mailchimp automations is a materially deeper integration, and a materially stickier account, than a blog with a pasted signup form.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mandrill and DNS-Level Email Signals
&lt;/h3&gt;

&lt;p&gt;A company can send Mailchimp campaigns from a domain whose website carries no Mailchimp code at all: think of a business whose site is a brochure but whose newsletter goes out weekly. Sending leaves traces in DNS instead. Domains that authenticate Mailchimp campaigns add &lt;code&gt;servers.mcsv.net&lt;/code&gt; to their SPF record and provision DKIM under the &lt;code&gt;k1&lt;/code&gt; selector. Mandrill, Mailchimp's transactional email arm, uses the &lt;code&gt;mandrill&lt;/code&gt; selector.&lt;/p&gt;

&lt;p&gt;DetectZeStack's &lt;code&gt;GET /dns&lt;/code&gt; endpoint surfaces both. It parses the domain's SPF record into an &lt;code&gt;includes&lt;/code&gt; array where an &lt;code&gt;mcsv.net&lt;/code&gt; entry is plainly visible, and it probes eight common DKIM selectors in parallel, including &lt;code&gt;k1&lt;/code&gt;, &lt;code&gt;mailchimp&lt;/code&gt;, and &lt;code&gt;mandrill&lt;/code&gt;, reporting which one answered in &lt;code&gt;dkim.selector_tested&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="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://detectzestack.p.rapidapi.com/dns?domain=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="se"&gt;\&lt;/span&gt;
| jq &lt;span class="s1"&gt;'{spf_includes: .spf.includes, dkim: .dkim}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A &lt;code&gt;servers.mcsv.net&lt;/code&gt; include or a DKIM hit on &lt;code&gt;k1&lt;/code&gt; or &lt;code&gt;mandrill&lt;/code&gt; is strong evidence the company sends through Mailchimp even when the homepage is silent about it. For prospecting, treat the website signal as primary and the DNS signal as the recall booster that catches senders without on-site forms. There is a full walkthrough of the DNS endpoint in the &lt;a href="https://detectzestack.com/blog/dns-intelligence-api-spf-dkim-dmarc" rel="noopener noreferrer"&gt;DNS intelligence guide&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check a Single Domain with the DetectZeStack API
&lt;/h2&gt;

&lt;p&gt;Before writing any code, confirm the signal by hand. The &lt;code&gt;/demo&lt;/code&gt; endpoint needs no API key and no signup:&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=themarginalian.org"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
| jq &lt;span class="s1"&gt;'.technologies[] | select(.name == "MailChimp")'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which returns:&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;"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;"MailChimp"&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="s2"&gt;"Marketing automation"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;"Email"&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;"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;"Mailchimp is a marketing automation platform and email marketing 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://mailchimp.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;"mailchimp.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="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;Note the capital C. The canonical name in the fingerprint database is MailChimp, not Mailchimp, and the technologies array uses the canonical spelling. Your jq filters and code must match it exactly or they will silently match nothing. The tech parameter on /check is case insensitive on input, so tech=mailchimp works there; the response echoes back MailChimp.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  curl Example — GET /analyze
&lt;/h3&gt;

&lt;p&gt;The demo endpoint is rate limited and meant for spot checks. For real volume, get a free API key from &lt;a href="https://rapidapi.com/mlugoapx/api/detectzestack" rel="noopener noreferrer"&gt;RapidAPI&lt;/a&gt; and use the authenticated &lt;code&gt;/analyze&lt;/code&gt; endpoint, which returns the full stack:&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/analyze?url=themarginalian.org"&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;'.'&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://themarginalian.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;"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;"themarginalian.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;"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;"MailChimp"&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;"Marketing automation"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Email"&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;"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="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;"WordPress"&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="s2"&gt;"Blogs"&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;"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="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;"WordPress Super 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;"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;"Caching"&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;"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="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;"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="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;"PHP"&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;"Programming languages"&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;"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="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;"MySQL"&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;"Databases"&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;"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="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;"Marketing automation"&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;"MailChimp"&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"&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;"MailChimp"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"CMS"&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;"WordPress"&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;11&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;1204&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;
  
  
  Reading the Response: technologies, categories, confidence
&lt;/h3&gt;

&lt;p&gt;Three parts of the response do the prospecting work. The &lt;code&gt;technologies&lt;/code&gt; array is the evidence: each entry carries the canonical name, its categories, a &lt;code&gt;confidence&lt;/code&gt; score, and a &lt;code&gt;source&lt;/code&gt; telling you whether the detection came from the HTTP response or a DNS or TLS signal. The &lt;code&gt;categories&lt;/code&gt; object is the fast filter: it maps category names to the technologies found in them, so checking whether a domain runs any email platform is one lookup on &lt;code&gt;categories["Marketing automation"]&lt;/code&gt; rather than a scan of the array. That lookup catches MailChimp, Klaviyo, and &lt;a href="https://detectzestack.com/blog/how-to-detect-hubspot" rel="noopener noreferrer"&gt;HubSpot&lt;/a&gt; in a single pass; filtering on the name &lt;code&gt;MailChimp&lt;/code&gt; catches Mailchimp specifically. Pick based on whether you are qualifying a category budget or a displacement target.&lt;/p&gt;

&lt;p&gt;And &lt;code&gt;meta.status_code&lt;/code&gt; is the honesty check. Mailchimp is detected from the HTML a site returns, so if a site answers the scan with a &lt;code&gt;403&lt;/code&gt; instead of its page, there is nothing to inspect and Mailchimp will be absent even if the site runs it. Treat any non-200 &lt;code&gt;status_code&lt;/code&gt; as inconclusive rather than negative, or you will silently drop real Mailchimp users from your list.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scan Your Whole Prospect List with POST /analyze/batch
&lt;/h2&gt;

&lt;p&gt;Batch is how you work through a list. It accepts up to &lt;strong&gt;10 URLs per request&lt;/strong&gt; and scans them concurrently:&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="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": ["themarginalian.org", "davidlebovitz.com", "waitbutwhy.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;'.results[]
| select(.result.technologies[]?.name == "MailChimp")
| .result.domain'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response wraps one result per URL with a per-item &lt;code&gt;error&lt;/code&gt; field, so a single dead domain does not fail the batch, and the jq filter above prints only the domains where MailChimp was found. Each URL in a batch counts as one request against your monthly quota; batching saves round trips and wall-clock time, not quota. For lists past a few hundred domains, the &lt;a href="https://detectzestack.com/blog/batch-scan-1000-websites" rel="noopener noreferrer"&gt;1,000-site batch scanning guide&lt;/a&gt; covers chunking, retries, and rate pacing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Compare Mailchimp vs Klaviyo Adoption Across Competitors with POST /compare
&lt;/h2&gt;

&lt;p&gt;When the question is not "who uses Mailchimp" but "which ESP does each of these companies use," &lt;code&gt;POST /compare&lt;/code&gt; answers it in one call. It scans 2 to 10 domains and splits every detected technology into what is &lt;code&gt;shared&lt;/code&gt; across all of them and what is &lt;code&gt;unique&lt;/code&gt; to each:&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="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": ["themarginalian.org", "ridge.com"]}'&lt;/span&gt; | jq &lt;span class="s1"&gt;'{
shared,
esp: [.domains[] | {domain, unique}]
}'&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;"shared"&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;"esp"&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;"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;"themarginalian.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;"unique"&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;"MailChimp"&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"&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 Super Cache"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"PHP"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MySQL"&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;"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;"ridge.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;"unique"&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;"Klaviyo"&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"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Intelligems"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Fondue"&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="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;Run this across a competitor set and the ESP split falls out immediately: the domains with &lt;code&gt;MailChimp&lt;/code&gt; in their list are on the entry-level generalist, the ones with &lt;code&gt;Klaviyo&lt;/code&gt; have graduated to the ecommerce specialist, and the pattern across five or ten competitors tells you where a market segment is in its email maturity. That is a positioning insight you would otherwise pay a technographics vendor for, and here it is one API call.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building a Lead List Workflow from Detection Results
&lt;/h2&gt;

&lt;p&gt;Putting it together: read domains from a file, scan them in batches of 10, keep the Mailchimp users, and write a CSV your CRM can ingest.&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;csv&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="n"&gt;API&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/batch&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="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="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;BATCH_SIZE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;  &lt;span class="c1"&gt;# API maximum per request
&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;domains&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Scan up to 10 domains, yielding (domain, tech_names, status_code).&lt;/span&gt;&lt;span class="sh"&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="n"&gt;API&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;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;domains&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;60&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;for&lt;/span&gt; &lt;span class="n"&gt;item&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;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;item&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;result&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="n"&gt;result&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;  skipped &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;item&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="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;item&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;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;no result&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="k"&gt;continue&lt;/span&gt;
&lt;span class="n"&gt;names&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="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="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&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;meta&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;status_code&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;yield&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="n"&gt;names&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&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;domains.txt&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;domains&lt;/span&gt; &lt;span class="o"&gt;=&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="nf"&gt;strip&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;line&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt;

&lt;span class="n"&gt;prospects&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;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&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="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&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;BATCH_SIZE&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="n"&gt;chunk&lt;/span&gt; &lt;span class="o"&gt;=&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;i&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;BATCH_SIZE&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;Scanning &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&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;i&lt;/span&gt; &lt;span class="o"&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;chunk&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; of &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;domains&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="k"&gt;for&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;techs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="ow"&gt;in&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;chunk&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;status&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="c1"&gt;# No page HTML means no script-based detection is possible.
&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;domain&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: status &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;, inconclusive&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;continue&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MailChimp&lt;/span&gt;&lt;span class="sh"&gt;"&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;prospects&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="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="n"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;depth&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;ecommerce-sync&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MailChimp for WooCommerce&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;techs&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;wordpress-plugin&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MailChimp for WordPress&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;techs&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;embed&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;stack&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;techs&lt;/span&gt;&lt;span class="p"&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;domain&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: MailChimp&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;mailchimp_prospects.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="nc"&gt;DictWriter&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;fieldnames&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;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;depth&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;stack&lt;/span&gt;&lt;span class="sh"&gt;"&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;writeheader&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;writerows&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prospects&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="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prospects&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; Mailchimp sites out of &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;domains&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; domains.&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="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two details in that script earn their keep. The &lt;code&gt;status != 200&lt;/code&gt; guard keeps inconclusive scans out of your negatives, and the &lt;code&gt;depth&lt;/code&gt; column records whether the integration is a pasted embed, the WordPress plugin, or a full WooCommerce purchase-data sync. Depth is the qualification: an embed can be abandoned in an afternoon, while a store syncing order data has automations wired to it and will hold still long enough for a sales cycle. The &lt;code&gt;stack&lt;/code&gt; column carries the rest of the scan, which is what turns a generic opener into a specific one; the &lt;a href="https://detectzestack.com/blog/lead-enrichment-pipeline-with-tech-detection" rel="noopener noreferrer"&gt;lead enrichment pipeline guide&lt;/a&gt; and &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; show how to push it into a CRM.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get Your API Key
&lt;/h2&gt;

&lt;p&gt;Plans are the standard DetectZeStack tiers, and every URL scanned counts as one request:&lt;/p&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;Requests / month&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;Free&lt;/td&gt;
&lt;td&gt;100&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;/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;/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;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Results are cached for 24 hours by default; a cache hit comes back with &lt;code&gt;"cached": true&lt;/code&gt;, so rescanning the same domain twice in a row measures the cache rather than the scanner. The free tier's 100 requests are enough to validate the whole workflow on a real slice of your prospect list before paying anything.&lt;/p&gt;

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

&lt;p&gt;Mailchimp announces itself in embed forms, connected-site scripts, and DNS records, and each of those signals is one API call away. Start with &lt;code&gt;/demo&lt;/code&gt; to see a detection on a site you know, use &lt;code&gt;/analyze/batch&lt;/code&gt; to sweep your prospect list, &lt;code&gt;/compare&lt;/code&gt; to map ESP adoption across a competitor set, and &lt;code&gt;/dns&lt;/code&gt; to catch the senders whose websites keep quiet. Filter on the canonical &lt;code&gt;MailChimp&lt;/code&gt; name, guard on &lt;code&gt;meta.status_code&lt;/code&gt;, and the output is a lead list with the research already attached.&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-klaviyo" rel="noopener noreferrer"&gt;How to Find Companies Using Klaviyo&lt;/a&gt; — The ecommerce-specialist ESP on the other side of the migration path&lt;/li&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; — The B2B counterpart signal in the same category&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&lt;/a&gt; — Scaling the batch endpoint past a handful of domains&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; — Automating prospect qualification end to end&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; — Pushing technographic data into your CRM&lt;/li&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, DMARC&lt;/a&gt; — The email authentication signals behind the /dns endpoint&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>techstack</category>
      <category>webdev</category>
      <category>api</category>
    </item>
    <item>
      <title>How to Detect Typekit (Adobe Fonts) on Any Website (2026)</title>
      <dc:creator>MikeL</dc:creator>
      <pubDate>Fri, 24 Jul 2026 14:01:20 +0000</pubDate>
      <link>https://dev.to/detectzestack/how-to-detect-typekit-adobe-fonts-on-any-website-2026-58o6</link>
      <guid>https://dev.to/detectzestack/how-to-detect-typekit-adobe-fonts-on-any-website-2026-58o6</guid>
      <description>&lt;p&gt;Typekit has not officially existed since 2018, and yet it is still one of the most-detected font technologies on the web. That is because when Adobe rebranded the service to Adobe Fonts, the serving infrastructure kept its old hostnames: every site using it today still loads a stylesheet from &lt;code&gt;use.typekit.net&lt;/code&gt;, exactly as it did a decade ago. Those hostnames are the detection signature, and they are impossible to hide.&lt;/p&gt;

&lt;p&gt;This guide covers how to detect Typekit by hand in under a minute, why the manual approach stops working the moment you have a list of domains instead of one, and how to do the same check programmatically with the DetectZeStack API. Every response shown below comes from the live API against a real site.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is Typekit (and Why It's Now Adobe Fonts)
&lt;/h2&gt;

&lt;p&gt;Typekit launched in 2009 as a subscription library of licensed web fonts, was acquired by Adobe in 2011, and was folded into Creative Cloud as Adobe Fonts in 2018. The product name changed; the plumbing did not. Web projects are still identified by a short kit ID, stylesheets are still served from &lt;code&gt;use.typekit.net&lt;/code&gt;, and the legacy JavaScript loader still lives on &lt;code&gt;use.typekit.com&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That continuity has a practical consequence for anyone doing technology detection: &lt;strong&gt;Typekit and Adobe Fonts are the same signal.&lt;/strong&gt; Fingerprint databases carry both names because both eras of the product left embeds in the wild, and both fingerprints match the same hostnames. Scan a site with a live embed and you will get two results describing one integration. This is expected, and we will see it in a real API response below.&lt;/p&gt;

&lt;p&gt;The signal is also worth detecting. Adobe Fonts rides on a paid Creative Cloud subscription, so unlike a free font CDN, its presence tells you the company behind the site pays for typography. If you want to turn that into a prospect list rather than a yes/no check, see &lt;a href="https://detectzestack.com/blog/find-companies-using-adobe-fonts" rel="noopener noreferrer"&gt;how to find companies using Adobe Fonts&lt;/a&gt;, which applies this detection to sales prospecting end to end.&lt;/p&gt;

&lt;h2&gt;
  
  
  Manual Ways to Detect Typekit on a Website
&lt;/h2&gt;

&lt;p&gt;For a single site you already have open in a browser, three manual checks settle the question.&lt;/p&gt;

&lt;h3&gt;
  
  
  Check for use.typekit.net Script and Stylesheet URLs
&lt;/h3&gt;

&lt;p&gt;View the page source (&lt;code&gt;Ctrl+U&lt;/code&gt; in most browsers) and search for &lt;code&gt;typekit&lt;/code&gt;. The modern embed is a stylesheet link in the head:&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;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://use.typekit.net/abc1def.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;Older integrations use the JavaScript embed instead: a script served from &lt;code&gt;use.typekit.com&lt;/code&gt; plus a load call:&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://use.typekit.com/abc1def.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;script&amp;gt;&lt;/span&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Typekit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;async&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;});}&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&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;p&gt;Either one is conclusive. No technology other than Adobe's font service loads assets from those hosts, which is why automated detection assigns this signature full confidence.&lt;/p&gt;

&lt;h3&gt;
  
  
  Look for the Kit ID and wf-loading Body Classes
&lt;/h3&gt;

&lt;p&gt;The short lowercase token in the embed URL, the &lt;code&gt;abc1def&lt;/code&gt; above, is the kit ID. Adobe generates one per web project, and it identifies which licensed fonts the page may load. It is visible to anyone, but it is domain-scoped on Adobe's side, so seeing it does not let a third party reuse the fonts.&lt;/p&gt;

&lt;p&gt;Sites using the JavaScript embed give you a second, runtime clue. The loader stamps state classes on the &lt;code&gt;html&lt;/code&gt; or &lt;code&gt;body&lt;/code&gt; element while fonts load: &lt;code&gt;wf-loading&lt;/code&gt; while requests are in flight, then &lt;code&gt;wf-active&lt;/code&gt; on success or &lt;code&gt;wf-inactive&lt;/code&gt; on failure. Open the browser console and check:&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="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;documentElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;className&lt;/span&gt;
&lt;span class="c1"&gt;// "wf-typekit-active wf-active ..." on a Typekit JS-embed site&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note the limitation: these classes are added by JavaScript at runtime, so they only exist after the page executes its scripts, and only with the JS embed. The stylesheet embed, which is what Adobe generates for new projects, produces no &lt;code&gt;wf-*&lt;/code&gt; classes at all. Treat their absence as meaningless and their presence as supporting evidence.&lt;/p&gt;

&lt;h3&gt;
  
  
  Inspect Network Requests to p.typekit.net
&lt;/h3&gt;

&lt;p&gt;The third check is the network tab. Open developer tools, reload the page, and filter requests by &lt;code&gt;typekit&lt;/code&gt;. A site with a live integration shows the kit CSS from &lt;code&gt;use.typekit.net&lt;/code&gt; and then the actual font files from &lt;code&gt;p.typekit.net&lt;/code&gt;, Adobe's font-serving host. You can do the same from the console without watching the waterfall:&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="nx"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getEntriesByType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;resource&lt;/span&gt;&lt;span class="dl"&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;map&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="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&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;filter&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="nx"&gt;u&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;indexOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;typekit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&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 that returns URLs, the fonts are not just referenced, they are being served. This distinguishes a live integration from a leftover embed pointing at a deleted kit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Manual Detection Breaks at Scale
&lt;/h2&gt;

&lt;p&gt;All three checks above take under a minute for one site. They stop being viable the moment the question changes from "does this site use Typekit?" to "which of these 500 domains use Typekit?" Manual checking at that scale fails in predictable ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;It does not batch.&lt;/strong&gt; Thirty seconds per site is over four hours of tab-switching for 500 domains, with no machine-readable output at the end.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It is inconsistent.&lt;/strong&gt; A human checker misses the JS embed on one site, forgets the network tab on another, and mistakes a dead kit for a live one on a third. A fingerprint engine applies the same rules to every domain.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It captures nothing else.&lt;/strong&gt; While you are in the page source looking for one string, the site's CMS, analytics stack, and CDN are sitting in the same HTML unrecorded. An API scan returns all of it in one pass.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It does not repeat.&lt;/strong&gt; Technology lists go stale. Rescanning a list monthly by hand is not a workflow anyone sustains; rerunning a script is.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The fix is to move the same signatures into an API call.&lt;/p&gt;

&lt;h2&gt;
  
  
  Detect Typekit With the DetectZeStack API
&lt;/h2&gt;

&lt;p&gt;DetectZeStack detects Typekit server-side from the HTML a site returns: a &lt;code&gt;link&lt;/code&gt; tag pointing at &lt;code&gt;use.typekit.net&lt;/code&gt; or &lt;code&gt;use.typekit.com&lt;/code&gt;, or a script sourced from &lt;code&gt;use.typekit.com&lt;/code&gt;. Both patterns resolve at a &lt;code&gt;confidence&lt;/code&gt; of &lt;code&gt;100&lt;/code&gt;, and because they sit in the raw HTML, no headless browser is involved.&lt;/p&gt;

&lt;p&gt;Try it first with no API key. The &lt;code&gt;/demo&lt;/code&gt; endpoint is free and needs no signup; Behance, Adobe's own portfolio network, is a convenient live example:&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=behance.net"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
| jq &lt;span class="s1"&gt;'.technologies[] | select(.name == "Typekit")'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which returns:&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;"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;"Typekit"&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="s2"&gt;"Font scripts"&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;"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;"Typekit is an online service which offers a subscription library of fonts."&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://typekit.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;"Typekit.png"&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="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;source&lt;/code&gt; field is &lt;code&gt;http&lt;/code&gt;, meaning the detection came from the page HTML. That is the only place Typekit can appear: fonts load from Adobe's domain rather than the customer's, so there is no DNS record or TLS artifact to key on. If a site answers a scan with an error page instead of its real HTML, the embed is invisible and the detection cannot fire, which is why checking &lt;code&gt;meta.status_code&lt;/code&gt; matters, covered below.&lt;/p&gt;

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

&lt;p&gt;The demo endpoint is rate limited and meant for spot checks. For real use, get a free API key from &lt;a href="https://rapidapi.com/mlugoapx/api/detectzestack" rel="noopener noreferrer"&gt;RapidAPI&lt;/a&gt; and call &lt;code&gt;/analyze&lt;/code&gt;, which returns the full stack:&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/analyze?url=behance.net"&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;'.'&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://www.behance.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;"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;"www.behance.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;"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;"Adobe Fonts"&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;"Font scripts"&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;"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="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;"Typekit"&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;"Font scripts"&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;"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="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;"Vue.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;"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="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;"Varnish"&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;"Caching"&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;"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="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="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="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;"HTTP/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;"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;"Miscellaneous"&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;"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="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;"Let's Encrypt"&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;"Font scripts"&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;"Adobe Fonts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Typekit"&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;"Vue.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;"Caching"&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;"Varnish"&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;"Miscellaneous"&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;"HTTP/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;"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;"Let's Encrypt"&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;7&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;4415&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;There is the double entry promised earlier: &lt;code&gt;Typekit&lt;/code&gt; and &lt;code&gt;Adobe Fonts&lt;/code&gt;, both under &lt;strong&gt;Font scripts&lt;/strong&gt;, both matched by the same &lt;code&gt;use.typekit.net&lt;/code&gt; embed. Filter on either name, or on the category, and do not count them as two technologies. The &lt;code&gt;categories&lt;/code&gt; object makes the category route a single key lookup: &lt;code&gt;.categories["Font scripts"]&lt;/code&gt; answers "does this site use a hosted font service?" without walking the array.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Check meta.status_code before trusting an absence. Typekit is detected only from the returned HTML. A site that answers your scan with a 403 or 429 shows no embed even if it uses the service, and the scan does not fail loudly; it just comes back thinner. Treat a non-200 status as inconclusive, not as a negative.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Results are cached for 24 hours by default; a repeat scan of the same domain returns &lt;code&gt;"cached": true&lt;/code&gt; with a much lower &lt;code&gt;response_ms&lt;/code&gt;. That is worth knowing when benchmarking: the second scan measures the cache, not the scanner.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scanning Many Domains With POST /analyze/batch
&lt;/h3&gt;

&lt;p&gt;Batch is how you work through a list. It accepts up to 10 URLs per request and scans them concurrently:&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="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": ["behance.net", "example.com", "stripe.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;'.results[]
| select(.result.technologies[]?.name == "Typekit")
| .result.domain'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response wraps one result per URL with a per-item &lt;code&gt;error&lt;/code&gt; field, so one unreachable domain does not fail the batch, and the &lt;code&gt;jq&lt;/code&gt; filter prints only the domains where Typekit was found. Each URL counts as one request against your monthly quota; batching saves round trips, not quota. For working through lists in the hundreds or thousands, &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; covers chunking, retries, and rate pacing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Typekit vs Google Fonts vs Self-Hosted Fonts: Telling Them Apart
&lt;/h2&gt;

&lt;p&gt;Font loading comes in three flavors, and each leaves a different trail:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Approach&lt;/th&gt;
&lt;th&gt;Signature&lt;/th&gt;
&lt;th&gt;What it implies&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Typekit / Adobe Fonts&lt;/td&gt;
&lt;td&gt;Stylesheet or script from use.typekit.net / use.typekit.com; fonts from p.typekit.net&lt;/td&gt;
&lt;td&gt;Paid Creative Cloud subscription; licensed typefaces; an active design budget&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Google Fonts&lt;/td&gt;
&lt;td&gt;Stylesheet from fonts.googleapis.com; fonts from fonts.gstatic.com&lt;/td&gt;
&lt;td&gt;Free hosted fonts; a typeface choice, but no spend signal&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Self-hosted&lt;/td&gt;
&lt;td&gt;@font-face rules pointing at the site's own domain; no third-party font hosts&lt;/td&gt;
&lt;td&gt;Performance or privacy priorities, or a licensed font served under its own terms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Both hosted services land in the &lt;strong&gt;Font scripts&lt;/strong&gt; category (Google's entry is named &lt;code&gt;Google Font API&lt;/code&gt;), so a category filter catches either while a name filter isolates the paid signal. Self-hosted fonts, by design, have no third-party host to fingerprint; their absence from a scan is not a detection failure but the actual answer. The same host-based logic powers detection of other asset CDNs; &lt;a href="https://detectzestack.com/blog/how-to-detect-cdnjs" rel="noopener noreferrer"&gt;detecting cdnjs&lt;/a&gt; is the same pattern applied to JavaScript libraries, and &lt;a href="https://detectzestack.com/blog/how-to-detect-google-tag-manager" rel="noopener noreferrer"&gt;detecting Google Tag Manager&lt;/a&gt; applies it to the tag-management layer of the same pages.&lt;/p&gt;

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

&lt;p&gt;The free plan covers 100 requests per month with no credit card, which is enough to confirm the signal on the sites you care about; paid plans start at $9 for 1,000 requests. Every plan returns the same full response: Typekit alongside the CMS, analytics, CDN, and everything else in the stack, in one call.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Spot-check a site with &lt;code&gt;/demo&lt;/code&gt;, no key required.&lt;/li&gt;
&lt;li&gt;Get a free key at &lt;a href="https://rapidapi.com/mlugoapx/api/detectzestack" rel="noopener noreferrer"&gt;RapidAPI&lt;/a&gt; and move to &lt;code&gt;/analyze&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Feed your domain list through &lt;code&gt;/analyze/batch&lt;/code&gt;, 10 URLs at a time.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;Typekit is one of the easiest technologies on the web to detect because it cannot be consumed without advertising itself: the embed sits in the HTML, the hostnames never changed through a rebrand, and there is no false-positive path, since nothing else loads assets from Adobe's font hosts. Check one site by searching the source for &lt;code&gt;use.typekit.net&lt;/code&gt;; check five hundred with an API call that applies the same signature uniformly and hands you the rest of the stack for free. Just remember the two quirks: the API returns both Typekit and Adobe Fonts for one integration, and a non-200 &lt;code&gt;status_code&lt;/code&gt; means inconclusive, not absent.&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-adobe-fonts" rel="noopener noreferrer"&gt;How to Find Companies Using Adobe Fonts&lt;/a&gt; — Turning this detection into a design-budget prospect list&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/how-to-detect-google-tag-manager" rel="noopener noreferrer"&gt;How to Detect Google Tag Manager&lt;/a&gt; — The same host-signature approach on the tag-management layer&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/how-to-detect-cdnjs" rel="noopener noreferrer"&gt;How to Detect cdnjs&lt;/a&gt; — Detecting asset CDNs by the hosts they load from&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/how-to-detect-font-awesome" rel="noopener noreferrer"&gt;How to Detect Font Awesome on Any Website&lt;/a&gt; — The icon-font side of web typography, and why a CSS-only install is the common false negative&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&lt;/a&gt; — Scaling the batch endpoint past a handful of domains&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 imagesLoaded: API Guide (2026)</title>
      <dc:creator>MikeL</dc:creator>
      <pubDate>Thu, 16 Jul 2026 14:01:15 +0000</pubDate>
      <link>https://dev.to/detectzestack/find-companies-using-imagesloaded-api-guide-2026-43ld</link>
      <guid>https://dev.to/detectzestack/find-companies-using-imagesloaded-api-guide-2026-43ld</guid>
      <description>&lt;p&gt;imagesLoaded is a small JavaScript library by David DeSandro that answers one question: have the images inside a container finished loading? That sounds too narrow to be a prospecting signal, and that narrowness is exactly why it is a good one. Nobody adds imagesLoaded on a whim. It appears on sites with image-heavy layouts that break without it, and it almost always arrives as part of a specific, dateable front-end stack: jQuery, a masonry-style grid, a WordPress theme or page builder doing the enqueueing.&lt;/p&gt;

&lt;p&gt;This guide shows how imagesLoaded is detected from the outside and how to turn that detection into a prospect list with the DetectZeStack API. The worked example is a live site, and every response shape below comes from the live API.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is imagesLoaded and Why Track Sites That Use It
&lt;/h2&gt;

&lt;p&gt;Browsers report an element's dimensions as zero until its images arrive. Any layout that positions items based on their rendered height — a masonry wall, a justified photo grid, an infinite-scroll feed — will compute positions from those zero heights and paint overlapping bricks unless something waits for the images first. imagesLoaded is that something. It watches a container, fires a callback when every image has loaded or errored, and lets the layout engine run against real dimensions.&lt;/p&gt;

&lt;p&gt;As a technographic signal, that tells you three things about a site before you ever open it. First, the site is visually driven: portfolios, photography, real estate, media, ecommerce catalogs. Second, its layout is computed in JavaScript rather than in modern CSS, which dates the front end — CSS grid and aspect-ratio have made much of this machinery unnecessary. Third, someone assembled this stack deliberately, usually via a WordPress theme, a page builder, or a hand-rolled gallery, and that assembly is now a maintenance surface.&lt;/p&gt;

&lt;h3&gt;
  
  
  How imagesLoaded Fits Into a Front-End Stack (Masonry, Isotope, jQuery Galleries)
&lt;/h3&gt;

&lt;p&gt;imagesLoaded rarely travels alone. It is the companion utility for the same author's layout libraries — Masonry, Isotope, Packery, Flickity — and for jQuery gallery and carousel plugins that need to measure images before arranging them. The canonical pattern 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="c1"&gt;// wait for images, then lay out the grid&lt;/span&gt;
&lt;span class="nf"&gt;imagesLoaded&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.grid&lt;/span&gt;&lt;span class="dl"&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="p"&gt;{&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Masonry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.grid&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;itemSelector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.grid-item&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The other common delivery vehicle is WordPress itself. WordPress core ships imagesLoaded in &lt;code&gt;wp-includes/js/imagesloaded.min.js&lt;/code&gt;, and themes and page-builder plugins enqueue it whenever a masonry block, filterable portfolio, or gallery widget needs it. That is worth knowing because it shapes what a detection means: a large share of imagesLoaded sites are WordPress sites, and the scan that finds the library will usually name the theme's ecosystem — Elementor, Slick, jQuery — in the same response.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who Buys From Companies Using imagesLoaded
&lt;/h2&gt;

&lt;p&gt;A company running imagesLoaded has an image-heavy site built on a JavaScript-layout stack that is, in 2026, at least one generation old. Two groups sell into exactly that profile.&lt;/p&gt;

&lt;h3&gt;
  
  
  Agencies and Freelancers Selling Front-End Modernization
&lt;/h3&gt;

&lt;p&gt;imagesLoaded is a proxy for the whole jQuery-era gallery stack. A site loading it as a standalone file is very likely also loading jQuery, a carousel plugin, and a theme's worth of layout scripts — the exact surface an agency pitches to replace with modern CSS, a component framework, or a lighter theme. The signal also implies the site owner cares how the site looks: they picked an image-forward design and paid someone to build it once, which makes "your gallery stack is five years old and costing you Core Web Vitals" a pitch aimed at someone who already values the outcome. Because the detection usually arrives with the CMS and page builder attached, the outreach can be specific: you are not guessing that they run WordPress with Elementor, the scan said so.&lt;/p&gt;

&lt;h3&gt;
  
  
  SaaS Vendors Replacing Custom Gallery and Layout Code
&lt;/h3&gt;

&lt;p&gt;Every imagesLoaded detection marks a site that solved image loading and layout by hand. That is the displacement target for gallery and portfolio plugins, digital asset management tools, image CDNs and optimization services, and headless media platforms. The pitch writes itself from the stack: a photography studio gluing imagesLoaded to Masonry inside a WordPress theme is maintaining code that a managed gallery product makes obsolete. And because imagesLoaded correlates with pages that ship many large images, image-optimization vendors get a second angle — these are precisely the sites where LCP improvements are visible to the owner.&lt;/p&gt;

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

&lt;p&gt;DetectZeStack analyzes the HTML a server returns; it does not execute JavaScript. For imagesLoaded that is enough, because the sites worth finding load it as a named file the scanner can see.&lt;/p&gt;

&lt;h3&gt;
  
  
  Script Signatures and CDN Fingerprints
&lt;/h3&gt;

&lt;p&gt;The fingerprint keys on the script source. A script tag whose &lt;code&gt;src&lt;/code&gt; ends in &lt;code&gt;imagesloaded.js&lt;/code&gt; or &lt;code&gt;imagesloaded.min.js&lt;/code&gt; resolves the site to imagesLoaded with a confidence of 100, whether the file is served from the site's own origin, from &lt;code&gt;wp-includes/js/&lt;/code&gt;, or from a public CDN. The signature also captures the version from a &lt;code&gt;?v=&lt;/code&gt; or &lt;code&gt;?ver=&lt;/code&gt; query string when one is present:&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;"/wp-content/plugins/.../imagesloaded.min.js?ver=3.0.0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That &lt;code&gt;?ver=&lt;/code&gt; pattern is how WordPress enqueues every bundled script, which is why imagesLoaded detections so often come with a version number attached and a WordPress detection in the same scan. The version matters for qualification: it is the version of the library the theme shipped, and an old one is a direct measure of how long the front end has gone untouched.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The blind spot to know about: a site that compiles imagesLoaded into a webpack or similar bundle never exposes the filename, so no external scanner can see it — the library's own documentation site bundles its assets and scans clean. In practice this filters your list in a useful direction: script-source detection surfaces exactly the sites loading it the old way, as a standalone file, which are the modernization prospects anyway.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  API Example: Check a Single Domain for imagesLoaded
&lt;/h2&gt;

&lt;p&gt;Confirm the signal by hand first. The &lt;code&gt;/demo&lt;/code&gt; endpoint needs no API key and no signup. Here it is against &lt;code&gt;wpastra.com&lt;/code&gt;, the site of the Astra WordPress theme:&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=wpastra.com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
| jq &lt;span class="s1"&gt;'.technologies[] | select(.name == "imagesLoaded")'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which returns:&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;"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;"imagesLoaded"&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;"3.0.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;"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="s2"&gt;"JavaScript libraries"&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;"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;"jQuery plugin for seeing if the images are loaded."&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://imagesloaded.desandro.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;"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="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;Three fields matter. &lt;code&gt;confidence&lt;/code&gt; is &lt;code&gt;100&lt;/code&gt; because the script source matched exactly. &lt;code&gt;version&lt;/code&gt; is &lt;code&gt;3.0.0&lt;/code&gt;, captured from the &lt;code&gt;?ver=&lt;/code&gt; query string on the enqueue. &lt;code&gt;source&lt;/code&gt; is &lt;code&gt;http&lt;/code&gt;, meaning the detection came from the HTML response rather than a DNS or TLS signal. The same scan returned the rest of the story: WordPress, Elementor, Slick, jQuery, and jQuery Migrate — the full image-heavy WordPress stack this article has been describing, in one call.&lt;/p&gt;

&lt;p&gt;For real volume, get a free API key from &lt;a href="https://rapidapi.com/mlugoapx/api/detectzestack" rel="noopener noreferrer"&gt;RapidAPI&lt;/a&gt; and use the authenticated endpoints. When you only need a yes or no, &lt;code&gt;/check&lt;/code&gt; returns one directly:&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/check?url=wpastra.com&amp;amp;tech=imagesLoaded"&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;'.'&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;"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;"wpastra.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;"imagesLoaded"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"detected"&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;"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;"3.0.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;"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;"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;431&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="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;tech&lt;/code&gt; parameter is case insensitive, so &lt;code&gt;tech=imagesloaded&lt;/code&gt; works and the response echoes the canonical name &lt;code&gt;imagesLoaded&lt;/code&gt;. When the library is absent, &lt;code&gt;detected&lt;/code&gt; is &lt;code&gt;false&lt;/code&gt; and &lt;code&gt;confidence&lt;/code&gt; is &lt;code&gt;0&lt;/code&gt;. When a site loads the file without a version query string, &lt;code&gt;version&lt;/code&gt; comes back as an empty string; that is a normal detection, not a partial one.&lt;/p&gt;

&lt;h2&gt;
  
  
  API Example: Build a List of Companies Using imagesLoaded
&lt;/h2&gt;

&lt;p&gt;Single checks answer "does this domain run it?" and require you to bring the domain. The next two endpoints build lists.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using /lookup?tech=imagesLoaded with Pagination and Tier Caps
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;/lookup&lt;/code&gt; inverts the question: it returns domains already in DetectZeStack's scan index that were observed running imagesLoaded.&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/lookup?tech=imagesLoaded&amp;amp;limit=50"&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;'.'&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;"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;"imagesLoaded"&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"&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;"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;"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;"wpastra.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;"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;"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="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;"3.0.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;"first_seen"&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-07-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;"last_seen"&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-07-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="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"limit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"offset"&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="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;18&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;&lt;code&gt;first_seen&lt;/code&gt; and &lt;code&gt;last_seen&lt;/code&gt; have no equivalent in a live scan: they tell you when the index first observed the library on that domain and when it was last confirmed. Page through results with &lt;code&gt;limit&lt;/code&gt; and &lt;code&gt;offset&lt;/code&gt;. The rows returned per request are capped by plan, and requesting more than your cap clamps to it rather than erroring:&lt;/p&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;Max /lookup rows per request&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;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pro ($9/mo)&lt;/td&gt;
&lt;td&gt;50&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ultra ($29/mo)&lt;/td&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mega ($79/mo)&lt;/td&gt;
&lt;td&gt;800&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;/lookup&lt;/code&gt; reflects what has already been scanned, so treat it as a warm start rather than a census of the web. For a niche library like imagesLoaded, the stronger play is the other direction: bring your own candidate domains and scan them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scaling Up with POST /analyze/batch for Your Own Domain Lists
&lt;/h3&gt;

&lt;p&gt;Batch accepts up to &lt;strong&gt;10 URLs per request&lt;/strong&gt; and scans them concurrently. Feed it a directory of photography studios, a list of agencies' portfolio clients, or an export from any lead database:&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="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": ["wpastra.com", "thisiscolossal.com", "example.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;'.results[]
| select(.result.technologies[]?.name == "imagesLoaded")
| .result.domain'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response wraps one result per URL with a per-item &lt;code&gt;error&lt;/code&gt; field, so a single unreachable domain does not fail the batch, and the top level reports &lt;code&gt;total_ms&lt;/code&gt;, &lt;code&gt;successful&lt;/code&gt;, and &lt;code&gt;failed&lt;/code&gt; counts. Each URL in a batch counts as one request against your monthly quota — a 10-URL batch costs 10 requests. Batching saves round trips, not quota.&lt;/p&gt;

&lt;h2&gt;
  
  
  Turning Detections Into a Prospect List
&lt;/h2&gt;

&lt;p&gt;Putting it together: read domains from a file, scan them in batches of 10, keep the imagesLoaded sites, and record the stack context that makes the outreach specific.&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;csv&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="n"&gt;API&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/batch&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="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="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;BATCH_SIZE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;  &lt;span class="c1"&gt;# API maximum per request
&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;domains&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Scan up to 10 domains, yielding (domain, technologies, status_code).&lt;/span&gt;&lt;span class="sh"&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="n"&gt;API&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;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;domains&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;60&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;for&lt;/span&gt; &lt;span class="n"&gt;item&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;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;item&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;result&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="n"&gt;result&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;  skipped &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;item&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="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;item&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;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;no result&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="k"&gt;continue&lt;/span&gt;
&lt;span class="n"&gt;techs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&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="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&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;meta&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;status_code&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;yield&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="n"&gt;techs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&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;domains.txt&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;domains&lt;/span&gt; &lt;span class="o"&gt;=&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="nf"&gt;strip&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;line&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt;

&lt;span class="n"&gt;prospects&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;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&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="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&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;BATCH_SIZE&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="n"&gt;chunk&lt;/span&gt; &lt;span class="o"&gt;=&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;i&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;BATCH_SIZE&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;Scanning &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&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;i&lt;/span&gt; &lt;span class="o"&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;chunk&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; of &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;domains&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="k"&gt;for&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;techs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="ow"&gt;in&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;chunk&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;status&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="c1"&gt;# The page never loaded, so script tags could not be seen.
&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;domain&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: status &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;, inconclusive&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;continue&lt;/span&gt;
&lt;span class="n"&gt;names&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;techs&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;imagesLoaded&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="n"&gt;il&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;next&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;techs&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;imagesLoaded&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;prospects&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="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="n"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;imagesloaded_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;il&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="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;wordpress&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;yes&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;WordPress&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;names&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;no&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;jquery&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;yes&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;jQuery&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;names&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;no&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;stack&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="nf"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="p"&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;domain&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: imagesLoaded &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;il&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="ow"&gt;or&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;(no version)&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="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;imagesloaded_prospects.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="nc"&gt;DictWriter&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;fieldnames&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;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;imagesloaded_version&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;wordpress&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;jquery&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;stack&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;writer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeheader&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;writerows&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prospects&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="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prospects&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; imagesLoaded sites out of &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;domains&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; domains.&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="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two details in that script carry most of the value. The &lt;code&gt;status != 200&lt;/code&gt; guard treats blocked or failed fetches as inconclusive instead of negative — a site behind aggressive bot protection returns no HTML, so the library will be absent from results even if the site runs it, and silently dropping those rows corrupts the list. And the script records the version and the surrounding stack, because "you are running imagesLoaded 3.x inside an Elementor theme with jQuery Migrate" is an opener that proves you looked, where "I noticed you have a website" is not.&lt;/p&gt;

&lt;p&gt;Results are cached for 24 hours by default. A cache hit comes back with &lt;code&gt;"cached": true&lt;/code&gt;, which is worth knowing when you rescan a list: the second pass measures the cache, not the site.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get Started
&lt;/h2&gt;

&lt;p&gt;imagesLoaded is a narrow library with a broad implication: an image-heavy site whose layout still depends on jQuery-era JavaScript, usually inside a WordPress theme that names itself in the same scan. One API call finds the library, its version, and the entire stack around it — which is the research a modernization pitch or a gallery-SaaS displacement pitch actually needs.&lt;/p&gt;

&lt;p&gt;Start with &lt;code&gt;/demo&lt;/code&gt; to confirm the signal on a site you know. Move to &lt;code&gt;/check&lt;/code&gt; for booleans, &lt;code&gt;/analyze/batch&lt;/code&gt; for your own lists, and &lt;code&gt;/lookup&lt;/code&gt; for a warm start from the index.&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-jquery" rel="noopener noreferrer"&gt;How to Detect jQuery on Any Website&lt;/a&gt; — The library imagesLoaded grew up inside, and the anchor of the same legacy stack&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/how-to-detect-slick" rel="noopener noreferrer"&gt;How to Detect Slick on Any Website&lt;/a&gt; — The carousel that shows up next to imagesLoaded on the same scans&lt;/li&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; — One of the CDNs that serves imagesLoaded as a standalone, detectable file&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/how-to-detect-cdnjs" rel="noopener noreferrer"&gt;How to Detect cdnjs on Any Website&lt;/a&gt; — The other major library-delivery CDN, detected from the page HTML the same way&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/find-companies-using-elementor" rel="noopener noreferrer"&gt;Find Companies Using Elementor&lt;/a&gt; — The page builder that enqueues imagesLoaded for its gallery widgets&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&lt;/a&gt; — Scaling the batch endpoint past a handful of domains&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; — Automating prospect qualification end to end&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; — Pushing technographic data into your CRM&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>techstack</category>
      <category>webdev</category>
      <category>api</category>
    </item>
    <item>
      <title>How to Find Companies Using WP Engine (API Guide 2026)</title>
      <dc:creator>MikeL</dc:creator>
      <pubDate>Wed, 08 Jul 2026 14:00:55 +0000</pubDate>
      <link>https://dev.to/detectzestack/how-to-find-companies-using-wp-engine-api-guide-2026-hjj</link>
      <guid>https://dev.to/detectzestack/how-to-find-companies-using-wp-engine-api-guide-2026-hjj</guid>
      <description>&lt;p&gt;WP Engine is the managed WordPress host that companies graduate to when their site becomes revenue-critical. Its plans start well above commodity shared hosting, so “uses WP Engine” is one of the rare technographic signals that encodes budget as well as technology: it tells you the company runs WordPress, cares enough about that site to pay a premium for it, and has already delegated the hosting layer to a vendor.&lt;/p&gt;

&lt;p&gt;This guide covers what a WP Engine detection tells you about a company, the exact DNS CNAME and HTTP header signals that reveal the platform, and how to turn a raw domain list into a WP Engine-confirmed lead list with the DetectZeStack API—starting with a single curl command you can run right now, no API key required.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Find Companies Using WP Engine?
&lt;/h2&gt;

&lt;p&gt;Technographic data—what technology a company actually runs—often qualifies a prospect better than firmographics alone. A WP Engine detection is a specific, verifiable fact about a company’s infrastructure, and it feeds two distinct workflows.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sales Prospecting for WordPress Agencies and Plugin Vendors
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;It confirms WordPress with budget attached.&lt;/strong&gt; Every WP Engine customer runs WordPress—the platform hosts nothing else—and pays managed-hosting prices to do it. If you sell WordPress plugins, themes, maintenance retainers, performance audits, or agency services, a WP Engine list is a WordPress list pre-filtered for willingness to spend on the site.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It maps the buyer.&lt;/strong&gt; A company on managed hosting has already decided not to run its own servers. The conversation is with a marketing or web team that owns the site as a business asset, not with an infrastructure team—which changes both the pitch and the pain points: plugin conflicts, page speed, redesigns, content workflows.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It stacks with other filters.&lt;/strong&gt; WP Engine alone is a solid segment; WP Engine plus a page builder or a marketing tool detection is a sharp one. Because a tech detection API returns the whole stack in one response, intersecting filters costs nothing extra—the same trick our &lt;a href="https://detectzestack.com/blog/find-companies-using-elementor" rel="noopener noreferrer"&gt;Elementor prospecting guide&lt;/a&gt; uses at the plugin layer.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Competitive and Migration Intelligence
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hosting-switch campaigns.&lt;/strong&gt; If you sell a competing platform or migration services, a WP Engine-confirmed list is your total addressable market, enumerated. Rescanning the same list on a schedule shows who has left the platform—and who just arrived.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Market sizing.&lt;/strong&gt; Scanning a vertical for managed WordPress adoption shows how seriously that segment treats its web presence, and how the managed-hosting share shifts over time between WP Engine, Kinsta, Pantheon, Flywheel, and the rest—all of which are detectable from the same DNS layer.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How WP Engine Reveals Itself (Detection Signals)
&lt;/h2&gt;

&lt;p&gt;WP Engine shows up in two independent layers: the DNS records that route traffic to the platform, and the HTTP headers its cache tier stamps on every response. A site that hides one layer frequently gives away the other.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Signal&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;DNS CNAME&lt;/td&gt;
&lt;td&gt;*.wpengine.com&lt;/td&gt;
&lt;td&gt;The domain points at a classic WP Engine install hostname&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DNS CNAME&lt;/td&gt;
&lt;td&gt;*.wpenginepowered.com&lt;/td&gt;
&lt;td&gt;The newer install hostname pattern (e.g. wp.wpenginepowered.com)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DNS CNAME&lt;/td&gt;
&lt;td&gt;*.wpeproxy.com&lt;/td&gt;
&lt;td&gt;The domain routes through WP Engine’s proxy network&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTTP header&lt;/td&gt;
&lt;td&gt;X-Powered-By: WP Engine&lt;/td&gt;
&lt;td&gt;The response was served by the WP Engine platform&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTTP header&lt;/td&gt;
&lt;td&gt;WPE-Backend: ...&lt;/td&gt;
&lt;td&gt;WP Engine’s cache tier names the backend that produced the response&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTTP header&lt;/td&gt;
&lt;td&gt;X-Pass-Why / X-WPE-Loopback-Upstream-Addr&lt;/td&gt;
&lt;td&gt;Cache-diagnostic headers unique to WP Engine’s stack&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  DNS CNAME Records Pointing to *.wpengine.com
&lt;/h3&gt;

&lt;p&gt;Every WP Engine install gets a platform hostname, and custom domains reach it through DNS. The classic pattern is a CNAME to &lt;code&gt;&amp;lt;install&amp;gt;.wpengine.com&lt;/code&gt;; newer installs use &lt;code&gt;&amp;lt;install&amp;gt;.wpenginepowered.com&lt;/code&gt;, and traffic routed through the platform’s proxy network resolves through &lt;code&gt;*.wpeproxy.com&lt;/code&gt; hostnames. A single &lt;code&gt;dig&lt;/code&gt; shows 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="nv"&gt;$ &lt;/span&gt;dig www.example.com CNAME +short
examplesite.wpengine.com.

&lt;span class="nv"&gt;$ &lt;/span&gt;dig www.another-example.com CNAME +short
wp.wpenginepowered.com.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All three suffixes are unambiguous—no one CNAMEs to a WP Engine hostname without being a customer. DetectZeStack matches all of them and follows the full CNAME chain to find them, since a domain often resolves through a vanity or CDN host first. For the mechanics of chain resolution, see &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;h3&gt;
  
  
  WP Engine Cache Headers and Server Fingerprints
&lt;/h3&gt;

&lt;p&gt;WP Engine fronts every install with its own caching and proxy tier, and that tier writes identifiable headers into responses. The clearest is &lt;code&gt;X-Powered-By: WP Engine&lt;/code&gt;; alongside it the platform emits &lt;code&gt;WPE-Backend&lt;/code&gt; (naming the backend that produced the response) and cache diagnostics like &lt;code&gt;X-Pass-Why&lt;/code&gt; and &lt;code&gt;X-WPE-Loopback-Upstream-Addr&lt;/code&gt;. One &lt;code&gt;curl -I&lt;/code&gt; surfaces 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;-sI&lt;/span&gt; https://www.example.com | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-iE&lt;/span&gt; &lt;span class="s2"&gt;"x-powered-by|wpe|x-pass"&lt;/span&gt;
X-Powered-By: WP Engine
WPE-Backend: apache
X-Pass-Why:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Any one of these headers confirms the platform. They are also the reason a WP Engine detection doubles as a WordPress detection: the platform hosts WordPress exclusively, so the header implies the CMS even on sites that have stripped every conventional WordPress fingerprint—a useful backdoor when the methods in &lt;a href="https://detectzestack.com/blog/check-if-website-uses-wordpress" rel="noopener noreferrer"&gt;our WordPress detection guide&lt;/a&gt; come up empty.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Header Checks Alone Miss Hardened Sites
&lt;/h3&gt;

&lt;p&gt;Neither layer is complete on its own. A CDN or security proxy in front of WP Engine can strip or overwrite the platform headers, so a header-only check returns a false negative for exactly the security-conscious companies you may most want to find. In those setups DNS often still tells the truth—or the reverse: a domain whose DNS routes through a CDN hides the WP Engine CNAME while the platform headers pass through the edge untouched. The practical rule: check both layers, and treat a hit on either as a confirmation. That is what the API does in a single request.&lt;/p&gt;

&lt;h2&gt;
  
  
  Manual Detection Methods (and Their Limits)
&lt;/h2&gt;

&lt;p&gt;For one domain, the two commands above—&lt;code&gt;dig ... CNAME +short&lt;/code&gt; and &lt;code&gt;curl -sI ... | grep -iE "wpe|x-powered-by"&lt;/code&gt;—are all you need. The limits appear when the task changes shape:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Scale.&lt;/strong&gt; Checking two layers by hand across a 1,000-domain prospect list is a script-writing project with retries, timeouts, and rate limiting to solve before you see a single result.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Chain resolution.&lt;/strong&gt; &lt;code&gt;dig +short&lt;/code&gt; shows one CNAME hop. Real domains resolve through chains—vanity host to CDN to platform—and the WP Engine hostname may sit two hops deep, where a naive check misses it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Context.&lt;/strong&gt; A manual check answers exactly one question. An API scan returns the entire stack—CMS, page builder, analytics, marketing tools—so the same request that confirms WP Engine also scores the lead.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Detect WP Engine with the DetectZeStack API
&lt;/h2&gt;

&lt;p&gt;The API runs the header and DNS checks together, follows CNAME chains, and returns everything else it finds along the way.&lt;/p&gt;

&lt;h3&gt;
  
  
  Single Domain Check with /analyze (curl example)
&lt;/h3&gt;

&lt;p&gt;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 == "WP Engine")'&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;"WP Engine"&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;"PaaS"&lt;/span&gt;, &lt;span class="s2"&gt;"Hosting"&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;"WP Engine is a website hosting provider."&lt;/span&gt;,
&lt;span class="s2"&gt;"website"&lt;/span&gt;: &lt;span class="s2"&gt;"https://wpengine.com"&lt;/span&gt;,
&lt;span class="s2"&gt;"icon"&lt;/span&gt;: &lt;span class="s2"&gt;"wpengine.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;The &lt;code&gt;source&lt;/code&gt; field tells you which layer produced the evidence. A &lt;code&gt;source: "http"&lt;/code&gt; entry at confidence 100 came from the platform headers—&lt;code&gt;X-Powered-By: WP Engine&lt;/code&gt;, &lt;code&gt;WPE-Backend&lt;/code&gt;, or one of the cache diagnostics. When only DNS gives it away, the same technology comes back with &lt;code&gt;source: "dns"&lt;/code&gt; at confidence 80 under the Hosting category instead—reliable, but one step removed from a live header match. A header-level hit also implies WordPress, so expect a WordPress entry alongside it.&lt;/p&gt;

&lt;p&gt;For production use, 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;"WP Engine"&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;"PaaS"&lt;/span&gt;, &lt;span class="s2"&gt;"Hosting"&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;"WP Engine is a website hosting provider."&lt;/span&gt;,
&lt;span class="s2"&gt;"website"&lt;/span&gt;: &lt;span class="s2"&gt;"https://wpengine.com"&lt;/span&gt;,
&lt;span class="s2"&gt;"icon"&lt;/span&gt;: &lt;span class="s2"&gt;"wpengine.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;"WordPress"&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;"CMS"&lt;/span&gt;, &lt;span class="s2"&gt;"Blogs"&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;"WordPress is a free and open-source content management system written in PHP and paired with a MySQL or MariaDB database. Features include a plugin architecture and a template system."&lt;/span&gt;,
&lt;span class="s2"&gt;"website"&lt;/span&gt;: &lt;span class="s2"&gt;"https://wordpress.org"&lt;/span&gt;,
&lt;span class="s2"&gt;"icon"&lt;/span&gt;: &lt;span class="s2"&gt;"WordPress.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;"cpe:2.3:a:wordpress:wordpress:*:*:*:*:*:*:*:*"&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;"PaaS"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"WP Engine"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;,
&lt;span class="s2"&gt;"Hosting"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"WP Engine"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;,
&lt;span class="s2"&gt;"CMS"&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;"Blogs"&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="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;The top-level &lt;code&gt;categories&lt;/code&gt; map groups every detection by category so you can slice the stack 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, not inside &lt;code&gt;meta&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;meta.scan_depth&lt;/code&gt; matters for list building. A value of &lt;code&gt;"full"&lt;/code&gt; means the HTTP fetch succeeded and the header check ran. A value of &lt;code&gt;"partial"&lt;/code&gt; means the site blocked or timed out the HTTP request and only the DNS and TLS layers completed. Because WP Engine is also detectable from its CNAME suffixes, a &lt;code&gt;"partial"&lt;/code&gt; scan can still confirm it—but an &lt;em&gt;absent&lt;/em&gt; WP Engine entry on a &lt;code&gt;"partial"&lt;/code&gt; scan is an unknown, not a no. Those domains belong in a retry queue.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scanning a Lead List with /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:&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", "example.org", "example.net"]}'&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, plus batch-level counters:&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;"example.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;"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.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;"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;h2&gt;
  
  
  Building a WP Engine Prospect List Workflow
&lt;/h2&gt;

&lt;p&gt;Because each batch &lt;code&gt;result&lt;/code&gt; matches the single-domain shape, the filtering logic is identical at any scale. 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, and appends every WP Engine-confirmed domain to &lt;code&gt;wpengine_leads.csv&lt;/code&gt; with the detection source and tech count:&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-wpengine.sh — filter a domain list down to WP Engine-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,source,tech_count"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; wpengine_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
| ($r.technologies[] | select(.name == "WP Engine")) as $wpe
| [$r.domain, $wpe.source, ($r.meta.tech_count | tostring)]
| @csv'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; wpengine_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; wpengine_leads.csv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A 1,000-domain list becomes 100 batch calls. Recording &lt;code&gt;$wpe.source&lt;/code&gt; per row lets you split header-confirmed hits from DNS-only ones downstream, 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;). Three refinements worth making before outreach:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Split by source.&lt;/strong&gt; An &lt;code&gt;http&lt;/code&gt;-sourced hit at confidence 100 means the platform headers are live on the response right now. A &lt;code&gt;dns&lt;/code&gt;-sourced hit at confidence 80 means the domain routes to a WP Engine hostname. Both are real customers; the first is the stronger opener.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-reference the rest of the stack.&lt;/strong&gt; The full &lt;code&gt;technologies&lt;/code&gt; array came back with every row you kept. WP Engine plus Elementor is an agency-built marketing site; WP Engine plus WooCommerce is a store with revenue riding on uptime—different pitches to different buyers. The broader version of this segmentation is covered in &lt;a href="https://detectzestack.com/blog/find-companies-using-wordpress" rel="noopener noreferrer"&gt;finding companies using WordPress&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Score by &lt;code&gt;meta.tech_count&lt;/code&gt;.&lt;/strong&gt; Tech count is a rough proxy for stack maturity, useful for prioritizing which confirmed leads get personal outreach first.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;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;, and the throughput, retry, and rate-limit mechanics are in &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;blockquote&gt;
&lt;p&gt;Widen the net to all managed WordPress hosts. WP Engine’s neighbors—Kinsta (.kinsta.cloud), Pantheon (.pantheonsite.io), Flywheel (.flywheelsites.com), and WordPress VIP (.go-vip.net)—are all detectable from their own CNAME suffixes in the same scan. If your real qualifier is “pays for managed WordPress” rather than “WP Engine specifically,” widen the jq filter to match any of them; every result row already contains the data.&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;The free Basic plan 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 WP Engine comes down to reading two layers well: the &lt;code&gt;X-Powered-By: WP Engine&lt;/code&gt;, &lt;code&gt;WPE-Backend&lt;/code&gt;, and cache-diagnostic response headers, and the &lt;code&gt;.wpengine.com&lt;/code&gt;, &lt;code&gt;.wpenginepowered.com&lt;/code&gt;, and &lt;code&gt;.wpeproxy.com&lt;/code&gt; DNS CNAMEs. Headers are the strongest signal; DNS is the reliable backup that still works when the HTTP fetch is blocked—and every confirmed hit doubles as a WordPress confirmation with hosting budget attached. 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 list into a WP Engine-confirmed lead list, and the &lt;code&gt;source&lt;/code&gt; and &lt;code&gt;meta.scan_depth&lt;/code&gt; fields tell you how much to trust each row. Swap the &lt;code&gt;jq&lt;/code&gt; filter and the same pipeline segments by Kinsta, Pantheon, or any other detectable technology 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-wordpress" rel="noopener noreferrer"&gt;Find Companies Using WordPress: Build Targeted Lead Lists&lt;/a&gt; — The CMS-level version of this playbook; WP Engine narrows it to paying hosts&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; — Manual and API methods for single-domain WordPress detection&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://detectzestack.com/blog/find-companies-using-elementor" rel="noopener noreferrer"&gt;Find Companies Using Elementor: Technographic API Guide&lt;/a&gt; — The page-builder filter that stacks cleanly on a WP Engine list&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 chain resolution surfaces hosting that headers hide&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 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>
  </channel>
</rss>
