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

# Upsert brands

> Create or update up to 100 brands by external id in one request.

Send an array of brands. Each item creates the brand when its `id` does not exist, or updates it when it does. Send only the fields to change. `id` comes from each item and cannot be renamed here.

> [!NOTE]
>
> Requires an access token with the `brands:write` scope. See
> [Token](https://firespark.cloud/docs/integrations-api/oauth/token/post.md) to obtain a token.

An item with only `id` refreshes `updated_at` when the brand already exists. A new `id` requires `name`. Omitted `status` defaults to `ACTIVE`. Omitted `cms_template_id` stays unset.

## Request

```bash theme={null}
curl -X PUT "https://firespark.cloud/api/integrations/v1/brands" \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '[
    { "id": "0001", "name": "Burger Co", "status": "ACTIVE" },
    { "id": "0002", "name": "Pizza Co" }
  ]'
```

## Body

An array of 1 to 100 items. Each item takes these fields:

| Field | Type | Description |
| - | - | - |
| `id` | string | External brand id. Required. Alphanumeric characters, `_`, and `-`, 1–64 characters. |
| `name` | string | Display name, 1–100 characters. Letters, numbers, and single spaces. Required when creating. |
| `cms_template_id` | string (UUID) | CMS template to link. `null` clears it. |
| `status` | string | `ACTIVE` or `INACTIVE`. |

`labels`, `cms`, `uid`, `merchant_id`, and `env` are ignored if sent.

## Response

Zod validates the entire body before saving. If any field is invalid, HTTP `400` is returned and no items are saved. When the body is valid, items are saved one after another. HTTP `200` only when every item is saved. If a later item hits a business error, HTTP is that item's status (`422` or `500`).

| Field | Description |
| - | - |
| `id` | The item `id`. `null` when it was missing or invalid. |
| `status` | `200` when saved. `422` when `name` is already used by another brand, or a new `id` was sent without `name`. `500` for an unexpected failure. |
| `data` | The saved brand, including `labels` and `cms`. Only when `status` is `200`. |
| `error` | Error message. Only when `status` is not `200`. |
| `details` | Error details for item-level failures. |

```json Success theme={null}
{
  "data": [
    {
      "id": "0001",
      "status": 200,
      "data": {
        "id": "0001",
        "uid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
        "merchant_id": "c1d2e3f4-a5b6-7890-cdef-123456789abc",
        "name": "Burger Co",
        "status": "ACTIVE",
        "cms_template_id": null,
        "cms": null,
        "labels": []
      }
    },
    {
      "id": "0002",
      "status": 422,
      "error": "Brand name already exists",
      "details": null
    }
  ]
}
```

```json Invalid fields theme={null}
{
  "error": "Invalid fields",
  "details": {
    "0.name": "Only letters and numbers are allowed"
  }
}
```

## Error responses

| Status | Description |
| - | - |
| `400` | The body is not an array of 1 to 100 items, or any item has invalid fields. No items are saved. |
| `401` | Missing or invalid access token. |
| `403` | Token does not include the `brands:write` scope. |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.