Outbound Mail GA (M3)
| Status | Managed cloud GA deliverability layer |
|---|
> Cross-reference: product-plan-email-deliverability.md · managed-cloud-beta.md · self-hosted-smtp-relay.md
Principles
- Never send from bare
@anoobot.com— per-tenant subdomain only:mail.{slug}.send.anoobot.com - Paid managed tenants only — lite/free blocked at API layer (M1)
- Suppress bounces/complaints — webhook-driven suppression list
- Auto-suspend on complaint threshold — default 3 complaints / 24h
- Blocklist monitoring — optional DNS RBL scan on
OUTBOUND_SENDING_IP
Environment
ENABLE_OUTBOUND_MAIL=true
OUTBOUND_WEBHOOK_SECRET=<openssl rand -hex 32>
OUTBOUND_SEND_ROOT=send.anoobot.com
OUTBOUND_SPF_INCLUDE=include:amazonses.com
OUTBOUND_DKIM_CNAME_TARGET=anoobot1.dkim.send.anoobot.com
OUTBOUND_RETURN_PATH_CNAME=bounce.send.anoobot.com
OUTBOUND_SENDING_IP=203.0.113.10 # for blocklist cron
OUTBOUND_COMPLAINT_SUSPEND_THRESHOLD=3
ENABLE_BLOCKLIST_MONITOR=true
DISABLE_BLOCKLIST_CRON=false
BLOCKLIST_CHECK_MS=900000
Provider choice (configure in AWS/Postmark console — webhooks point to gateway):
| Provider | Webhook URL |
|---|---|
| Postmark | POST /api/v1/outbound/webhooks/postmark |
| AWS SES (SNS) | POST /api/v1/outbound/webhooks/ses |
Header: X-Outbound-Webhook-Secret: <OUTBOUND_WEBHOOK_SECRET>
API
| Method | Path | Auth | Purpose |
|---|---|---|---|
| GET | /api/v1/outbound/sending-domain/:domainId | Domain member | SPF/DKIM/DMARC DNS templates |
| GET | /api/v1/outbound/metrics/:domainId | Domain admin | Bounce/complaint counters |
| POST | /api/v1/outbound/webhooks/postmark | Webhook secret | Bounce/complaint ingestion |
| POST | /api/v1/outbound/webhooks/ses | Webhook secret | Bounce/complaint ingestion |
Mesh send (POST /api/v1/messages) checks:
OUTBOUND_SUSPENDEDif domain flaggedRECIPIENT_SUPPRESSEDif recipient on suppression list
DNS setup (per tenant)
After managed provisioning, call GET /outbound/sending-domain/:domainId and publish returned records to your DNS host. Example subdomain:
mail.acme-corp.send.anoobot.com