Brands group products by manufacturer or label (e.g. "Acme", "Nike"). Each product can be assigned to a single brand, and brands can be shown and filtered on your storefront. A brand can be addressed by its UUID or by its URL slug.

## List Brands

```
GET /api/v1/brands
```

Returns a paginated list of brands for the store, ordered by newest first. Pass `?lang=` to overlay translated fields onto each brand.

### Query Parameters

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `limit` | `number` | 10 | Brands per page (1-100) |
| `offset` | `number` | 0 | Brands to skip |
| `query` | `string` | – | Search by brand name |
| `active` | `boolean` | – | Filter by active status |
| `lang` | `string` | – | Locale code for translations (e.g. `pl-PL`) |

```bash
curl \
  -H "Authorization: Bearer your_api_key" \
  "https://your-store.yns.store/api/v1/brands?active=true&limit=20"
```

### Response

```json
{
  "data": [
    {
      "id": "0191abc0-1234-7def-8000-000000000001",
      "name": "Acme",
      "slug": "acme",
      "description": null,
      "longDescription": null,
      "image": "https://cdn.example.com/brands/acme.png",
      "website": "https://acme.example.com",
      "active": true,
      "seo": {},
      "createdAt": "2024-05-01T09:00:00.000Z",
      "updatedAt": "2024-05-01T09:00:00.000Z",
      "tr": []
    }
  ],
  "meta": {
    "count": 1
  }
}
```

---

## Create Brand

```
POST /api/v1/brands
```

Creates one brand (object body, returns `201`) or many brands at once (array body of up to 500 items, returns `200`). Slug is auto-generated from the name when omitted. Unknown fields are rejected. In batch mode, per-row errors (such as slug conflicts) are reported without aborting the other rows.

### Request Body

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `name` | `string` | Yes | Brand display name |
| `slug` | `string` | No | URL slug, lowercase letters, numbers, and hyphens only (auto-generated from name) |
| `description` | `string` | No | Plain text description |
| `image` | `string` | No | Brand logo / image URL |
| `website` | `string` | No | Brand website URL |
| `active` | `boolean` | No | Visible on storefront (default: `true`) |

```bash
# Single brand
curl -X POST \
  -H "Authorization: Bearer your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"name": "Acme", "website": "https://acme.example.com"}' \
  https://your-store.yns.store/api/v1/brands

# Many brands
curl -X POST \
  -H "Authorization: Bearer your_api_key" \
  -H "Content-Type: application/json" \
  -d '[{"name": "Acme"}, {"name": "Globex"}]' \
  https://your-store.yns.store/api/v1/brands
```

### Response (201, single)

```json
{
  "brand": {
    "id": "0191abc0-1234-7def-8000-000000000001",
    "name": "Acme",
    "slug": "acme",
    "description": null,
    "longDescription": null,
    "image": null,
    "website": "https://acme.example.com",
    "active": true,
    "seo": {},
    "createdAt": "2024-06-15T10:30:00.000Z",
    "updatedAt": "2024-06-15T10:30:00.000Z"
  }
}
```

### Response (200, batch)

```json
{
  "ok": true,
  "created": [
    {
      "id": "0191abc0-1234-7def-8000-000000000002",
      "name": "Acme",
      "slug": "acme"
    }
  ],
  "errors": [
    {
      "index": 1,
      "name": "Globex",
      "error": "Slug \"globex\" already exists"
    }
  ]
}
```

A single-mode create returns `409` when a brand with the same slug already exists.

---

## Get Brand

```
GET /api/v1/brands/{idOrSlug}
```

Returns a single brand by UUID or slug, including its translations and the count of products currently assigned to it.

```bash
curl \
  -H "Authorization: Bearer your_api_key" \
  https://your-store.yns.store/api/v1/brands/acme
```

### Response

```json
{
  "id": "0191abc0-1234-7def-8000-000000000001",
  "name": "Acme",
  "slug": "acme",
  "description": null,
  "longDescription": null,
  "image": "https://cdn.example.com/brands/acme.png",
  "website": "https://acme.example.com",
  "active": true,
  "seo": {},
  "createdAt": "2024-05-01T09:00:00.000Z",
  "updatedAt": "2024-05-01T09:00:00.000Z",
  "tr": [],
  "productCount": 12
}
```

A `404` is returned when no brand matches the identifier.

---

## Update Brand

```
PATCH /api/v1/brands/{idOrSlug}
```

Partially updates a brand by UUID or slug. Unknown fields are rejected. Pass `image: null` or `website: null` to clear those fields.

### Request Body

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `name` | `string` | No | Brand display name |
| `slug` | `string` | No | URL slug (lowercase letters, numbers, and hyphens only) |
| `image` | `string \| null` | No | Image URL, or `null` to clear |
| `website` | `string \| null` | No | Website URL, or `null` to clear |
| `active` | `boolean` | No | Visible on storefront |

```bash
curl -X PATCH \
  -H "Authorization: Bearer your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"active": false}' \
  https://your-store.yns.store/api/v1/brands/acme
```

### Response

```json
{
  "id": "0191abc0-1234-7def-8000-000000000001",
  "name": "Acme",
  "slug": "acme",
  "image": "https://cdn.example.com/brands/acme.png",
  "website": "https://acme.example.com",
  "active": false,
  "seo": {},
  "createdAt": "2024-05-01T09:00:00.000Z",
  "updatedAt": "2024-06-15T11:00:00.000Z"
}
```

---

## Delete Brand

```
DELETE /api/v1/brands/{idOrSlug}
```

Hard-deletes the brand. Products previously assigned to this brand have their `brandId` set to `null`.

```bash
curl -X DELETE \
  -H "Authorization: Bearer your_api_key" \
  https://your-store.yns.store/api/v1/brands/acme
```

### Response

```json
{
  "ok": true,
  "deleted": 1
}
```

---

## Assign Brand to Products

```
POST /api/v1/brands/{idOrSlug}/products
```

Sets `brandId` on every product whose UUID appears in `productIds` and belongs to the store. Up to 1000 product IDs per request. Idempotent – re-running is safe. The response reports how many were assigned plus any IDs that did not match (wrong store or non-existent). To clear a brand from a single product, use `PATCH /api/v1/products/{id}` with `{ "brandId": null }`.

### Request Body

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `productIds` | `string[]` | Yes | Product UUIDs to assign this brand to (1-1000) |

```bash
curl -X POST \
  -H "Authorization: Bearer your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"productIds": ["0191abc0-0000-7000-8000-000000000100", "0191abc0-0000-7000-8000-000000000101"]}' \
  https://your-store.yns.store/api/v1/brands/acme/products
```

### Response

```json
{
  "ok": true,
  "brandId": "0191abc0-1234-7def-8000-000000000001",
  "assigned": 1,
  "notFound": ["0191abc0-0000-7000-8000-000000000101"]
}
```