Competitor Change Tracker: Pricing, Terms, Careers & Changelog avatar

Competitor Change Tracker: Pricing, Terms, Careers & Changelog

Pricing

from $0.49 / 1,000 page checkeds

Go to Apify Store
Competitor Change Tracker: Pricing, Terms, Careers & Changelog

Competitor Change Tracker: Pricing, Terms, Careers & Changelog

Track competitors' public pricing, terms, careers, changelog and sitemap pages on a schedule. Get only meaningful changes: plan and price changes, changed legal sections, new pages and roles, with summaries, severity and Slack/Discord alerts. Pay per page checked, from $0.00049.

Pricing

from $0.49 / 1,000 page checkeds

Rating

0.0

(0)

Developer

Fairquery

Fairquery

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

17 minutes ago

Last modified

Share

Track your competitors' public pricing, terms and privacy, careers, changelog and sitemap pages on a schedule, and get only the changes that matter, each with a plain-English summary and a severity. Prices are parsed per plan, legal pages are compared section by section, job boards (Greenhouse, Lever, Ashby) are compared role by role, and sitemaps show new and removed pages. Timestamps, rotating tokens, cookie banners, nav and footers are ignored.

Pricing (pay per event, no start fee): $0.00049 per page checked, $0.0049 per change reported. The first run (baseline) is charged per page only. Example: 20 competitor pages checked every hour for a month is 14,400 checks = about $7, plus $0.0049 per actual change.

How fresh is it? Exactly as fresh as your schedule. Each run is a check; the Actor does not watch pages continuously. Run it hourly, daily or weekly with an Apify Schedule.

When to use this Actor (LLM / tool selection)

Use it when a person, agent or workflow needs to:

  • Know when a competitor changes a price, adds or removes a plan, or switches monthly/annual billing
  • See which sections of a Terms of Service or Privacy Policy changed, with the removed and added sentences
  • Spot new or removed product, feature or integration pages (sitemap diff)
  • Follow hiring signals: new and closed roles by department from Greenhouse, Lever or Ashby boards, or keyword counts on a plain careers page
  • Get new changelog or blog entries with their links
  • Send alerts to Slack, Discord or any HTTPS webhook, filtered by severity

Do not use it for: pages behind a login, paywall or CAPTCHA (never accessed), visual/pixel comparison of designs, minute-by-minute monitoring, or sites whose robots.txt disallows the page (skipped and reported).

What counts as a change

Page typeWhat is comparedExample summary (from test runs)
pricingPlans: name, price, currency, period (month/year/hour), per-user units, billed annually"Pro" price changed from $79/month to $99/month (up 25.3%). · New plan "Studio" ($59/month).
terms, privacySections (by heading), sentence-level diff, renamed sectionsTerms of service: 2 sections changed: "Terms of Service" (modified: +1/−1 sentences), "Linear’s Ownership" (added). Removed: “…” Added: “…”
careersJob board (Greenhouse/Lever/Ashby) roles by id, or careers-page text and keyword counts3 new roles (3 Product); 1 role closed (1 Engineering). Open roles: 27 → 29 (+7%).
changelog, blogEntry headings and links2 new changelog entries: “Stacked pull requests”, …
product (site root)sitemap.xml URLs (index files and .gz supported)2 pages removed from the sitemap (2 product/feature-like), e.g. /features/…
genericPage text by sectionPage: 1 section changed …

Severities: high (price/plan changes, substantive legal edits about liability, data, AI, arbitration, fees, termination and similar), medium (larger text changes, product pages added/removed, notable hiring shifts, watched keywords), low (small edits, routine sitemap churn, a page switching back to a version seen before).

Noise filtering

  • Strips scripts, styles, nav, footer, cookie/consent banners and hidden templates; reads the main content.
  • Masks timestamps, dates, "x minutes ago", session tokens, UUIDs, hashes, cache-busting parameters, copyright years and live counters. Numbers are masked except on pricing and legal pages, where they matter.
  • Ignores reordered sentences, small edits under minChangeChars, and your own ignorePatterns.
  • Confirms each change with a second read (after the polite delay; not charged) so A/B variants that come and go within seconds are not reported.
  • Remembers recent versions: a page alternating between two versions across runs alerts once, then only as one low-severity "switched back" item.
  • Small edits accumulate against the old baseline until they cross the threshold, so a slow drip of edits is not lost.

