SaaS Competitor Monitor
Pricing
from $6.00 / 1,000 page checkeds
SaaS Competitor Monitor
Monthly-friendly competitor monitoring for SaaS pricing pages, changelogs/release notes, docs homepages and careers/jobs pages. Fetches each page, diffs it against the last stored snapshot, and flags exactly what changed so you can wire alerts into Make/n8n/Zapier/Slack.
Pricing
from $6.00 / 1,000 page checkeds
Rating
0.0
(0)
Developer
Tommi Sullivan
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
9 days ago
Last modified
Categories
Share
SaaS Competitor Monitor — Pricing, Changelog, Docs & Jobs Change Detection (Pay Per Page-Check)
Know the moment a competitor changes their pricing, ships a release, rewrites their docs, or opens a new role. Point this actor at a list of competitor domains, schedule it monthly (or weekly), and get one clean dataset record per competitor per page-type telling you exactly what changed since last time — ready to filter and pipe into Slack, Make, n8n, or Zapier alerts.
Keywords: competitor monitoring, saas competitive intelligence, pricing page change detection, changelog tracker, website change alert, competitor pricing tracker.
Why this actor
- Alert-ready by design. Every dataset record has a
changedboolean. Filter onchanged == trueand you have a ready-made trigger for any no-code automation tool — no custom diffing logic needed downstream. - Fair pay-per-page-check pricing. No monthly subscription tool to forget about and keep paying for. Schedule this actor once a month and you pay only for the pages actually checked — see PRICING.md for the full $6/1,000 breakdown and why PPE nets out like a subscription without subscription infra.
- No browser tax. These are ordinary public marketing/docs/changelog/careers pages, not bot-protected like an app or marketplace backend, so this actor uses a plain HTTP client (
httpx) instead of a browser or TLS-impersonation stack — keeping the cost per page-check low. See "Fetching approach" below. - Real diffs, not just "something changed." Every changed page gets a human-readable
diff_summaryplus a capped unified diff, so you can see what changed without opening the page yourself.
What it does
- Accepts a list of competitors (domain/name plus optional explicit URLs for pricing, changelog, docs, and careers pages).
- For any page type without an explicit URL, falls back to a best-effort guessed path off the domain (e.g.
/pricing,/changelog,/docs,/careers) — TODO-VERIFY: these guesses are generic and not confirmed against real competitor site structures; supply explicit URLs whenever you know them for reliable results. - Fetches each page over plain HTTP, strips script/style/nav/header/footer noise, and extracts meaningful text.
- Computes a
content_hash(sha256) and, if a previous snapshot exists in the actor's key-value store, a unified diff via Python'sdifflib. - The first run for any competitor+page-type always sets
changed=falseandis_first_run=true— there's nothing to compare against yet, so it is never treated as an alert-worthy change. - Pushes one dataset record per competitor per page-type per run, and writes the new snapshot back to the key-value store for next time.
- Respects a global
maxPageChecksspend cap so a large competitor list can't run away unbounded.
Fetching approach: httpx, no browser
Competitor pricing/changelog/docs/careers pages are normal public marketing sites — they are not protected by bot-detection layers like Datadome the way a scraped app backend or marketplace API might be. There is no need for TLS/JA3 browser impersonation or residential proxies here, so this actor uses a plain httpx client. That keeps compute and bandwidth cost low, which is reflected directly in the PRICING.md.
TODO-VERIFY — known limitation: pages that render their content client-side via JavaScript (a React/Vue SPA whose pricing table is fetched and rendered after the initial HTML loads, for example) will not be captured correctly by a plain HTTP GET — the raw HTML payload may be near-empty of the actual pricing content. There is no headless browser in this build. If you notice a competitor's snapshot_text looks empty or unrelated to the real page content, that's the likely cause; a future version could add an optional headless-browser fetch path for such sites.
Input
| Field | Type | Description |
|---|---|---|
competitors | array | Competitor objects: domain/name plus optional pricingUrl, changelogUrl, docsUrl, careersUrl. Missing URLs fall back to guessed paths (see above). |
pageTypes | array | Which page types to check: pricing, changelog, docs, jobs. Defaults to all four. |
maxPageChecks | integer | Global cap on total page-checks (competitors × page-types) performed and charged per run. Default 200. |
requestTimeoutSecs | integer | Per-page HTTP timeout in seconds. Default 20. |
maxSnapshotKb | integer | Caps stored/returned snapshot text size in KB; longer pages are truncated with a note. Default 200. |
proxyConfiguration | object | Optional. Not required by default since these sites aren't typically bot-protected. Enable only if a specific competitor blocks datacenter IPs. |
Input example
{"competitors": [{"name": "Acme SaaS","domain": "acme.example.com","pricingUrl": "https://acme.example.com/pricing","changelogUrl": "https://acme.example.com/changelog"},{"name": "Beta Cloud","domain": "betacloud.example.com"}],"pageTypes": ["pricing", "changelog", "docs", "jobs"],"maxPageChecks": 200}
Output
One dataset record per competitor per page-type per run.
| Field | Type | Description |
|---|---|---|
domain | string | Normalised competitor domain. |
page_type | string | pricing / changelog / docs / jobs. |
url | string | The URL actually fetched (explicit or guessed). |
fetched_at | string | ISO-8601 UTC fetch timestamp. |
content_hash | string | sha256 hex digest of the extracted page text. |
changed | boolean | True only if this differs from the last stored snapshot. Always false on the first run. Filter on this for alerts. |
is_first_run | boolean | True if no prior snapshot existed for this competitor+page-type. |
diff_summary | string | Short human-readable summary (e.g. "3 line(s) added, 1 line(s) removed"). Only populated when changed=true. |
unified_diff | string | Capped unified diff of old vs. new text. Only populated when changed=true. |
snapshot_text | string | Extracted page text (capped at maxSnapshotKb, with a truncation note if exceeded). |
snapshot_truncated | boolean | True if snapshot_text was cut down to fit the size cap. |
http_status | number | HTTP status code of the fetch. |
Output example
{"domain": "acme.example.com","page_type": "pricing","url": "https://acme.example.com/pricing","fetched_at": "2026-07-06T09:00:00Z","content_hash": "3b1f...c9","changed": true,"is_first_run": false,"diff_summary": "2 line(s) added, 1 line(s) removed","unified_diff": "--- https://acme.example.com/pricing (previous)\n+++ https://acme.example.com/pricing (current)\n@@ -4,3 +4,4 @@\n-Starter plan: $10/month\n+Starter plan: $15/month\n+Enterprise plan: contact us","snapshot_text": "Pricing\nStarter plan: $15/month\nPro plan: $30/month\nEnterprise plan: contact us","snapshot_truncated": false,"http_status": 200}
Use cases
- Pricing-change alerts. Get pinged the moment a competitor raises, lowers, or restructures their pricing tiers.
- Changelog / release-notes tracking. Know when a competitor ships a feature that matters to your positioning, without manually checking their changelog every week.
- Docs-drift monitoring. Track when a competitor's docs homepage changes significantly (new product area, restructured navigation, new integration highlighted).
- Hiring-signal tracking. New roles on a competitor's careers page (e.g. "Enterprise Sales", "ML Engineer") are a leading indicator of their next move.
- Monthly competitive-intelligence digest. Schedule this actor once a month and build a standing "what changed" report across your whole competitive set.
Integrations
- Export to JSON, CSV, Excel, or Google Sheets.
- Apify API — pull results programmatically, schedule monthly/weekly runs.
- Make / n8n / Zapier — filter the dataset on
changed == trueand wire straight into a Slack/email/webhook alert. This is the intended integration pattern — see "What it does" above. - Apify schedules — the cleanest way to get "subscription-like" monthly monitoring: schedule the actor to run monthly with the same competitor list, and each run only pays for the page-checks performed. See PRICING.md.
FAQ
Do I need a proxy?
No, not by default. These are normal public marketing/docs pages, not bot-protected like a scraped marketplace API. proxyConfiguration is optional — only turn it on if a specific competitor blocks datacenter IPs.
What happens on the very first run for a competitor?
changed is always false and is_first_run is true — there's no prior snapshot to compare against yet, so it can never be a false-positive "change" alert. Real change detection starts from the second run onward.
Will this work on JavaScript-heavy pricing pages?
Not reliably in this version. If a competitor's page renders its real content client-side via JS, the plain HTTP fetch may miss it. See the "Fetching approach" section above — this is a known TODO-VERIFY limitation.
How accurate are the guessed default paths (/pricing, /changelog, etc.)?
Unverified — they're generic best-effort fallbacks. Real sites vary (changelog might be /release-notes, careers might be on a separate ATS subdomain like jobs.lever.co). Supply explicit URLs in competitors whenever you know them.
How is pricing structured? Pay-per-page-check: $6 per 1,000 page-checks, no subscription. See PRICING.md for the full cost breakdown and comparison to monitoring-as-a-service tools.
Legality
This actor fetches only publicly available marketing/docs/changelog/careers pages — the same pages any visitor's browser would load. It does not log in, bypass paywalls, or access private data. You are responsible for reviewing the target sites' robots.txt and terms of service and using this actor in line with applicable law. Not affiliated with or endorsed by any company whose public pages you choose to monitor.
