# Configure mail on TurboStack

Outbound mail is a host-level service. You configure two things: **DKIM** signing for your sending
domains, and an optional **development mail-catcher**. Both live under the host's
**Advanced > Mail Settings**. For the background on how mail works, see
[What is mail on TurboStack?](what-is.md).

![Mail Settings on the host's Advanced tab|1000](../../assets/screenshots/platform/hosts/advanced_mail.png)

## Where to configure it

Open the host, go to the **Advanced** tab, and select **Mail Settings**. Changes are written to the
host's YAML and applied on the next deployment.

> [!NOTE]
> There is no on/off switch for the local mail service - it is available on the host for your
> applications to send through. What you configure here is domain signing (DKIM) and the optional
> development mail-catcher. High-volume or marketing mail should go through an external SMTP provider,
> not the local service.

## Set up DKIM

DomainKeys Identified Mail (DKIM) signs your outbound mail so receiving servers can confirm it
genuinely came from your domain. In **Mail Settings**, add one DKIM entry per sending domain:

1. Enter the **FQDN** - the Fully Qualified Domain Name you send mail from (for example
   `example.com`).
2. Enter a **selector** - this becomes the subdomain part of the DKIM DNS record. If you leave it
   empty, TurboStack uses the default selector `cloud`.
3. Save the entry and deploy.
4. Connect over [SSH](../../platform/hosts/ssh.md) and run `tscli dkim records` to get the DKIM TXT
   record to publish.
5. Add that record as a **TXT** record in your domain's Domain Name System (DNS) - in the
   [Customer Center DNS management](../../customer-center/services/dns-management.md) if Hosted Power
   manages your DNS, otherwise at your DNS provider.
6. Back on the server, run `tscli dkim validate` to confirm the record was created correctly.

You can add multiple DKIM entries if you send from more than one domain. For Sender Policy Framework
(SPF) and Domain-based Message Authentication, Reporting and Conformance (DMARC), which are DNS-only
and not set here, see [Mail deliverability](deliverability.md).

## Development mail-catcher

A mail-catcher captures outbound mail so you can inspect it in a web interface instead of delivering
it - useful while building or testing an application. Enable it under **Mail Settings** with the
**Enable mail capturing and mail testing** option, then choose which tool to run:

- **Mailpit** - the recommended catcher.
- **Mailhog** - the older catcher; no longer maintained.

Once enabled, PHP mail is intercepted automatically (via `php.ini`) by default, so mail your
application sends is captured without any code change. You can turn off auto-interception if you only
want the catcher available for applications that target it directly.

> [!WARNING]
> A mail-catcher intercepts mail instead of sending it. Never enable one on a production host, or real
> mail (password resets, order confirmations) silently disappears. This is the most common reason
> production mail "stops sending" - see [Mail deliverability](deliverability.md).

## YAML configuration

These are the keys the Mail Settings form writes to the host YAML.

### DKIM

DKIM is configured as a `dkim` object with a `keys` list. Each entry sets the `fqdn` and, optionally,
the `selector` (defaults to `cloud`).

```yaml
dkim:
  keys:
    - fqdn: example.com
      selector: cloud
    - fqdn: shop.example.com
      selector: cloud
```

### Development mail-catcher

| Key | Meaning |
|---|---|
| `mail_devtool` | Which catcher to install: `mailpit` or `mailhog`. This is the key that switches the catcher on - set it and the matching catcher is installed, leave it out and neither is installed (an existing one is removed). No other value is accepted. |
| `mailhog_install` | The **Enable mail capturing and mail testing** toggle in Mail Settings. It controls whether the catcher choice is shown in the form and is not read during deployment, so on its own it installs nothing. |
| `mail_auto_intercept` | Whether PHP mail is auto-intercepted through `php.ini`. Defaults to `true`, so interception is on; set it to `false` to leave PHP alone and catch only the mail that applications send to the catcher directly. |

```yaml
# Installs Mailpit as the mail-catcher:
mail_devtool: mailpit
# Optional - auto-interception is on by default; set it to false to turn it off:
mail_auto_intercept: false
```

> [!NOTE]
> Only `mail_devtool` decides whether a catcher is installed. You may still see `mailhog_install: true`
> in an existing host YAML - it is harmless, but it does not enable a catcher on its own.

## Related

- [What is mail on TurboStack?](what-is.md)
- [Mail deliverability](deliverability.md) - SPF, DKIM and DMARC, and blocklists.
- [Email deliverability troubleshooting](../../troubleshooting/email-deliverability.md) - mail not sending, reading the mail log and the mail queue.
- [SMTP error codes](smtp-error-codes.md) - decode a `5.7.x` bounce.
- [Email](../../platform/hosts/advanced/email.md) - Mail Settings on the host's Advanced tab.
- [Host Advanced settings](../../platform/hosts/advanced/index.md).
- [Connecting your domain](../../getting-started/connecting-your-domain.md) - where to add DNS records.
