Self-hosting
SMTP gateway
Expose authenticated submission with trusted TLS.
Configure TLS
Point an unproxied SMTP hostname to your server and open TCP 465 and 587. Provide fullchain.pem and privkey.pem in a restricted directory readable by container UID 1000. Restart after certificate renewal.
Start the profile
SMTP_HOST=smtp.example.com
SMTP_CERT_DIR=/absolute/path/to/certificatesdocker compose --env-file .env.docker --profile smtp up -d --build smtpSet SMTP_HOST in Convex too so Settings displays the correct host. Each team must enable SMTP.
Authenticate
Use username opensend and an os_ API key as the password. Port 465 is implicit TLS; port 587 requires STARTTLS. The gateway needs neither AWS credentials nor the deployment admin key. The internal HTTP target is port 3211.
Limits and retries
The MIME limit is 40 MiB; body/header, recipient, JSON, and proxy limits still apply. There are at most 16 clients per listener. AUTH and submission share the team’s 10 requests/second API budget. Opensend-Idempotency-Key maps to HTTP idempotency for 24 hours. No special SMTP tags header is interpreted.
Keep Opensend-Idempotency-Key stable when retrying a message. It must contain 1–256 printable non-space ASCII characters; duplicate or invalid headers return SMTP 554. The gateway removes it from the delivered message. A committed submission response survives crashes and logging failures; matching in-flight submissions receive a temporary conflict. See idempotency keys for replay and reservation timing.