Skip to main content
Multi-tenant applications require isolating email sending infrastructure, tracking, and analytics per tenant. SendPost provides sub-accounts, domain management, IPPool routing, and custom headers to build scalable multi-tenant email systems.

Architecture Overview

A multi-tenant email application typically requires:
  1. Sub-account isolation: Create a separate sub-account for each tenant
  2. Domain management: Whitelist and verify sending domains per sub-account
  3. Custom headers: Include tenant identifiers in email requests for webhook reconciliation
  4. IPPool routing: Use shared IPPools for smaller tenants and dedicated IPPools for high-volume senders
  5. Webhook processing: Consume webhook events with custom headers to reconcile stats per tenant

Creating Sub-Accounts for Tenants

Create a new sub-account for each tenant when they sign up or when you need to isolate their email sending.
POST /api/v1/account/subaccount/
X-Account-ApiKey: your_account_api_key

{
  "name": "tenant-acme-corp",
  "companyName": "Acme Corporation"
}
Each sub-account receives its own API key (X-SubAccount-ApiKey) for sending emails and managing sub-account resources. Store the sub-account ID and API key in your tenant database.
Use the Account API key (X-Account-ApiKey) to create and manage sub-accounts. Use the Sub-Account API key (X-SubAccount-ApiKey) for all email sending and sub-account-specific operations.

Managing Domains Per Sub-Account

After creating a sub-account, create and verify sending domains for that tenant. Each sub-account can have multiple verified domains.

Creating a Domain

POST /api/v1/subaccount/domain
X-SubAccount-ApiKey: tenant_subaccount_api_key

{
  "domain": "mail.acme-corp.com"
}

Verifying Domain Ownership

After creating a domain, SendPost provides DNS records (SPF, DKIM, DMARC) that must be added to your tenant’s DNS. Retrieve the domain details to get the required DNS records:
GET /api/v1/subaccount/domain/{domain_id}
X-SubAccount-ApiKey: tenant_subaccount_api_key
Once DNS records are verified, the domain is ready for sending. Use the verified domain in the from.email field when sending emails for that tenant.
Domain verification is required before sending emails. Unverified domains will cause email sending to fail. See Create a New Domain for detailed DNS configuration steps.

Using Custom Headers for Tenant Identification

Include custom headers in every email request to identify the tenant and enable webhook reconciliation. Headers are preserved throughout the email lifecycle and included in all webhook events.
{
  "from": {
    "email": "[email protected]",
    "name": "Acme Corp"
  },
  "to": [
    {
      "email": "[email protected]",
      "name": "John Doe"
    }
  ],
  "subject": "Welcome to Acme Corp",
  "htmlBody": "<p>Welcome aboard!</p>",
  "headers": {
    "Tenant-ID": "acme-corp-123",
    "Workspace-ID": "workspace-456",
    "User-ID": "user-789"
  },
  "trackOpens": true,
  "trackClicks": true,
  "ippool": "shared-marketing"
}

Header Best Practices

  • Use consistent naming conventions (e.g., Tenant-ID, Workspace-ID)
  • Include tenant identifiers in every email request
  • Store header values in your tenant database for easy lookup
  • Use headers to filter webhook events in your application
Custom headers are included in all webhook events (Processed, Delivered, Opened, Clicked, Bounced, Unsubscribed, Spam), making it easy to reconcile events per tenant. See Custom Headers for more details.

Managing IPPools for Multi-Tenant Routing

IPPools control which IP addresses or third-party sending providers (TPSPs) are used for sending emails. Use different IPPool strategies based on tenant volume and requirements.

Shared IPPools for Smaller Tenants

Smaller tenants should use shared IPPools that distribute sending across multiple IPs and TPSPs. This provides cost efficiency and adequate deliverability.
{
  "from": {
    "email": "[email protected]",
    "name": "Acme Corp"
  },
  "to": [
    {
      "email": "[email protected]"
    }
  ],
  "subject": "Welcome",
  "htmlBody": "<p>Welcome!</p>",
  "ippool": "shared-pool"
}

Dedicated IPPools for High-Volume Tenants

Large-volume tenants may require dedicated IPPools for better deliverability, reputation management, and compliance. Create dedicated IPPools and assign them to specific tenants.
POST /api/v1/account/ippool
X-Account-ApiKey: your_account_api_key

{
  "name": "acme-corp-dedicated",
  "ips": ["IP_100", "IP_101"],
  "routingStrategy": 0,
  "routingMetaData": "{}"
}
Then use the dedicated IPPool when sending emails for that tenant:
{
  "from": {
    "email": "[email protected]",
    "name": "Acme Corp"
  },
  "to": [
    {
      "email": "[email protected]"
    }
  ],
  "subject": "Welcome",
  "htmlBody": "<p>Welcome!</p>",
  "ippool": "acme-corp-dedicated"
}

IPPool Routing Strategies

SendPost supports multiple routing strategies for IPPools:
  • Round Robin (0): Distribute emails evenly across all IPs and TPSPs
  • Email Provider Strategy (1): Route emails based on recipient email provider (Gmail, Yahoo, Microsoft, etc.)
  • Volume Percentage Strategy (2): Assign specific volume percentages to each IP or TPSP
  • Sending Domain Strategy (3): Route emails based on the sending domain
