# Update a template

`PATCH /v1/templates/{id}`

Requires an API key with the `templates:write` scope. [About keys and scopes](/docs/api/authentication)

Edits the template's draft. Campaigns and journeys that already copied it keep the content they were built with, and API sends keep the published version until `POST /templates/{id}/publish`. The envelope (`subject`, `previewText`, `from`, `replyTo`) is part of the draft and is published with it; `null` clears a field.

## Path parameters

- `id` (string, required, uuid)

## Request body

- `name` (string, optional, 1–255 characters)
- `schemaVersion` (integer, optional, min > 0, max 1000) — The block format version.
- `blocks` (EmailBlockInput[], optional, at least 1 item, at most 200 items) — At most 200 blocks across the entire tree and five levels including the root. Footer blocks must remain at root. Known child fields are validated recursively.
  - `id` (string, required, 1–128 characters) — Identifies the block within the template; unique among its blocks.
  - `type` (string, required, 1–64 characters) — The block type: `header`, `heading`, `text`, `image`, `button`, `divider`, `spacer`, `columns`, `columns3`, `imagetext`, `imagegroup`, `boxed`, `quote`, `list`, `product`, `video`, `social`, `menu`, `html`, `section`, `footer`, `repeat`, `shared`. Each type reads its own fields next to `type`; an unknown type is kept but not validated.
  - `style` (EmailBlockStyleInput, optional) — Visual overrides for this block, such as colours, font and spacing.
    - `backgroundColor` (string, optional) — Fill behind the block.
    - `fontFamily` (string, optional, one of `Arial`, `Verdana`, `Georgia`, `Tahoma`, `Times New Roman`, `Courier New`, `Inter`, `Roboto`, `Open Sans`, `Lato`, `Montserrat`, `Poppins`, `DM Sans`, `Nunito`, `Work Sans`, `Oswald`, `Playfair Display`, `Merriweather`, `Lora`, `Libre Baskerville`, `EB Garamond`) — A font every client has (Arial, Verdana, Georgia, Tahoma, Times New Roman, Courier New), or a web font, which shows where the client loads it and falls back to a safe font elsewhere.
    - `fontSize` (integer, optional, min 12, max 72) — Text size in px, 12 to 72.
    - `mobileFontSize` (integer, optional, min 12, max 72) — Text size in px on phones (screens up to 620px), 12 to 72.
    - `padding` (object, optional) — Space inside the block in px, 0 to 100 per side; omitted sides keep their default.
      - `top` (integer, optional, min 0, max 100)
      - `right` (integer, optional, min 0, max 100)
      - `bottom` (integer, optional, min 0, max 100)
      - `left` (integer, optional, min 0, max 100)
    - `borderWidth` (integer, optional, min 0, max 10) — Border thickness in px; 0 for none.
    - `borderStyle` (string, optional, one of `solid`, `dashed`, `dotted`) — Border line style.
    - `borderColor` (string, optional) — Border colour.
    - `borderRadius` (integer, optional, min 0, max 100) — Corner rounding in px, 0 to 100.
    - `textColor` (string, optional) — Text colour.
    - `linkColor` (string, optional) — Colour of links in the text.
    - `letterSpacing` (number, optional, min -2, max 20) — Space between letters in px, such as 3 for a spaced-out eyebrow line.
    - `textTransform` (string, optional, one of `none`, `uppercase`) — Set to `uppercase` to capitalise all text.
    - `lineHeight` (number, optional, min 1, max 3) — A multiple of the font size.
    - `fontWeight` (string, optional, one of `regular`, `bold`) — Text weight.
    - `fontStyle` (string, optional, one of `normal`, `italic`) — Text style.
    - `inset` (boolean, optional) — Draw the background and border as a box within the content width, not across the whole row.
  - `visibleIf` (object, optional) — Show the block only to contacts these segment rules match, checked as each message is rendered. Omit to show it to everyone. Not allowed on the footer.
    - One of: **Match all**
      - `all` (object[], required, at least 1 item, at most 20 items) — Every rule or nested group must match.
    - One of: **Match any**
      - `any` (object[], required, at least 1 item, at most 20 items) — At least one rule or nested group must match.
  - `showOn` (string, optional, one of `mobile`, `desktop`) — Show the block only on phones (screens up to 620px) or only on wider screens. Clients that ignore screen size show the desktop version, and so does plain text. Omit to show it everywhere. Not allowed on the footer.
  - `columns` (object[][], optional, at most 3 items) — Nested child block arrays: exactly two for columns, three for columns3. Each child follows this block contract. Omit to retain legacy text columns.
  - `blocks` (object[], optional, at most 200 items) — A section's child blocks, drawn inside its box; or a repeat block's, written out once per item of its `list`, where `{{ item.<field> }}` reads that item. Repeats do not nest.
