External API docs

Search companies

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: send your key in the X-API-Key header. Authorization: Bearer <key> is also accepted.

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.
Parameter
search_param.location
Type
array[object]
Required
No
Example
[{"country":"US","state":"CA","city":"San Francisco"}]
Description
Geographic filter. Each entry must include country. Omitting this field defaults to US.
Parameter
pagination.limit
Type
integer
Required
No
Example
2
Description
Page size, default 100, max 500.
Parameter
estimate_total
Type
boolean
Required
No
Example
true
Description
When true, the response includes an approximate total hit count.

cURL request

cURL
curl --request POST \
  --url https://api.openmart.ai/api/v2/brands/search \
  --header 'Accept: application/json' \
  --header 'X-API-Key: <your_api_key>' \
  --header 'Content-Type: application/json' \
  --data '{
    "search_param": {
      "search_term": "coffee shop",
      "location": [
        {
          "country": "US",
          "state": "CA",
          "city": "San Francisco"
        }
      ]
    },
    "pagination": { "limit": 2 },
    "estimate_total": true
  }'

Response details

This request returns coffee-shop brands in San Francisco, with:

  • an approximate match count in total
  • the next-page cursor in encoded_cursor
  • up to two brand rows in data (truncated below for readability)

Response example

JSON
{
  "total": 87,
  "encoded_cursor": "7b225f73636f7265223a34393639...",
  "data": [
    {
      "brand_id": "02c6be6a-d0a4-4345-9625-19442df5c8c9",
      "business_name": "Cable Car Coffee SF",
      "business_type": "Coffee Shop",
      "business_categories": ["RESTAURANTS_DINING"],
      "business_specialty": "Warm brews",
      "business_keywords": ["coffee", "brews", "SF"],
      "product_services_offered": ["coffee", "warm brews"],
      "brand_description": "Cable Car Coffee SF is a coffee shop specializing in warm brews located in San Francisco.",
      "website_url": "https://cablecarcoffeesf.com/",
      "business_emails": null,
      "business_phones": null,
      "social_media_links": {
        "FACEBOOK": null,
        "LINKEDIN": null,
        "INSTAGRAM": null,
        "TWITTER": null,
        "X": null,
        "PINTEREST": null,
        "TIKTOK": null,
        "YOUTUBE": null
      },
      "ownership_type": "",
      "staffs": null,
      "domain_ident": "cablecarcoffeesf.com",
      "num_stores": 1
    },
    {
      "brand_id": "05fb7b97-e724-4608-9d1c-bbeb87e37bc1",
      "business_name": "Sisters Coffee Shop",
      "business_type": "Coffee Shop",
      "business_categories": ["RESTAURANTS_DINING"],
      "ownership_type": "FAMILY",
      "domain_ident": "sisterscoffeeshop.com",
      "website_url": "https://sisterscoffeeshop.com/",
      "business_phones": ["+14159326848"],
      "social_media_links": {
        "INSTAGRAM": ["https://www.instagram.com/sisterscoffeeshop/"],
        "TIKTOK": ["https://www.tiktok.com/@sisterscoffeeshop"]
      },
      "num_stores": 1
    }
  ]
}

Key elements of the API response

Response element
total
Description
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).
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.
Parameter
search_param.ownership_type
Type
array[string]
Required
No
Example
["FRANCHISE","CHAIN"]
Description
Allowed values: INDEPENDENT, FAMILY, FRANCHISE, CHAIN.
Parameter
pagination.limit
Type
integer
Required
No
Example
20
Description
Page size, default 100, max 500.

cURL request

cURL
curl --request POST \
  --url https://api.openmart.ai/api/v2/brands/search \
  --header 'Accept: application/json' \
  --header 'X-API-Key: <your_api_key>' \
  --header 'Content-Type: application/json' \
  --data '{
    "search_param": {
      "search_term": "coffee",
      "location": [{ "country": "US", "state": "CA" }],
      "num_stores": [{ "ge": 5 }],
      "ownership_type": ["FRANCHISE", "CHAIN"]
    },
    "pagination": { "limit": 20 }
  }'