See IPPool Routing for detailed routing strategy configuration.
IPPools are managed at the account level using X-Account-ApiKey, but can be used by any sub-account when sending emails. Assign IPPool names to tenants in your database to control which pool each tenant uses.

Webhook Reconciliation

When an email is processed, delivered, hard bounced, soft bounced, opened, clicked, unsubscribed, or marked as spam, SendPost sends a webhook event to your configured endpoint. The webhook payload includes your custom headers, allowing you to reconcile events per tenant.

Webhook Event Structure

{
  "event": {
    "eventID": "edhg-123gh-afasdf-124egh",
    "type": 5,
    "messageID": "mjhl-1401-sasdf-129324",
    "eventMetadata": {
      "userAgent": {
        "Family": "Chrome",
        "Major": "91"
      }
    }
  },
  "emailMessage": {
    "messageID": "mjhl-1401-sasdf-129324",
    "from": {
      "email": "[email protected]",
      "name": "Acme Corp"
    },
    "to": [
      {
        "email": "[email protected]",
        "name": "John Doe"
      }
    ],
    "subject": "Welcome to Acme Corp",
    "headers": {
      "Tenant-ID": "acme-corp-123",
      "Workspace-ID": "workspace-456",
      "User-ID": "user-789"
    },
    "groups": ["transactional", "welcome"]
  }
}

Processing Webhooks

  1. Extract tenant identifier: Read emailMessage.headers.Tenant-ID from the webhook payload
  2. Identify event type: Check event.type to determine the event (Delivered, Opened, Clicked, etc.)
  3. Update tenant stats: Update your tenant’s statistics based on the event type
  4. Store event data: Persist the event in your database for analytics and reporting

Webhook Event Types

Event TypeType ValueDescription
Processed0Email accepted and queued for sending
Dropped1Email dropped before delivery (invalid address or in suppression list)
Delivered2Email successfully delivered to recipient’s mail server
SoftBounced3Temporary delivery failure (will retry)
HardBounced4Permanent delivery failure (invalid address)
Opened5Recipient opened the email
Clicked6Recipient clicked a link in the email
Unsubscribed7Recipient clicked unsubscribe link
Spam8Recipient marked email as spam
Custom headers are included in every webhook event for a given email, allowing you to filter and process webhooks based on tenant identifiers without needing to store additional mapping data. See Understanding Webhook Event Lifecycle for complete event lifecycle details.

Complete Multi-Tenant Example

Here’s a complete example of setting up and sending emails for a new tenant:

1. Create Sub-Account

POST /api/v1/account/subaccount/
X-Account-ApiKey: your_account_api_key

{
  "name": "tenant-acme-corp",
  "companyName": "Acme Corporation"
}
Response:
{
  "id": 12345,
  "name": "tenant-acme-corp",
  "companyName": "Acme Corporation",
  "apiKey": "AHEZEP8192SEGH"
}

2. Create and Verify Domain

POST /api/v1/subaccount/domain
X-SubAccount-ApiKey: AHEZEP8192SEGH

{
  "domain": "mail.acme-corp.com"
}
Add DNS records to tenant’s DNS, then verify domain is ready for sending.

3. Send Email with Custom Headers

POST /api/v1/subaccount/email/
X-SubAccount-ApiKey: AHEZEP8192SEGH

{
  "from": {
    "email": "[email protected]",
    "name": "Acme Corp"
  },
  "to": [
    {
      "email": "[email protected]",
      "name": "John Doe",
      "customFields": {
        "firstName": "John"
      }
    }
  ],
  "subject": "Welcome {{firstName}}!",
  "htmlBody": "<p>Hi {{firstName}}, welcome to Acme Corp!</p><p><a href='{{unsubscribe}}'>Unsubscribe</a></p>",
  "headers": {
    "Tenant-ID": "acme-corp-123",
    "Workspace-ID": "workspace-456"
  },
  "ippool": "shared-pool",
  "trackOpens": true,
  "trackClicks": true,
  "groups": ["transactional", "welcome"]
}

4. Process Webhook Events

When the email is delivered, opened, or clicked, you’ll receive webhook events with the custom headers:
{
  "event": {
    "type": 5,
    "messageID": "mjhl-1401-sasdf-129324"
  },
  "emailMessage": {
    "headers": {
      "Tenant-ID": "acme-corp-123",
      "Workspace-ID": "workspace-456"
    }
  }
}
Extract Tenant-ID from headers and update tenant statistics accordingly. Multi-tenant applications also leverage these features:

Best Practices

  1. Isolate by sub-account: Create separate sub-accounts for each tenant to ensure complete isolation
  2. Verify domains early: Set up and verify domains as part of tenant onboarding
  3. Always include headers: Include tenant identifiers in every email request for webhook reconciliation
  4. Choose appropriate IPPools: Use shared IPPools for smaller tenants and dedicated IPPools for high-volume senders
  5. Process webhooks idempotently: Use eventID to prevent duplicate processing of webhook events
  6. Monitor tenant stats: Use custom headers to filter and aggregate statistics per tenant from webhook events
Each sub-account requires its own verified domain. Sending from unverified domains will fail. Ensure domains are verified before sending emails for a tenant.
Sub-accounts provide complete isolation: each tenant has separate API keys, domains, suppressions, and statistics. Use sub-accounts to ensure tenant data and sending infrastructure remain isolated.