# POST Create a letter type

Adds a letter type to the customiser, at the end of the current presentation order. `name` is required, and the letter type must be renderable: it needs at least one active entry in `letter_parts` (422 `letter_part_required`), a lightbox letter type needs a `shape` (422 `shape_required`), and every other category refuses one (422 `shape_not_supported`). Every other field has a documented default (`base_price` 0, `price_multiplier` 1, `price_multiplier_target` base_letter_price). Image fields are read-only until the upload surface ships, and `sort_order` moves only through the reorder operation — naming either is a 422. A cut-out metal or stencil customiser refuses the operation with a 422 `letter_types_not_supported`. Requires `customisers:write` and an `Idempotency-Key`. A lightbox letter type's `letter_parts` are normalised on the way in: the parts its shape cannot draw are dropped, the face and border are forced active, and the rest are ordered as the shape draws them. Read the response rather than assuming the list came back verbatim. Creating a letter type does not create the colour selections for its parts. Add each one through the letter-part routes, which is also where a part's colours are managed. The write clears the customiser's cached storefront configuration and runs the advisory language sync. It never regenerates Shopify products, product images, or the product cache, so live listings are untouched. Option writes also spend one unit of a separate per-key option-write budget; exhausting it returns a 429 with `retry_after`.

- Source URL: https://www.signcustomiser.com/help/api/v3-post-create-a-letter-type/
- Markdown URL: https://www.signcustomiser.com/help/api/v3-post-create-a-letter-type.md
- Group: Customiser letter types
- Method: POST
- Path: /api/v3/customisers/{customiser_id}/letter-types
- Auth: Bearer token
- Required scopes: `customisers:write`

## Path parameters

- customiser_id (string, required): The customiser id. Example: 1

## Body parameters

- shape (string, optional): No description provided.
- letter_parts (array, optional): No description provided.
- price_multiplier_target (string, optional): No description provided.
- name (string, optional): No description provided.
- description (string, optional): No description provided.
- base_price (integer, optional): No description provided.
- price_multiplier (number, optional): No description provided.

## Request body example

```json
{
  "shape": "rectangle",
  "letter_parts": [
    {
      "letter_part": "face",
      "active": true
    }
  ],
  "price_multiplier_target": "base_letter_price",
  "name": "Front lit",
  "description": "Light through the face",
  "base_price": 500,
  "price_multiplier": 1.2
}
```

## cURL example

```bash
curl https://web.signcustomiser.com/api/v3/customisers/1/letter-types \
  --request POST \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer YOUR_API_TOKEN' \
  --header 'Content-Type: application/json' \
  --data '{
  "shape": "rectangle",
  "letter_parts": [
    {
      "letter_part": "face",
      "active": true
    }
  ],
  "price_multiplier_target": "base_letter_price",
  "name": "Front lit",
  "description": "Light through the face",
  "base_price": 500,
  "price_multiplier": 1.2
}'
```

## Response examples

### 201 POST 201 example 1

```json
{
  "data": {
    "object": "letter_type",
    "id": 7,
    "customiser_id": 42,
    "name": "Front lit",
    "description": null,
    "shape": null,
    "letter_parts": [
      {
        "letter_part": "face",
        "active": true
      }
    ],
    "base_price": 0,
    "currency": "USD",
    "price_multiplier": 1,
    "price_multiplier_target": "base_letter_price",
    "sort_order": 1,
    "image_url": null,
    "created_at": "2026-08-13T00:00:00Z",
    "updated_at": "2026-08-13T00:00:00Z"
  },
  "links": {
    "self": "https://web.signcustomiser.com/api/v3/customisers/42/letter-types/7",
    "documentation": "https://www.signcustomiser.com/help/api/"
  },
  "meta": {
    "api_version": "v3",
    "request_id": "req_01jz9x2k7c8f3m5n6p7q8r9s0t"
  }
}
```

### 400 Missing idempotency key

```json
{
  "type": "https://www.signcustomiser.com/help/api/problems/missing_idempotency_key",
  "title": "Missing idempotency key",
  "status": 400,
  "code": "missing_idempotency_key",
  "detail": "Provide an Idempotency-Key header for this write.",
  "request_id": "req_01jz9x2k7c8f3m5n6p7q8r9s0t"
}
```

### 401 Missing API key

```json
{
  "type": "https://www.signcustomiser.com/help/api/problems/missing_api_key",
  "title": "Missing API key",
  "status": 401,
  "code": "missing_api_key",
  "detail": "Provide a store API key as a bearer token.",
  "request_id": "req_01jz9x2k7c8f3m5n6p7q8r9s0t"
}
```

### 403 Insufficient scope

```json
{
  "type": "https://www.signcustomiser.com/help/api/problems/insufficient_scope",
  "title": "Insufficient scope",
  "status": 403,
  "code": "insufficient_scope",
  "detail": "This operation requires the customisers:write scope.",
  "required_scopes": [
    "customisers:write"
  ],
  "granted_scopes": [
    "customisers:read"
  ],
  "request_id": "req_01jz9x2k7c8f3m5n6p7q8r9s0t"
}
```

### 404 Unknown customiser

```json
{
  "type": "https://www.signcustomiser.com/help/api/problems/resource_not_found",
  "title": "Resource not found",
  "status": 404,
  "code": "resource_not_found",
  "detail": "The requested resource does not exist or does not belong to the authenticated store.",
  "request_id": "req_01jz9x2k7c8f3m5n6p7q8r9s0t"
}
```

### 409 Idempotency conflict

```json
{
  "type": "https://www.signcustomiser.com/help/api/problems/idempotency_key_conflict",
  "title": "Idempotency key conflict",
  "status": 409,
  "code": "idempotency_key_conflict",
  "detail": "This Idempotency-Key was already used for a different request body on this operation.",
  "request_id": "req_01jz9x2k7c8f3m5n6p7q8r9s0t"
}
```

### 413 Request body too large

```json
{
  "type": "https://www.signcustomiser.com/help/api/problems/request_too_large",
  "title": "Request too large",
  "status": 413,
  "code": "request_too_large",
  "detail": "The request body must not exceed 2 MiB.",
  "request_id": "req_01jz9x2k7c8f3m5n6p7q8r9s0t"
}
```

### 422 Letter types not supported

```json
{
  "type": "https://www.signcustomiser.com/help/api/problems/letter_types_not_supported",
  "title": "Letter types not supported",
  "status": 422,
  "code": "letter_types_not_supported",
  "detail": "This customiser cuts its sign from a single sheet, so it offers no letter types and none can be created.",
  "errors": [
    {
      "pointer": "",
      "code": "letter_types_not_supported",
      "detail": "This customiser category does not offer letter types."
    }
  ],
  "request_id": "req_01jz9x2k7c8f3m5n6p7q8r9s0t"
}
```

### 429 Option write budget exhausted

```json
{
  "type": "https://www.signcustomiser.com/help/api/problems/rate_limited",
  "title": "Too many requests",
  "status": 429,
  "code": "rate_limited",
  "detail": "You have exceeded the request limit for this API key.",
  "retry_after": 37,
  "request_id": "req_01jz9x2k7c8f3m5n6p7q8r9s0t"
}
```
