# Create brand

> POST /v1/brands · Core resources API

Source: https://developer.kustomer.com/api/core-resources/create-brand

```http
POST https://{orgname}.api.kustomerapp.com/v1/brands
Authorization: Bearer <API key>
```

## Authorization

Requires any one of these roles: `org.permission.brand.create`; or legacy `org.admin.brand.write`. The API key or user must hold at least one of them. Legacy roles predate permission sets and still work.

Creates a brand resource.

## About Brands

A brand represents one of the companies, products or storefronts you support from a single Kustomer org. Brands let each one have its own name and icon, chat widget settings, knowledge base and email addresses.

Many businesses run more than one brand out of one support team, for example a retailer with two storefronts. In Kustomer each of these is a brand. Admins manage brands in the admin settings, and other configuration hangs off them: chat settings (colors, greeting, business hours and assistant) are set per brand, each knowledge base belongs to a brand, and the web chat SDK takes a `brandId` to choose which brand's widget to load. Every org starts with one brand, created when the org is registered and marked `default: true`. Chat uses the default brand when it starts without a `brandId`.

#### Brand fields

A brand is small: `name` and `iconUrl` are the only fields you write, and both are required when you create or update one. `default` tells you whether it's the org's default brand. The public API has no endpoint for deleting a brand.

#### Brand address mappings

A brand address mapping links an email address to a brand, so Kustomer knows which brand an address belongs to. One address can be mapped to several brands, and each brand can mark at most one of its mapped addresses with `isDefault: true`. Addresses are matched case-insensitively.

These endpoints behave differently from most write endpoints:

- `POST /v1/brandAddresses` is idempotent. Posting an address and brand pair that already exists returns the existing mapping with `200` instead of creating a duplicate. A new mapping returns `201`.
- `POST` accepts an optional `allBrands` flag. When `true`, the address is shared across every brand, and Kustomer syncs the flag onto every mapping for that address. If you leave it out on create and another mapping for the same address is already shared, the new mapping inherits `true`.
- `PATCH` changes only `isDefault` and `allBrands`, and needs at least one of them. Setting `isDefault` to `true` moves the default from the brand's previous default address. Deleting the default mapping leaves the brand with no default; Kustomer doesn't promote another address automatically.
- Deleting all mappings for an address first checks whether the address is still connected to an email account in Kustomer. If it is, nothing is deleted and the response reports `live: true`. If Kustomer can't confirm either way, it deletes nothing and returns `503`.

#### Which endpoint to use

