Search brand-level company records — one row per brand (not per physical store) — with filters for location, ownership, store count, and more.
Overview
Use this endpoint to find brands in the Openmart database. A brand aggregates all of the physical stores that share the same business identity, so results are deduplicated at the company level.
You can filter by:
free-text search term and location
number of stores, ownership type (INDEPENDENT, FAMILY, FRANCHISE, CHAIN)
whether the brand has staff info, business email, or business phone
website root domain (include or exclude) and social media URLs
Use this endpoint when you want brand-level targeting for outbound, account research, or market sizing — and store-level results fromPOST /api/v1/search would over-count multi-location companies.
Before you start
Make sure you have:
an Openmart account
an API key
a tool to send API requests, such as Postman or curl
Authentication. We recommend sending your API key as Authorization: Bearer <your_api_key>. If your current integration already uses X-API-Key: <your_api_key>, it will continue to work.
1
Example 1: Search coffee shops in San Francisco, CA
Find brands whose identity matches “coffee shop” in San Francisco, ask for an approximate total, and return the first two results.
Endpoint
POST https://api.openmart.ai/api/v2/brands/search
Parameters
Parameter
search_param.search_term
Type
string
Required
No
Example
"coffee shop"
Description
Free-text relevance term used to rank brand results.
Approximate match count. Present only when the request had estimate_total=true.
Response element
encoded_cursor
Description
Opaque cursor for the NEXT page. Copy it into pagination.encoded_cursor on the next request. Empty string on the last page.
Response element
data[]
Description
One brand per entry.
Response element
data[].brand_id
Description
Stable UUID for the brand.
Response element
data[].business_name
Description
Canonical display name for the brand.
Response element
data[].domain_ident
Description
Normalized root domain; doubles as a stable brand identifier alongside brand_id.
Response element
data[].num_stores
Description
Count of physical stores currently aggregated under this brand.
Response element
data[].ownership_type
Description
One of INDEPENDENT, FAMILY, FRANCHISE, CHAIN, or "" when not classified.
Response element
data[].business_categories
Description
Top-level categories (enum list includes RESTAURANTS_DINING, BEAUTY_PERSONAL_CARE, HEALTH_WELLNESS, SHOPPING_RETAIL, and more).
Response element
data[].social_media_links
Description
Map of platform keys (FACEBOOK, LINKEDIN, INSTAGRAM, TWITTER, X, PINTEREST, TIKTOK, YOUTUBE) to arrays of URLs. Individual platform slices may be null.
Response element
data[].business_emails / business_phones / staffs
Description
Brand-level contact + people data. These array fields may be null (consumers should handle null and empty array equivalently).
Response element
Description
total
Approximate match count. Present only when the request had estimate_total=true.
encoded_cursor
Opaque cursor for the NEXT page. Copy it into pagination.encoded_cursor on the next request. Empty string on the last page.
data[]
One brand per entry.
data[].brand_id
Stable UUID for the brand.
data[].business_name
Canonical display name for the brand.
data[].domain_ident
Normalized root domain; doubles as a stable brand identifier alongside brand_id.
data[].num_stores
Count of physical stores currently aggregated under this brand.
data[].ownership_type
One of INDEPENDENT, FAMILY, FRANCHISE, CHAIN, or "" when not classified.
data[].business_categories
Top-level categories (enum list includes RESTAURANTS_DINING, BEAUTY_PERSONAL_CARE, HEALTH_WELLNESS, SHOPPING_RETAIL, and more).
data[].social_media_links
Map of platform keys (FACEBOOK, LINKEDIN, INSTAGRAM, TWITTER, X, PINTEREST, TIKTOK, YOUTUBE) to arrays of URLs. Individual platform slices may be null.
data[].business_emails / business_phones / staffs
Brand-level contact + people data. These array fields may be null (consumers should handle null and empty array equivalently).
2
Example 2: California coffee brands with 5+ stores, franchise or chain only
Combine a numeric range filter on num_stores with an ownership_type enum filter. This is a typical pattern for brand-level account targeting.
Endpoint
POST https://api.openmart.ai/api/v2/brands/search
Parameters
Parameter
search_param.search_term
Type
string
Required
No
Example
"coffee"
Description
Free-text relevance term.
Parameter
search_param.location
Type
array[object]
Required
No
Example
[{"country":"US","state":"CA"}]
Description
State-wide filter, country required on each entry.
Parameter
search_param.num_stores
Type
array[range]
Required
No
Example
[{"ge":5}]
Description
Store-count range. Each entry is {ge?,gt?,le?,lt?}; multiple entries are OR’d together.
Request body for POST /api/v2/brands/search. All fields are optional in practice — if you omit search_param entirely the server seeds a default location of [{"country":"US"}]. Array filters are capped at 20 entries each.
Most common filters
Start here. These are the fields integrations adjust first when narrowing brand results.
search_param.search_termstringRequired: No
Example: "coffee shop"
Free-text term used for brand relevance ranking. Single string, not a list.
Geographic filter. Up to 20 entries. Each entry must include country; city, state, zipcode, and geo_radius are optional narrowings. If you omit location entirely, the request defaults to [{"country":"US"}].
Opaque cursor copied from the previous response’s encoded_cursor. Omit on the first request. Preview API keys are not allowed to set this.
cURL example
cURL
curl--requestPOST\--urlhttps://api.openmart.ai/api/v2/brands/search\--header'Accept: application/json'\--header'Authorization: Bearer <your_api_key>'\--header'Content-Type: application/json'\--data'{"search_param":{"location":[{"country":"US"}]},"pagination":{"limit":100,"encoded_cursor":"<paste from prior response>"}}'
pagination.order_byarray[object]Required: No
Example: [{"field":"num_stores","asc":true}]
Optional sort directives. Each entry is {field, asc}. Up to 20 entries. Known limitation: the API currently requires asc to be true and rejects {"asc": false} with a 422 "Asc is required" validator error.