> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sendpost.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Amazon SES Compatible API

> Migrate from Amazon SES with minimal code changes using SendPost's Amazon SES Compatible API.

If you're currently using Amazon SES and want to migrate to SendPost, we offer **Amazon SES Compatible APIs** (v1 and v2) that minimize code changes. You only need to change the endpoint URL and replace AWS Signature authentication with a simple API key header.

***

## Quick Migration Steps

<Steps>
  <Step title="Change the endpoint URL">
    <Tabs>
      <Tab title="SES v1">
        * From: `https://email.{region}.amazonaws.com/`
        * To: `https://api.sendpost.io/api/v1/subaccount/email/ses/v1`
      </Tab>

      <Tab title="SES v2">
        * From: `https://email.{region}.amazonaws.com/v2/email/outbound-emails`
        * To: `https://api.sendpost.io/api/v1/subaccount/email/ses/v2`
      </Tab>
    </Tabs>
  </Step>

  <Step title="Update authentication">
    * From: AWS Signature Version 4 (complex signing with access/secret keys)
    * To: `X-SubAccount-ApiKey: YOUR_SENDPOST_API_KEY` header
  </Step>

  <Step title="Keep your request body">
    Use the exact same SES v1 or v2 JSON request format - no changes needed!
  </Step>

  <Step title="Optional: Add SendPostOptions">
    Optionally add `SendPostOptions` to leverage SendPost-specific features like IP Pool routing
  </Step>
</Steps>

***

## SES v1 Migration Example

<Tabs>
  <Tab title="Before (Amazon SES v1)">
    ```bash theme={null}
    curl -X POST "https://email.us-east-1.amazonaws.com/" \
      -H "Authorization: AWS4-HMAC-SHA256 Credential=..." \
      -H "Content-Type: application/x-amz-json-1.0" \
      -d '{
        "Source": "sender@example.com",
        "Destination": {
          "ToAddresses": ["recipient@example.com"]
        },
        "Message": {
          "Subject": {
            "Data": "Hello World",
            "Charset": "UTF-8"
          },
          "Body": {
            "Text": {
              "Data": "Hello!",
              "Charset": "UTF-8"
            },
            "Html": {
              "Data": "<p>Hello!</p>",
              "Charset": "UTF-8"
            }
          }
        }
      }'
    ```
  </Tab>

  <Tab title="After (SendPost SES v1)">
    ```bash theme={null}
    curl -X POST "https://api.sendpost.io/api/v1/subaccount/email/ses/v1" \
      -H "X-SubAccount-ApiKey: YOUR_SENDPOST_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "Source": "sender@example.com",
        "Destination": {
          "ToAddresses": ["recipient@example.com"]
        },
        "Message": {
          "Subject": {
            "Data": "Hello World",
            "Charset": "UTF-8"
          },
          "Body": {
            "Text": {
              "Data": "Hello!",
              "Charset": "UTF-8"
            },
            "Html": {
              "Data": "<p>Hello!</p>",
              "Charset": "UTF-8"
            }
          }
        },
        "SendPostOptions": {
          "IPPool": "ses-pool"
        }
      }'
    ```
  </Tab>
</Tabs>

***

## SES v2 Migration Example

<Tabs>
  <Tab title="Before (Amazon SES v2)">
    ```bash theme={null}
    curl -X POST "https://email.us-east-1.amazonaws.com/v2/email/outbound-emails" \
      -H "Authorization: AWS4-HMAC-SHA256 Credential=..." \
      -H "Content-Type: application/x-amz-json-1.0" \
      -d '{
        "FromEmailAddress": "sender@example.com",
        "Destination": {
          "ToAddresses": ["recipient@example.com"]
        },
        "Content": {
          "Simple": {
            "Subject": {
              "Data": "Hello World",
              "Charset": "UTF-8"
            },
            "Body": {
              "Text": {
                "Data": "Hello!",
                "Charset": "UTF-8"
              },
              "Html": {
                "Data": "<p>Hello!</p>",
                "Charset": "UTF-8"
              }
            }
          }
        }
      }'
    ```
  </Tab>

  <Tab title="After (SendPost SES v2)">
    ```bash theme={null}
    curl -X POST "https://api.sendpost.io/api/v1/subaccount/email/ses/v2" \
      -H "X-SubAccount-ApiKey: YOUR_SENDPOST_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "FromEmailAddress": "sender@example.com",
        "Destination": {
          "ToAddresses": ["recipient@example.com"]
        },
        "Content": {
          "Simple": {
            "Subject": {
              "Data": "Hello World",
              "Charset": "UTF-8"
            },
            "Body": {
              "Text": {
                "Data": "Hello!",
                "Charset": "UTF-8"
              },
              "Html": {
                "Data": "<p>Hello!</p>",
                "Charset": "UTF-8"
              }
            }
          }
        },
        "SendPostOptions": {
          "IPPool": "ses-pool"
        }
      }'
    ```
  </Tab>
