Website Tech Stack Scraper & Change Monitor avatar

Website Tech Stack Scraper & Change Monitor

Pricing

$1.00 / 1,000 successful domain checks

Go to Apify Store
Website Tech Stack Scraper & Change Monitor

Website Tech Stack Scraper & Change Monitor

Detect website technologies in bulk and monitor when prospects or competitors add, remove, or switch SaaS tools. Get deterministic fingerprints, confirmed-removal semantics, CRM IDs, DNS/TLS enrichment, and explicit per-domain failures without a BuiltWith or Wappalyzer account.

Pricing

$1.00 / 1,000 successful domain checks

Rating

0.0

(0)

Developer

Vadim Bezrukov

Vadim Bezrukov

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Share

Detect technologies used by websites in bulk and monitor when prospects or competitors add, remove, or switch SaaS tools. Use it as a website technology checker, technology stack detector API, technographic data feed, or confirmed technology change monitor.

The Actor analyzes each target website directly. It does not scrape BuiltWith or Wappalyzer, does not require an account with either service, and is not affiliated with them. The detector uses a small independently authored set of high-confidence signatures rather than a large third-party fingerprint dump.

What it returns

Every requested domain gets exactly one record, including invalid, blocked, and failed inputs. A successful record contains:

  • the normalized current technology stack with category, version when explicit, confidence, and evidence surface names;
  • optional normalized MX/nameserver providers and TLS certificate metadata;
  • a deterministic semantic fingerprint and versioned detector metadata;
  • BASELINE, UNCHANGED, TECH_ADDED, MISSING_PENDING, TECH_REMOVED_CONFIRMED, or TECH_VERSION_CHANGED events;
  • your own external_id for CRM/account/watchlist joins.

technologies: [] with SUCCESS means a complete public page was fetched and none of the supported high-confidence signatures matched. A timeout, 403, challenge page, invalid response, or truncated page is never converted into that answer; it is FAILED, BLOCKED, or PARTIAL. If a pay-per-event run reaches the user's maximum charge, untouched inputs receive SKIPPED_BILLING_LIMIT and their monitor state is retained.

Pricing

The Actor costs $0.001 per distinct complete SUCCESS domain check — $1 per 1,000 successful websites. Platform usage is included and there is no start fee. Snapshot and monitor checks have the same predictable price, including an UNCHANGED result because a fresh live verification was performed.

Duplicate aliases, retries, PARTIAL, FAILED, BLOCKED, INVALID_DOMAIN, and SKIPPED_BILLING_LIMIT are free. DNS queries, TLS enrichment and emitted change events are not separate billable events. The Actor charges while the successful row is stored; monitor state advances only after that row was delivered and billed.

Ready-to-run examples

Quick start: one-domain lookup

{
"domains": [{ "domain": "example.com" }],
"mode": "snapshot",
"outputMode": "all",
"includeDns": true,
"includeTls": false
}

Run from the CLI after the Actor is deployed:

$apify call YOUR_USERNAME/website-tech-stack-monitor --input-file input.json

The full input and representative output are in examples/.

CRM domain batch

{
"domains": [
{ "domain": "prospect-a.com", "externalId": "salesforce-001" },
{ "domain": "prospect-b.com", "externalId": "salesforce-002" },
{ "domain": "prospect-c.com", "externalId": "salesforce-003" }
],
"mode": "snapshot",
"outputMode": "all"
}

The Actor fetches duplicate normalized domains once, but still emits one row per input so every external ID receives an answer.

Competitor watchlist

{
"domains": [
{ "domain": "competitor-a.com", "externalId": "competitor-a" },
{ "domain": "competitor-b.com", "externalId": "competitor-b" }
],
"mode": "monitor",
"outputMode": "changesOnly",
"watchTechnologies": ["Shopify", "WooCommerce", "Magento", "HubSpot", "Klaviyo"],
"includeDns": true
}

The current stack is always present because the per-domain status row must remain unambiguous. changesOnly suppresses the redundant UNCHANGED object inside events, while keeping the main row with change_type: UNCHANGED; it never suppresses failure or invalid-domain rows. This preserves the batch invariant: 100 inputs produce 100 explicit statuses. all includes the explicit UNCHANGED event as well.

Sales and competitive signals

Shopify migration

A switch from Shopify to another platform is reported as exact raw events, not an invented intent score:

[
{ "type": "TECH_ADDED", "technology": "Magento", "before": null, "after": { "name": "Magento" } },
{ "type": "TECH_REMOVED_CONFIRMED", "technology": "Shopify", "before": { "name": "Shopify" }, "after": null, "missing_successful_scans": 2 }
]

The events may arrive on different runs: addition is immediate on strong evidence, while removal needs two independent complete successful missing scans.

HubSpot or Klaviyo adoption

Use watchTechnologies: ["HubSpot", "Klaviyo"]. A new strong vendor-script or cookie signal produces TECH_ADDED with exact after technology data. That row can go directly to a CRM webhook as an adoption trigger.

Safe change semantics

Monitor state lives only in Apify KVS and is keyed by normalized domain plus the relevant scan configuration. It stores the last confirmed technology set, compact evidence/confidence, missing counters, fingerprint, detector versions, and observation time.

present -> first complete successful scan missing -> MISSING_PENDING
-> second complete successful scan missing -> TECH_REMOVED_CONFIRMED

