Prompt
multi tenant email sending API
Latest observation
Oct 4, 2026
OpenAI APIWeb search: off
Here’s a solid blueprint for a multi-tenant email sending API.
1) Core goal
Let multiple customers/tenants send email through one shared platform while keeping:
- isolation of data and sending limits
- per-tenant configuration like domains, templates, rate limits, SMTP/provider credentials
- tracking and observability per tenant
- secure authentication/authorization
2) Main API resources
Tenants
Represents a customer/account.
tenant_id- name
- status
- limits/quota
- default sender settings
Sender identities
Verified email addresses or domains per tenant.
sender_idtenant_id- email/domain
- verification status
- provider config
Templates
Reusable email content.
template_idtenant_id- subject/body
- variables schema
- versioning
Messages
An email send request.
message_idtenant_id- recipients
- subject/body/template reference
- status: queued/sent/failed/delivered/bounced
- metadata
Webhooks/events
Delivery status and engagement notifications.
event_idtenant_idmessage_id- event type
- payload
3) Suggested endpoints
Auth / tenant context
POST /v1/auth/tokenGET /v1/tenants/me
Send email
POST /v1/emails
{
"tenant_id": "ten_123",
"from": "no-reply@example.com",
"to": ["user@example.com"],
"subject": "Welcome",
"text": "Hello!",
"html": "<p>Hello!</p>",
"tags": ["welcome"],
"metadata": {
"user_id": "u_456"
}
}
Send using template
POST /v1/emails/send-template
{
"tenant_id": "ten_123",
"template_id": "tpl_789",
"to": ["user@example.com"],
"variables": {
"first_name": "Sam"
}
}
Template management
POST /v1/templatesGET /v1/templatesGET /v1/templates/{id}PUT /v1/templates/{id}DELETE /v1/templates/{id}
Sender/domain verification
POST /v1/sendersPOST /v1/senders/{id}/verifyGET /v1/senders
Message status
GET /v1/emails/{message_id}GET /v1/emails?tenant_id=...
Webhooks
POST /v1/webhooksGET /v1/webhooks- Events:
email.queuedemail.sentemail.deliveredemail.openedemail.clickedemail.bouncedemail.complainedemail.failed
4) Multi-tenant design choices
Tenant isolation
Choose one:
- Shared DB, tenant_id column
- simplest, cheapest
- enforce row-level security carefully
- Shared DB + separate schema per tenant
- more isolation
- more operational complexity
- Separate database per tenant
- strongest isolation
- expensive and harder to maintain
For most SaaS systems: shared DB + tenant_id + strict authorization works well.
Authentication
Use:
- API keys per tenant, or
- OAuth2/JWT with tenant claims
Example JWT claims:
{
"sub": "service_user_123",
"tenant_id": "ten_123",
"roles": ["email_sender"]
}
Rate limiting
Per tenant:
- requests/minute
- emails/day
- recipients/minute
Quotas
Track:
- monthly send volume
- bounce rate
- complaint rate
- suppressed recipients
5) Sending flow
- Client authenticates
- API validates tenant and sender identity
- API validates content and recipient list
- API stores message as
queued - Worker picks up message
- Worker sends via email provider
- Status callbacks/webhooks update message lifecycle
Use a queue like:
- SQS
- RabbitMQ
- Kafka
- Redis queue
6) Important operational features
Idempotency
Prevent duplicate sends:
- support
Idempotency-Keyheader - store request hash + result
Suppression list
Do not send to:
- unsubscribed users
- bounced addresses
- complaint addresses
Delivery tracking
Use provider webhooks to sync events back to your API.
Security
- encrypt API keys/secrets
- sign webhooks
- validate tenant ownership on every resource
- audit logs for sends and config changes
7) Minimal database tables
tenants
- id
- name
- status
- created_at
tenant_api_keys
- id
- tenant_id
- key_hash
- last_used_at
- revoked_at
sender_identities
- id
- tenant_id
- type
- value
- verified_at
templates
- id
- tenant_id
- name
- subject
- html
- text
- version
email_messages
- id
- tenant_id
- from_address
- subject
- body_html
- body_text
- status
- provider_message_id
- created_at
email_recipients
- id
- message_id
- status
email_events
- id
- tenant_id
- message_id
- event_type
- payload
- created_at
8) Example response
{
"message_id": "msg_001",
"tenant_id": "ten_123",
"status": "queued",
"created_at": "2026-10-04T12:00:00Z"
}
9) Recommended extras
- sandbox/test mode
- attachment support
- bulk send endpoints
- template preview/render endpoint
- domain reputation monitoring
- per-tenant analytics dashboard
If you want, I can turn this into:
- an OpenAPI spec,
- a database schema, or
- a Node.js / FastAPI implementation.
Brands