- `theme` (EmailThemeInput, optional) — Theme values this email overrides.
  - `font` (string, optional, up to 200 characters) — Body font stack, such as `Inter, sans-serif`.
  - `hfont` (string, optional, up to 200 characters) — Heading font stack.
  - `bg` (string, optional) — Background of the email card, as hex.
  - `canvas` (string, optional) — Background behind the card, as hex.
  - `text` (string, optional) — Default text colour, as hex.
  - `accent` (string, optional) — Brand colour for buttons and highlights, as hex.
  - `link` (string, optional) — Link colour, as hex.
  - `width` (string, optional, one of `560px`, `600px`, `680px`) — Width of the email card on wide screens.
  - `radius` (string, optional, one of `0px`, `6px`, `12px`, `16px`, `24px`, `999px`) — Corner rounding of the email's card.
  - `btnRadius` (string, optional, one of `0px`, `6px`, `12px`, `16px`, `24px`, `999px`) — Button corners; `radius` rounds the email's card and, when this is unset, buttons.
  - `btn` (string, optional, one of `solid`, `outline`) — Button style.
- `plainTextOverride` (string | null, optional, up to 100000 characters) — Plain text sent instead of the version generated from the blocks; `null` clears it.
- `subject` (string | null, optional, 1–998 characters) — Used by an API send that names this template, unless the send gives its own. Merge tags may read `event.properties.*`.
- `previewText` (string | null, optional, 1–255 characters) — Used by an API send that names this template, unless the send gives its own. Merge tags may read `event.properties.*`.
- `from` (string | null, optional, 1–320 characters) — Used by an API send that names this template, unless the send gives its own. One address, optionally with a display name; its domain must be verified when a send uses it.
- `replyTo` (string | null, optional, email, up to 320 characters) — Used by an API send that names this template, unless the send gives its own.
- `alias` (string | null, optional, up to 64 characters) — Unique in the workspace; an API send may name the template by it in `templateId`. Null clears it.
- `expectedRevision` (integer, optional, min > 0, max 2147483647) — The `revision` you read. When it is no longer current the update is refused with 409 `REVISION_CONFLICT`, whose details carry the current revision, `updatedAt` and who made the change. Omit it to overwrite whatever is there.

## Returns

Returns `200 OK` with a `Template` in `data`. Otherwise returns an error; [Errors](/docs/api/errors) lists every code and which to retry.

