Skip to main content
Have an agent build it. Copy the brief below into Claude Code, Cursor, or any coding agent with access to your project. It states the calls, the questions worth asking you first, and the mistakes to avoid.
Pricing pages move. Competitors quietly add a feature. A supplier changes their terms. You want to know when, without a person checking every week. There is no change endpoint. There is something better: fetches that are cheap when nothing moved, so a scheduled re-read is affordable and you diff the results yourself.

The pipeline

1. Pick the pages, once

Use map to list the site, and keep the handful that actually matter. Watching a whole site produces noise; watching a pricing page and a features page produces signal.

2. Re-read them on your schedule

Run a batch over the watched URLs from your own cron, and set maxAge to control how stale a stored copy may be before we go back to the origin.
Set maxAge to 0 when the whole point is to see the current state. Leave it high when you are rebuilding an index and a day old copy is fine.

3. Normalise before you compare

This is the step that decides whether anyone still reads your alerts in a month. A page changes on every single request for reasons that have nothing to do with the content: a rotating testimonial, a “trusted by 4,312 teams” counter, a copyright year, a build hash in a footer, a relative timestamp reading “3 hours ago”. Diff the raw text and every one of those fires an alert, and a channel that cries wolf daily gets muted in a week. Strip them before comparing. Drop anything matching a date or time pattern, collapse runs of whitespace, and remove the lines you have already seen change without meaning anything. Keep the list of exclusions in code next to the watch, because it grows every time a new false positive appears. Compare the cleaned Markdown rather than the HTML. HTML changes constantly and means nothing: a reordered script tag, a rotated asset hash, a session id. The Markdown changes when the words change, which is the thing you actually wanted to be told about.

4. Treat a failure as a change too

A page that stops answering is news. If a URL you have watched for six months starts returning a 404, that is a product that got retired or a page that moved, and it is usually more interesting than an edited sentence. Every batch result carries a per-page status, and a failed page carries an error and an errorCode. Report those rather than skipping them, but do not treat one bad run as a deletion. A page has to fail two or three consecutive runs before it is gone, otherwise a momentary blip reads as a removal.

5. Get told, instead of polling

Attach a webhook to the batch and receive the results when they land, rather than holding a polling loop open. See Jobs and webhooks for the delivery shape and retry behaviour.

Making the alert worth reading

An alert saying “example.com/pricing changed” is a task, not information. The reader still has to open two tabs and compare them by eye, and after the third such alert they stop. Store the previous Markdown itself, not a hash of it. A hash tells you something changed and nothing about what, which turns every alert into an investigation. With the previous version in hand you can show a real diff in the message. Send the diff, trimmed to the changed lines with a little surrounding context. For most watches that is three or four lines, and it is the difference between an alert someone acts on and one they archive. Say what did not change too, at least in a weekly summary. Silence is ambiguous: it reads the same whether nothing moved or the watch quietly broke three weeks ago.

Knowing the watch still works

A monitor that fails silently is worse than no monitor, because you believe you are covered. Record every run, not just the ones that found something. If a watch has reported no changes for a month, check that it is still running and still fetching successfully rather than assuming the site is stable. Watch the fetch quality as well as the content. A page that starts coming back with a much lower wordCount than usual has probably started serving a consent wall or a login page rather than losing most of its content, and diffing that against last week produces a spectacular and completely useless alert. Re-run discovery occasionally. A map every month or so catches the pages that appeared since you picked your list, which is how a competitor’s new pricing tier gets noticed rather than missed because it lives at a URL you never knew existed.

What it costs

1 credit per page read. Watching six pages daily is 6 credits a day, or about 180 a month. Discovery is 1 credit per map, so a monthly re-check of the URL list is a rounding error against the watching itself.

What to watch for

Daily is almost always enough. Nobody’s pricing page changes hourly, and reading it hourly is how you become a problem for someone else’s site. Watch few pages deliberately rather than a whole site automatically. Ten pages you chose produce signal; four hundred pages you crawled produce a feed nobody reads. Set maxAge to 0 when the whole point is to see the current state. Leaving the default means a stored copy can answer, which is right for indexing and wrong for monitoring.