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.
/v1/chainsFreechain_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}.| Name | Type | Description |
|---|---|---|
slugs | string | Comma-separated chain slugs, e.g. wegmans,heb,lidl. Max 50. When omitted, returns all chains (subject to online_only). |
online_only | booleandefault: true | When 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. |
count field is the total matching the filter, not the number of returned rows (no pagination on this route).curl 'https://api.mainmarket.com/v1/chains?slugs=wegmans,heb,lidl&online_only=true'{
"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.
The hot path. Pull stores once, dedupe slugs, hydrate chain config in one call.
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']}")Pull every chain we support, sorted by slug. Useful for an admin dashboard or a coverage page on a marketing site.
curl 'https://api.mainmarket.com/v1/chains?online_only=false&limit=200'count is the total matching the filter, not the number of returned rows.slugs=. If you need more, omit the filter and get the full set.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).Three URL fields work together to build a working deep link to any chain's search results:
online_search_url_prefix"https://www.heb.com/search?q=". Sandwich the URL-encoded query between this and online_search_url_suffix.online_search_space_char+ or %20. Replace literal spaces in the query with this character before URL-encoding the rest.online_search_url_suffixstorefront_url + search_url_template{store_id} and {query} placeholders. {store_id} is the chain's own web_external_id (from Get a store), not our canonical UUID.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.
| Name | Type | Description |
|---|---|---|
422 | Unprocessable Entity | More than 50 slugs supplied. |
500 | Internal Server Error | Unexpected server fault. |