- `id` (string, required, uuid)
- `name` (string, required)
- `schemaVersion` (integer, required, min > 0, max 1000) — The block format version.
- `blocks` (EmailBlock[], required, at least 1 item, at most 200 items) — At most 200 blocks across the entire tree and five levels including the root. Footer blocks must remain at root. Known child fields are validated recursively.
  - `id` (string, required, 1–128 characters) — Identifies the block within the template; unique among its blocks.
  - `type` (string, required, 1–64 characters) — The block type: `header`, `heading`, `text`, `image`, `button`, `divider`, `spacer`, `columns`, `columns3`, `imagetext`, `imagegroup`, `boxed`, `quote`, `list`, `product`, `video`, `social`, `menu`, `html`, `section`, `footer`, `repeat`, `shared`. Each type reads its own fields next to `type`; an unknown type is kept but not validated.
  - `style` (EmailBlockStyle, optional) — Visual overrides for this block, such as colours, font and spacing.
    - `backgroundColor` (string, optional) — Fill behind the block.
    - `fontFamily` (string, optional, one of `Arial`, `Verdana`, `Georgia`, `Tahoma`, `Times New Roman`, `Courier New`, `Inter`, `Roboto`, `Open Sans`, `Lato`, `Montserrat`, `Poppins`, `DM Sans`, `Nunito`, `Work Sans`, `Oswald`, `Playfair Display`, `Merriweather`, `Lora`, `Libre Baskerville`, `EB Garamond`) — A font every client has (Arial, Verdana, Georgia, Tahoma, Times New Roman, Courier New), or a web font, which shows where the client loads it and falls back to a safe font elsewhere.
    - `fontSize` (integer, optional, min 12, max 72) — Text size in px, 12 to 72.
    - `mobileFontSize` (integer, optional, min 12, max 72) — Text size in px on phones (screens up to 620px), 12 to 72.
    - `padding` (object, optional) — Space inside the block in px, 0 to 100 per side; omitted sides keep their default.
      - `top` (integer, optional, min 0, max 100)
      - `right` (integer, optional, min 0, max 100)
      - `bottom` (integer, optional, min 0, max 100)
      - `left` (integer, optional, min 0, max 100)
    - `borderWidth` (integer, optional, min 0, max 10) — Border thickness in px; 0 for none.
    - `borderStyle` (string, optional, one of `solid`, `dashed`, `dotted`) — Border line style.
    - `borderColor` (string, optional) — Border colour.
    - `borderRadius` (integer, optional, min 0, max 100) — Corner rounding in px, 0 to 100.
    - `textColor` (string, optional) — Text colour.
    - `linkColor` (string, optional) — Colour of links in the text.
    - `letterSpacing` (number, optional, min -2, max 20) — Space between letters in px, such as 3 for a spaced-out eyebrow line.
    - `textTransform` (string, optional, one of `none`, `uppercase`) — Set to `uppercase` to capitalise all text.
    - `lineHeight` (number, optional, min 1, max 3) — A multiple of the font size.
    - `fontWeight` (string, optional, one of `regular`, `bold`) — Text weight.
    - `fontStyle` (string, optional, one of `normal`, `italic`) — Text style.
    - `inset` (boolean, optional) — Draw the background and border as a box within the content width, not across the whole row.
  - `visibleIf` (object, optional) — Show the block only to contacts these segment rules match, checked as each message is rendered. Omit to show it to everyone. Not allowed on the footer.
    - One of: **Match all**
      - `all` (object[], required, at least 1 item, at most 20 items) — Every rule or nested group must match.
    - One of: **Match any**
      - `any` (object[], required, at least 1 item, at most 20 items) — At least one rule or nested group must match.
  - `showOn` (string, optional, one of `mobile`, `desktop`) — Show the block only on phones (screens up to 620px) or only on wider screens. Clients that ignore screen size show the desktop version, and so does plain text. Omit to show it everywhere. Not allowed on the footer.
  - `columns` (object[][], optional, at most 3 items) — Nested child block arrays: exactly two for columns, three for columns3. Each child follows this block contract. Omit to retain legacy text columns.
  - `blocks` (object[], optional, at most 200 items) — A section's child blocks, drawn inside its box; or a repeat block's, written out once per item of its `list`, where `{{ item.<field> }}` reads that item. Repeats do not nest.
