Every store sends transactional emails – order confirmations, shipping updates, welcome coupons. Each email event always exists: a store that has never edited one still sends the built-in default. This API lets you read the effective template for every event and override any of them.

Deleting a customization reverts to the built-in default rather than removing the email entirely.

**Scopes:** `settings:read` for GET, `settings:write` for PATCH/DELETE.

## Available Events

| Event | Description |
|-------|-------------|
| `purchase_confirmation` | Sent when an order is paid |
| `order_shipped` | Sent when a shipment is created |
| `order_delivered` | Sent when an order is marked delivered |
| `order_refunded` | Sent when an order is refunded |
| `order_withdrawal` | Sent on a consumer withdrawal request |
| `ticket_confirmation` | Sent when an event ticket is purchased |
| `cart_abandonment_reminder` | Sent to recover an abandoned cart |
| `restock_notification` | Sent when a back-in-stock item is available |
| `newsletter_welcome` | Sent to new newsletter subscribers |
| `newsletter_confirmation` | Sent for double opt-in confirmation |
| `welcome_coupon_expiry_reminder` | Sent before a welcome coupon expires |

---

## List Email Templates

```
GET /api/v1/email-templates
```

Returns every event with its effective template – the store's custom version when one exists, otherwise the built-in default.

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

### Response

```json
{
  "data": [
    {
      "event": "purchase_confirmation",
      "name": "Purchase Confirmation",
      "description": "Sent when an order is paid",
      "customized": true,
      "enabled": true,
      "sendingDisabled": false,
      "subject": "Your order {{orderLookup}} is confirmed!",
      "content": "Hi {{customerName}}, thank you for your order.",
      "format": "text",
      "htmlTemplateKey": null,
      "variables": ["customerName", "orderLookup", "orderTotal"],
      "blockVariables": ["orderLineItems"],
      "updatedAt": "2025-08-01T12:00:00.000Z"
    }
  ],
  "meta": { "count": 11 }
}
```

### Response Fields

| Field | Type | Description |
|-------|------|-------------|
| `event` | `string` | Event identifier |
| `name` | `string` | Human-readable name |
| `description` | `string` | What triggers this email |
| `customized` | `boolean` | Whether the store has overridden the built-in default |
| `enabled` | `boolean` | Whether the store's custom wording is used — `false` falls back to the built-in default copy and the email still sends. Not a send switch. |
| `sendingDisabled` | `boolean` | The actual off switch: `true` means this email is suppressed and will not reach customers |
| `subject` | `string` | Subject line (may contain `{{tokens}}`) |
| `content` | `string` | Body copy |
| `format` | `string` | `"text"` (injected into the branded email shell) or `"html"` (the entire email) |
| `htmlTemplateKey` | `string \| null` | Predefined HTML design key, or `null` for custom/text |
| `variables` | `string[]` | Tokens the copy may interpolate |
| `blockVariables` | `string[]` | HTML-only tokens that expand to pre-rendered fragments |
| `updatedAt` | `string \| null` | Last customization time, or `null` if using the default |

---

## Get Email Template

```
GET /api/v1/email-templates/:event
```

Returns one event's effective template. The `:event` parameter must be one of the [available events](#available-events).

```bash
curl -H "Authorization: Bearer your_api_key" \
  https://your-store.yns.store/api/v1/email-templates/purchase_confirmation
```

Returns the same shape as a single item from the list response.

---

## Update Email Template

```
PATCH /api/v1/email-templates/:event
```

Overrides the template for one event. Send only the fields you want to change; omitted fields keep their current value (or the built-in default if the store has never customized this event).

`enabled` is **not** a send switch — `false` only reverts the send to the built-in copy. To stop the email entirely set `sendingDisabled: true` (`false` resumes). That switch lives in store settings, and the same set is exposed as `notifications.disabledEmailEvents` on `PATCH /api/v1/settings`.

### Request Body

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `subject` | `string` | No | Subject line; may use `{{tokens}}` (1–300 chars) |
| `content` | `string` | No | Body copy (1–100,000 chars) |
| `enabled` | `boolean` | No | Use the store's custom wording. `false` reverts the send to the built-in default copy — the email still goes out. Not a send switch. |
| `sendingDisabled` | `boolean` | No | Stop sending this email to customers entirely; `false` resumes it. Stored in store settings, so a `sendingDisabled`-only PATCH does not mark the template customized. |
| `format` | `string` | No | `"text"` or `"html"` |
| `htmlTemplateKey` | `string \| null` | No | Predefined HTML design key; only valid when `format` is `"html"`. Pass `null` for custom HTML in `content`. |

```bash
curl -X PATCH \
  -H "Authorization: Bearer your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"subject": "Thanks for your order, {{customerName}}!"}' \
  https://your-store.yns.store/api/v1/email-templates/purchase_confirmation
```

### Response (200)

Returns the updated effective template.

### Errors

| Status | Condition |
|--------|-----------|
| `400` | `htmlTemplateKey` set with `format: "text"` |
| `400` | `sendingDisabled: true` on `newsletter_confirmation` — double opt-in signups could never be confirmed without it |
| `404` | Unknown event name |

---

## Delete Email Template Customization

```
DELETE /api/v1/email-templates/:event
```

Reverts to the built-in default for this event. The email keeps sending – only the store's custom copy is removed. Returns `404` if the store has not customized this event (it is already using the default).

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

### Response (200)

Returns the effective template after reverting (the built-in default).