MainMarket's data model is small but each piece carries enough signal to surface to end users. Read this once before wiring the API into a product so you know which responses are authoritative and which are best-effort fallbacks.
Chains are the legal/operational parents — Wegmans, Kroger, H-E-B, Whole Foods. Each chain is tagged with two attributes that drive how you should present its data:
pricing_scopeper_store (every store has its own prices, like Kroger), chain_level (one price applies chain-wide, like Lidl), or no_ecommerce (no online catalog at all).market_positionvalue, mainstream, premium, or luxury. Used to filter constituents into the income-tier indices and to power category comparisons.Stores are physical locations under a chain — addresses, lat/lng, hours, format (supermarket, hypermarket, dark store, club). Stores are the unit you geo-search against and the unit prices attach to.
Products are canonical UPCs — one row per real-world SKU, normalized across every chain that carries it. A 12-pack of Diet Coke 12oz cans is one product whether you're looking at it through Wegmans, H-E-B, or Whole Foods. ~528,000 canonical products today, sourced exclusively from the web scraper fleet (Scout iOS scans match into this catalog; they don't extend it).
Every row from /v1/prices carries a source_tier that tells you how confident you should be in the price for the requested store:
specificregionalsource_distance_mi) does. Common for chains that price uniformly within a metro.chainchain_level this is authoritative; for per_store chains it's a directional estimate, not a guarantee.per_store chain, do not present a regional or chain price as if it were the price at the requested store. Surface the tier (e.g. "approx. $4.99 — based on a nearby Kroger, 3.2 mi away") and let the user decide.Each response also carries meta.freshness_p50_hours, the median age of the contributing scrapes. Most chains refresh weekly; freshness above ~200 hours means the chain hasn't been re-scraped in over a week and you should treat the price as stale.
MainMarket publishes monthly price indices for institutional consumers — hedge funds, journalists, government economists. Today we publish four:
Indices use medians (not means) following BLS practice for retail food prices, and every constituent UPC has explicit floor/ceiling bounds that exclude obvious data errors before aggregation. Multi-SKU baskets weight constituents by store distribution so that a UPC carried at 700 stores contributes more than one carried at 400.
Each snapshot ships with a coverage_score (0–1, fraction of in-scope stores that contributed) and a publish_status of either auto, beta, forced_publish, or flagged_for_review. April 2026 = beta inception; May 2026 = live inception. Beta snapshots are excluded from the default API response unless ?include_beta=true.
The full methodology — formulas, regional rollups, anomaly checks, revision policy, BLS/USDA/FAO citations — is at api.mainmarket.com/methodology.md. Cite that URL in research products; link to it from any consumer surface that displays an index value.
GET /v1/indices/eggs_cage_free_large_dozen?region=northeast&from=2026-01
Authorization: Bearer mm_internal_...Coupons are active digital and clippable promotions sourced directly from chain loyalty platforms (Inmar Falcon, AisleAhead, Wynshop, "for U", Freshop, Instacart, Publix Direct, HEB mobile, Schnucks, Lidl Plus, Kroger). Each coupon is matched against the canonical product catalog so you can pull every active deal for a given UPC or every active deal at a given store.
Coupon endpoints support geo filtering (lat/lng/radius_mi, default 25 mi) and time-bounded queries (valid_on, defaults to today). Each row carries a computed savings_pct and arating (good / better / best) keyed off our catalog price benchmark, plus the chain's deep_link_url for clipping in the chain's own app.
requires_loyalty: true need the user to be signed into the chain's loyalty program for the discount to apply at checkout. Surface the loyalty-program name (and a sign-up link if you have one) before showing the savings.