Response example

JSON
{
  "encoded_cursor": "7b225f73636f72...",
  "data": [
    {
      "brand_id": "6c7b...",
      "business_name": "Black Rock Coffee Bar",
      "business_type": "Coffee Shop",
      "ownership_type": "CHAIN",
      "domain_ident": "br.coffee",
      "num_stores": 190
    },
    {
      "brand_id": "f23c...",
      "business_name": "Bottoms Up Espresso",
      "business_type": "Coffee Shop",
      "ownership_type": "FRANCHISE",
      "num_stores": 13
    }
  ]
}

All request parameters

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.

cURL example
cURL
curl --request POST \
  --url https://api.openmart.ai/api/v2/brands/search \
  --header 'Accept: application/json' \
  --header 'X-API-Key: <your_api_key>' \
  --header 'Content-Type: application/json' \
  --data '{"search_param":{"search_term":"coffee shop","location":[{"country":"US"}]},"pagination":{"limit":5}}'
search_param.locationarray[object]Required: No
Example: [{"country":"US","state":"CA","city":"San Francisco"}]

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"}].

cURL example
cURL
curl --request POST \
  --url https://api.openmart.ai/api/v2/brands/search \
  --header 'Accept: application/json' \
  --header 'X-API-Key: <your_api_key>' \
  --header 'Content-Type: application/json' \
  --data '{"search_param":{"location":[{"country":"US","state":"CA","city":"San Francisco"}]},"pagination":{"limit":5}}'
search_param.num_storesarray[range]Required: No
Example: [{"ge":5,"le":100}]

Filter by physical-store count. Each entry is a range object with any subset of {ge, gt, le, lt}. Up to 20 entries; multiple entries are OR’d.

cURL example
cURL
curl --request POST \
  --url https://api.openmart.ai/api/v2/brands/search \
  --header 'Accept: application/json' \
  --header 'X-API-Key: <your_api_key>' \
  --header 'Content-Type: application/json' \
  --data '{"search_param":{"location":[{"country":"US"}],"num_stores":[{"ge":5,"le":100}]},"pagination":{"limit":5}}'
search_param.ownership_typearray[string]Required: No
Example: ["FRANCHISE","CHAIN"]

Filter by ownership classification. Allowed values: INDEPENDENT, FAMILY, FRANCHISE, CHAIN. Up to 20 entries.

cURL example
cURL
curl --request POST \
  --url https://api.openmart.ai/api/v2/brands/search \
  --header 'Accept: application/json' \
  --header 'X-API-Key: <your_api_key>' \
  --header 'Content-Type: application/json' \
  --data '{"search_param":{"location":[{"country":"US"}],"ownership_type":["FRANCHISE","CHAIN"]},"pagination":{"limit":5}}'

Location object fields

Use these inside each entry of `search_param.location`. `country` is required on every entry.

countrystringRequired: Yes
Example: "US"

Country code. Required on every location entry. Returns HTTP 422 "Country is required" otherwise.

cURL example
cURL
curl --request POST \
  --url https://api.openmart.ai/api/v2/brands/search \
  --header 'Accept: application/json' \
  --header 'X-API-Key: <your_api_key>' \
  --header 'Content-Type: application/json' \
  --data '{"search_param":{"location":[{"country":"US"}]},"pagination":{"limit":1}}'
statestringRequired: No
Example: "CA"

State or region filter.

cURL example
cURL
curl --request POST \
  --url https://api.openmart.ai/api/v2/brands/search \
  --header 'Accept: application/json' \
  --header 'X-API-Key: <your_api_key>' \
  --header 'Content-Type: application/json' \
  --data '{"search_param":{"location":[{"country":"US","state":"CA"}]},"pagination":{"limit":1}}'
citystringRequired: No
Example: "San Francisco"

City filter.

