# Mail and notifications (https://docs.vitrinka.ai/operator/mail)



## Who may change it [#who]

The mailer sends every password reset and sign-in code on the install, so it is a deployment-wide setting. Platform admins change it through any organization they administer; with `VITRINKA_OPS_ORG` set, that organization's admins change it through that organization too. Unset, platform admins alone hold it — an ordinary organization admin never qualifies, because any account that signs up can own an organization ([the first admin](/operator/install#admin)).

Anyone else is refused: `set` or `test` exits 2 without changing anything. While `VITRINKA_OPS_ORG` is unset, and inside that organization when it is set, they also see why and whom to ask — Settings shows the server's reason in place of the form, and `status` prints the reason and the fix. With it set, an admin of any other organization sees no mailer at all, as on the hosted service.

## In the product [#settings]

**Settings → Organization → Email** holds the same fields as `set` — host, port, encryption, user, password, from address and an optional private-CA bundle — plus **send test email** and **remove saved settings**. A saved configuration wins over the `SMTP_*` / `RESEND_API_KEY` environment and applies to the next email.

## Configure the relay [#set]

```bash
vitrinka admin smtp set \
  --host smtp.example.com --port 587 --tls starttls \
  --from "vitrinka@example.com" --user mailer --password-stdin
```

| Flag               | What it does                                                                  |
| ------------------ | ----------------------------------------------------------------------------- |
| `--host`           | Relay host.                                                                   |
| `--port`           | Relay port. Server default 587.                                               |
| `--tls`            | `starttls`, `implicit` or `none`.                                             |
| `--from`           | From address.                                                                 |
| `--user`           | Relay user. An empty value switches to an anonymous relay.                    |
| `--password-stdin` | Read the relay password from stdin.                                           |
| `--password`       | The password as an argument — &#x2A;*prefer `--password-stdin`**.             |
| `--ca`             | Path to a private-CA PEM bundle.                                              |
| `--no-ca`          | Drop the stored CA bundle and go back to system roots.                        |
| `--clear`          | Delete the saved config and fall back to the env `SMTP_*` / `RESEND_API_KEY`. |

<Callout type="warn">
  Prefer `--password-stdin`. A password passed as `--password` is visible in `ps` to anyone else on the box.
</Callout>

## Check it works [#check]

`status` reports the source, the host, TLS mode and from-address, and whether a password is stored. `test` sends a test email to your own address.

```bash
vitrinka admin smtp status
vitrinka admin smtp test
```

Without starting the server — before the first boot, say — `vitrinka smtp-test` on the server binary sends one test mail through the `SMTP_*` relay in your `.env`:

```bash
docker compose run --rm --no-deps vitrinka smtp-test -to you@example.com
```

## Which organization [#org]

All three subcommands go through an organization you administer. `--org` picks which one when your login belongs to more than one; it falls back to `$VITRINKA_ORG`, then the bound workspace's organization, then your sole membership. A platform admin may use any organization they administer, and an admin of the `VITRINKA_OPS_ORG` organization goes through that one — name it with `--org` when your login belongs to several.

```bash
vitrinka admin smtp status --org acme
```

## Push notifications [#push]

Web push reaches a person's devices even with the tab closed. It needs a VAPID key pair — `VAPID_PUBLIC_KEY` and `VAPID_PRIVATE_KEY`, generated once with any Web Push library — and `VAPID_SUBSCRIBER`, the `mailto:` contact push services may use to reach you: set it to your own address, because the default is a placeholder. With the keys in place, each person turns push on per device under **Settings → Preferences → Notifications** ([notifications](/use#notifications)).

`AIR_GAP=1` blanks web push, because it posts to the browser vendors' push services. Email notifications go out through the deployment mailer above and stay off until each person turns them on.
