Website Tech Stack Monitor: Added & Removed avatar

Website Tech Stack Monitor: Added & Removed

Pricing

from $3.50 / 1,000 website checkeds

Go to Apify Store
Website Tech Stack Monitor: Added & Removed

Website Tech Stack Monitor: Added & Removed

Technology stack monitor for a public web page. Reads HTML, response headers and script URLs, then lists the technologies it can identify. Later runs report technologies added or removed since the last run. Obeys robots.txt. Does not scrape BuiltWith. Not affiliated with Wappalyzer or BuiltWith.

Pricing

from $3.50 / 1,000 website checkeds

Rating

0.0

(0)

Developer

Muhammet Mustafa Dincer

Muhammet Mustafa Dincer

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

1

Monthly active users

4 days ago

Last modified

Categories

Features

Limited permissions

Share

What is Website Tech Stack Monitor?

Website Tech Stack Monitor reads one public page and names the technologies it can see there: the CMS, the store platform, the analytics tag, the CDN, the framework. The first run saves that list. Every later run with the same watchlist name tells you what was added or removed. A technology lookup that returns one snapshot is a photo. This Actor is the diff.

Paste a domain or a page address, click Start, and schedule it. The Actor requests that page and its robots.txt. It reads the HTML, the response headers and the script, stylesheet, image and frame URLs. It does not log in, it does not run a browser, and it does not open BuiltWith, Wappalyzer or any other lookup site.

Because it runs on Apify you also get an API, schedules, webhooks and the dataset as JSON, CSV or Excel. Point a webhook at the run and the added or removed rows are the alert.

Quick answer: when should you pick this Actor?

Pick Website Tech Stack Monitor when you want to know which tools a public site is using, and you want a later run to say what changed. A company that adds a marketing tag or drops a store platform is making a tooling decision. The change rows are that signal, taken from the site itself.

Use a one-shot technology lookup when you need a single dump and you do not care about the next week. This Actor still gives you that dump on the first run. The reason to keep it scheduled is the diff.