cURL example
cURL
curl --request POST \
  --url https://api.openmart.ai/api/v2/brands/search \
  --header 'Accept: application/json' \
  --header 'X-API-Key: <your_api_key>' \
  --header 'Content-Type: application/json' \
  --data '{"search_param":{"location":[{"country":"US","state":"CA","city":"San Francisco"}]},"pagination":{"limit":1}}'
zipcodearray[string]Required: No
Example: ["10001","10002"]

One or more postal codes.

cURL example
cURL
curl --request POST \
  --url https://api.openmart.ai/api/v2/brands/search \
  --header 'Accept: application/json' \
  --header 'X-API-Key: <your_api_key>' \
  --header 'Content-Type: application/json' \
  --data '{"search_param":{"location":[{"country":"US","zipcode":["10001","10002"]}]},"pagination":{"limit":1}}'
geo_radiusobjectRequired: No
Example: {"lat":40.7128,"lon":-74.006,"radius":5000}

Radius search around a point. radius is in meters; lat/lon use WGS84.

cURL example
cURL
curl --request POST \
  --url https://api.openmart.ai/api/v2/brands/search \
  --header 'Accept: application/json' \
  --header 'X-API-Key: <your_api_key>' \
  --header 'Content-Type: application/json' \
  --data '{"search_param":{"location":[{"country":"US","geo_radius":{"lat":40.7128,"lon":-74.006,"radius":5000}}]},"pagination":{"limit":1}}'

Contact and people filters

Narrow to brands that have (or do not have) certain contact or people data.

search_param.has_staff_infobooleanRequired: No
Example: true

Tri-state filter. true = only brands with staff records, false = only brands without, omit = no filter.

cURL example
cURL
curl --request POST \
  --url https://api.openmart.ai/api/v2/brands/search \
  --header 'Accept: application/json' \
  --header 'X-API-Key: <your_api_key>' \
  --header 'Content-Type: application/json' \
  --data '{"search_param":{"location":[{"country":"US"}],"has_staff_info":true},"pagination":{"limit":5}}'
search_param.has_business_emailbooleanRequired: No
Example: true

Tri-state filter for brand-level email presence. Same semantics as has_staff_info.

cURL example
cURL
curl --request POST \
  --url https://api.openmart.ai/api/v2/brands/search \
  --header 'Accept: application/json' \
  --header 'X-API-Key: <your_api_key>' \
  --header 'Content-Type: application/json' \
  --data '{"search_param":{"location":[{"country":"US"}],"has_business_email":true},"pagination":{"limit":5}}'
search_param.has_business_phone_numberbooleanRequired: No
Example: true

Tri-state filter for brand-level phone presence. Same semantics as has_staff_info.

cURL example
cURL
curl --request POST \
  --url https://api.openmart.ai/api/v2/brands/search \
  --header 'Accept: application/json' \
  --header 'X-API-Key: <your_api_key>' \
  --header 'Content-Type: application/json' \
  --data '{"search_param":{"location":[{"country":"US"}],"has_business_phone_number":true},"pagination":{"limit":5}}'

Domain and social filters

Target or exclude brands by their website root domain or social URLs.

search_param.website_urlarray[string]Required: No
Example: ["bluebottlecoffee.com"]

Include brands whose website matches any of these hostnames (matched by normalized root domain). Up to 20.

cURL example
cURL
curl --request POST \
  --url https://api.openmart.ai/api/v2/brands/search \
  --header 'Accept: application/json' \
  --header 'X-API-Key: <your_api_key>' \
  --header 'Content-Type: application/json' \
  --data '{"search_param":{"website_url":["bluebottlecoffee.com"]},"pagination":{"limit":1}}'
search_param.exclude_website_urlarray[string]Required: No
Example: ["yelp.com","facebook.com"]

Exclude brands whose website matches any of these hostnames. Up to 20.

cURL example
cURL
curl --request POST \
  --url https://api.openmart.ai/api/v2/brands/search \
  --header 'Accept: application/json' \
  --header 'X-API-Key: <your_api_key>' \
  --header 'Content-Type: application/json' \
  --data '{"search_param":{"location":[{"country":"US"}],"exclude_website_url":["yelp.com","facebook.com"]},"pagination":{"limit":5}}'
