Email Servers API

The Email Servers API provides full CRUD (Create, Read, Update, Delete) operations for managing email server configurations. You can create, list, view, update, delete, and test email server connections programmatically.

This is particularly useful for automating the setup of email infrastructure or integrating with AI tools like Claude for automated onboarding flows.

Required Permissions

All endpoints require authentication via an API token with appropriate permissions:

  • Read Permission: Required for GET endpoints (list, show)
  • Write Permission: Required for POST, PATCH, DELETE endpoints, including test connection (it updates the server’s active and connection_failed_at values) and copy to channel

Email Server Object

The email server object contains the following fields:

Field Description
`id` Unique identifier of the email server
`label` Display name for the email server
`vendor` Email service provider (aws_ses, sendgrid, postmark, mailgun, inboxroad, resend, smtp_com, test_server, other)
`delivery_method` How emails are sent (smtp or api)
`active` Whether the server is active and can be used for sending
`emails_per_hour` Rate limit for emails sent per hour
`use_for_broadcasts` Whether this server can be used for broadcast emails
`use_for_sequences` Whether this server can be used for sequence emails
`use_for_transactionals` Whether this server can be used for transactional emails
`include_unsubscribe_header` Whether to include List-Unsubscribe header in emails
`include_unsubscribe_link` Whether to include unsubscribe link in email body
`use_custom_unsubscribe_link` Whether to use a custom unsubscribe URL
`custom_unsubscribe_link` Custom unsubscribe URL (if enabled)
`smtp_address` SMTP server hostname
`smtp_port` SMTP server port (typically 587 or 465)
`smtp_username` SMTP username (returned in plain text)
`smtp_password` SMTP password (redacted in responses)
`smtp_authentication` Authentication method (plain, login, cram_md5)
`smtp_enable_starttls_auto` Whether STARTTLS is automatically enabled
`aws_region` AWS region for SES (e.g., us-east-1)
`aws_ses_configuration_set` AWS SES configuration set name
`aws_access_key_id` AWS access key for webhook auto-setup (redacted)
`aws_secret_access_key` AWS secret key for webhook auto-setup (redacted)
`outbound_aws_access_key_id` AWS access key for API delivery (redacted)
`outbound_aws_secret_access_key` AWS secret key for API delivery (redacted)
`aws_setup_completed` Whether AWS webhook auto-setup has been completed
`postmark_api_token` Postmark API token (redacted)
`postmark_unsubscribe_handling` Postmark only, read-only. The unsubscribe handling of the server’s `broadcast` message stream as Broadcast last read it: `Custom`, `Postmark`, `None`, or `missing` (the stream does not exist). `null` until Broadcast checks it. See [Postmark unsubscribe handling](#postmark-unsubscribe-handling).
`postmark_unsubscribe_handling_checked_at` Postmark only, read-only. When Broadcast last read the handling (ISO 8601), or `null`
`postmark_unsubscribe_handling_error` Postmark only, read-only. Why Postmark refused to switch the stream to `Custom` handling (Postmark’s own error text), or `null`
`postmark_subscription_sync` Postmark only. When `true` (the default), an unsubscribe through Postmark’s own link unsubscribes the subscriber in Broadcast, and a resubscribe in Broadcast removes the Postmark suppression
`inboxroad_api_token` Inboxroad API token (redacted)
`inboxroad_sync_enabled` Whether Inboxroad bounce/complaint sync is enabled
`smtp_com_api_key` SMTP.com API key (redacted)
`smtp_com_channel` SMTP.com channel name
`smtp_com_callback_setup` Whether SMTP.com callback has been configured
`email_headers` Array of custom email headers (each with id, key, value)
`connection_failed_at` Timestamp of last connection failure (null if healthy)
`created_at` When the email server was created
`updated_at` When the email server was last updated

Security Note

For security, sensitive credentials (passwords, API tokens, secret keys) are redacted in API responses. You can set these values when creating or updating an email server, but they will never be returned in plain text.

Redacted fields include: - smtp_password - aws_secret_access_key - outbound_aws_secret_access_key - aws_access_key_id - outbound_aws_access_key_id - postmark_api_token - inboxroad_api_token - smtp_com_api_key

Supported Vendors

Vendor Value Delivery Methods
AWS SES `aws_ses` SMTP, API
Postmark `postmark` SMTP, API
SendGrid `sendgrid` SMTP (API in the dashboard only)
Mailgun `mailgun` SMTP (API in the dashboard only)
Inboxroad `inboxroad` SMTP
Resend `resend` SMTP
SMTP.com `smtp_com` SMTP
Test Server `test_server` SMTP
Other `other` SMTP

List Email Servers

GET /api/v1/email_servers

Retrieve a list of all email servers for the authenticated broadcast channel.

Query Parameters

  • limit (optional): Maximum number of email servers to return, from 1 to 1000
  • offset (optional): Number of email servers to skip, 0 or more

A limit or offset outside those ranges, or that is not a whole number, returns 422 Unprocessable Entity.

Request

curl -X GET \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  https://your-domain.com/api/v1/email_servers

Response

{
  "data": [
    {
      "id": 1,
      "label": "Production AWS SES",
      "vendor": "aws_ses",
      "delivery_method": "smtp",
      "active": true,
      "emails_per_hour": 1000,
      "use_for_broadcasts": true,
      "use_for_sequences": true,
      "use_for_transactionals": false,
      "include_unsubscribe_header": true,
      "include_unsubscribe_link": true,
      "use_custom_unsubscribe_link": false,
      "custom_unsubscribe_link": null,
      "smtp_address": "email-smtp.us-east-1.amazonaws.com",
      "smtp_port": 587,
      "smtp_username": "AKIAIOSFODNN7EXAMPLE",
      "smtp_password": "••••••••",
      "smtp_authentication": "plain",
      "smtp_enable_starttls_auto": true,
      "aws_region": "us-east-1",
      "aws_ses_configuration_set": "my-config-set",
      "aws_access_key_id": null,
      "aws_secret_access_key": null,
      "outbound_aws_access_key_id": null,
      "outbound_aws_secret_access_key": null,
      "aws_setup_completed": false,
      "postmark_api_token": null,
      "postmark_unsubscribe_handling": null,
      "postmark_unsubscribe_handling_checked_at": null,
      "postmark_unsubscribe_handling_error": null,
      "postmark_subscription_sync": true,
      "inboxroad_api_token": null,
      "inboxroad_sync_enabled": false,
      "smtp_com_api_key": null,
      "smtp_com_channel": null,
      "smtp_com_callback_setup": false,
      "email_headers": [],
      "connection_failed_at": null,
      "created_at": "2024-01-01T12:00:00Z",
      "updated_at": "2024-01-01T12:00:00Z"
    }
  ],
  "total": 1
}

Get Email Server

GET /api/v1/email_servers/:id

Retrieve details of a specific email server.

Request

curl -X GET \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  https://your-domain.com/api/v1/email_servers/1

Response

{
  "id": 1,
  "label": "Production AWS SES",
  "vendor": "aws_ses",
  "delivery_method": "smtp",
  "active": true,
  "emails_per_hour": 1000,
  "use_for_broadcasts": true,
  "use_for_sequences": true,
  "use_for_transactionals": false,
  "include_unsubscribe_header": true,
  "include_unsubscribe_link": true,
  "use_custom_unsubscribe_link": false,
  "custom_unsubscribe_link": null,
  "smtp_address": "email-smtp.us-east-1.amazonaws.com",
  "smtp_port": 587,
  "smtp_username": "AKIAIOSFODNN7EXAMPLE",
  "smtp_password": "••••••••",
  "smtp_authentication": "plain",
  "smtp_enable_starttls_auto": true,
  "aws_region": "us-east-1",
  "aws_ses_configuration_set": "my-config-set",
  "aws_access_key_id": null,
  "aws_secret_access_key": null,
  "outbound_aws_access_key_id": null,
  "outbound_aws_secret_access_key": null,
  "aws_setup_completed": false,
  "postmark_api_token": null,
  "postmark_unsubscribe_handling": null,
  "postmark_unsubscribe_handling_checked_at": null,
  "postmark_unsubscribe_handling_error": null,
  "postmark_subscription_sync": true,
  "inboxroad_api_token": null,
  "inboxroad_sync_enabled": false,
  "smtp_com_api_key": null,
  "smtp_com_channel": null,
  "smtp_com_callback_setup": false,
  "email_headers": [],
  "connection_failed_at": null,
  "created_at": "2024-01-01T12:00:00Z",
  "updated_at": "2024-01-01T12:00:00Z"
}

Create Email Server

POST /api/v1/email_servers

Create a new email server configuration.

Required Parameters

  • label (required): Display name for the email server
  • emails_per_hour (required): Rate limit (minimum 15)
  • At least one of: use_for_broadcasts, use_for_sequences, use_for_transactionals must be true

SMTP Parameters (required for SMTP delivery)

  • smtp_address: SMTP server hostname
  • smtp_port: SMTP server port
  • smtp_username: SMTP username
  • smtp_password: SMTP password
  • smtp_authentication: Authentication method (plain, login, cram_md5)

Optional Parameters

  • vendor: Email provider (default: aws_ses). Always send it.
  • delivery_method: smtp or api (default: smtp)
  • active: Whether server is active (default: true)
  • smtp_enable_starttls_auto: Enable STARTTLS (default: true)
  • include_unsubscribe_header: Include List-Unsubscribe header (default: true)
  • include_unsubscribe_link: Include unsubscribe link in emails (default: true)
  • use_custom_unsubscribe_link: Use custom unsubscribe URL
  • custom_unsubscribe_link: Custom unsubscribe URL
  • email_headers_attributes: Array of custom email headers (see below)

Custom Email Headers

You can add custom email headers to be included with every email sent through this server:

{
  "email_server": {
    "email_headers_attributes": [
      { "key": "X-Custom-Header", "value": "custom-value" },
      { "key": "X-Campaign-ID", "value": "spring-2024" }
    ]
  }
}

To update existing headers, include the id. To remove a header, include _destroy: true:

{
  "email_server": {
    "email_headers_attributes": [
      { "id": 1, "key": "X-Custom-Header", "value": "updated-value" },
      { "id": 2, "_destroy": true }
    ]
  }
}

Vendor-Specific Parameters

AWS SES: - aws_region: AWS region (e.g., us-east-1) - aws_ses_configuration_set: SES configuration set name - aws_access_key_id: For webhook auto-setup - aws_secret_access_key: For webhook auto-setup - outbound_aws_access_key_id: For API delivery method - outbound_aws_secret_access_key: For API delivery method

Postmark: - postmark_api_token: Required for API delivery method - postmark_subscription_sync: true or false (default true). See Postmark unsubscribe handling.

SendGrid and Mailgun: The API cannot set the SendGrid or Mailgun API credentials (sendgrid_api_key, mailgun_api_key, mailgun_domain, mailgun_region). It ignores them with an unrecognized_parameter warning. Create these servers with delivery_method: "smtp" and the provider’s SMTP credentials. An API-delivery server for SendGrid or Mailgun needs the dashboard.

Inboxroad: - inboxroad_api_token: For bounce/complaint sync - inboxroad_sync_enabled: Enable automatic sync

SMTP.com: - smtp_com_api_key: For callback configuration - smtp_com_channel: SMTP.com channel name

Example: Create SMTP Server (AWS SES)

curl -X POST \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "email_server": {
      "label": "Production AWS SES",
      "vendor": "aws_ses",
      "delivery_method": "smtp",
      "smtp_address": "email-smtp.us-east-1.amazonaws.com",
      "smtp_port": 587,
      "smtp_username": "AKIAIOSFODNN7EXAMPLE",
      "smtp_password": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
      "smtp_authentication": "plain",
      "emails_per_hour": 1000,
      "use_for_broadcasts": true,
      "use_for_sequences": true,
      "use_for_transactionals": false,
      "aws_region": "us-east-1"
    }
  }' \
  https://your-domain.com/api/v1/email_servers