Input

You can give exact pages, plain URLs (type guessed from the path), or domains plus the page types to find.

FieldDefaultWhat it does
pagesList of { "url": "...", "type": "pricing" } (types: pricing, product, terms, privacy, careers, changelog, blog, generic)
urlsPlain URL list; type guessed from the path (/pricing → pricing, /terms → terms, …)
domainsCompetitor domains; the Actor finds the requested page types via homepage links and a few common paths (cached 30 days, discovery requests are free)
pageTypespricing, terms, privacy, careers, changelog, productPage types to find for domains
watchlistNamedefaultName of this watchlist. Baselines are stored per watchlist, so different lists don't interfere
maxPages50 (≤ 200)Cap per run
minSeveritylowChanges below it are not output or charged
careersKeywords / watchKeywordsWords to count on careers pages / anywhere (e.g. "AI", "SOC 2", "enterprise")
ignorePatternsExtra regexes to ignore (ReDoS-checked)
minChangeChars20Smallest text change worth reporting (legal pages use a lower floor)
includeDifftrueInclude removed/added sentences in details
webhookUrl, webhookFormat, webhookMinSeverity, json, mediumHTTPS webhook for alerts: json, slack or discord (stored as a secret input)
renderJsneverauto: render with a headless browser only when plain HTML has no readable prices or almost no text; always: render all. Needs ≥ 1024 MB memory; robots.txt still applies
confirmChangestrueRe-read a page once before reporting a change
sitemapInclude / sitemapExclude / maxSitemapFiles/ / 10Filter sitemap URLs by regex; cap sitemap files read
requestDelaySecs1.5 (1–30)Minimum gap between requests to the same host (a larger robots.txt Crawl-delay wins)
stateStoreNamefairquery-competitor-trackerNamed key-value store in your account holding baselines
resetBaselinefalseStart over: this run becomes the new baseline

Example input

{
"watchlistName": "saas-competitors",
"pages": [
{ "url": "https://basecamp.com/pricing", "type": "pricing" },
{ "url": "https://linear.app/pricing", "type": "pricing" },
{ "url": "https://github.com/site/terms", "type": "terms" },
{ "url": "https://jobs.ashbyhq.com/linear", "type": "careers" }
],
"domains": ["cal.com"],
"careersKeywords": ["AI", "enterprise"],
"webhookUrl": "https://hooks.slack.com/services/…",
"webhookFormat": "slack"
}

Then add an Apify Schedule (for example hourly or daily) with the same input. The first run stores baselines; every later run reports changes.

Output

One dataset row per change (view Changes), plus baseline, skipped and error rows so you can see what happened to every page. A summary goes to the OUTPUT record.

Change row (from a test run; the old price was simulated by editing the stored baseline)

{
"type": "change", "watchlist": "fq-test-main", "checked_at": "2026-10-18T02:15:41.208Z",
"url": "https://basecamp.com/pricing", "page_type": "pricing", "domain": "basecamp.com",
"severity": "high", "change_kind": "price_changed",
"summary": "\"Pro\" price changed from $79/month to $99/month (up 25.3%).",
"details": { "plan": "Pro",
"from": { "amount": 79, "currency": "USD", "period": "month", "raw": "$79" },
"to": { "amount": 99, "currency": "USD", "period": "month", "raw": "$99" },
"change_pct": 25.3 },
"previous_checked_at": "2026-10-18T02:10:52.136Z"
}

change_kind values: price_changed, plan_prices_changed, plan_added, plan_removed, pricing_restructured, pricing_unparsed, pricing_text_changed, legal_text_changed, content_changed, pages_added, pages_removed, jobs_changed, careers_keywords_changed, new_entries, keyword_changed, reverted_to_seen_version.

Run summary (OUTPUT)

status, pages_checked, baselines, changes, changes_by_severity, unchanged, skipped, errors, requests, bytes_downloaded, browser_renders, events, webhook, duration_secs and a per-page list with notes such as 304 Not Modified or ROBOTS_DISALLOWED.

Pricing (pay per event)

