Skip to content

Configure

Email

Configure and verify transactional email delivery

Configure a mail provider for workspace invitations, email verification, password resets, and notifications. Use a sender address the provider is authorized to send as.

Provider selection

There is no provider-selection flag. Every configured, usable provider participates in this fallback order:

Resend → AWS SES → SMTP → Azure Communication Services → Gmail

The first provider handles normal traffic. Later providers are tried only after a failure. Configure a single provider or verify the sender and permissions for every fallback you enable.

Shared settings

VariableBehavior
FROM_EMAIL_ADDRESSSender, such as Sim <noreply@example.com>.
EMAIL_DOMAINWhen the sender is unset, use noreply@EMAIL_DOMAIN.
EMAIL_VERIFICATION_ENABLEDSet true to require signup verification when a mail provider is configured.

Configure a provider

Code
RESEND_API_KEY=re_...
FROM_EMAIL_ADDRESS="Sim <noreply@yourdomain.com>"

Verify your sending domain and add Resend's DNS records before production delivery. See Resend domain setup.

Apply configuration

For Compose, save provider settings in .env beside the Compose file and recreate the app:

Code
docker compose -f docker-compose.prod.yml up -d --force-recreate simstudio

For a source checkout, save them in apps/sim/.env and restart the app.

Kubernetes

Choose one of the chart's secret strategies:

  • Inline mode: set credentials under app.env; Helm writes them to a Secret but also retains them in release values. Do not commit secret values to Git.
  • Existing Secret: add the provider keys to the pre-created app Secret. Credentials set explicitly under app.env in this mode are inlined into pod specs.
  • ESO: map each credential under externalSecrets.remoteRefs.app; the chart-managed inline Secret is disabled. Use app.envDefaults for non-secret sender settings.

For example, merge this into a complete ESO configuration whose store and core secrets are already configured:

Code
app:
  envDefaults:
    FROM_EMAIL_ADDRESS: "Sim <noreply@yourdomain.com>"
externalSecrets:
  remoteRefs:
    app:
      RESEND_API_KEY: "sim/app/resend-api-key"

Restart the affected app pods after the credentials have synchronized:

Code
kubectl rollout restart deployment/sim-app -n simstudio

Verify delivery

Invite a test member from workspace settings, confirm the message arrives, and accept it. If verification is required, also test a new account's verification message and a password reset.

Set LOG_LEVEL=INFO and restart/recreate the app before using logs to diagnose skipped delivery. The production default is ERROR; log-level values are uppercase.

Code
kubectl logs -n simstudio -l app.kubernetes.io/component=app --tail=100 | grep -i mail

For Compose, use docker compose -f docker-compose.prod.yml logs simstudio.

SignalDiagnosis
No-provider log with recipient, subject, and senderSim skipped delivery. Configure a usable provider.
Provider errorCheck the named provider's credentials, sender, permissions, and quotas. Later configured providers may be tried.
Provider acceptance but no messageCheck delivery status in its dashboard, recipient filtering, SPF, DKIM, and DMARC. Acceptance does not prove inbox delivery.

Troubleshooting

FailureAction
Gmail unauthorized_client or delegation deniedMatch the JSON client_id to the Workspace delegation entry and confirm the exact gmail.send scope and impersonated user.
Sender rejected or rewrittenMatch the verified sender/domain; for Gmail, use the impersonated sender or its registered alias.
SES rejects an unverified recipientRequest production access in the configured region.
SMTP connection failsCheck host/port, reachability, matching username/password, and implicit TLS versus STARTTLS.
SMTP rejects EHLO, such as 421-4.7.0Set SMTP_EHLO_NAME to a dotted hostname accepted by the relay. Older releases used [127.0.0.1] on Kubernetes; upgrade to use the public-domain derivation.
Mail is filtered as spamVerify sending-domain SPF, DKIM, and DMARC, then inspect provider delivery events.
Was this helpful?
Suggest an edit