Example: Create API Server (Postmark)

curl -X POST \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "email_server": {
      "label": "Postmark Transactional",
      "vendor": "postmark",
      "delivery_method": "api",
      "postmark_api_token": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "emails_per_hour": 500,
      "use_for_broadcasts": false,
      "use_for_sequences": false,
      "use_for_transactionals": true
    }
  }' \
  https://your-domain.com/api/v1/email_servers

Response

{
  "id": 1,
  "label": "Production AWS SES",
  "vendor": "aws_ses",
  "delivery_method": "smtp",
  "active": true,
  "emails_per_hour": 1000,
  "use_for_broadcasts": true,
  "use_for_sequences": true,
  "use_for_transactionals": false,
  "include_unsubscribe_header": true,
  "include_unsubscribe_link": true,
  "use_custom_unsubscribe_link": false,
  "custom_unsubscribe_link": null,
  "smtp_address": "email-smtp.us-east-1.amazonaws.com",
  "smtp_port": 587,
  "smtp_username": "AKIAIOSFODNN7EXAMPLE",
  "smtp_password": "••••••••",
  "smtp_authentication": "plain",
  "smtp_enable_starttls_auto": true,
  "aws_region": "us-east-1",
  "aws_ses_configuration_set": null,
  "aws_access_key_id": null,
  "aws_secret_access_key": null,
  "outbound_aws_access_key_id": null,
  "outbound_aws_secret_access_key": null,
  "aws_setup_completed": false,
  "postmark_api_token": null,
  "postmark_unsubscribe_handling": null,
  "postmark_unsubscribe_handling_checked_at": null,
  "postmark_unsubscribe_handling_error": null,
  "postmark_subscription_sync": true,
  "inboxroad_api_token": null,
  "inboxroad_sync_enabled": false,
  "smtp_com_api_key": null,
  "smtp_com_channel": null,
  "smtp_com_callback_setup": false,
  "email_headers": [],
  "connection_failed_at": null,
  "created_at": "2024-01-01T12:00:00Z",
  "updated_at": "2024-01-01T12:00:00Z"
}

