# Codebook: pricing-page corpus, 9 August 2026 Every field in `corpus.csv` is machine-derived from a rendered page that is archived. Two rows per vendor, one per language arm. `frame.md` is the vendor list, fixed before any page was opened. ## The definition > **The pricing page a visitor reaches from the vendor's own homepage navigation**: English under > `Accept-Language: en-US`, German under `de-DE`. Not "a pricing page exists somewhere". A page nobody can navigate to is not a disclosure. This is **stricter** than what other published counts appear to measure, which is part of why the rate here is lower: a fact about definitions, not a claim that anyone else is wrong. ## Fields | Field | Meaning | |---|---| | `arm` | `en` or `de`: the language the request asked for | | `status` | `coded`, `no_pricing_link_in_nav`, or `UNMEASURED_*` | | `valid` | false when the fetch never returned a real page. **Missing data, never a negative** | | `content_lang` | the language the page actually came back in, detected from the text | | `shows_price` | ≥1 currency amount rendered on the page | | `contact_wall_near_price` | a contact-sales prompt **within 1,500 characters of a price**: the strict, tier-level reading | | `contact_wall_anywhere` | a contact-sales prompt anywhere on the page: the loose reading | | `n_price_points` | count of distinct currency amounts. A **proxy** for priced tiers, not a tier count: add-ons and monthly/annual pairs inflate it | | `dom_sha256` | first 16 hex of the rendered DOM hash | ## Why the contact-wall figure is two fields and not one The first version of this corpus reported the loose code as a single number. It should not have: **16 of the 27 pages it counted carry the same phrase on the vendor's homepage**, where there are no tiers at all, so the loose code cannot separate a tier-level contact wall from site-wide chrome. Both codes are published and the honest statement is the range between them. ## Two collection defects, recorded rather than buried 1. **A first collection scored 53 CDN challenge pages and consent interstitials as vendors with no pricing link.** The cause was an unfingerprinted headless browser and no validity screen on a render. Every observation now passes an anchor-count and byte floor with one retry, and anything that still fails is `UNMEASURED_*`. 2. **A same-domain filter rejected vendor subdomains**, discarding DocuSign's `Plans & Pricing` link because it points at `ecom.docusign.com`. Residual: **21 of 128 observations are unmeasured**, across 13 vendors, and they are in the file with that status rather than counted as opacity. ## Standing limitations - Collection ran from a German IP, so geo-routing and `Accept-Language` can disagree. This is measured rather than assumed: `content_lang` records what actually came back, and 19 of 34 German-arm pages came back in English. - One observation per vendor per arm, on one day. Page churn is unmeasured. - Contact-CTA detection is an English/German phrase list; unusual wording reads as no wall. - The frame is US-listed public cloud companies. It is not "SaaS" and generalises to nothing wider. Full archives of every rendered page, the collector as run, and the audit that caught defect 1 are retained in the source library alongside this file.