search_param.social_media_linkarray[string]Required: No
Example: ["https://www.instagram.com/bluebottle/"]

Filter by social media URLs associated with the brand. Up to 20.

cURL example
cURL
curl --request POST \
  --url https://api.openmart.ai/api/v2/brands/search \
  --header 'Accept: application/json' \
  --header 'X-API-Key: <your_api_key>' \
  --header 'Content-Type: application/json' \
  --data '{"search_param":{"social_media_link":["https://www.instagram.com/bluebottle/"]},"pagination":{"limit":1}}'

Pagination and response shape

Control page size, iterate via opaque cursor, and opt into a total-count estimate.

pagination.limitintegerRequired: No
Example: 100

Page size. Default 100, max 500. Values ≤ 0 are coerced to 100. Preview API keys must use limit ≤ 100.

cURL example
cURL
curl --request POST \
  --url https://api.openmart.ai/api/v2/brands/search \
  --header 'Accept: application/json' \
  --header 'X-API-Key: <your_api_key>' \
  --header 'Content-Type: application/json' \
  --data '{"search_param":{"location":[{"country":"US"}]},"pagination":{"limit":100}}'
pagination.encoded_cursorstringRequired: No
Example: "7b225f73636f7265..."

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 --request POST \
  --url https://api.openmart.ai/api/v2/brands/search \
  --header 'Accept: application/json' \
  --header 'X-API-Key: <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.

cURL example
cURL
curl --request POST \
  --url https://api.openmart.ai/api/v2/brands/search \
  --header 'Accept: application/json' \
  --header 'X-API-Key: <your_api_key>' \
  --header 'Content-Type: application/json' \
  --data '{"search_param":{"location":[{"country":"US"}]},"pagination":{"limit":10,"order_by":[{"field":"num_stores","asc":true}]}}'
estimate_totalbooleanRequired: No
Example: true

When true, the response includes an approximate `total` hit count. When false or omitted, `total` is omitted from the response entirely.

cURL example
cURL
curl --request POST \
  --url https://api.openmart.ai/api/v2/brands/search \
  --header 'Accept: application/json' \
  --header 'X-API-Key: <your_api_key>' \
  --header 'Content-Type: application/json' \
  --data '{"search_param":{"location":[{"country":"US"}]},"pagination":{"limit":1},"estimate_total":true}'
# Search Companies (Brands)

## Endpoint

POST https://api.openmart.ai/api/v2/brands/search

## Description

Brand-level search. One row per brand (not per store). Use this when
store-level search over-counts multi-location companies.

## Authentication

- `X-API-Key: <your_api_key>` (recommended)
- `Authorization: Bearer <your_api_key>` (also accepted)

## Request body

```json
{
  "search_param": {
    "search_term": "coffee shop",
    "location": [{ "country": "US", "state": "CA", "city": "San Francisco" }],
    "num_stores": [{ "ge": 5 }],
    "ownership_type": ["FRANCHISE", "CHAIN"],
    "has_staff_info": true,
    "has_business_email": true,
    "has_business_phone_number": true,
    "website_url": ["bluebottlecoffee.com"],
    "exclude_website_url": ["yelp.com"],
    "social_media_link": ["https://www.instagram.com/bluebottle/"]
  },
  "pagination": {
    "limit": 100,
    "encoded_cursor": "<copy from prior response>",
    "order_by": [{ "field": "num_stores", "asc": false }]
  },
  "estimate_total": false
}
```

### Notes

- `search_param` is optional in practice. Omitting it defaults the
  location filter to `[{"country": "US"}]`.
- Each entry of `search_param.location` MUST include `country`,
  otherwise the API returns HTTP 422 "Country is required".
- `search_param.num_stores` is an array of range objects; each entry
  is any subset of `{ge, gt, le, lt}`.