Update Email Server

PATCH /api/v1/email_servers/:id

Update an existing email server configuration.

Request

curl -X PATCH \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "email_server": {
      "label": "Updated Server Name",
      "emails_per_hour": 2000
    }
  }' \
  https://your-domain.com/api/v1/email_servers/1

Response

{
  "id": 1,
  "label": "Updated Server Name",
  "vendor": "aws_ses",
  "delivery_method": "smtp",
  "active": true,
  "emails_per_hour": 2000,
  "use_for_broadcasts": true,
  "use_for_sequences": true,
  "use_for_transactionals": false,
  "include_unsubscribe_header": true,
  "include_unsubscribe_link": true,
  "use_custom_unsubscribe_link": false,
  "custom_unsubscribe_link": null,
  "smtp_address": "email-smtp.us-east-1.amazonaws.com",
  "smtp_port": 587,
  "smtp_username": "AKIAIOSFODNN7EXAMPLE",
  "smtp_password": "••••••••",
  "smtp_authentication": "plain",
  "smtp_enable_starttls_auto": true,
  "aws_region": "us-east-1",
  "aws_ses_configuration_set": null,
  "aws_access_key_id": null,
  "aws_secret_access_key": null,
  "outbound_aws_access_key_id": null,
  "outbound_aws_secret_access_key": null,
  "aws_setup_completed": false,
  "postmark_api_token": null,
  "postmark_unsubscribe_handling": null,
  "postmark_unsubscribe_handling_checked_at": null,
  "postmark_unsubscribe_handling_error": null,
  "postmark_subscription_sync": true,
  "inboxroad_api_token": null,
  "inboxroad_sync_enabled": false,
  "smtp_com_api_key": null,
  "smtp_com_channel": null,
  "smtp_com_callback_setup": false,
  "email_headers": [],
  "connection_failed_at": null,
  "created_at": "2024-01-01T12:00:00Z",
  "updated_at": "2024-01-01T13:00:00Z"
}