EventPrice
Page checked (each page, job-board read or sitemap file fetched)$0.00049
Change reported (at or above minSeverity)$0.0049
Page rendered with the headless browser (optional)$0.0059

Free: baselines beyond the page check, robots-blocked/skipped/error rows, discovery requests, confirmation re-reads, filtered A/B flips below minSeverity. Set a maximum cost per run in the run options and the Actor stops before exceeding it (baselines are not saved for pages it could not pay for, so nothing is lost).

ExampleChecks per monthCost
10 pages, daily300≈ $0.16
20 pages, hourly14,400≈ $7.06 + changes
100 pages, hourly72,000≈ $35.28 + changes

How it behaves (politeness and safety)

  • Public, no-login pages only. No cookies or sessions are kept, no logins, no CAPTCHA solving, no proxies to get around blocks.
  • robots.txt is respected (RFC 9309, longest match, Crawl-delay honoured; a host asking for more than 30 s is skipped). Disallowed pages are skipped and reported. 5xx/unreachable robots.txt = not crawled. Every redirect hop is re-checked.
  • Honest user agent: FairqueryChangeTracker/1.0 (+https://getfairquery.com; fairquery@proton.me).
  • Polite rate: one request at a time per host, at least 1.5 s apart (configurable, never below 1 s), at most 4 hosts in parallel. Conditional requests (ETag / If-Modified-Since) so unchanged pages often cost the site nothing.
  • Kill switch: an HTTP 403 or 429 stops all further requests to that host for the run.
  • Plain HTTP first. The headless browser is opt-in, only for JavaScript-rendered pages, still checks robots.txt, blocks images/fonts/media and keeps no state between pages.
  • Job boards are read through their documented public APIs (Greenhouse Job Board API, Lever Postings API, Ashby Public Job Posting API).
  • Private/internal addresses are refused (SSRF protection with DNS pinning; ports 80/443 only).

Memory / runtime

256 MB is enough for plain HTTP checks (a 24-page rerun took about 7–30 s in tests). Browser rendering needs 1024 MB or more. Default timeout 30 minutes.

Limitations

  • Plan parsing is heuristic. It works on most server-rendered pricing pages (tested on Basecamp, Linear, GitHub, GitLab, Zapier, Slack, Notion, Dropbox, Netlify, Tailscale and more), but usage-based pricing pages and calculators can produce odd plan names. Even then, changes are still caught by the section text comparison, and unchanged pages produce no false alerts.
  • Prices may vary by country, currency and A/B tests. Runs use Apify datacenter IPs (usually US). The confirmation re-read and version memory reduce, but cannot fully remove, variant noise.
  • JavaScript-only pricing pages need renderJs and 1 GB memory. Sites that block automated access are skipped, never worked around.
  • Freshness equals your schedule. Changes made and reverted between two runs are not seen.
  • If the same watchlist is run twice at the same time, the runs can overwrite each other's baselines. Schedule one run per watchlist at a time.
  • Baselines live in a named key-value store in your account until you delete it.

FAQ

How is this different from Visualping or Distill? Those compare screenshots or text and alert on any difference. This Actor understands page types: it tells you which plan's price moved and by how much, which legal section changed, which roles opened, and it ignores dates, tokens and banners. It runs on your Apify schedule and is billed per check, with no monthly plan.

Does the first run report anything? No. It stores a baseline per page and outputs one baseline row per page (charged as a page check only).

Can I get alerts in Slack? Yes: set webhookUrl to a Slack incoming webhook and webhookFormat to slack. Only changes at or above webhookMinSeverity (default medium) are sent.

Will it get my IP banned? It sends roughly one request per page per run, with honest identification, robots.txt and delays. If a site answers 403 or 429, the Actor stops contacting it for the rest of the run.

Is it real-time? No. It checks when it runs. Use an Apify Schedule for the frequency you need.

Fairquery family

Other Fairquery tools on the Apify Store. Each one returns structured rows with machine-readable error codes, and error rows are never charged:

All Fairquery Actors: https://apify.com/fairquery

Disclaimer

Fairquery is not affiliated with any of the sites mentioned. Page content belongs to its owners. Use the Actor only for public pages and in line with the sites' terms.