Outbound Mail GA (M3)

StatusManaged cloud GA deliverability layer

> Cross-reference: product-plan-email-deliverability.md · managed-cloud-beta.md · self-hosted-smtp-relay.md


Principles

  1. Never send from bare @anoobot.com — per-tenant subdomain only: mail.{slug}.send.anoobot.com
  2. Paid managed tenants only — lite/free blocked at API layer (M1)
  3. Suppress bounces/complaints — webhook-driven suppression list
  4. Auto-suspend on complaint threshold — default 3 complaints / 24h
  5. 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):

ProviderWebhook URL
PostmarkPOST /api/v1/outbound/webhooks/postmark
AWS SES (SNS)POST /api/v1/outbound/webhooks/ses

Header: X-Outbound-Webhook-Secret: <OUTBOUND_WEBHOOK_SECRET>


API

MethodPathAuthPurpose
GET/api/v1/outbound/sending-domain/:domainIdDomain memberSPF/DKIM/DMARC DNS templates
GET/api/v1/outbound/metrics/:domainIdDomain adminBounce/complaint counters
POST/api/v1/outbound/webhooks/postmarkWebhook secretBounce/complaint ingestion
POST/api/v1/outbound/webhooks/sesWebhook secretBounce/complaint ingestion

Mesh send (POST /api/v1/messages) checks:

  • OUTBOUND_SUSPENDED if domain flagged
  • RECIPIENT_SUPPRESSED if 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