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

# Cigar composition

> Use normalized wrapper, binder, and filler tobacco components from REST, GraphQL, and the TypeScript SDK.

Boxpressd normalizes cigar composition into structured tobacco components. The `wrapper`, `binder`, and `filler` fields are arrays. They are never nullable strings.

```typescript theme={null}
type TobaccoComponent = {
  region: string | null
  type: string | null
  shade: WrapperShade | null
  year: number | null
  label: string
}
```

## Cigar fields

| Field | REST type | GraphQL type | Description |
| - | - | - | - |
| `origin` | `string` | `String!` | Canonical country string for the cigar's overall origin. |
| `wrapper` | `TobaccoComponent[]` | `[TobaccoComponent!]!` | Normalized wrapper components. |
| `binder` | `TobaccoComponent[]` | `[TobaccoComponent!]!` | Normalized binder components. |
| `filler` | `TobaccoComponent[]` | `[TobaccoComponent!]!` | Normalized filler components. |

`origin` remains a single canonical country string. It is separate from the `region` on each composition component.

## Tobacco component fields

| Field | Type | Description |
| - | - | - |
| `region` | `string \| null` | Canonical country or region when known and applicable. |
| `type` | `string \| null` | Normalized tobacco seed, varietal, or named type when known. |
| `shade` | `WrapperShade \| null` | Controlled wrapper shade when known and applicable. |
| `year` | `number \| null` | Four-digit tobacco year when the source identifies a separate year. |
| `label` | `string` | Preferred display value for the component. |

Nullable fields represent structured details that are unknown or inapplicable. A null does not make the component itself missing. When source data does not contain a wrapper, binder, or filler value, the corresponding array is `[]`.

Use `label` in your UI. When an array contains multiple components, join their labels with `", "`:

```typescript theme={null}
const fillerLabel = cigar.filler.map(({ label }) => label).join(", ")
```

<Warning>
  Normalization happens server-side. Do not infer or normalize geography, shades, or years from `label` or any other field. Use the structured values exactly as returned.
</Warning>

## Controlled wrapper shades

| REST display value | GraphQL enum |
| - | - |
| `Candela` | `CANDELA` |
| `Claro` | `CLARO` |
| `Colorado Claro` | `COLORADO_CLARO` |
| `Colorado` | `COLORADO` |
| `Colorado Maduro` | `COLORADO_MADURO` |
| `Maduro` | `MADURO` |
| `Oscuro` | `OSCURO` |

REST serializes display values such as `"Maduro"`. GraphQL serializes enum values such as `MADURO` and `COLORADO_CLARO`.

## Canonical REST examples

```json theme={null}
{
  "origin": "Nicaragua",
  "wrapper": [
    { "region": "Ecuador", "type": "Habano", "shade": null, "year": null, "label": "Ecuadorian Habano" },
    { "region": "United States", "type": "Broadleaf", "shade": "Maduro", "year": null, "label": "Connecticut Broadleaf" }
  ],
  "binder": [
    { "region": "Mexico", "type": "San Andres", "shade": null, "year": null, "label": "Mexican San Andres" }
  ],
  "filler": [
    { "region": null, "type": "Criollo", "shade": null, "year": 1998, "label": "Criollo '98" },
    { "region": null, "type": "Habano 2000", "shade": null, "year": null, "label": "Habano 2000" }
  ]
}
```

The source value `San Andreas` normalizes to `type: "San Andres"` and `label: "Mexican San Andres"`. A comma-separated source becomes one component per value:

```json theme={null}
{
  "filler": [
    { "region": "Nicaragua", "type": "Habano", "shade": null, "year": null, "label": "Nicaraguan Habano" },
    { "region": "Honduras", "type": "Corojo", "shade": null, "year": null, "label": "Honduran Corojo" }
  ]
}
```

Missing composition uses empty arrays:

```json theme={null}
{
  "wrapper": [],
  "binder": [],
  "filler": []
}
```

## TypeScript SDK

Install or update the current API client so your application uses the normalized generated types:

```bash theme={null}
npm install @boxpressd/api-client@latest
```

```typescript theme={null}
import type {
  Cigar,
  TobaccoComponent,
  WrapperShade,
} from "@boxpressd/api-client"

function compositionLabel(components: TobaccoComponent[]): string {
  return components.map(({ label }) => label).join(", ")
}

function wrapperShades(cigar: Cigar): WrapperShade[] {
  return cigar.wrapper.flatMap(({ shade }) => shade === null ? [] : [shade])
}

function wrapperLabel(cigar: Cigar): string {
  return compositionLabel(cigar.wrapper)
}
```

Do not copy local versions of these types. Update `@boxpressd/api-client` and import its latest generated exports. See the [JavaScript client guide](/developer-api/javascript-client) for ESM and CommonJS setup.
