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

# Brands

> Create brands and find the brand IDs that scope products and templates.

An organization API key can access multiple brands. Every product belongs to a
brand, so listing brands is usually the first call of an integration.

**Endpoints:** `GET https://makelocalads.com/api/v1/brands` and
`POST https://makelocalads.com/api/v1/brands`
**Permissions:** list with `products:read`, create with `products:create`

<Card title="Open in LocalAds" icon="arrow-up-right" href="https://makelocalads.com/app">
  The brands and products of your workspace, on the app's home screen.
</Card>

## List brands

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl https://makelocalads.com/api/v1/brands \
  --header "Authorization: Bearer $LOCALADS_API_KEY"
```

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "data": [
    {
      "id": "1423f915-beca-4c53-a5e4-7c8c99537be9",
      "name": "Example Beauty",
      "slug": "example-beauty",
      "website_url": "https://example.com",
      "created_at": "2026-07-20T10:00:00.000Z",
      "updated_at": "2026-07-20T10:00:00.000Z"
    }
  ]
}
```

Use the returned `id` as `brand_id` when creating a product, or when listing
products and templates.

## Create a brand

If the brand you need is not in the list, create it. This is the first call
for a website LocalAds has not seen before.

<CodeGroup>
  ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
  curl --request POST \
    --url https://makelocalads.com/api/v1/brands \
    --header "Authorization: Bearer $LOCALADS_API_KEY" \
    --header "Content-Type: application/json" \
    --header "Idempotency-Key: 8f0a1c2e-quenzy-setup" \
    --data '{
      "name": "Quenzy",
      "website_url": "https://thequenzy.com",
      "selling_countries": ["IN"]
    }'
  ```

  ```javascript JavaScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
  const response = await fetch("https://makelocalads.com/api/v1/brands", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.LOCALADS_API_KEY}`,
      "Content-Type": "application/json",
      "Idempotency-Key": "8f0a1c2e-quenzy-setup",
    },
    body: JSON.stringify({
      name: "Quenzy",
      website_url: "https://thequenzy.com",
      selling_countries: ["IN"],
    }),
  });

  const brand = await response.json();
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
  import os
  import requests

  response = requests.post(
      "https://makelocalads.com/api/v1/brands",
      headers={
          "Authorization": f"Bearer {os.environ['LOCALADS_API_KEY']}",
          "Content-Type": "application/json",
          "Idempotency-Key": "8f0a1c2e-quenzy-setup",
      },
      json={
          "name": "Quenzy",
          "website_url": "https://thequenzy.com",
          "selling_countries": ["IN"],
      },
  )

  brand = response.json()
  ```
</CodeGroup>

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "id": "9f2b7c41-58a0-4c3e-9d61-2f0c8b7d4a15",
  "name": "Quenzy",
  "slug": "quenzy",
  "website_url": "https://thequenzy.com",
  "created_at": "2026-08-12T10:00:00.000Z",
  "updated_at": "2026-08-12T10:00:00.000Z"
}
```

### Input fields

<ParamField body="name" type="string" required>
  The brand's name, 1 to 200 characters.
</ParamField>

<ParamField body="website_url" type="string">
  The brand's own site, as a URL. LocalAds uses it to fetch the logo, and to
  keep one brand per website.
</ParamField>

<ParamField body="selling_countries" type="array">
  ISO 3166-1 alpha-2 country codes where the brand sells, up to 50. Defaults
  to an empty list.
</ParamField>

<Accordion title="Complete JSON schema">
  ```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
  {
    "type": "object",
    "additionalProperties": false,
    "required": ["name"],
    "properties": {
      "name": { "type": "string", "minLength": 1, "maxLength": 200 },
      "website_url": { "type": ["string", "null"], "format": "uri" },
      "selling_countries": {
        "type": "array",
        "maxItems": 50,
        "items": { "type": "string", "minLength": 2, "maxLength": 2 }
      }
    }
  }
  ```
</Accordion>

## One brand per website

Posting a second brand for a domain that already has one returns
`409 brand_website_exists` with the existing brand's name, so retrying a
setup script does not litter the account with duplicates. Send an
`Idempotency-Key` to make a network retry safe as well; see
[Idempotent requests](/concepts/idempotency).

| Status | Code | Meaning |
| - | - | - |
| 409 | `brand_website_exists` | A brand for this website already exists. List brands and reuse its ID |
| 422 | `brand_limit_reached` | The plan's brand allowance is used up |

You do not need to send `brand_id` when retrieving a resource by its ID.
Photoshoot creation also omits it: LocalAds derives the brand from the
selected product, and requires a template to belong to that same brand.
