"Testing" in supplement publishing usually means one of two things: a brand pays a lab to confirm what is already on its own label, or an editor tries the product and writes a review. We do neither as the spine of the site. ProteinPrice is a price and value engine. Our job is to verify, every day, that the retailer prices feeding into the Value Score are real and that the label specs we rank against are accurate. This page is the full account of how that verification works, what we do not do, and how to flag a discrepancy.
Price verification methodology
Every price you see on a ProteinPrice product page started its life as a number rendered on a retailer's live product page within the last 48 hours. Brands do not submit prices to us. We do not buy a syndicated price feed that brands also have access to. The path from a retailer's HTML to our ranking looks like this:
- Targeted scraper hits the retailer's product detail page. Each SKU in the catalog is mapped to canonical product URLs at every retailer where it is sold. The scraper requests the page on a schedule (see refresh cadence below), identifies itself in its User-Agent string, and respects robots.txt directives.
- Parser reads structured data first. Where the retailer publishes schema.org Product markup or JSON-LD (most major US retailers do), the parser reads the structured
offers.price,offers.priceCurrency, andoffers.availabilityfields directly. This is faster, more accurate, and less brittle than visual scraping. - Visual fallback for retailers without structured data. Where no structured price block is present, the parser falls back to retailer-specific CSS selectors. These selectors are versioned and re-validated when a parse error rate crosses a threshold.
- Sanity range check ($5 to $500). Any returned price outside this window is rejected as a parsing error. Protein tubs do not retail for $1 or $5,000. A returned value of $0.00 or $9,999.99 is almost always a layout change or a "From $14.99" lure that the parser misread.
- Swing rejection (more than 50% move requires corroboration). If the new value is more than 50% above or below the prior verified value for that SKU at that retailer, we require at least one other retailer to have moved in the same direction before accepting the change. A lone $89.99 spike on one retailer while every other retailer holds at $39.99 is suppressed.
- Cross-retailer outlier rejection (more than 30% from median). Once all retailers have been scraped for a given cycle, any single value sitting more than 30% from the cross-retailer median is rejected. This catches stale list prices, wrong-SKU matches, currency-conversion glitches, and bundle-vs-single misclassifications.
- Accepted values write to the catalog and the audit log. Values that survive every check are written into the live
productsfeed and appended toprice_history-YYYY-MM.jsonlat /data/. The history file is append-only and never rewritten. - Last-success timestamps update. Each retailer slot on each product carries a UTC timestamp of its last verified scrape. These timestamps are visible in the public JSON and surface live at /scraper-status/.
What this means in practice: when a price disappears from a product page, it is usually our safeguards refusing to publish a number we do not trust. We treat "no price" as a safer answer than "wrong price."
Retailer sources
The catalog is scraped from twelve US retailers. We chose this set deliberately: it covers mass-market, specialist sports nutrition, warehouse club, brand-direct, and one large drop-shipper, so that every major price point in the protein category gets at least one independent comparison.
Retailer slots are not all equal in coverage. Mass-market sites carry a wide protein selection but rotate SKUs aggressively, so we expect some products to drop in and out. Brand-direct sites carry only that brand's catalog but tend to have the most reliable spec data. Costco and Walmart in some protein categories do not have an affiliate program, which is fine: they are scraped and ranked exactly the same way, and they win the "Best Price" slot whenever the math says so.
The full retailer roster, with last-scrape health visible per retailer, lives at /retailers/. Live scraper health (last success, error counts, status code distribution) is published openly at /scraper-status/ so anyone can audit which retailers are healthy on any given day.
Refresh cadence
The default cycle for the full catalog is daily, scheduled overnight US time so that morning rankings reflect the prior day's close. Several categories run more frequently:
- Daily full-catalog refresh. Every SKU at every retailer is rescraped at least once every 24 hours. This is the floor.
- 2-hour high-value cycle for top movers. SKUs with high traffic, frequent price changes, or active deal events get a faster cycle so that "Best Price" badges do not lag a flash sale by half a day.
- On-demand recheck for reader-reported issues. When a reader emails about a price that looks wrong, we can trigger an out-of-cycle recheck for that SKU at every retailer. Replies typically include the result.
- 48-hour stale flag. If the last successful scrape for a retailer is over 48 hours old, that listing is flagged stale and marked
inStock: falsein the public JSON. The ranking ignores stale offers when computing the Value Score.
"Daily refresh" is the published cadence we hold ourselves to. Per-product, per-retailer last-success timestamps are the proof: every product page surfaces them and the live status board at /scraper-status/ aggregates them across the fleet.
Spec verification (protein, servings, ingredients)
The Value Score depends on three numbers per SKU: protein per serving, servings per container, and the best verified retailer price. The first two come from the product label and the brand's official product page, not from a lab.
- Protein per serving is read off the brand's published supplement facts panel as displayed on either the brand's own product page or the retailer's product page where the label image is included.
- Servings per container is read from the same supplement facts panel. For multi-serving formats (powders, RTDs in multi-packs, bars in boxes), the package count is the canonical figure.
- Ingredient highlights, flavour lineups, allergen flags come from the brand's own product page text and the supplement facts panel. Where a retailer-listed ingredient set differs from the brand's, we defer to the brand.
- Reformulations and relaunches trigger a manual re-verification. When a brand publicly announces a formula change, the SKU is queued for review and the catalog values are updated on the next pass.
We scrape what brands publish on their labels. We do not lab-test what is inside the tub. This is the most important boundary on the site. If the published protein content turns out to be inaccurate, we will reflect a confirmed correction once the brand or a third party has demonstrated it, but ProteinPrice is not a contract lab and never markets itself as one.
What we deliberately do NOT test
Just as important as what we do is what we do not. Drawing the boundary publicly avoids over-promising:
- No independent lab analysis. We do not run third-party assays on protein content, amino acid profiles, heavy metal levels, microbial contamination, or banned-substance screening. Sites like NSF Certified for Sport, Informed Sport, and ConsumerLab cover that territory and do it well. We will cite their findings when they are public, but we do not duplicate the work.
- No taste or texture testing for the ranking. The Value Score is purely a price-per-gram metric. Subjective qualities (flavour, mixability, mouthfeel) appear in long-form brand reviews at /reviews/ as additional context, but they do not move a product up or down the value rankings.
- No medical, nutritional, or dosing advice. We do not tell you how much protein to eat, when to take it, what your macros should be, or whether a particular product is right for your goals. Talk to a registered dietitian or a physician.
- No certification of brand claims. "Grass-fed," "single-source," "no artificial sweeteners," "X grams of BCAAs" and similar marketing claims are reported as-published. We do not verify them in a lab, and the Value Score does not adjust for them.
- No "best whey of 2026" editor's pick that overrides the math. Curated guides exist, but the ranking inside any "best of" page is generated by the same Value Score formula as the rest of the site. There is no manual reshuffle.
If those are the things you came here for, ProteinPrice is not the right resource. We try to be honest about that up front rather than pretend otherwise.
Brand communication
Brands occasionally contact us about coverage. Here is how that works in practice:
- Spec corrections are welcomed and processed. If we have an outdated protein figure or serving count, send the corrected supplement facts panel and we will update the catalog. Confirmed corrections typically ship within five business days.
- Brand-direct affiliate or retailer-feed requests are evaluated separately. Whether to add a brand-direct retailer to the scrape pool is decided on coverage grounds (does the brand have meaningful US distribution? does brand-direct undercut other retailers?), not on commercial grounds.
- Press kits, news, and announcements are read but do not generate automatic coverage. We do not run press releases as posts.
- "Could you fix our ranking?" requests get a polite no. The ranking is the formula. The only way to move the ranking is to actually change one of the formula's inputs (lower the retail price, raise the protein content, ship a larger tub at the same price).
- Sample requests for hands-on review are accepted when we ask for them. Sample provision does not feed into the Value Score and never will.
- Press inquiries live at /press/.
Reporting inaccuracies
Live scraped data is messy. Retailer pages change layouts. Bundles get listed as singles. Subscribe-and-save toggles flip and show a different number. SKUs get accidentally mapped to similar-looking variants. The only way we catch these quickly is reader feedback.
- Email data corrections to [email protected]. Include the product URL or slug, the retailer in question, the number shown on ProteinPrice, the number actually displayed at the retailer, and a screenshot or link if possible.
- For ranking or coverage concerns, email [email protected] instead. See our Editorial Standards for the policies that govern those decisions.
- For scraper health concerns, the live board at /scraper-status/ shows per-retailer last-success and error stats so you can see whether a missing price is a known scraper outage or a genuine inventory drop.
- For historical audit, the append-only price log at /data/ lets you reconstruct exactly what we showed and when. We cannot retroactively change those records, which is the point.
We aim to acknowledge corrections within one business day and resolve within five. Persistent issues (a scraper that keeps misreading bundle pricing, for example) get a permanent fix in the parser, not just a one-off override.
Methodology changelog
When the verification methodology itself changes, we log the change here rather than rolling it out silently. Examples of changes that would land here: tightening the outlier threshold from 30% to 25%, adding a new retailer to the scrape pool, removing a retailer whose data quality dropped, or moving the stale-flag window from 48 to 36 hours.
- 21 May 2026. Initial publication of this page. Reflects: daily refresh cadence, 12-retailer pool, $5 to $500 sanity range, 50% swing rule, 30% cross-retailer outlier rule, 48-hour stale flag, append-only price history at /data/.
For the upstream ranking methodology (how scraped prices and spec data are combined into the Value Score itself), see /how-it-works/. For the policies governing rankings, recommendations, and corrections, see /editorial-standards/.