The one-line rule

Every price published on PlanIntel must come from a real HTTP fetch of a real official source — the provider's own pricing page or their App Store listing — stored with a timestamp, a source URL, and a content hash. No estimates, no manual entry, no third-party price aggregators.

If we cannot fetch a reliable price from an official source, we do not publish a price.

Step 1: Source selection

Each service has one collector with one predetermined source URL per market:

Service Source type Why
Netflix netflix.com/[cc]/ pricing page Server-rendered, publicly accessible, embeds price JSON in page data
Spotify spotify.com/[cc]/premium/ Server-rendered pricing section
ChatGPT Plus Apple App Store (App ID 6448311069) chatgpt.com is Cloudflare-gated and requires login; App Store is public
Audible Apple App Store (App ID 379693831) Same reason as ChatGPT Plus
Crunchyroll Apple App Store (App ID 329913454) Same reason
Paramount+ Apple App Store (App ID 1340650234) Same reason

When we use App Store pricing, the page notes "price via App Store listing" and the source_type field in our database is set to app_store. The App Store lists the same price the subscriber actually pays, verified by Apple's billing system.

Step 2: Parsing

Collectors use two strategies depending on the source:

JSON extraction (Netflix, Spotify): the page embeds structured price data in a __NEXT_DATA__ blob or similar JSON payload. We extract from the structured data, not from the visible HTML text — this is more reliable than text parsing and survives layout redesigns.

Text extraction (App Store pages): we identify the price by locating a known text anchor (plan name, "per month" label) and applying a regex to the scoped text window around it. The currency is verified against the market's expected currency before the price is accepted.

Step 3: Sanity bands

Every service-market combination has a minimum and maximum price. A price outside this band is never auto-published; it is queued for human review.

The bands are intentionally wide — they catch catastrophic parser failures (a decimal shift turning €13.99 into €139.90) but allow all plausible legitimate price movements. A band set to min €3.00 / max €50.00 passes any realistic streaming price while blocking obviously wrong extractions.

Step 4: Append-only storage

When a new observation matches the current price, it updates the observation timestamp only — a freshness confirmation with no price change event generated.

When the price differs, a change event is recorded: old price, new price, percentage change, effective date, and the collection run that produced it. The old price record is never deleted or overwritten.

This means:

  • Every historical price on PlanIntel can be traced to the exact collection run that produced it
  • Corrections are audited: if a price was wrong and we correct it, the correction event shows the reviewer and timestamp; the original observation remains in the history
  • There is no interpolation: the history charts only show dates when we actually collected a reading

What "verified" means on a price page

When a price page shows "Verified 2026-08-02", it means: our collector fetched this price from the official source on that date, the parsed value passed the sanity band check, and it was stored in the database as the authoritative current price.

It does not mean the price is guaranteed to be correct today — prices can change between collection runs. If a price changes between our weekly collection sweeps, the page will show the previous observation's date and a "last verified X days ago" signal. The freshness SLA for our standard services is 7 days.

Reporting a wrong price

If you believe a displayed price is incorrect, use the report form on how-we-source-prices. We will re-verify against the source URL, and if you are right, we will record a correction with your report timestamp. The original observation is never deleted.