Skip to content
AI Price WatchPublic price desk

How this desk works

What we capture, and what we refuse to guess

AI Price Watch is a static site. A rebuild reads the latest weekly snapshot for each tool from D1 when a Cloudflare API token is available, and fetches the public pricing page when that row is missing or the API cannot be read. The change log keeps the hand-checked cited sources, and adds snapshot diffs from D1 when that read succeeds.

This build

Oct 16, 2026.48 of 73 tools include at least one currency amount. This build fetched public pricing pages. No D1 snapshot was used.

Fetcher

AIPriceWatchBot/1.0 (+https://ai-price-watch.pages.dev/methodology; public pricing snapshot)

Not a quote

Extracted lines can miss prices that only appear after JavaScript runs. The vendor page is the authority.

Build-time capture

npm run build runs scripts/fetch-pricing.ts before Astro. When CLOUDFLARE_API_TOKEN is set, the script queries this project’s D1 database over the Cloudflare API and keeps the newest snapshot per tool. Set CLOUDFLARE_ACCOUNT_ID when that token can see more than one account. Tools with no snapshot row are fetched live. If the token is missing or the API call fails, every public pricing page is fetched instead. For a live fetch the script requests /robots.txt, parses Allow and Disallow for AIPriceWatchBot and the * group, and skips the page when the pricing path is disallowed. If robots.txt cannot be read, the page is skipped rather than fetched blind. Redirects are followed only over https, and each hop is checked again.

From the HTML we keep plan names, currency amounts, and short surrounding lines. We do not store the full page. Structured data (application/ld+json offers) is included when the page publishes it. A tool counts as a live capture only when that extract contains at least one currency amount.

Terms

We fetch public marketing and documentation URLs that vendors publish for pricing. We do not log in, bypass paywalls, or send a browser identity to get around a block. Crawl-delay is honored up to three seconds. If a vendor’s terms forbid automated access even when robots.txt allows it, remove that URL from src/data/catalog.json.

Change log

Seed entries in src/data/changes.json are limited to pages we opened that show both a date and the pricing fact. Each entry links that page. A price that only appears in memory, a social post we did not archive, or an undated aggregator is left out. “Held” means a vendor cancelled a scheduled increase or kept an introductory price. “Repriced” means the meter changed without a single new sticker price.

Weekly worker

worker/index.ts is a Cloudflare Worker with a D1 binding. Five Monday cron triggers each snapshot 12 tools, so a full pass of the catalog finishes in one afternoon without a single invocation fetching every site. The worker uses the same robots check and the same price-line extract. When two successful extracts differ, it writes a row to price_changes. The next static build that can read D1 copies the latest snapshots onto the tool pages and lists those diffs as Snapshot diff. Cited entries in src/data/changes.json stay either way. After migrations/0002_snapshot_payload.sql is applied, the cron also stores the full plan extract, so a rebuild can show plan names and not only the normalized price lines.

Affiliate links

Alternative cards link to /go/[tool]. That page says the link is a placeholder. There is no affiliate network, no tracking parameter, and no payment. The button on that page sends you to the vendor’s own site.

Capture outcomes in this build

  • Live price capture48
  • HTTP error7
  • Page loaded, no currency amount in the HTML13
  • robots.txt could not be read4
  • Fetch failed1