Skip to main content

Email Configuration

Parcelis sends transactional email through SMTP. The SMTP values in your deployment environment provide the default configuration. An organization owner or administrator can optionally save a separate SMTP configuration in Settings → Organization → Email; that configuration takes precedence for email sent for that organization.

Configure the deployment environment​

Add the following values to .env for local development or .env.production for a Docker Compose deployment. Replace the example values with credentials from your SMTP provider.

# Transactional Email Configuration
EMAIL_FROM="Parcelis <no-reply@example.com>"
SMTP_HOST="smtp.example.com"
SMTP_PORT="465"
SMTP_SECURE="true"
SMTP_USER="your-smtp-user"
SMTP_PASSWORD="your-smtp-password"

# Required to save organization-level SMTP passwords
EMAIL_SETTINGS_ENCRYPTION_KEY="your-base64-encoded-32-byte-key"
VariableRequiredDescription
EMAIL_FROMYesSender shown on transactional messages. Use a mailbox or domain that your SMTP provider permits.
SMTP_HOSTYesSMTP server hostname.
SMTP_PORTYesSMTP server TCP port, from 1 to 65535. Common values are 465 for implicit TLS and 587 for STARTTLS.
SMTP_SECUREYesSet to true for implicit TLS, commonly port 465; set to false for a non-implicit-TLS connection. It must be exactly true or false.
SMTP_USERYesSMTP authentication username.
SMTP_PASSWORDYesSMTP authentication password or provider-issued app password. Keep it out of version control.
EMAIL_SETTINGS_ENCRYPTION_KEYRequired to save organization SMTP credentialsA base64-encoded 32-byte secret used to encrypt saved organization SMTP passwords.

For example, generate an encryption key with:

openssl rand -base64 32

Keep EMAIL_SETTINGS_ENCRYPTION_KEY stable and provide the same value to every API and worker instance. The worker loads the organization’s current saved SMTP settings when delivering queued email. Changing or losing it prevents Parcelis from decrypting previously saved organization SMTP passwords. It does not replace the deployment SMTP_PASSWORD.

TLS and STARTTLS​

The deployment variables distinguish only implicit TLS from a non-implicit-TLS connection:

  • For a provider that uses implicit TLS, set SMTP_SECURE="true" and use its TLS port, commonly 465.
  • For a provider that uses STARTTLS, set SMTP_SECURE="false" and use its STARTTLS port, commonly 587.

For organization-level settings, choose TLS for implicit TLS or STARTTLS for STARTTLS in the Email settings page. The organization form also supports an unencrypted connection only when explicitly required by the provider.

Verify delivery​

After starting the application with the new environment values, use Settings → Organization → Email and select Send test email after saving an organization configuration. If the organization has no saved configuration, account verification and password reset messages use the deployment SMTP values.

Do not commit .env or .env.production files containing SMTP credentials or encryption keys.

Background delivery and recovery​

For accounts with a default organization, account verification and password reset emails are recorded in PostgreSQL before they are sent. A scheduled email remains there until its due time, so a Redis outage does not erase the pending work. The worker dispatches due events to BullMQ and checks about once a minute for dispatched emails whose Redis job is missing. It restores those jobs using the original job ID. Legacy accounts without a default organization still use direct SMTP delivery and do not have this outbox recovery.

The worker renders account verification and password-reset notifications with the Parcelis email templates before sending them. Older queued notifications with a plain-text body remain deliverable. The worker makes up to three delivery attempts. Temporary SMTP and database failures are retried with exponential backoff; permanent SMTP failures and invalid email settings stop immediately. The delivery record tracks attempts and ends as sent or failed.

When rolling out this version, deploy the updated worker before the API. Older workers reject notification jobs with the new template field, so deploying the API first would prevent verification and password-reset emails from being delivered.

Recovery avoids adding another queued job when the original still exists. Email delivery is nevertheless at least once: if an SMTP server accepts an email immediately before the worker loses its progress record, a recovered job can send that email again. Parcelis cannot guarantee exactly one email across an SMTP and Redis failure.