Detect changes on a SaaS pricing page
Build a local pricing-page tracker that preserves good snapshots and reports changed content for review.
Build a pricing-page review signal
This small program checks a public pricing page, stores its Markdown locally, and compares the next successful result with that baseline. It prints added and removed lines when content changes. It makes no claim that a text edit proves a price increase: plan descriptions, dates and experiments can change too.
First, try the page in Website to Markdown. Confirm that the prices and billing periods you care about are in the extracted content before making it repeatable.
Run it twice
Use Node.js 22 or later. Create a FetchRelay key and set FETCHRELAY_API_KEY in your terminal environment or secret manager.
git clone https://github.com/JAIPilot/fetchrelay-integrations.git
cd fetchrelay-integrations/examples/web-data-recipes
node pricing-tracker.mjs https://fetchrelay.com/pricing pricing.state.json
node pricing-tracker.mjs https://fetchrelay.com/pricing pricing.state.json
FetchRelay's own public pricing page is the starter target. Replace the URL with a public page you have permission to access. Use a separate state file for every URL. Every successful invocation consumes an account credit; the example requests fresh extraction rather than cached content.
Read the three outcomes
| Status | Meaning | Next action |
|---|---|---|
baseline_created | First successful snapshot saved | Keep the state file for the next run |
unchanged | Extracted Markdown matches the baseline after line-ending normalization and trimming | No content difference detected |
content_changed | Extracted Markdown differs | Inspect added and removed lines, then verify the source page |
A changed response includes addedLines and removedLines. The comparison uses sets of lines, so it is not a complete ordered diff. Reordering text can change the content hash without producing added or removed lines. Review the source when that happens.
The tests use synthetic $10 and $20 fixtures to exercise changed-content behavior. Those values are not a report about an actual company's prices. The live release check creates and repeats a baseline on FetchRelay's pricing page.
Preserve the last good result
An empty result, extraction warning or failed request leaves the baseline unchanged. A successful snapshot replaces it using a temporary file and rename. A lock prevents overlapping writers; if a process is forcibly killed, remove the leftover lock only after confirming no instance is still running. A baseline belonging to another URL or with invalid content is rejected before a new extraction is requested.
Keep the state file outside version control. It stores the last successful snapshot, not an audit history. Save the program's JSON output separately if you need to retain every change event. There are no automatic email, webhook or chat messages.
Schedule only after checking quality
Run manually on your target first. Use a scheduler only when you can persist the state file, store the key as a secret and prevent overlapping executions. Choose a frequency that fits your allowance and the site's access policy. If a request times out, check usage before retrying.
Navigation, currency localization and A/B tests can produce differences unrelated to pricing. Confirm plan name, currency, monthly versus annual billing and the effective date before reporting a price change. For hosted scheduling and run history, see FetchRelay monitors.
Clone the complete pricing tracker. It has no npm dependencies and includes tests for baseline creation, changes, corrupt state and preserving the baseline after failures.