# Tech Stack Change Detector (`zinin/tech-stack-change-detector`) Actor

Detect a website's current technologies (CMS, ecommerce, analytics, marketing/CRM, framework, hosting/CDN, chat, payments) and diff it against a previously-seen stack you supply, so you get exactly what was added or removed. No browser, no proxies, no login.

- **URL**: https://apify.com/zinin/tech-stack-change-detector.md
- **Developed by:** [Tim Zinin](https://apify.com/zinin) (community)
- **Categories:** Developer tools, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $8.50 / 1,000 domains

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Tech-Stack Change Detector — Diff a Site's Stack

Know when a prospect or competitor swaps a tool — Shopify replacing WooCommerce, HubSpot dropping in, a migration to Next.js — without paying for a technographic monitoring seat. Give this Actor a domain and, optionally, the stack you saw last time, and it returns what's live right now plus what was **added** and **removed** versus what you supplied.

### What you get

- **A real diff, not just a snapshot.** Supply `domain|Tech1,Tech2` and get back exactly what changed since you last looked — `added` and `removed`, not just a technology list to compare by eye.
- **Stateless by design.** No stored history to trust or pay for — you own the "previous" side of the diff, this Actor just reads the current stack fresh every run.
- CMS, ecommerce, analytics, marketing/CRM, chat, JS framework, payments and hosting/CDN signatures — the same detection engine as [`tech-stack-detector`](https://apify.com/zinin/tech-stack-detector).
- A `stackHash` — a stable, sorted fingerprint you can store and feed back in as the `previousStack` next time.
- No browser, no proxies, no login — reads public HTML and HTTP headers only.
- Runs on Apify: schedule it, monitor it, call it from the API or the MCP server, export to JSON, CSV or Excel, or push results straight into your own pipeline.

### How to run it

1. Click **Try for free** — no card needed on the free plan.
2. Paste domains into **Domains**, one per line — bare (`example.com`) to just read the current stack, or with a previous stack after a pipe (`example.com|Tech1,Tech2`) to get a diff.
3. Hit **Start** and pull the results from the dataset (UI, API or webhook).

### Pricing

Pay-per-event: **$0.005 per run start + $0.01 per domain checked**. No monthly seat. 100 domains cost about **$1.01**; 1,000 domains about **$10.01**.

A domain that could not be fetched (timeout, blocked, HTTP error) is still returned with `found: false` and the reason — and it is **not** charged. You pay for domains actually analyzed.

### Input

Each item is a domain, optionally followed by `|` and a comma-separated list of technologies you last saw for that domain:

| Field | Required | What it does |
|---|---|---|
| `items` | yes | `"example.com"` to just read the current stack, or `"example.com\|Tech1,Tech2"` to diff against a previous stack. Up to 100 per run. |
| `maxConcurrency` | no | How many domains to check in parallel (1–50, default 10). |

```json
{
    "items": ["gymshark.com", "gymshark.com|WordPress"]
}
```

### Output

One row per domain. This is a real row from a real run, for the diff-form input `gymshark.com|WordPress` — the domain redirects to its checkout subdomain, which no longer runs the WordPress it once did:

```json
{
    "input": "gymshark.com|WordPress",
    "domain": "us.checkout.gymshark.com",
    "found": true,
    "httpStatus": 200,
    "technologies": ["Shopify", "Zendesk", "Cloudflare"],
    "stackHash": "Cloudflare|Shopify|Zendesk",
    "previousStack": ["WordPress"],
    "added": ["Shopify", "Zendesk", "Cloudflare"],
    "removed": ["WordPress"],
    "checkedAt": "2026-07-26T13:23:09.900Z"
}
```

| Field | What it means |
|---|---|
| `domain` | The resolved hostname actually checked (redirects are followed) |
| `technologies` | Every technology detected right now |
| `stackHash` | Sorted, pipe-joined technology list — a stable fingerprint you can store and pass back in as `previousStack` next time |
| `previousStack` | Echo of what you supplied after the `\|` (empty array if you didn't supply one — a bare `"example.com"` input returns `added: []` and `removed: []`) |
| `added` | Technologies present now but not in `previousStack` |
| `removed` | Technologies in `previousStack` but not detected now |
| `found` | Whether the fetch succeeded |

### How to track real change over time

This Actor doesn't keep a database of past runs. To monitor drift, **you** keep the last `stackHash`/`technologies` for each domain (a small key-value store, a spreadsheet column, whatever fits your pipeline) and feed it back in as the `|previousStack` on the next run. That keeps the Actor cheap and lets you own the history.

#### Related tools

Related tools for adjacent workflows in B2B lead generation and data enrichment.

| Actor | What it does |
|---|---|
| [Website Tech Stack Detector](https://apify.com/zinin/tech-stack-detector) | Pair it in the B2B lead generation and data enrichment workflow: Detect the technologies a website runs — CMS, ecommerce platform, analytics, marketing/CRM, JS framework,... |
| [Company Profile Lookup](https://apify.com/zinin/company-lookup) | Pair it in the B2B lead generation and data enrichment workflow: Turn a domain or company name into one unified company card: website tech stack (CMS, ecommerce, key tech)... |
| [Company Hiring Radar](https://apify.com/zinin/company-hiring-radar) | Pair it in the B2B lead generation and data enrichment workflow: Pull every open role a company is hiring for from its public job board (Greenhouse, Lever, Ashby) and turn... |
| [B2B Lead Enricher](https://apify.com/zinin/b2b-lead-enricher) | Pair it in the B2B lead generation and data enrichment workflow: Turn a list of company websites into sales-qualified lead cards: detected tech stack, a rough revenue... |
| [Company Registry Enricher](https://apify.com/zinin/company-registry-enricher) | Pair it in the B2B lead generation and data enrichment workflow: Turn a company name, LEI or UK company number into an official registry card: legal name, status,... |

### FAQ / Limitations

**Does it store history between runs?** No. Supply the previous stack yourself via `domain|Tech1,Tech2` to get a real diff; omit it to just read the current stack.

**Does it render JavaScript?** No — it reads served HTML and headers, same as `tech-stack-detector`. Technologies injected only after heavy client-side rendering may not appear.

**Is this legal?** Yes — it reads publicly served HTML and standard HTTP headers, the same data any browser receives.

**Can I call it from an AI agent?** Yes — it's a standard Apify Actor, callable via the Apify API or the Apify MCP server.

**What this is NOT.** It does not crawl a whole site or discover pages — it checks the one URL you give it (after redirects) and does not detect a technology change that happened and reverted between two of your runs.

Found a wrong result, or need a check we don't run? Open an issue on this Actor's page.

***

Built by [zinin](https://apify.com/zinin). Questions? Telegram [@timzinin](https://t.me/timzinin).

# Actor input Schema

## `items` (type: `array`):

One entry per domain. Bare form: "example.com" (just detects the current stack). Diff form: "example.com|Tech1,Tech2,Tech3" — everything after the pipe is the stack you last saw for this domain; the Actor returns what was added/removed vs. right now.

## `maxConcurrency` (type: `integer`):

How many domains to check in parallel.

## Actor input object example

```json
{
  "items": [
    "shopify.com",
    "wordpress.org|WordPress,jQuery"
  ],
  "maxConcurrency": 10
}
```

# Actor output Schema

## `results` (type: `string`):

API URL for the default dataset items produced by this run.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "items": [
        "shopify.com",
        "wordpress.org|WordPress,jQuery"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("zinin/tech-stack-change-detector").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "items": [
        "shopify.com",
        "wordpress.org|WordPress,jQuery",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("zinin/tech-stack-change-detector").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "items": [
    "shopify.com",
    "wordpress.org|WordPress,jQuery"
  ]
}' |
apify call zinin/tech-stack-change-detector --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=zinin/tech-stack-change-detector",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/gBbWeNb0ipM0b0VE0/builds/dtxyVJ4sepmsp3dkl/openapi.json
