MainMarketDocumentation
Get Access
Get started
  • Welcome
  • Getting started
  • Authentication
  • Pricing
Concepts
  • Stores, chains, products
  • Pricing tiers + freshness
  • Indices + methodology
  • Coupons
Use cases
  • Cheapest near me
  • Track price trends
  • Resolve a shopping list
  • Compare across chains
  • Coupons & deals nearby
  • Plan an in-store route
  • Monthly inflation snapshot
Reference
  • API Reference →
  • Methodology
  • OpenAPI spec
  • Agent skill spec
Get started
  • Welcome
  • Getting started
  • Authentication
  • Pricing
Concepts
  • Stores, chains, products
  • Pricing tiers + freshness
  • Indices + methodology
  • Coupons
Use cases
  • Cheapest near me
  • Track price trends
  • Resolve a shopping list
  • Compare across chains
  • Coupons & deals nearby
  • Plan an in-store route
  • Monthly inflation snapshot
Reference
  • API Reference →
  • Methodology
  • OpenAPI spec
  • Agent skill spec

Concepts

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.

Stores, chains, and products

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_scope
One of per_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_position
One of value, 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).

Pricing tiers and freshness

Every row from /v1/prices carries a source_tier that tells you how confident you should be in the price for the requested store:

specific
The price was scraped at the exact store you asked about. Gold standard — surface it without caveats.
regional
The requested store has no recent scrape, but a sibling store in the same chain (within source_distance_mi) does. Common for chains that price uniformly within a metro.
chain
Fallback to the chain's representative store. For chains tagged chain_level this is authoritative; for per_store chains it's a directional estimate, not a guarantee.
⚠
Always disclose non-specific tiers
For a 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.

Indices and methodology

MainMarket publishes monthly price indices for institutional consumers — hedge funds, journalists, government economists. Today we publish four:

Egg Indexeggs_cage_free_large_dozen
Single-SKU median, modeled on BLS APU0000708111.
Soda Indexsoda_12pk_12oz_cans
Distribution-weighted basket of 5 UPCs, all in 12pk × 12oz cans.
Low Income Basketbasket_low_income
USDA Thrifty Food Plan-anchored basket evaluated at value-tier chains.
High Income Basketbasket_high_income
USDA Liberal Food Plan-anchored basket evaluated at premium-tier chains.

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.

Sample index callhttp
GET /v1/indices/eggs_cage_free_large_dozen?region=northeast&from=2026-01
Authorization: Bearer mm_internal_...

Coupons

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.

ℹ
Loyalty-gated coupons
Coupons with 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.