Set up SMTP for self-hosted Appwrite

Self-hosted Appwrite sends email verification, magic URL logins, password recovery and team invites with the `_APP_SMTP_*` variables in the `.env` file of your install. `_APP_SMTP_SECURE` must be set: left empty, Appwrite connects without TLS and never tries STARTTLS, and Unitpost refuses to log in on an unencrypted connection.

Need an API key?

SMTP password is a Unitpost API key with emails:send. Username is always unitpost.

  • 5,000 emails/month
  • 3 API keys
  • 5 sending domains
Get free SMTP key
  1. Create a send-only key

    In Unitpost, open Settings → SMTP and create a send-only key. _APP_SYSTEM_EMAIL_ADDRESS defaults to team@appwrite.io; change it to an address on a verified domain.

  2. Set the SMTP variables

    In Appwrite, tls means STARTTLS (port 587) and ssl means implicit TLS (port 465).

    Env
    _APP_SMTP_HOST=smtp.unitpost.com
    _APP_SMTP_PORT=587
    _APP_SMTP_SECURE=tls
    _APP_SMTP_USERNAME=unitpost
    _APP_SMTP_PASSWORD=pk_live_...
    _APP_SYSTEM_EMAIL_ADDRESS=no-reply@yourdomain.com

    For port 465, use _APP_SMTP_PORT=465 and _APP_SMTP_SECURE=ssl.

  3. Apply the changes

    Recreate the containers, then confirm the values loaded. If they didn't, run docker compose up -d --build --force-recreate.

    Shell
    docker compose up -d
    docker compose exec appwrite vars
  4. Send a test

    Sign out of the Console and request a password recovery, or invite someone to a team. Follow the mail worker with docker compose logs -f appwrite-worker (appwrite-worker-mails if you run workers separately), and look for the send in Unitpost Emails.

  5. If it fails

    538 in the worker log means _APP_SMTP_SECURE is empty, so the login went out before TLS. 550 5.7.1 means _APP_SYSTEM_EMAIL_ADDRESS is still team@appwrite.io or another unverified domain.

Search docs and guides

Search the docs and product guides.