- `theme` (EmailTheme, required) — Theme values this email overrides.
  - `font` (string, optional, up to 200 characters) — Body font stack, such as `Inter, sans-serif`.
  - `hfont` (string, optional, up to 200 characters) — Heading font stack.
  - `bg` (string, optional) — Background of the email card, as hex.
  - `canvas` (string, optional) — Background behind the card, as hex.
  - `text` (string, optional) — Default text colour, as hex.
  - `accent` (string, optional) — Brand colour for buttons and highlights, as hex.
  - `link` (string, optional) — Link colour, as hex.
  - `width` (string, optional, one of `560px`, `600px`, `680px`) — Width of the email card on wide screens.
  - `radius` (string, optional, one of `0px`, `6px`, `12px`, `16px`, `24px`, `999px`) — Corner rounding of the email's card.
  - `btnRadius` (string, optional, one of `0px`, `6px`, `12px`, `16px`, `24px`, `999px`) — Button corners; `radius` rounds the email's card and, when this is unset, buttons.
  - `btn` (string, optional, one of `solid`, `outline`) — Button style.
- `plainTextOverride` (string | null, required) — Plain text sent instead of the version generated from the blocks.
- `subject` (string | null, required) — What an API send by `templateId` uses by default.
- `previewText` (string | null, required) — What an API send by `templateId` uses by default.
- `from` (string | null, required) — What an API send by `templateId` uses by default.
- `replyTo` (string | null, required, email) — What an API send by `templateId` uses by default.
- `alias` (string | null, required) — The name an API send may use in `templateId`.
- `publishedVersion` (integer | null, required, min > 0, max 9007199254740991) — The version API sends use; null until published. The template itself is the draft.
- `hasUnpublishedChanges` (boolean, required) — The draft differs from the published version, or was never published.
- `revision` (integer, required, min > 0, max 2147483647) — Raised by every edit. Send it back as `expectedRevision` on the update so a change made since you read it is refused instead of overwritten.
- `thumbnailUrl` (string | null, required, uri) — A small picture of the design (WebP, 320 × 427), redrawn a few seconds after each save; null until the first is drawn.
- `thumbnailUpdatedAt` (string | null, required, date-time) — When the thumbnail was last drawn.
- `createdAt` (string, required, date-time)
- `updatedAt` (string, required, date-time)

## Example

```bash
curl -X PATCH https://api.kirora.io/v1/templates/018f2a4e-6b1c-7d3e-9f40-37386ae05a6b \
  -H "Authorization: Bearer $KIRORA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Weekend specials",
    "schemaVersion": 1,
    "blocks": [
      {
        "id": "id_example",
        "type": "type_example"
      }
    ],
    "theme": {},
    "plainTextOverride": "plainTextOverride_example",
    "subject": "Your order is on its way",
    "previewText": "Arriving Thursday",
    "from": "Juniper Kitchen <hello@juniperkitchen.com>",
    "replyTo": "amaka@juniperkitchen.com",
    "alias": "alias_example",
    "expectedRevision": 1
  }'
```

Response `200`:

```json
{
  "data": {
    "id": "018f2a4e-6b1c-7d3e-9f40-37386ae05a6b",
    "name": "Weekend specials",
    "schemaVersion": 1,
    "blocks": [
      {
        "id": "id_example",
        "type": "type_example"
      }
    ],
    "theme": {},
    "plainTextOverride": "plainTextOverride_example",
    "subject": "Your order is on its way",
    "previewText": "Arriving Thursday",
    "from": "Juniper Kitchen <hello@juniperkitchen.com>",
    "replyTo": "amaka@juniperkitchen.com",
    "alias": "alias_example",
    "publishedVersion": 1,
    "hasUnpublishedChanges": true,
    "revision": 1,
    "thumbnailUrl": "https://example.com",
    "thumbnailUpdatedAt": "2030-03-14T09:30:00Z",
    "createdAt": "2030-03-14T09:30:00Z",
    "updatedAt": "2030-03-14T09:30:00Z"
  }
}
```