Postmark unsubscribe handling

Postmark adds its own unsubscribe link to a broadcast when the server’s broadcast message stream has Postmark unsubscribe handling. Broadcast checks the stream when you connect the server and when you click Check now on the email server page. If the stream has Postmark handling, Broadcast asks Postmark to switch it to Custom. Postmark allows Custom only for accounts it approved. The three postmark_unsubscribe_handling fields show the result. They are read-only: a value you send is ignored with a parameter_ignored warning.

postmark_subscription_sync keeps the two unsubscribe lists in agreement while Postmark handling is in effect. Set it like any other field:

curl -X PATCH \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "email_server": { "postmark_subscription_sync": false } }' \
  https://your-domain.com/api/v1/email_servers/1
  • A value that is not true or false returns 422 Unprocessable Entity and changes nothing.
  • If Broadcast set up the server’s Postmark webhooks (the server was connected with a Postmark account token), a change also turns Postmark’s SubscriptionChange webhook on or off, as the switch on the email server page does. If Postmark refuses, the change is still saved and the response has a provider_setup_failed warning with Postmark’s error.

Delete Email Server

DELETE /api/v1/email_servers/:id

Delete an email server configuration.

Request

curl -X DELETE \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  https://your-domain.com/api/v1/email_servers/1

Response