</Tabs>

***

## Field Mappings

### SES v1 → SendPost

| SES v1 Field                      | SendPost Field            | Notes                           |
| --------------------------------- | ------------------------- | ------------------------------- |
| `Source`                          | `From.Email`, `From.Name` | Supports "Name \<email>" format |
| `Destination.ToAddresses[]`       | `To[].Email`              | Direct mapping                  |
| `Destination.CcAddresses[]`       | `To[].Cc[]`               | Direct mapping                  |
| `Destination.BccAddresses[]`      | `To[].Bcc[]`              | Direct mapping                  |
| `Message.Subject.Data`            | `Subject`                 | Direct mapping                  |
| `Message.Body.Text.Data`          | `TextBody`                | Direct mapping                  |
| `Message.Body.Html.Data`          | `HtmlBody`                | Direct mapping                  |
| `ReplyToAddresses[]`              | `ReplyTo.Email`           | First address only              |
| `Tags[]`                          | `Groups[]`                | Formatted as "Name:Value"       |
| `SendPostOptions.IPPool`          | `IPPool`                  | **SendPost extension**          |
| `SendPostOptions.TrackOpens`      | `TrackOpens`              | **SendPost extension**          |
| `SendPostOptions.TrackClicks`     | `TrackClicks`             | **SendPost extension**          |
| `SendPostOptions.WebhookEndpoint` | `WebhookEndpoint`         | **SendPost extension**          |

### SES v2 → SendPost

| SES v2 Field                      | SendPost Field            | Notes                                |
| --------------------------------- | ------------------------- | ------------------------------------ |
| `FromEmailAddress`                | `From.Email`, `From.Name` | Supports "Name \<email>" format      |
| `Destination.ToAddresses[]`       | `To[].Email`              | Direct mapping                       |
| `Destination.CcAddresses[]`       | `To[].Cc[]`               | Direct mapping                       |
| `Destination.BccAddresses[]`      | `To[].Bcc[]`              | Direct mapping                       |
| `Content.Simple.Subject.Data`     | `Subject`                 | Only `Simple` content type supported |
| `Content.Simple.Body.Text.Data`   | `TextBody`                | Direct mapping                       |
| `Content.Simple.Body.Html.Data`   | `HtmlBody`                | Direct mapping                       |
| `ReplyToAddresses[]`              | `ReplyTo.Email`           | First address only                   |
| `EmailTags[]`                     | `Groups[]`                | Formatted as "Name:Value"            |
| `SendPostOptions.IPPool`          | `IPPool`                  | **SendPost extension**               |
| `SendPostOptions.TrackOpens`      | `TrackOpens`              | **SendPost extension**               |
| `SendPostOptions.TrackClicks`     | `TrackClicks`             | **SendPost extension**               |
| `SendPostOptions.WebhookEndpoint` | `WebhookEndpoint`         | **SendPost extension**               |

***

## SendPostOptions Extension

SendPost offers optional extensions through the `SendPostOptions` field that are not available in the standard SES API:

```json theme={null}
{
  "SendPostOptions": {
    "IPPool": "ses-pool",              // IP pool name for routing
    "TrackOpens": true,                 // Enable open tracking
    "TrackClicks": true,                // Enable click tracking
    "WebhookEndpoint": "https://..."    // Webhook URL for events
  }
}
```

<Info>
  **Tracking Explained**: Open and click events are tracked via Amazon SES's configuration set ("sendpost-events") and delivered to SendPost through SNS notifications. The `TrackOpens` and `TrackClicks` options in `SendPostOptions` control SendPost's tracking pixels, which provide additional tracking when emails are processed by SendPost before being sent to SES. Both tracking methods work independently.
</Info>

***

## Supported SES Features

