> ## Documentation Index
> Fetch the complete documentation index at: https://docs.closient.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Find stores carrying a brand

> Returns the brand's identity and the physical stores within `radius` km of (`lat`, `lon`) that carry at least one of the brand's products as an active in-store offer, sorted by ascending great-circle distance. **Public, unauthenticated** — designed to be called from the brand's website via the embeddable widget. CORS is open. Coordinates are WGS 84 / EPSG:4326 (the standard used by browsers' `navigator.geolocation` and Google Maps); PostGIS computes distance on the geography type.



## OpenAPI

````yaml /openapi/openapi-brands.json get /brands/api/v1/public/brands/{brand_id}/locator
openapi: 3.1.0
info:
  title: Brands API
  version: 1.0.0
  description: >
    Brand management: list, create, update, and manage brand profiles.


    ## Authentication


    All endpoints require an API key passed via the `X-API-Key` HTTP header,
    unless otherwise noted.


    ```

    X-API-Key: csb_<body>_<checksum>

    ```


    Generate API keys in **Settings > API Keys** in your dashboard, or via the
    Account API.

    Session-based (cookie) authentication is also accepted for browser-based
    access.


    ## Rate Limits


    | Tier        | Requests / minute | Requests / day |

    |-------------|-------------------|----------------|

    | Default     | 300               | 10,000         |

    | Custom      | Contact us        | Contact us     |


    Rate-limit headers are included on every response so callers can
    self-throttle without

    hitting our 429s ("informed governor"):


    - `RateLimit-Policy` — every active window, e.g. `300;w=60, 10000;w=86400`

    - `RateLimit-Limit` — quota for the **most-restrictive** currently-active
    window

    - `RateLimit-Remaining` — requests left in that window

    - `RateLimit-Reset` — seconds until that window resets (relative; clock-skew
    safe)


    Legacy `X-RateLimit-*` aliases are also emitted for back-compat.
    `X-RateLimit-Reset`

    keeps the absolute Unix-timestamp shape to avoid breaking existing
    consumers.


    When rate-limited, you receive `429 Too Many Requests` with a
    `retry_after_seconds` field

    in the error envelope and a `Retry-After` header.


    ## Pagination


    List endpoints return paginated results in this envelope:


    ```json

    {
      "data": [...],
      "pagination": {
        "page": 1,
        "page_size": 25,
        "total_count": 342,
        "total_pages": 14,
        "has_next": true,
        "has_previous": false
      }
    }

    ```


    Use `?page=2&page_size=50` query parameters. Maximum page size is 100.


    ## Error Responses


    All errors conform to [RFC 9457 Problem
    Details](https://www.rfc-editor.org/rfc/rfc9457)

    with `Content-Type: application/problem+json`:


    ```json

    {
      "type": "https://closient.com/docs/errors/not_found",
      "title": "Not Found",
      "status": 404,
      "detail": "The requested resource was not found.",
      "error_code": "not_found",
      "retryable": false,
      "timestamp": "2026-03-31T12:00:00+00:00"
    }

    ```


    Common error codes: `unauthorized` (401), `forbidden` (403), `not_found`
    (404),

    `validation_error` (422), `rate_limited` (429), `internal_error` (500).
  termsOfService: https://www.closient.com/terms/
servers:
  - url: https://www.closient.com
security: []
tags:
  - name: Brands
    description: Brand CRUD operations.
  - name: Brand Locator (Public)
    description: >-
      Unauthenticated endpoints that power the embeddable brand product-locator
      widget (C-1803). Mounted under the `/public/` prefix so the widget CORS
      middleware opens CORS for them.
externalDocs:
  description: Closient Documentation
  url: https://docs.closient.com
paths:
  /brands/api/v1/public/brands/{brand_id}/locator:
    get:
      tags:
        - Brand Locator (Public)
      summary: Find stores carrying a brand
      description: >-
        Returns the brand's identity and the physical stores within `radius` km
        of (`lat`, `lon`) that carry at least one of the brand's products as an
        active in-store offer, sorted by ascending great-circle distance.
        **Public, unauthenticated** — designed to be called from the brand's
        website via the embeddable widget. CORS is open. Coordinates are WGS 84
        / EPSG:4326 (the standard used by browsers' `navigator.geolocation` and
        Google Maps); PostGIS computes distance on the geography type.
      operationId: apps_brands_api_public_list_brand_locator_stores
      parameters:
        - in: path
          name: brand_id
          schema:
            description: Brand short id (22-char shortuuid).
            format: shortuuid
            maxLength: 22
            minLength: 22
            pattern: ^[23456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{22}$
            title: Brand Id
            type: string
          required: true
          description: Brand short id (22-char shortuuid).
        - in: query
          name: lat
          schema:
            description: >-
              Latitude of the search centre in decimal degrees, WGS 84 /
              EPSG:4326. Typically obtained from the browser's
              `navigator.geolocation` API or a geocoded user query.
            maximum: 90
            minimum: -90
            title: Lat
            type: number
          required: true
          description: >-
            Latitude of the search centre in decimal degrees, WGS 84 /
            EPSG:4326. Typically obtained from the browser's
            `navigator.geolocation` API or a geocoded user query.
        - in: query
          name: lon
          schema:
            description: >-
              Longitude of the search centre in decimal degrees, WGS 84 /
              EPSG:4326.
            maximum: 180
            minimum: -180
            title: Lon
            type: number
          required: true
          description: >-
            Longitude of the search centre in decimal degrees, WGS 84 /
            EPSG:4326.
        - in: query
          name: radius
          schema:
            default: 50
            description: >-
              Search radius in kilometres. Locations farther than this from
              (`lat`, `lon`) are excluded.
            exclusiveMinimum: 0
            title: Radius
            type: number
          required: false
          description: >-
            Search radius in kilometres. Locations farther than this from
            (`lat`, `lon`) are excluded.
        - in: query
          name: limit
          schema:
            default: 20
            description: >-
              Maximum number of stores to return (1-100). Results are pre-sorted
              by distance ascending.
            maximum: 100
            minimum: 1
            title: Limit
            type: integer
          required: false
          description: >-
            Maximum number of stores to return (1-100). Results are pre-sorted
            by distance ascending.
        - in: query
          name: product_id
          schema:
            anyOf:
              - type: string
              - type: 'null'
            description: >-
              Optional product short id to filter stores by. When set, only
              stores carrying that specific product are returned.
            title: Product Id
          required: false
          description: >-
            Optional product short id to filter stores by. When set, only stores
            carrying that specific product are returned.
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BrandLocatorResponse'
components:
  schemas:
    BrandLocatorResponse:
      description: Top-level payload for the brand locator endpoint.
      examples:
        - brand:
            id: 2sP1Y9pZ4xQ6rNvHwT3kBe
            logo_url: https://cdn.closient.com/brands/acme/logo.png
            name: Acme Beverages
            website: https://acme.example.com
          stores: []
      properties:
        brand:
          $ref: '#/components/schemas/BrandSummaryOut'
          description: >-
            Identity of the brand the widget is rendering. Lets the widget
            render branding without a second request.
        stores:
          description: >-
            Physical stores within `radius` km of (`lat`, `lon`) that carry at
            least one of the brand's products, sorted by ascending great-circle
            distance. Empty list when no stores match.
          items:
            $ref: '#/components/schemas/StoreLocatorOut'
          title: Stores
          type: array
      required:
        - brand
        - stores
      title: BrandLocatorResponse
      type: object
    BrandSummaryOut:
      description: Brand identity returned alongside locator results.
      examples:
        - id: 2sP1Y9pZ4xQ6rNvHwT3kBe
          logo_url: https://cdn.closient.com/brands/acme/logo.png
          name: Acme Beverages
          website: https://acme.example.com
      properties:
        id:
          description: >-
            URL-safe 22-character shortuuid encoding of the row's UUID primary
            key. Stable across the row's lifetime; suitable for sharing in URLs,
            log lines, and external SDK clients. Accepted on input as either the
            shortuuid form or the canonical UUID form
            (``xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx``).
          format: shortuuid
          maxLength: 22
          minLength: 22
          pattern: ^[23456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{22}$
          title: Id
          type: string
        name:
          description: Brand display name.
          title: Name
          type: string
        website:
          default: ''
          description: Brand website URL. Empty string when unset.
          title: Website
          type: string
        logo_url:
          anyOf:
            - type: string
            - type: 'null'
          description: Absolute URL of the brand logo image. Null when no logo is set.
          title: Logo Url
      required:
        - id
        - name
      title: BrandSummaryOut
      type: object
    StoreLocatorOut:
      description: A single physical store carrying the brand's products.
      examples:
        - address: 1758 99 Street NW, Edmonton, AB, T6N 1J5, Canada
          distance_km: 3.21
          id: 2sP1Y9pZ4xQ6rNvHwT3kBe
          lat: 53.4471
          lon: -113.4979
          name: Best Buy — South Edmonton Common
          phone: '+17804304100'
          product_count: 4
          retailer_name: Best Buy
          website: https://stores.bestbuy.ca/edmonton-south
      properties:
        id:
          description: >-
            URL-safe 22-character shortuuid encoding of the row's UUID primary
            key. Stable across the row's lifetime; suitable for sharing in URLs,
            log lines, and external SDK clients. Accepted on input as either the
            shortuuid form or the canonical UUID form
            (``xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx``).
          format: shortuuid
          maxLength: 22
          minLength: 22
          pattern: ^[23456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{22}$
          title: Id
          type: string
        name:
          description: >-
            Physical store display name (e.g. 'Best Buy — South Edmonton
            Common').
          title: Name
          type: string
        retailer_name:
          default: ''
          description: Display name of the retailer that owns the store.
          title: Retailer Name
          type: string
        address:
          description: >-
            Formatted full street address (line 1, optional line 2, city,
            region, postal code, country) joined with ', '.
          title: Address
          type: string
        lat:
          description: Latitude in decimal degrees, WGS 84 / EPSG:4326.
          maximum: 90
          minimum: -90
          title: Lat
          type: number
        lon:
          description: Longitude in decimal degrees, WGS 84 / EPSG:4326.
          maximum: 180
          minimum: -180
          title: Lon
          type: number
        distance_km:
          description: >-
            Great-circle distance from the search point in kilometres, rounded
            to two decimals. Computed by PostGIS on the geography type.
          minimum: 0
          title: Distance Km
          type: number
        product_count:
          description: >-
            Number of distinct products from the brand carried by this store as
            active in-store offers.
          minimum: 0
          title: Product Count
          type: integer
        phone:
          default: ''
          description: Primary phone number (E.164). Empty string when no phone is set.
          title: Phone
          type: string
        website:
          default: ''
          description: >-
            Primary website URL for the location. Empty string when no URL is
            set.
          title: Website
          type: string
      required:
        - id
        - name
        - address
        - lat
        - lon
        - distance_km
        - product_count
      title: StoreLocatorOut
      type: object

````