- `ownership_type` values: `INDEPENDENT`, `FAMILY`, `FRANCHISE`, `CHAIN`.
- `has_staff_info`, `has_business_email`, `has_business_phone_number`
  are tri-state: `true` = must have, `false` = must not, omit = no filter.
- Array filters are capped at 20 entries.
- `pagination.limit` defaults to 100, max 500. Preview API keys must
  use `limit <= 100` and cannot set `encoded_cursor`.
- `pagination.order_by[].asc` currently MUST be `true`; sending
  `false` returns 422 "Asc is required" because the server-side
  `required` validator treats the zero value as missing.
- `estimate_total`: when `true`, the response includes an approximate
  `total`; when `false` or omitted, `total` is omitted from the response.

## Example Request

```bash
curl -X POST "https://api.openmart.ai/api/v2/brands/search" \
  -H "Accept: application/json" \
  -H "X-API-Key: <your_api_key>" \
  -H "Content-Type: application/json" \
  -d '{
    "search_param": {
      "search_term": "coffee shop",
      "location": [{ "country": "US", "state": "CA", "city": "San Francisco" }]
    },
    "pagination": { "limit": 2 },
    "estimate_total": true
  }'
```

## Example Response

```json
{
  "total": 87,
  "encoded_cursor": "7b225f73636f7265223a3439363938...",
  "data": [
    {
      "brand_id": "02c6be6a-d0a4-4345-9625-19442df5c8c9",
      "business_name": "Cable Car Coffee SF",
      "business_type": "Coffee Shop",
      "business_categories": ["RESTAURANTS_DINING"],
      "business_specialty": "Warm brews",
      "business_keywords": ["coffee", "brews", "SF"],
      "product_services_offered": ["coffee", "warm brews"],
      "brand_description": "Cable Car Coffee SF is a coffee shop specializing in warm brews located in San Francisco.",
      "website_url": "https://cablecarcoffeesf.com/",
      "business_emails": null,
      "business_phones": null,
      "social_media_links": {
        "FACEBOOK": null, "LINKEDIN": null, "INSTAGRAM": null,
        "TWITTER": null, "X": null, "PINTEREST": null,
        "TIKTOK": null, "YOUTUBE": null
      },
      "ownership_type": "",
      "staffs": null,
      "domain_ident": "cablecarcoffeesf.com",
      "num_stores": 1
    }
  ]
}
```

### Response fields

- `total`: approximate count; present only when `estimate_total=true`.
- `encoded_cursor`: opaque cursor for the NEXT page. Pass it back in
  `pagination.encoded_cursor`. Empty string on the last page.
- `data[]`: one brand per entry. Each has:
  - `brand_id` (UUID), `business_name`, `business_type`
  - `business_categories` (array; enum values include
    `RESTAURANTS_DINING`, `BEAUTY_PERSONAL_CARE`, `HEALTH_WELLNESS`,
    `SHOPPING_RETAIL`, `FITNESS_RECREATION`, and more)
  - `business_specialty`, `business_keywords`, `product_services_offered`
  - `brand_description`, `website_url`
  - `business_emails`, `business_phones`, `staffs` — arrays that may be
    `null` (consumers should treat `null` and `[]` equivalently)
  - `social_media_links`: map of `FACEBOOK`, `LINKEDIN`, `INSTAGRAM`,
    `TWITTER`, `X`, `PINTEREST`, `TIKTOK`, `YOUTUBE` to arrays of URLs
    (individual slices may be `null`)
  - `ownership_type`: `INDEPENDENT`, `FAMILY`, `FRANCHISE`, `CHAIN`, or
    `""` when not classified
  - `domain_ident`: normalized root domain (stable brand domain identifier)
  - `num_stores`: count of physical stores for this brand

## Errors

- 401 — missing or invalid API key
- 402 — credit limit reached
- 403 — banned user, or preview token used with disallowed params / path
- 422 — JSON / validation failure (e.g. `limit > 500`, missing `country`
  in a location entry)