Defaults that work: leave the prefilled site (https://wordpress.org) and click Start. The first run returns a site summary with status baseline_saved and one technology row per match, with change type baseline. Run the same input again later. If nothing changed, the summary says so and, with the default Only added or removed technologies left on, no unchanged technology rows are written. A real first run of that prefilled site is saved in assets/sample-run-data.json (WordPress, Google Tag Manager, Google Fonts and nginx, on 5 November 2026).

At a glance

DoesReads a public page and lists matching technologies. Later runs report added and removed technologies
InputDomains or page addresses, up to 50. Optional category filter
OutputOne site summary, plus one technology row per reported technology
Change typesbaseline, added, removed, and unchanged when you ask for the full list
NeedsNo login, no API key, no browser, no proxy
PricingPay per event. The prices in pricing-ppe.json are set on the platform. About $0.003 to $0.006 per website checked, plus a start event
Does notScrape BuiltWith, run JavaScript, crawl the whole site, log in, or bypass a bot wall

Fingerprint licence

The detection method is the same idea as Wappalyzer: decide from the page itself, using its HTML, its response headers and its script URLs. The patterns are not Wappalyzer's.

This Actor ships an original catalogue, written for this repository and released under Apache-2.0, the same licence as the Actor (package.json). Each pattern looks for a publicly observable signal, such as a script host (cdn.shopify.com), a path (/wp-content/), a meta generator, or a response header (cf-ray). A paragraph that merely mentions a product does not match.

The following sources were checked and not copied into this Actor:

  • Current Wappalyzer data is not open. The public Wappalyzer repository was removed in August 2023. Using today's Wappalyzer fingerprint files would mean using proprietary data. This Actor does not do that.
  • The maintained community continuation, enthec/webappanalyzer, is GPL-3.0. The last public Wappalyzer snapshot (dochne/wappalyzer) is also GPL-3.0. GPL-3.0 is an open licence, and it is copyleft: shipping those JSON files inside this Actor would require this Actor's source to be offered under GPL-3.0. The rest of this repository is Apache-2.0. Those catalogues were not vendored.
  • An older npm wappalyzer range (5.9.33 up to, but not including, 6.10.55) was published as MIT, which can sit inside an Apache-2.0 program if the MIT notice is kept. That range was not vendored either. The upstream repository is gone, later releases switched back to GPL-3.0, and a wrong pin would import copyleft patterns. The patterns in src/fingerprints.js were written here. They are not a transcription of technologies/*.json.

BuiltWith.com is not requested and not parsed. The research note for this Actor forbids that, and it is unnecessary: the site you name already publishes the HTML, the headers and the script URLs.

This is an engineering decision about which data this repository is allowed to ship. It is not legal advice.

What the Actor can and cannot see

The catalogue is a curated list (CMS, ecommerce, website builders, JavaScript frameworks and libraries, analytics, tag managers, advertising pixels, marketing and support tools, payments, CDNs, web servers, a few frameworks, security and consent widgets, fonts, monitoring and search). It is not every product on the internet. Absence is not proof. A tool that is only injected after JavaScript runs, behind a tag manager, will not appear unless the HTML already contains its script URL. The Actor does not execute JavaScript and does not open a browser.

A match can be wrong. A tutorial page that loads gtm.js, or that quotes gtag('config'...) inside a script block, can look like it uses that product. Headers such as Server: nginx are marked medium confidence because a CDN often hides or replaces them. A technology marked implied was not seen directly: Next.js implies React, WooCommerce implies WordPress. The impliedBy field says so.

Evidence is short on purpose. Script URLs are stored without the query string, so a token in ?id= or ?key= is not written to the dataset. Cookie names can be a signal (_shopify_…, laravel_session). Cookie values are never stored. Request ids (cf-ray, x-vercel-id, and similar) are noted as "present" and the value is not stored.

How a watch works

  1. Open the Actor and click Start.
  2. Keep the prefilled website, or replace it with your own domain or page.
  3. Leave Only added or removed technologies on.
  4. Click Start. The first successful run finishes with status baseline_saved.
  5. Run it again later, or create a schedule. Download the Technologies view, or call the dataset API.

The baseline is stored in a named key-value store, website-tech-stack-monitor-state, under the watchlist name (monitorName, default default). The same name compares against the same baseline. Use two names if you want two independent watches. example.com and www.example.com share one home-page baseline. example.com/pricing is a different page and a different baseline. Changing the category filter, or shipping a new fingerprint catalogue version, saves a new baseline once, so the first run after that change does not report the whole stack as added.

If the run is not allowed to create that named store, the Actor does not crash. Apify's automated store test uses a token that answers the create call with HTTP 403 (insufficient-permissions). The Actor then writes the snapshot to this run's default key-value store and continues. That copy is not kept for the next run, so the check is a first look (baseline_saved) and the dataset still lists the stack. A customer run that can create the named store keeps using it.

A page that answers with a bot wall, a robots.txt disallow, or a crawl-delay over 10 seconds is skipped. The previous baseline is left as it was. A failed read is not reported as "every technology was removed". The Actor does not retry a 403 or a 429, and it does not rotate proxies. Redirects are followed, up to five, only when each hop is a public http or https address and robots.txt allows it. Private, local and internal hosts are refused before any request.

If the HTML is longer than the read limit, the summary says the page was cut. Removals are not reported for that run, because a tag past the limit would look deleted.

What can you use it for?

See the stack once

Run any public page. Technology rows on that first run use change type baseline. The site row lists the names. Schedule nothing yet.

{
"websites": ["https://wordpress.org"],
"monitorName": "wordpress"
}

Watch for a tool being added or removed

Keep the same monitorName and run again next week. An added row is a technology that was not in the previous baseline. A removed row is one that was, and is no longer visible on this page. Turn onlyChanges off if you also want the technologies that stayed, marked unchanged.

{
"websites": ["example.com", "https://example.com/pricing"],
"onlyChanges": true,
"categories": ["Analytics", "Marketing", "Ecommerce", "Tag manager"],
"monitorName": "competitors"
}

One section of the catalogue

categories limits both detection and the baseline. A filter of Analytics will not report a new CMS. Leave the list empty to use the whole catalogue.

Compliance

You choose the pages. The Actor only requests those URLs, plus robots.txt on the same hosts. It obeys robots.txt for the path it is about to fetch (RFC 9309, including a named group for the token techstackmonitor). It waits at least one second between requests to the same host, and longer when Crawl-delay asks for it, up to 10 seconds. It does not log in, does not send cookies you provide, and does not collect personal data. There is no field for an e-mail address, a phone number or an account name.

A site's terms may still restrict automated access. You are responsible for the sites you submit. If a rights holder complains about this Actor, the publisher should take it down. This project is not affiliated with Wappalyzer, BuiltWith, Apify's competitors, or any website you scan. Product names are used only to describe a technical signal.

Pricing

Pay per event. The price is about $0.003 to $0.006 per website whose page was read, plus a start event. The prices in pricing-ppe.json are set on the platform:

EventProposed free-plan priceWhen it is charged
Actor start (apify-actor-start)$0.0005Once per run, by the platform (one event per GB of memory, at least one)
Website checked (site-checked)$0.005Once per website whose page was read, including a baseline and a run that finds no change

Paid plans in the price file step down from that $0.005: Bronze $0.0045, Silver $0.004, Gold and above $0.0035. All of those sit inside the $0.003 to $0.006 band.

A website is charged only when the read succeeds (baseline_saved or compared). Technology rows are included. These are not charged: robots.txt disallows, bot walls, refusals, unreachable hosts, invalid entries, and websites skipped because the run reached its maximum charge (not_fetched). The previous baseline of a skipped website is left as it was.

Actor.charge returning zero events is not a spending limit. The Apify SDK does that when the Actor has no pay-per-event price yet, and it leaves the limit flag off. The run still writes the rows. A real limit sets the limit flag, and only then are later websites left unread.

To cap spending, pass fewer websites or set a maximum cost per run. One website on the free-plan proposal is $0.0055 with the start event. Fifty websites, all read, are $0.2505.

Public list prices for the products people compare this work with, checked in the research for this Actor (5 November 2026): BuiltWith Basic is listed at $295 per month, and Wappalyzer Business at $450 per month. Those products are not called by this Actor, and those figures are not this Actor's price.

Tips and limits

The home page is the default. A tag that exists only on the checkout or the blog will not show up unless you pass that URL. One address is one page, not a crawl.

A new fingerprint in a later version changes the catalogue version and starts a fresh baseline. That avoids a false "added" flood when the only thing that changed is the detector.

Web server and programming-language headers are easy to hide. Treat nginx, Apache and PHP as hints. Prefer a script host or a plugin path when you are making a decision.

Support

Open an issue on the GitHub repository with the input (the domain is enough), the run status and the site-row message. Do not paste cookie values or full page HTML if it contains anything private.