FAILED, BLOCKED, and PARTIAL scans never increment the counter and never overwrite good state. If the detector or signature database version changes, the first complete run emits DETECTOR_REBASELINE and adopts a fresh baseline; it does not manufacture a wave of additions/removals.

Daily schedule

First save the monitor input as an Apify Task and test it. Then create a daily 08:00 schedule with the API (replace placeholders; keep the token in an environment variable, never in source control):

curl -X POST "https://api.apify.com/v2/schedules" \
-H "Authorization: Bearer $APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Daily website technology watchlist",
"isEnabled": true,
"isExclusive": true,
"cronExpression": "0 8 * * *",
"timezone": "UTC",
"actions": [{ "type": "RUN_ACTOR_TASK", "actorTaskId": "YOUR_TASK_ID" }]
}'

Apify schedule syntax and timezone behavior are documented at https://docs.apify.com/actors/running/schedules.

Webhook sales trigger

Create a run-succeeded webhook on the saved Task. The payload carries the run and dataset IDs; your receiver then reads dataset rows whose events contain TECH_ADDED, TECH_REMOVED_CONFIRMED, or TECH_VERSION_CHANGED:

curl -X POST "https://api.apify.com/v2/webhooks" \
-H "Authorization: Bearer $APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"requestUrl": "https://crm.example/webhooks/technology-change",
"eventTypes": ["ACTOR.RUN.SUCCEEDED"],
"condition": { "actorTaskId": "YOUR_TASK_ID" },
"payloadTemplate": "{\"run_id\":\"{{resource.id}}\",\"dataset_id\":\"{{resource.defaultDatasetId}}\"}",
"shouldInterpolateStrings": true,
"description": "Website technology sales signals"
}'

Webhook behavior is documented at https://docs.apify.com/integrations/webhooks.

Use with AI agents through Apify MCP

Expose the Actor as a typed MCP tool:

https://mcp.apify.com?tools=automa-flow/website-tech-stack-monitor

Example prompt:

Run automa-flow/website-tech-stack-monitor for these company domains. Return the
detected ecommerce, analytics, CRM, email, and infrastructure technologies,
separate FAILED or PARTIAL scans, and cite each source_url and evidence surface.

For recurring sales or competitor workflows, use mode: monitor and act only on confirmed TECH_ADDED, TECH_VERSION_CHANGED, and TECH_REMOVED_CONFIRMED events. A failed scan never confirms a removal.

Detection surfaces and supported scope

The default path is one public homepage fetch. The Actor inspects final URL, HTTP headers, Set-Cookie names, generator/meta values, script/link URLs, and a small number of explicit inline identifiers. Optional DNS makes two queries (MX and NS). TLS is off by default. Raw HTML, cookie values, arbitrary TXT records, personal contacts, and giant evidence snippets are never returned.

Every initial target and redirect hop is resolved once and the connection is made to that exact verified public IP while retaining the original HTTP Host and TLS SNI. The optional proxy CONNECT target is pinned the same way. Private, loopback, link-local, and other non-public addresses are rejected before any request bytes are sent; transient resolver failures remain explicit failures rather than being mislabeled as invalid input.

The curated MVP covers 40+ commercially important technologies across CMS, ecommerce, frameworks, analytics, advertising, CRM/marketing automation, payments, live chat, CDN/hosting, and consent management. The exact selectable names are listed in the Input Schema.

Limitations

  • No JavaScript execution: runtime-only tools may be missed.
  • Normally one page: technologies absent from the homepage are not discovered.
  • Consent, geo/A-B variants, and personalized templates can hide scripts. This is why removals require confirmation.
  • Confidence is a deterministic rule strength, not a machine-learning probability and not a claim of complete coverage.
  • Direct HTTP is normal. An optional Apify datacenter proxy is attempted only after a failure/block when explicitly configured. Residential proxy, CAPTCHA solving, login, and access-control circumvention are out of scope.
  • Fingerprints are intentionally curated for precision. This Actor will detect fewer obscure technologies than a multi-thousand-rule browser database.

Economics and benchmark

The 2026-09-01 direct-HTTP PoC tested 100 diverse domains. At concurrency 10 it completed in 18.4 seconds: 81 SUCCESS, 11 BLOCKED, 8 transport failures, about 52.1 MB inspected, one normal request/domain, no browser, and no proxy. Concurrency 25/50 did not improve useful throughput, so the Actor caps work at 10 domains. Full research and raw per-domain measurements are under experiments/tech-stack/ in the source repository.

An official Tranco top-1,000 economics run completed in 154.5 seconds, inspected 197.4 MB, and measured 72.7 MB of peak traced Python allocations: 525 web successes, 89 blocks, and 386 failures/non-web endpoints. It made exactly 1,000 homepage requests and used no proxy/browser. Optional DNS adds two queries per successfully fetched domain; TLS remains opt-in.

The pay-per-event contract bills only a distinct complete SUCCESS domain check. Charging per technology change would make quiet daily monitors unpredictable, so exact change events remain included in the domain-check price.

Source-risk classification is MODERATE because every target domain has its own terms. The Actor accesses only public homepage technical signals, normally once per check. It does not log in, visit admin/private paths, bypass access controls, collect personal contacts, or build a copy of target content. Users must ensure their domain list and schedule comply with applicable terms and law.

Output contract

Records are history-ready from the first run: stable source_id, UTC scraped_at, additive schema_version, semantic fingerprint, detector_version, and fingerprint_database_version. Datasets remain append-only observations. The Actor does not build a historical database; KVS holds only compact monitoring state.