MainMarketAPI Reference
Get Access
Overview
  • Introduction
  • Authentication
  • Errors
Stores
  • List stores
  • Get a store
  • Store sentiment
  • Store coupons
  • Store aisles
Chains
  • List chains
  • Get a chain
  • Chain aisles
  • Resolve a list
Products
  • Catalog search
  • Get a product
  • Coupons for product
Prices
  • Search prices
  • Prices by UPC
  • Prices at a store
  • Cheapest nearby
Coupons
  • List coupons
  • Get a coupon
  • Coupon savings
Indices
  • Published indices
Discovery & meta
  • Discovery routes
  • OpenAPI spec
  • Agent skill spec
Overview
  • Introduction
  • Authentication
  • Errors
Stores
  • List stores
  • Get a store
  • Store sentiment
  • Store coupons
  • Store aisles
Chains
  • List chains
  • Get a chain
  • Chain aisles
  • Resolve a list
Products
  • Catalog search
  • Get a product
  • Coupons for product
Prices
  • Search prices
  • Prices by UPC
  • Prices at a store
  • Cheapest nearby
Coupons
  • List coupons
  • Get a coupon
  • Coupon savings
Indices
  • Published indices
Discovery & meta
  • Discovery routes
  • OpenAPI spec
  • Agent skill spec

List chains

Bulk lookup of grocery chains we cover with their online-shopping configuration: search URL templates, login URLs, native app URL schemes, add-to-cart detection. The catalog of every banner in the platform — about 70 chains today and growing.

GET/v1/chainsFree
ℹ
Free + bulk-friendly
No payment, no auth. Pre-flight a list of chains in one round-trip when you're bootstrapping a UI (chain picker, brand directory, deep-link library). The same per-chain payload as Get a chain — see that page for the full per-field reference.

What this is for

Chain picker / directory
Render a list of every chain we support, grouped by online-enabled vs. catalog-only. Filter on online_only=true to show just the chains where a 'Shop Online' button leads somewhere useful.
Bulk hydrate after a search
If you've fetched stores via List stores, you'll get a flat chain_slug on each row. Pass the unique slugs here in one call to enrich every result with logo / online-shopping config instead of N calls to /v1/chains/{slug}.
Deep-link infrastructure
Cache the full chain payload on app boot. Every 'Shop Online' tap then becomes a pure client-side URL build with no extra network call.

Query parameters

NameTypeDescription
slugsstringComma-separated chain slugs, e.g. wegmans,heb,lidl. Max 50. When omitted, returns all chains (subject to online_only).
online_onlybooleandefault: trueWhen true, filters to chains where online_shopping_enabled = true. Set false to include retailers we don't yet have an online-shopping deep link for.
ℹ
Chains are sorted alphabetically by slug. The count field is the total matching the filter, not the number of returned rows (no pagination on this route).

Request

Request
curl 'https://api.mainmarket.com/v1/chains?slugs=wegmans,heb,lidl&online_only=true'

Response

200 OKjson
{
  "count": 3,
  "chains": [
    {
      "slug": "wegmans",
      "name": "Wegmans",
      "logo_url": "https://.../wegmans.png",
      "website_url": "https://www.wegmans.com",
      "online_shopping_enabled": true,
      "online_search_url_prefix": "https://shop.wegmans.com/search?search_term=",
      "online_search_space_char": "+",
      "online_search_url_suffix": "",
      "storefront_url": "https://shop.wegmans.com/store/{store_id}",
      "search_url_template": "https://shop.wegmans.com/store/{store_id}/search?q={query}",
      "login_url": "https://shop.wegmans.com/login",
      "requires_auth": false,
      "session_cookie_domains": ["shop.wegmans.com"],
      "user_agent_override": null,
      "add_to_cart_detection_type": "url_match",
      "add_to_cart_detection_pattern": "/cart",
      "online_shopping_referral_params": null,
      "ios_app_url_scheme": "wegmans://",
      "android_app_url_scheme": null,
      "config_updated_at": "2026-04-29T12:30:00Z"
    }
  ]
}

See Get a chain for the per-field reference.

Workflow: bulk hydrate chain config from a store list

The hot path. Pull stores once, dedupe slugs, hydrate chain config in one call.

Request
import httpx

# Step 1: get stores (free)
stores = httpx.get(
    "https://api.mainmarket.com/v1/stores",
    params={"lat": 40.6892, "lng": -73.9942, "radius": 5, "limit": 50},
).json()["stores"]

# Step 2: bulk-fetch chain config for every unique chain in the result
slugs = sorted({s["chain_slug"] for s in stores if s.get("chain_slug")})
chains = httpx.get(
    "https://api.mainmarket.com/v1/chains",
    params={"slugs": ",".join(slugs), "online_only": False},
).json()
chain_by_slug = {c["slug"]: c for c in chains["chains"]}

# Step 3: render — every store now has its chain config available
for s in stores:
    c = chain_by_slug.get(s["chain_slug"])
    online = "✓" if c and c["online_shopping_enabled"] else "·"
    print(f"  {online}  {s['chain_name']}  {s['name']}")

Workflow: full chain directory

Pull every chain we support, sorted by slug. Useful for an admin dashboard or a coverage page on a marketing site.

curl — every chainbash
curl 'https://api.mainmarket.com/v1/chains?online_only=false&limit=200'

Notable behavior

  • Sort. Alphabetical by slug. Stable, deterministic — safe to memoize on the client.
  • No pagination. Returns the full matching set in one response. We have ~70 chains so this stays under 100KB. count is the total matching the filter, not the number of returned rows.
  • 50-slug cap on slugs=. If you need more, omit the filter and get the full set.
  • online_only defaults to true. By default you only see chains where deep-linking actually works. Pass online_only=false to include chains where we have catalog data but no working storefront URL pattern (yet).

URL construction

Three URL fields work together to build a working deep link to any chain's search results:

online_search_url_prefix
The chain-wide search URL prefix, e.g. "https://www.heb.com/search?q=". Sandwich the URL-encoded query between this and online_search_url_suffix.
online_search_space_char
Character to substitute for spaces. Most chains use + or %20. Replace literal spaces in the query with this character before URL-encoding the rest.
online_search_url_suffix
Trailing string for the search URL. Often empty; some chains require a sentinel like '&searchType=text'.
storefront_url + search_url_template
Per-store variants with {store_id} and {query} placeholders. {store_id} is the chain's own web_external_id (from Get a store), not our canonical UUID.

Caching

Chain config changes infrequently (a few times per year). Responses send Cache-Control: public, max-age=300, stale-while-revalidate=600. Use config_updated_at as a cache-busting key client-side: re-fetch only when any timestamp moves forward.

Related

  • Get a chain — single-chain detail with the same payload + a worked deep-link example.
  • Chain aisles — chain-wide aisle vocabulary.
  • Resolve a list — bulk shopping-list resolution scoped to one chain.
  • List stores — pre-flight a chain lookup with a geo-filtered store list.

Errors

NameTypeDescription
422Unprocessable EntityMore than 50 slugs supplied.
500Internal Server ErrorUnexpected server fault.