# Email Servers API

> Manage SMTP and ESP email server configurations with the Broadcast API: list, create, update, and rotate sending servers directly from your application code.

Source: https://sendbroadcast.net/docs/api-email-servers

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) and test connection
- **Write Permission**: Required for POST, PATCH, DELETE endpoints

## 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 (redacted in responses) |
| `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) |
| `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 |
| `sendgrid_api_key` | SendGrid API key for API delivery (redacted) |
| `mailgun_api_key` | Mailgun API key for API delivery (redacted) |
| `mailgun_domain` | Mailgun sending domain |
| `mailgun_region` | Mailgun region (us or eu, default: us) |
| `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`
- `smtp_username`
- `aws_secret_access_key`
- `outbound_aws_secret_access_key`
- `aws_access_key_id`
- `outbound_aws_access_key_id`
- `postmark_api_token`
- `sendgrid_api_key`
- `mailgun_api_key`
- `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 |
| Mailgun | `mailgun` | SMTP, API |
| 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
- `offset` (optional): Number of email servers to skip for pagination

### Request

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

### Response

```json
{
  "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": "AKIA••••••••••••XXXX",
      "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,
      "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

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

### Response

```json
{
  "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": "AKIA••••••••••••XXXX",
  "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,
  "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: other)
- `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:

```json
{
  "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`:

```json
{
  "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

**SendGrid:**
- `sendgrid_api_key`: Required for API delivery method

**Mailgun:**
- `mailgun_api_key`: Required for API delivery method
- `mailgun_domain`: Required for API delivery method (your verified sending domain)
- `mailgun_region`: Region for API endpoint (`us` or `eu`, default: `us`)

**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)

```bash
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)

```bash
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

```json
{
  "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": "AKIA••••••••••••MPLE",
  "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,
  "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

```bash
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

```json
{
  "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": "AKIA••••••••••••XXXX",
  "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,
  "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"
}
```

## Delete Email Server

```
DELETE /api/v1/email_servers/:id
```

Delete an email server configuration.

### Request

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

### Response

```json
{
  "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

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

### Success Response

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

### Failure Response (422 Unprocessable Entity)

```json
{
  "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](https://sendbroadcast.net/docs/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

```bash
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

```json
{
  "error": "Unauthorized"
}
```

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

### 404 Not Found

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

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

### 422 Unprocessable Entity

```json
{
  "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:

```bash
# 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
```
