For researchers

Data dictionary

Every column in the published dataset, what it means, and the traps worth knowing about before you analyze it. The same schema is returned by the CSV download and by the public API rows. Current through August 2026.

Getting the data

What you wantURL
Everything (national + every metro, full history, both bases)/price-index/download
One monthly release/price-index/download?period=YYYY-MM
One metro, full history/price-index/download?geo=houston-tx
Restrict to one price basis (combines with the above)/price-index/download?basis=shelf

Fields

One row per (period, geography, taxonomy, category, price basis). That tuple is the primary key — no duplicates, and it's safe to upsert on.

period_startdate (YYYY-MM-01)

First day of the calendar month the figure describes. Always the 1st; the index is monthly, not daily. A release for this period publishes mid-way through the following month.

price_basisenumshelf | marketplace

Where the price was observed. "shelf" is an in-store price (the headline series). "marketplace" is a delivery-platform listing, which carries platform markup. Never combine the two: a marketplace basket_cost is not comparable to a shelf basket_cost. Month-over-month changes are comparable across bases, because a roughly constant markup cancels in a matched ratio.

geo_levelenumnational | metro

Geographic granularity of the row.

geo_codestring

Geography identifier. "US" for national rows; the CBSA code for metro rows.

geo_namestring

Human-readable geography, e.g. "United States" or "Houston-The Woodlands-Sugar Land, TX". Metro names are full Census CBSA titles, which list several principal cities.

geo_slugstring

URL-safe geography key: "us" nationally, or "city-st" for a metro (e.g. houston-tx). Stable across releases — safe to join on. Maps to /price-index/metro/{geo_slug}.

taxonomyenumbls | gcpi

Which category scheme category_code belongs to. "bls" mirrors the Bureau of Labor Statistics food-at-home groups and is what the site publishes; "gcpi" is our own finer grouping. Filter to one taxonomy before aggregating, or you will double-count.

category_codestring

Category key within the taxonomy. "all" is the aggregate across categories. BLS values: all, cereals_and_bakery_products, meats_poultry_fish_and_eggs, dairy_and_related_products, fruits_and_vegetables, nonalcoholic_beverages, other_food_at_home.

category_namestring

Display label for category_code.

index_valuenumeric | null

Chained price index, April 2026 = 100. Built by chaining month-over-month changes, not by dividing basket costs. Null means the chain could not be continued — typically the month before was suppressed. A value of exactly 100.00 in a period after April 2026 marks a chain restart (a fresh base), not "unchanged since April".

mom_pctnumeric (percent) | null

Month-over-month percent change, from a matched sample: only (store, item) pairs observed in BOTH months, aggregated with a trimmed Jevons geometric mean. This is the field to use for "prices rose X%". Null NEVER means zero, and it has two distinct causes: either the comparison did not clear our thresholds, or the month follows a methodology change that makes it incomparable with the month before. August 2026 is such a month — mom_pct is null for all 133 of its rows and index_value restarts at 100, by design and not for want of data.

yoy_pctnumeric (percent) | null

Year-over-year percent change. Null for every row until the series is 13 months old (first non-null: spring 2027). We do not publish annual comparisons before the data supports them.

basket_costnumeric (USD) | null

Weighted average unit price of the basket, in dollars. A comparative measure of price level — NOT a weekly grocery bill. Treat it as indicative: the value depends on which items and stores cleared suppression for that geography and basis, so a difference between two basket_cost values mixes real price differences with coverage differences. Never derive a "delivery premium" by dividing a marketplace basket_cost by a shelf one — the two bases do not price the same item mix. Use mom_pct for any precise comparison.

dispersion_pctnumeric (percent) | null

Price spread for identical items: the p10-to-p90 range across store-level medians, weight-averaged over the basket. Roughly "how much you can save by shopping around". National dispersion includes genuine regional differences; metro dispersion is the within-market figure.

n_observationsinteger

DISTINCT price observations behind the cell: the first reading for a given product at a given store in the period, plus every price change. Re-reading an unchanged price does not count again. The minimum-sample floors apply to this number. For periods published before September 2026 this column counts READINGS instead — see n_readings and the methodology.

n_readingsinteger | null

How many times those prices were read. Empty for periods published before September 2026, which did not count the two separately — empty means not measured, not zero. The gap between the two is large and uneven: measured over the 30 days to 2026-09-20, readings exceeded distinct observations by 4.98x across our corpus, and by 21.3x for one chain.

n_storesinteger

Number of distinct stores contributing to the cell.

n_bannersinteger

Number of distinct grocery banners (store brands) contributing. Published cells require at least three, so no single retailer can be reverse-engineered from a figure.

methodology_versionstring

Version of the computation that produced the row. If the method changes materially, the whole series is recomputed under the new version rather than spliced — check this before combining downloads taken months apart.

Corrections (gcpi_correction)

When a published cell turns out to be wrong it is withdrawn from the dataset above, never silently overwritten — and it is recorded here, with the values exactly as they were originally published. Rows are append-only: a correction is never edited or removed. The reasoning for each is on the methodology page.

Columns: corrected_at, action (withdrawn | restated), the cell key (period_start, price_basis, geo_level, geo_code, taxonomy, category_code), the published values (old_basket_cost, old_n_observations, old_n_stores, old_n_banners), the replacement value for a restatement (new_basket_cost, blank when withdrawn), and public_note / reason.

Download corrections (CSV)

Reading the data correctly

  • Empty is not zero, and empty has more than one cause. Usually the cell did not meet publication thresholds (currently 400 observations, 8 stores, and 3 banners) and was withheld. But yoy_pct is blank on every row until the series is 13 months old, and after a methodology change mom_pct is blank because the months are not comparable — August 2026 is blank for that reason, not for want of data. Whichever the cause, please don't interpolate it — treat it as missing.
  • Use mom_pct for change, basket_cost for level. Dividing consecutive basket_cost values does not give you the monthly change: basket cost reflects the whole observed panel, while mom_pct is computed from a matched sample of the same items at the same stores. The panel grows over time; the matched sample is what removes that effect.
  • Never mix price_basis. A marketplace figure and a shelf figure are not two measurements of one thing. Their basket costs are built from different item mixes, so the gap between them is not a clean platform markup — it is markup plus coverage difference, and we don't publish it as a premium for that reason.
  • Pick one taxonomy. BLS and GCPI rows describe the same underlying prices grouped two different ways; summing across both double-counts.
  • Early months are provisional in interpretation. April–May 2026 reflect a smaller matched panel; the panel is stable from June 2026 onward.
  • index_value = 100.00 can mean a restart. After a suppressed month the chain re-bases rather than pretending continuity. Check the prior month before reading a 100.00 as "flat since April".

License & citation

The dataset is licensed CC BY 4.0 — reuse it in research, articles, dashboards, or products, commercially or otherwise, with attribution.

GroceryChop Price Index, August 2026. GroceryChop. grocerychop.com/price-index

Method details live on the methodology page. Need a cut we don't publish? Get in touch.