| To | Call |
| --- | --- |
| List brands, for example to find a `brandId` for chat | [`GET /v1/brands`](https://developer.kustomer.com/api/core-resources/get-brands) |
| Get the org's default brand | [`GET /v1/brands/default`](https://developer.kustomer.com/api/core-resources/get-default-brand) |
| Create, read or update a brand | [`POST /v1/brands`](https://developer.kustomer.com/api/core-resources/create-brand), [`GET`](https://developer.kustomer.com/api/core-resources/get-brand-by-id) or [`PATCH /v1/brands/{id}`](https://developer.kustomer.com/api/core-resources/update-brand) |
| See which brands an email address is mapped to | [`GET /v1/brandAddresses`](https://developer.kustomer.com/api/core-resources/list-brand-address-mappings), with `address` to look up one address |
| Map an address to a brand | [`POST /v1/brandAddresses`](https://developer.kustomer.com/api/core-resources/create-brand-address-mapping) |
| Make a mapped address the brand's default, or clear it | [`PATCH /v1/brandAddresses/{id}`](https://developer.kustomer.com/api/core-resources/update-brand-address-mapping) |
| Remove one mapping | [`DELETE /v1/brandAddresses/{id}`](https://developer.kustomer.com/api/core-resources/delete-brand-address-mapping-by-id) |
| Remove every mapping for an address, or for a brand | [`DELETE /v1/brandAddresses/address/{address}`](https://developer.kustomer.com/api/core-resources/delete-all-mappings-for-an-address) or [`DELETE /v1/brandAddresses/brand/{brandId}`](https://developer.kustomer.com/api/core-resources/delete-all-mappings-for-a-brand) |

Brand reads are available to most users. Writing brands needs brand write permission, and brand address mappings use the apps permissions. A brand can have only one default address at a time, so if two requests try to set different defaults for the same brand at once, one of them can fail with `409 Conflict`. Read the mappings again and retry.

Related: [Chat settings](https://developer.kustomer.com/api/settings-and-configurations#chat-settings), [Knowledge bases](https://developer.kustomer.com/api/knowledge-base#knowledge-bases), [Web chat](https://developer.kustomer.com/docs/chat/web)

### Recipes

#### 1. Load the right chat widget on each storefront

Look up each brand's ID so every site you run opens chat with its own brand's settings and knowledge base.

**Step 1.** [`GET /v1/brands`](https://developer.kustomer.com/api/core-resources/get-brands.md). List the brands and note each one's ID. The brand with `default: true` is the one chat falls back to.

```bash title="cURL"
curl "https://api.kustomerapp.com/v1/brands" \
  --header "Authorization: Bearer $KUSTOMER_API_KEY"
```

```bash title="kusty"
kusty api GET /v1/brands --all \
  | jq -r '[.data.id, .data.attributes.name, .data.attributes.default] | @tsv'
```

**Step 2.** Pass the brand's ID as `brandId` when you start the [web chat SDK](https://developer.kustomer.com/docs/chat/web) on that storefront. Without it, chat loads the default brand.

```js
Kustomer.start({ brandId: 'YOUR_BRAND_ID' })
```

#### 2. Map support addresses to a brand

Tell Kustomer which email addresses belong to a brand, for example when you add a new storefront with its own support inbox.

**Step 1.** [`GET /v1/brands`](https://developer.kustomer.com/api/core-resources/get-brands.md). Find the brand's ID by name.

```bash title="cURL"
curl "https://api.kustomerapp.com/v1/brands" \
  --header "Authorization: Bearer $KUSTOMER_API_KEY"
```

```bash title="kusty"
BRAND_ID=$(kusty api GET /v1/brands --all \
  | jq -r 'select(.data.attributes.name == "Kustom Socks") | .data.id')
```

**Step 2.** [`POST /v1/brandAddresses`](https://developer.kustomer.com/api/core-resources/create-brand-address-mapping.md). Map each address. The call is idempotent: if the address and brand are already mapped, you get the existing mapping back with `200` instead of a duplicate, so it's safe to run from a setup script.

```bash title="cURL"
curl --request POST "https://api.kustomerapp.com/v1/brandAddresses" \
  --header "Authorization: Bearer $KUSTOMER_API_KEY" \
  --header "Content-Type: application/json" \
  --data "{\"address\": \"support@kustomsocks.com\", \"brand\": \"$BRAND_ID\"}"
```

```bash title="kusty"
for address in support@kustomsocks.com returns@kustomsocks.com; do
  kusty api POST /v1/brandAddresses --field address=$address --field brand=$BRAND_ID --fields id
done
```

**Step 3.** [`PATCH /v1/brandAddresses/{id}`](https://developer.kustomer.com/api/core-resources/update-brand-address-mapping.md). Make the main address the brand's default. The previous default for the brand stops being the default. If another request sets a default for the same brand at the same moment, this can fail with `409 Conflict`; read the mappings again and retry.

```bash title="cURL"
curl --request PATCH "https://api.kustomerapp.com/v1/brandAddresses/$MAPPING_ID" \
  --header "Authorization: Bearer $KUSTOMER_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{"isDefault": true}'
```

```bash title="kusty"
kusty api PATCH /v1/brandAddresses/$MAPPING_ID --field isDefault:=true
```

#### 3. Retire a support address

Remove an old email address from every brand it's mapped to, after it's no longer used to send or receive mail.

**Step 1.** [`GET /v1/brandAddresses`](https://developer.kustomer.com/api/core-resources/list-brand-address-mappings.md). Check which brands the address is mapped to, and whether it's any brand's default. Removing a default mapping leaves that brand with no default address until you set another.

```bash title="cURL"
curl "https://api.kustomerapp.com/v1/brandAddresses?address=help@oldbrand.com" \
  --header "Authorization: Bearer $KUSTOMER_API_KEY"
```

```bash title="kusty"
kusty api GET /v1/brandAddresses --query address=help@oldbrand.com --all
```

**Step 2.** [`DELETE /v1/brandAddresses/address/{address}`](https://developer.kustomer.com/api/core-resources/delete-all-mappings-for-an-address.md). Delete every mapping for the address in one call. Kustomer first checks whether the address is still connected to an email account. If it is, nothing is deleted and `meta.live` is `true`; disconnect the account and try again. A `503` means Kustomer couldn't tell, and also deleted nothing, so retry later. Otherwise `meta.deletedCount` says how many mappings were removed.

```bash title="cURL"
curl --request DELETE "https://api.kustomerapp.com/v1/brandAddresses/address/help@oldbrand.com" \
  --header "Authorization: Bearer $KUSTOMER_API_KEY" \
  | jq '.meta'
```

### Example object

A real record from [`POST /v1/brands`](https://developer.kustomer.com/api/core-resources/create-brand.md):

```json
{
  "type": "brand",
  "id": "5e0f779ed95b430019b57715",
  "attributes": {
    "name": "Kustom Socks",
    "iconUrl": "https://s29093.pcdn.co/wp-content/uploads/2019/12/Kustomer_Logo-2.svg",
    "default": false,
    "createdAt": "2020-01-03T17:19:26.498Z",
    "updatedAt": "2020-01-03T17:19:26.498Z",
    "modifiedAt": "2020-01-03T17:19:26.498Z"
  },
  "relationships": {
    "org": {
      "links": {
        "self": "/v1/orgs/5d5dae1ccd1e87001a6a7ea4"
      },
      "data": {
        "type": "org",
        "id": "5d5dae1ccd1e87001a6a7ea4"
      }
    },
    "createdBy": {
      "links": {
        "self": "/v1/users/5e0e15a9b2d734001913256c"
      },
      "data": {
        "type": "user",
        "id": "5e0e15a9b2d734001913256c"
      }
    },
    "modifiedBy": {
      "links": {
        "self": "/v1/users/5e0e15a9b2d734001913256c"
      },
      "data": {
        "type": "user",
        "id": "5e0e15a9b2d734001913256c"
      }
    }
  },
  "links": {
    "self": "/v1/brands/5e0f779ed95b430019b57715"
  }
}
```

Fields:

- `attributes.name` (string): The brand's name. `PATCH` requires it together with `iconUrl`, so send the current value of whichever one you aren't changing.
- `attributes.iconUrl` (string): A URL for the brand's icon image. Like `name`, it's required on both `POST` and `PATCH`.
- `attributes.default` (boolean): Whether this is the org's default brand, which chat uses when it starts without a `brandId`. The first brand gets it when the org is created; brands you create are always `false`, and the API can't move the default.

### Relationships

- Referenced by **Knowledge bases** via `relationships.brand`: Each knowledge base belongs to exactly one brand, and a brand can have only one knowledge base. The default knowledge base uses the org's default brand.

### Permissions

Fewest roles for a read-only integration: `org.permission.brand.read`, `org.permission.apps.read`. For every endpoint: `org.permission.apps.delete`, `org.permission.brand.read`, `org.permission.apps.create`, `org.permission.apps.read`, `org.permission.apps.update`, `org.permission.brand.create`, `org.permission.brand.update`.

## Request body

Content type: `application/json` (required)

- `name` (string, required): Brand name (min length 1)
- `iconUrl` (string, required): Brand icon URL (min length 1)

Example:

```json
{
  "name": "Kustom Socks",
  "iconUrl": "https://s29093.pcdn.co/wp-content/uploads/2019/12/Kustomer_Logo-2.svg"
}
```

## Responses

### 201

Created

- `data` (object, required)
  - `type` (string, required)
  - `id` (string, required)
  - `attributes` (object, required)
    - `name` (string, required)
    - `iconUrl` (string, required)
    - `default` (boolean, required)
    - `createdAt` (string, required)
    - `updatedAt` (string, required)
    - `modifiedAt` (string, required)
  - `relationships` (object, required)
    - `org` (object, required)
    - `createdBy` (object, required)
    - `modifiedBy` (object, required)
  - `links` (object, required)
    - `self` (string, required)

```json
{
  "data": {
    "type": "brand",
    "id": "5e0f779ed95b430019b57715",
    "attributes": {
      "name": "Kustom Socks",
      "iconUrl": "https://s29093.pcdn.co/wp-content/uploads/2019/12/Kustomer_Logo-2.svg",
      "default": false,
      "createdAt": "2020-01-03T17:19:26.498Z",
      "updatedAt": "2020-01-03T17:19:26.498Z",
      "modifiedAt": "2020-01-03T17:19:26.498Z"
    },
    "relationships": {
      "org": {
        "links": {
          "self": "/v1/orgs/5d5dae1ccd1e87001a6a7ea4"
        },
        "data": {
          "type": "org",
          "id": "5d5dae1ccd1e87001a6a7ea4"
        }
      },
      "createdBy": {
        "links": {
          "self": "/v1/users/5e0e15a9b2d734001913256c"
        },
        "data": {
          "type": "user",
          "id": "5e0e15a9b2d734001913256c"
        }
      },
      "modifiedBy": {
        "links": {
          "self": "/v1/users/5e0e15a9b2d734001913256c"
        },
        "data": {
          "type": "user",
          "id": "5e0e15a9b2d734001913256c"
        }
      }
    },
    "links": {
      "self": "/v1/brands/5e0f779ed95b430019b57715"
    }
  }
}
```

### 400

Bad Request

### 401

Unauthorized

### 403

Forbidden

## Example request

```bash
curl --request POST \
  --url 'https://api.kustomerapp.com/v1/brands' \
  --header "Authorization: Bearer $KUSTOMER_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "name": "Kustom Socks",
  "iconUrl": "https://s29093.pcdn.co/wp-content/uploads/2019/12/Kustomer_Logo-2.svg"
}'
```
