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

Use cases

Four worked examples covering the most common shapes of MainMarket queries. Each uses real production endpoints; replace the example UUIDs with real IDs from /v1/stores or /v1/products. Authentication headers are omitted for brevity — see Authentication.

Cheapest near me

Goal: a user types "oat milk" and a location; show the cheapest store within 2 miles that carries it.

Two-step pattern: first resolve the catalog query to canonical product IDs, then pull store-level prices geo-filtered by the user's location.

Request
# Step 1: find the canonical product
curl 'https://api.mainmarket.com/v1/products?q=oat%20milk%2064oz&limit=5'

# Step 2: pull current prices within 2 miles
curl 'https://api.mainmarket.com/v1/prices?product_ids=PROD_A,PROD_B&near=40.7128,-74.0060&radius_mi=2&limit=20'
⚠
Filter on source_tier
Sort and rank only on source_tier="specific" rows. regional and chain rows are useful as a fallback when nothing specific is in range, but mixing them into the primary ranking will produce phantom "cheapest" results that aren't actually available at the named store.

Track grocery price trends

Goal: a hedge fund analyst wants to backfill the Northeast egg index since January and chart the trend.

Hit /v1/indices/{slug} with a region filter and a from period. The response carries a series of monthly snapshots, each with absolute USD value, indexed value (base May 2026 = 100), coverage score, and flagging metadata.

Request
curl 'https://api.mainmarket.com/v1/indices/eggs_cage_free_large_dozen?region=northeast&from=2026-01'
ℹ
Beta vs live
April 2026 snapshots are publish_status="beta" and excluded from responses by default. Pass ?include_beta=true to see them, but treat them as preview data per the methodology doc.

Resolve a shopping list

Goal: a Cart-style app has a user's grocery list ("12 eggs", "Tropicana OJ", "Heinz ketchup") and needs to map each item to a real product at a specific Wegmans store.

POST /v1/chains/{slug}/resolve-list takes up to 50 items at a time, runs each one through canonical-ID lookup first then pg_trgm fuzzy match, and returns the matched product, retailer SKU, PDP URL, current price, and match confidence per item.

Request
curl -X POST 'https://api.mainmarket.com/v1/chains/wegmans/resolve-list' \
  -H 'Content-Type: application/json' \
  -d '{
    "store_id": "4f2a...",
    "items": [
      {"client_id": "i1", "name": "12 large eggs"},
      {"client_id": "i2", "name": "Tropicana orange juice"},
      {"client_id": "i3", "name": "Heinz ketchup 32oz"}
    ]
  }'

Compare across chains

Goal: a comparison-shopping agent needs to see what one product costs across every major chain to find the cheapest banner.

Resolve the product once via /v1/products, then issue one paid call per chain with the same product_id filter. The response's source_tier tells you whether the chain returned an exact match or a chain-level fallback.

Request
# Step 1: find the canonical product
curl 'https://api.mainmarket.com/v1/products?q=Heinz%20Ketchup%2032oz&limit=1'

# Step 2: pull prices across each chain (returned product_id used here as PROD)
for chain in wegmans heb whole-foods kroger; do
  curl "https://api.mainmarket.com/v1/prices?product_id=PROD&chain=${chain}&limit=1"
done
ℹ
chain_level vs per_store comparisons
For chains tagged pricing_scope="chain_level" (Lidl, Trader Joe's, Aldi), one returned price applies chain-wide. For per_store chains (Kroger, H-E-B, Wegmans) the returned price is one representative store; expect per-store variance of roughly 3-8%.

Find coupons & deals nearby

Goal: a shopping app shows the user every active deal at the nearest grocery store, with the live shelf price + post-coupon deal price for each.

/v1/coupons takes lat+lng+radius_mi for a two-arm geo filter (store-pinned coupons match by store location; chain-wide coupons match if any store in that chain is in range). Pass with_prices=true + price_store_id to inline the current shelf price for each coupon's product, which the API uses to compute deal_price, total_savings, and a rating (great / good / okay / poor).

Request
curl 'https://api.mainmarket.com/v1/coupons?lat=40.6892&lng=-73.9942&radius_mi=5&with_prices=true&price_store_id=8c1a4d1e-30a7-4d92-9e1c-1cb43c6f2e10&limit=50'
ℹ
One row per (coupon, product) pair
Multi-UPC coupons expand into multiple rows — one per matched canonical product, each with its own savings math. The id field is the coupon UUID and is not unique within a response. Key on (id, product_id) if you need to dedup at the coupon level.

Plan an in-store route

Goal: a Cart-style app already has a resolved shopping list at a Wegmans store. Sort the items by aisle so the shopper walks the floor in one pass instead of zig-zagging.

Pull the store's frequency-ranked aisle list from /v1/stores/{id}/aisles. The endpoint cascades store-specific → chain-aggregated → generic when fewer than 30% of products at the store carry an aisle tag, so you always get an ordered vocabulary. Bucket the resolved items by their aisle field using that order as the walk sequence.

Request
# Step 1: resolve the shopping list at this store
curl -X POST 'https://api.mainmarket.com/v1/chains/wegmans/resolve-list' \
  -H 'Content-Type: application/json' \
  -d '{"store_id":"4f2a...","items":[{"client_id":"i1","name":"oat milk"},{"client_id":"i2","name":"eggs"},{"client_id":"i3","name":"bread"}]}'

# Step 2: pull frequency-ranked aisles for the same store
curl 'https://api.mainmarket.com/v1/stores/4f2a.../aisles?limit=20'
ℹ
Inspect coverage before trusting aisle order
The aisles response includes a coverage score (0.0-1.0). Below ~0.4 the chain-aggregate fallback is in play and the order is approximate; below ~0.2 you're seeing the generic vocabulary and per-store accuracy is gone. Show a "best guess" affordance in your UI when coverage is low.

Monthly inflation snapshot

Goal: a journalist or hedge-fund analyst pulls all four published indices for a single month to drop into a one-page report or a dashboard tile.

Issue four reads against /v1/indices/{slug} with the same region and a one-month window. The income-tier baskets ship a value_indexed against base May 2026 = 100, and you can derive the headline divergence ratio (basket_high_income.value_usd / basket_low_income.value_usd) directly from the response.

Request
for slug in eggs_cage_free_large_dozen soda_12pk_12oz_cans basket_low_income basket_high_income; do
  curl "https://api.mainmarket.com/v1/indices/${slug}?region=national&from=2026-04&to=2026-04"
done
ℹ
Snapshot, not stream
Indices are precomputed monthly. A 200 OK with empty data means the slug is valid but no snapshot was published for the requested period+region — typically because the period is too recent (next snapshot lands the first week of the following month) or because publish_status="beta" filtered it out. Add ?include_beta=true to peek at preview data, but treat it as non-production per the methodology doc.