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

# Email templates

> Customize the verification and password-recovery email templates and the sender branding — per environment, via the dashboard or the GraphQL API.

Archie Auth sends two transactional emails — a verification email at signup and a password-recovery email when the user requests a reset. Both the content and the sender branding are customizable per environment, in the dashboard or via the GraphQL API.

## The two default emails

| Email                 | Sent when                                   | Subject (default)                 | Code expiry |
| --------------------- | ------------------------------------------- | --------------------------------- | ----------- |
| **Verification**      | User signs up (if email verification is on) | `Verify your email — {AppName}`   | 1 hour      |
| **Password recovery** | User requests password recovery             | `Reset your password — {AppName}` | 1 hour      |

Both emails carry a 6-digit code. The recovery email also includes a "if you didn't request this, ignore" line.

## Customizing templates

Open **App Services → Authentication Providers → Archie Auth → Settings** and scroll to the **Email Templates** section. The editor has:

* **Template selector** — switch between **Verification** and **Recovery**.
* **Subject** — plain-text input.
* **Body** — rich-text editor (TipTap) with inline variable chips.
* **Live preview** — renders the email with branding and sample variable values in real time.

### Template variables

Insert variables as colored chips in the body. Click a variable in the toolbar to drop it at the cursor.

| Variable                   | What it expands to        | Example  |
| -------------------------- | ------------------------- | -------- |
| `{{otp}}`                  | The 6-digit code.         | `123456` |
| `{{otpExpirationMinutes}}` | Code validity in minutes. | `60`     |

### Reset to default

The **Reset to Default** button discards your custom template and falls back to the platform default. Reset is per-template — resetting Verification doesn't touch Recovery.

<Note>
  Templates are **per-environment**. Editing the template in `staging` doesn't affect `master`. Branching an environment doesn't copy templates — start from default in the new environment, or copy the body manually.
</Note>

## Customizing via the GraphQL API

For codified configuration, set templates with `configureProjectAuth`:

```graphql theme={null}
mutation {
  configureProjectAuth(input: {
    emailTemplates: {
      verification: {
        subject: "Welcome! Verify your email"
        body: "Hi! Your verification code is {{otp}}. It expires in {{otpExpirationMinutes}} minutes."
      }
      recovery: {
        subject: "Password Reset Request"
        body: "Your password reset code is {{otp}}. Valid for {{otpExpirationMinutes}} minutes. If you didn't request this, ignore this email."
      }
    }
  }) {
    success
  }
}
```

See the full [GraphQL API reference](/features/backend/app-services/authentication-providers/archie-auth/graphql-api#configureprojectauth) for every field on the `configureProjectAuth` input.

## Branding

Customize the visual identity of the emails — logo, company name, sender name, footer link.

### Branding fields

| Field               | What it controls                    | Default          |
| ------------------- | ----------------------------------- | ---------------- |
| **Logo URL**        | Image shown in the email header.    | Archie logo      |
| **Company Name**    | Footer company name.                | Archie           |
| **Company Website** | Footer link target.                 | archie.com       |
| **Sender Name**     | The "From" name on outgoing emails. | Platform default |

Set these in the **Email Branding** section of Settings, or programmatically:

```graphql theme={null}
mutation {
  configureProjectAuth(input: {
    emailBranding: {
      logoUrl: "https://example.com/logo.png"
      companyName: "Acme Corp"
      companyWebsite: "https://acme.com"
      senderName: "Acme Auth"
    }
  }) {
    success
  }
}
```

### Branding behavior

* Custom branding overrides Archie's defaults in the header, footer, and sender name.
* The overall email layout — structure, responsiveness — stays consistent. Only the branding slots change.
* Empty fields fall back to platform defaults.
* The `senderName` field overrides the SendGrid "From Name" without changing the verified sender email address (which stays platform-managed).
* Branding is **per-environment** — `staging` and `master` can use different logos and company names.

## Email delivery

Two transports back the same MJML templates:

| Transport | Description                                              |
| --------- | -------------------------------------------------------- |
| **SES**   | Amazon SES — production default.                         |
| **SMTP**  | Standard SMTP relay — used for self-hosted and fallback. |

The transport is configured at the platform level and isn't changeable per project. Both transports deliver identical emails.

For projects routing through SendGrid, see the [SendGrid integration](/features/backend/integrations/sendgrid).

### Rate limiting

Email sending is rate-limited to **5 emails per user per hour** to defend against abuse (someone repeatedly triggering recovery emails to flood an inbox).

## FAQ

<AccordionGroup>
  <Accordion title="Why aren't templates copied when I branch an environment?">
    Same reason auth secrets aren't — environment isolation. Branching a `staging` environment from `master` shouldn't silently propagate template wording you might be testing. Copy manually if you want them to match.
  </Accordion>

  <Accordion title="Can I add my own variables to a template?">
    Today the supported variables are `{{otp}}` and `{{otpExpirationMinutes}}`. Anything else in `{{...}}` is rendered as literal text. To inject more context, do it server-side via the auth events and send your own email through a custom function.
  </Accordion>

  <Accordion title="The user reports they didn't receive the email — what do I check?">
    First, the spam folder. Then verify the address in the user record (typos at signup are common). If consistently undelivered, check transport-level delivery logs in your email provider (SES or SendGrid) and confirm the sender domain's DKIM / SPF records are valid.
  </Accordion>

  <Accordion title="Can I send a custom email from auth events?">
    Yes — subscribe to events like `auth.user.registered` from a custom function or webhook and send your own email via the integrated provider. The built-in templates handle the OTP delivery; everything else (welcome flow, marketing onboarding) is yours.
  </Accordion>

  <Accordion title="Does the senderName appear in the From: header?">
    Yes — it overrides the display name. The sender email address stays the platform-verified address, which is what the receiving mail server validates against DKIM / SPF.
  </Accordion>
</AccordionGroup>