| Feature                                          | SES v1 | SES v2 | Notes                            |
| ------------------------------------------------ | ------ | ------ | -------------------------------- |
| `Source` / `FromEmailAddress`                    | ✅      | ✅      | Supports "Name \<email>" format  |
| `Destination.ToAddresses`                        | ✅      | ✅      | Direct mapping                   |
| `Destination.CcAddresses`                        | ✅      | ✅      | Direct mapping                   |
| `Destination.BccAddresses`                       | ✅      | ✅      | Direct mapping                   |
| `Message.Subject` / `Content.Simple.Subject`     | ✅      | ✅      | Direct mapping                   |
| `Message.Body.Text` / `Content.Simple.Body.Text` | ✅      | ✅      | Direct mapping                   |
| `Message.Body.Html` / `Content.Simple.Body.Html` | ✅      | ✅      | Direct mapping                   |
| `ReplyToAddresses`                               | ✅      | ✅      | First address only               |
| `Tags` / `EmailTags`                             | ✅      | ✅      | Mapped to Groups as "Name:Value" |
| `SendPostOptions`                                | ✅      | ✅      | **SendPost extension**           |

***

## Unsupported SES Features

<Warning>
  The following SES features are **not supported** and will return a `ValidationException` error if present:
</Warning>

| Feature                                         | Alternative                                                    |
| ----------------------------------------------- | -------------------------------------------------------------- |
| `RawMessage` (v1)                               | Use `Message` with `Subject` and `Body` instead                |
| `Content.Raw` (v2)                              | Use `Content.Simple` instead                                   |
| `Template`, `TemplateData`, `TemplateArn` (v1)  | Use SendPost's native template API or include content directly |
| `Content.Template` (v2)                         | Use SendPost's native template API or include content directly |
| `SourceArn`, `ReturnPath`, `ReturnPathArn` (v1) | Handled automatically by SendPost                              |
| `FromEmailAddressIdentityArn` (v2)              | Not needed with SendPost                                       |
| `FeedbackForwardingEmailAddress` (v2)           | Handled automatically by SendPost                              |
| `ListManagementOptions` (v2)                    | Use SendPost's `{{unsubscribe}}` template variable             |

**Error Response for Unsupported Fields**:

```json theme={null}
{
  "__type": "ValidationException",
  "message": "Field 'RawMessage' is not supported. Please use Message with Subject and Body instead."
}
```

***

## Response Format

### Success Response (HTTP 200)

```json theme={null}
{
  "MessageId": "550e8400-e29b-41d4-a716-446655440000"
}
```

### Error Response (HTTP 400/403/413/429/500)

```json theme={null}
{
  "__type": "ValidationException",
  "message": "1 validation error detected: Value at 'Source' failed to satisfy constraint: Member must satisfy regular expression pattern: [\\u0020-\\u007E]+"
}
```

### Error Types

| Error Type                           | HTTP Status | Description                                       |
| ------------------------------------ | ----------- | ------------------------------------------------- |
| `ValidationException`                | 400         | Invalid request format or missing required fields |
| `AccessDeniedException`              | 403         | Invalid or missing API key                        |
| `MessageRejected`                    | 400         | Email rejected (e.g., domain not verified)        |
| `MailFromDomainNotVerifiedException` | 400         | Domain not verified in SendPost                   |
| `MessageTooLarge`                    | 413         | Payload exceeds 10MB limit                        |
| `TooManyRequestsException`           | 429         | Rate limit exceeded                               |
| `ServiceException`                   | 500         | Internal server error                             |

***

## Key Differences: SES v1 vs v2

| Feature       | SES v1            | SES v2                                        |
| ------------- | ----------------- | --------------------------------------------- |
| Source field  | `Source`          | `FromEmailAddress`                            |
| Subject       | `Message.Subject` | `Content.Simple.Subject`                      |
| Body          | `Message.Body`    | `Content.Simple.Body`                         |
| Tags          | `Tags[]`          | `EmailTags[]`                                 |
| Content types | Simple only       | Simple, Raw, Template (only Simple supported) |

***

## IP Pool Routing

When using the Amazon SES Compatible API, you can specify an IP Pool through `SendPostOptions.IPPool`. This IP Pool must be configured in SendPost to route traffic to your Amazon SES provider.

<Note>
  **Important**: The IP Pool specified in `SendPostOptions.IPPool` must exist in SendPost and be configured to route to your Amazon SES provider. If not specified, the default IP Pool will be used.
</Note>

***

## Next Steps

* [Understand event types](/guides/amazon-ses/event-types) for tracking email status
* [View analytics](/guides/amazon-ses/analytics) for your Amazon SES emails
* [Troubleshoot issues](/guides/amazon-ses/troubleshooting) with the compatible API