{
  "message": "Email server deleted successfully"
}

Test Connection

POST /api/v1/email_servers/:id/test_connection

Test the SMTP connection for an email server. This will attempt to connect to the SMTP server and verify credentials. If successful, the server will be marked as active. If it fails, the server will be marked as inactive with a connection_failed_at timestamp.

Request

curl -X POST \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  https://your-domain.com/api/v1/email_servers/1/test_connection

Success Response

{
  "success": true,
  "message": "Connection successful"
}

Failure Response (422 Unprocessable Entity)

{
  "success": false,
  "message": "Connection failed"
}

Copy to Channel

POST /api/v1/email_servers/:id/copy_to_channel

Copies an email server’s full configuration into another channel, creating a new server there. Useful when you run several channels through the same provider and do not want to re-enter credentials for each one.

Warning

This endpoint requires an admin API token. A channel token is scoped to a single channel and cannot write to another one, so it gets 403 Forbidden with Admin API token required for cross-channel operations. See API Authentication.

Parameters

Parameter Required Description
target_channel_id Yes The channel to copy the server into
broadcast_channel_id Yes The channel that owns the source server, as with every admin-token request

Request

curl -X POST \
  -H "Authorization: Bearer YOUR_ADMIN_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"target_channel_id": 4}' \
  "https://your-broadcast-domain.com/api/v1/email_servers/1/copy_to_channel?broadcast_channel_id=3"

Response

Returns 201 Created with the newly created email server, which has its own id and belongs to the target channel. The source server is left untouched.

Errors

Status Condition
403 Forbidden Called with a channel token rather than an admin token
404 Not Found target_channel_id does not match a channel you can reach
422 Unprocessable Entity The target channel is the same as the source channel, or the copy failed validation

Error Responses

401 Unauthorized

{
  "error": "Unauthorized"
}

Returned when the API token is missing, invalid, or lacks the required permissions.

404 Not Found

{
  "error": "Email server not found"
}

Returned when the specified email server doesn’t exist or belongs to a different channel.

422 Unprocessable Entity

{
  "error": "Label can't be blank, At least one use case (broadcasts, sequences, or transactionals) must be selected"
}

Returned when validation fails. Common validation errors include: - Missing required fields (label, SMTP credentials for SMTP delivery) - No use case selected - Invalid emails_per_hour (must be at least 15) - Missing API credentials when using API delivery method

Example: Complete Setup Flow

Here’s an example of setting up an email server and testing it:

# 1. Create the email server
curl -X POST \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "email_server": {
      "label": "SendGrid Production",
      "vendor": "sendgrid",
      "smtp_address": "smtp.sendgrid.net",
      "smtp_port": 587,
      "smtp_username": "apikey",
      "smtp_password": "SG.xxxxxxxxxxxxxxxxxxxx",
      "smtp_authentication": "plain",
      "emails_per_hour": 5000,
      "use_for_broadcasts": true,
      "use_for_sequences": true,
      "use_for_transactionals": true
    }
  }' \
  https://your-domain.com/api/v1/email_servers

# Response: { "id": 5, ... }

# 2. Test the connection
curl -X POST \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  https://your-domain.com/api/v1/email_servers/5/test_connection

# Response: { "success": true, "message": "Connection successful" }

# 3. Verify the server is active
curl -X GET \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  https://your-domain.com/api/v1/email_servers/5

# Response shows active: true and connection_failed_at: null

Last updated

Was this page helpful?

Thanks for your feedback!

Thanks for letting us know. We'll work on improving this page.