
# Email templates

The `keenauth_email_template` resource manages the published content of one customizable email template: one family (for example `verify_email`) in one locale. It needs the Startup plan or higher (`403 plan_feature_unavailable` otherwise).

```terraform
resource "keenauth_email_template" "verify" {
  family    = "verify_email"
  locale    = "en"
  subject   = "Confirm your email"
  html      = "<p>Confirm your email address: <a href=\"{{ link }}\">Confirm</a></p>"
  text_body = "Confirm your email address: {{ link }}"
  from_name = "Acme"
}
```

| Attribute | Description |
|---|---|
| `family`, `locale` | The slot. Changing either manages a different template. |
| `subject` | Liquid, plain text, up to 200 characters, no line breaks. |
| `html` | Liquid HTML fragment, up to 256 KiB. |
| `text_body` | Liquid plain-text body (required), up to 64 KiB. |
| `from_name` | Optional sender display name, up to 64 characters. Unset uses the application or environment name. |
| `overwrite_pending_draft` | Optional, defaults to `false`. See below. |
| `version`, `latest_version` | Read only. The published version, and the slot's newest version. |

The server checks the content on write and again on publish: Liquid sandbox, balanced HTML, forbidden constructs, and the family's required `{{ link }}` or `{{ code }}` in both the HTML and the text body.

## How a change is applied

1. `PUT` writes the content as a new draft version. `If-Match` is the slot's newest version from the last read (`"0"` for a slot without versions).
2. `POST …:publish` publishes that version. The previous version is archived and stays in the history (the newest 50 versions plus the published one are kept).

The resource reads the **published** version. A version published or rolled back in the dashboard shows up as drift in the next `plan`.

## Pending drafts

A draft newer than the published version (saved in the dashboard, or left by a failed publish) is never overwritten silently:

- A draft with the same content as your configuration is published without writing another version. This also retries a failed publish.
- A different draft makes the change fail with `Pending email template draft`. Publish or review it in the dashboard, or set `overwrite_pending_draft = true` to write a newer version over it. The old draft stays in the history but can no longer be published.
- `plan` prints a warning while a pending draft exists.

If someone writes to the template between `plan` and `apply`, the API answers `412` and nothing changes. Run `plan` again.

## Create, import and destroy

- A create adopts a published template with the same content. If the slot already has a published template with other content, the provider does not overwrite it: import it with `tofu import keenauth_email_template.verify verify_email/en` and review the plan.
- Destroy only removes the resource from state. The API has no delete, so the published template and its history stay unchanged. Returning to the system default is not available through the API; to change what is sent, edit the template or run `keenauth email-templates rollback` for an earlier published version.
