

# Set up email sending with Amazon SES
<a name="send-email"></a>

You can send an email with Amazon Simple Email Service (Amazon SES) using the Amazon SES console, the Amazon SES Simple Mail Transfer Protocol (SMTP) interface, or the Amazon SES API. You typically use the console to send test emails and manage your sending activity. To send bulk emails, you use either the SMTP interface or the API. For information about Amazon SES email pricing, see [Amazon SES Pricing](https://aws.amazon.com/ses/pricing).
+ If you want to use an SMTP-enabled software package, application, or programming language to send email through Amazon SES, or integrate Amazon SES with your existing mail server, use the Amazon SES SMTP interface. For more information, see [Sending emails programmatically through the Amazon SES SMTP interface](send-using-smtp-programmatically.md).
+ If you want to call Amazon SES by using raw HTTP requests, use the Amazon SES API. For more information, see [Using the Amazon SES API to send email](send-email-api.md).

**Important**  
When you send an email to multiple recipients (recipients are "To", "CC", and "BCC" addresses) and the call to Amazon SES fails, the entire email is rejected and none of the recipients will receive the intended email. Therefore, we recommend that you send an email to one recipient at a time.

# Using the Amazon SES SMTP interface to send email
<a name="send-email-smtp"></a>

To send production email through Amazon SES, you can use the Simple Mail Transfer Protocol (SMTP) interface or the Amazon SES API. For more information about the Amazon SES API, see [Using the Amazon SES API to send email](send-email-api.md). This section describes the SMTP interface.

Amazon SES sends email using SMTP, which is the most common email protocol on the internet. You can send email through Amazon SES by using a variety of SMTP-enabled programming languages and software to connect to the Amazon SES SMTP interface. This section explains how to get your Amazon SES SMTP credentials, how to send email by using the SMTP interface, and how to configure several pieces of software and mail servers to use Amazon SES for email sending.

For solutions to common problems that you might encounter when you use Amazon SES through its SMTP interface, see [Amazon SES SMTP issues](troubleshoot-smtp.md). 

## Requirements to send email over SMTP
<a name="send-email-smtp-requirements"></a>

To send email using the Amazon SES SMTP interface, you need the following:
+ The SMTP endpoint address. For a list of Amazon SES SMTP endpoints, see [Connecting to an Amazon SES SMTP endpoint](smtp-connect.md).
+ The SMTP interface port number. The port number varies with the connection method. For more information, see [Connecting to an Amazon SES SMTP endpoint](smtp-connect.md).
+ An SMTP user name and password. SMTP credentials are unique to each AWS Region. If you plan to use the SMTP interface to send email in multiple AWS Regions, you need SMTP credentials for each Region.
**Important**  
Your SMTP credentials aren't identical to your AWS access keys or the credentials that you use to sign in to the Amazon SES console. For information about how to generate your SMTP credentials, see [Obtaining Amazon SES SMTP credentials](smtp-credentials.md).
+ Client software that can communicate using Transport Layer Security (TLS). For more information, see [Connecting to an Amazon SES SMTP endpoint](smtp-connect.md).
+ An email address that you've verified with Amazon SES. For more information, see [Verified identities in Amazon SES](verify-addresses-and-domains.md).
+ Increased sending quotas, if you want to send large quantities of email. For more information, see [Managing your Amazon SES sending limits](manage-sending-quotas.md).

## Methods to send email over SMTP
<a name="send-email-methods"></a>

You can send email over SMTP through any of the following methods:
+ To configure SMTP-enabled software to send email through the Amazon SES SMTP interface, see [Sending email through Amazon SES using software packages](send-email-smtp-software-package.md).
+ To program an application to send email through Amazon SES, see [Sending emails programmatically through the Amazon SES SMTP interface](send-using-smtp-programmatically.md).
+ To configure your existing email server to send all of your outgoing mail through Amazon SES, see [Integrating Amazon SES with your existing email server](send-email-smtp-existing-server.md).
+ To interact with the Amazon SES SMTP interface using the command line, which can be useful for testing, see [Testing your connection to the Amazon SES SMTP interface using the command line](send-email-smtp-client-command-line.md).

For a list of SMTP response codes, see [SMTP response codes returned by Amazon SES](troubleshoot-smtp.md#troubleshoot-smtp-response-codes).

## Email information to provide
<a name="smtp-parameters"></a>

When you access Amazon SES through the SMTP interface, your SMTP client application assembles the message, so the information you need to provide depends on the application that you're using. At a minimum, the SMTP exchange between a client and a server requires the following: 
+ a source address
+ a destination address
+ message data

If you're using the SMTP interface and have feedback forwarding enabled, then your bounces, complaints, and delivery notifications are sent to the "MAIL FROM" address. Any "Reply-To" address that you specify isn't used.



# Obtaining Amazon SES SMTP credentials
<a name="smtp-credentials"></a>

You need Amazon SES SMTP credentials to access the SES SMTP interface.

The credentials that you use to send email through the SES SMTP interface are unique to each AWS Region. If you use the SES SMTP interface to send email in more than one Region, you must generate a set of SMTP credentials for each Region that you plan to use.

Your SMTP password is different from your AWS secret access key. For more information about credentials, see [Types of Amazon SES credentials](send-email-concepts-credentials.md).

**Note**  
For a list of currently available SMTP endpoints, see [SMTP endpoints](https://docs.aws.amazon.com/general/latest/gr/ses.html#ses_smtp_endpoints) in the *AWS General Reference*. 

## Obtaining SES SMTP credentials using the SES console
<a name="smtp-credentials-console"></a>

**Requirement**  
An IAM user can create SES SMTP credentials, but the user's policy must give them permission to use IAM itself, because SES SMTP credentials are created by using IAM. Your IAM policy must allow you to perform the following IAM actions: `iam:CreateUser`, `iam:CreateGroup`, `iam:PutGroupPolicy`, `iam:AddUserToGroup`, and `iam:CreateAccessKey`. If you try to create SES SMTP credentials using the console and your IAM user doesn't have these permissions, you may see an error or the SMTP credentials may be created without the proper policy settings.

**Important**  
Some of the IAM actions referenced above, specifically `iam:PutGroupPolicy` and `iam:AddUserToGroup`, have the [Permission management](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_understand-policy-summary-access-level-summaries.html#access_policies_access-level) access level which is the highest IAM level because it gives permission to grant or modify resource permissions in the service. Therefore, to improve the security of your AWS account, it is highly recommended that you restrict or regularly monitor these policies that include the Permissions management access level classification.

**To create your SMTP credentials**

1. Sign in to the AWS Management Console and open the Amazon SES console at [https://console.aws.amazon.com/ses/](https://console.aws.amazon.com/ses/).

1. Choose **SMTP settings** in the left navigation pane - this will open the **Simple Mail Transfer Protocol (SMTP) settings** page.

1. Choose **Create SMTP Credentials** in the upper-right corner - the IAM console will open.

1. (Optional) If you need to view, edit, or delete SMTP users you’ve already created, choose **Manage my existing SMTP credentials** in the lower-right corner - the IAM console will open. Details for managing SMTP credentials is given following these procedures.

1. For **Create User for SMTP**, type a name for your SMTP user in the **User Name** field. Alternatively, you can use the default value that is provided in this field. When you finish, choose **Create user** in the bottom-right corner.

1. Select **Show** under *SMTP password* - your SMTP credentials are shown on the screen.

1. Download these credentials by choosing **Download .csv file** or copy them and store them in a safe place, because you can't view or save your credentials after you close this dialog box.

1. Choose **Return to SES console**.

You can view a list of the SMTP credentials you've created using this procedure in the IAM console under **Access management** and choosing **Users** followed by using the search bar to find all users that you've assigned SMTP credentials.

You can also use the IAM console to delete existing SMTP users. To learn more about deleting users, see [Managing IAM Users](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_manage.html) in the *IAM Getting Started Guide*.

If you want to change your SMTP password, delete your existing SMTP user in the IAM console. Then, to generate a new set of SMTP credentials, complete the previous procedures.

## Obtaining SES SMTP credentials by converting existing AWS credentials
<a name="smtp-credentials-convert"></a>

If you have a user that you set up using the IAM interface, you can derive the user's SES SMTP credentials from their AWS credentials.

**Important**  
Don't use temporary AWS credentials to derive SMTP credentials. The SES SMTP interface doesn't support SMTP credentials that have been generated from temporary security credentials. 

**To enable the IAM user to send email using the SES SMTP interface**

1. Derive the user's SMTP credentials from their AWS credentials by using the algorithm provided in this section following these procedures.

   Because you're starting from AWS credentials, the SMTP user name is the same as the AWS access key ID, so you only need to generate the SMTP password.

1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/).

1. Under **Access management**, choose **Polices** followed by **Create policy**.

1. In the **Policy editor**, select **JSON** and remove any example code in the editor.

1. Paste to the following permissions policy into the editor:

------
#### [ JSON ]

****  

   ```
   {
   "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
   "Effect": "Allow",
               "Action": "ses:SendRawEmail",
               "Resource": "*"
           }
       ]
   }
   ```

------

1. Select **Next** and enter `AmazonSesSendingAccess` in the **Policy name** field followed by **Create policy**.

1. Under **Access management**, choose **User groups** followed by **Create group**.

1. Enter `AWSSESSendingGroupDoNotRename` in the **User group name** field.

1. Add SMTP users to the group by selecting them from the **Add users to the group** table.

1. Attach the `AmazonSesSendingAccess` policy created previously by selecting it from the **Attach permissions policies** table followed by **Create user group**.

For more information about using SES with IAM, see [Identity and access management in Amazon SES](control-user-access.md).

**Note**  
Although you can generate SES SMTP credentials for any IAM user, we recommend that you create a separate IAM user when you generate your SMTP credentials. For information about why it's good practice to create users for specific purposes, go to [IAM Best Practices](https://docs.aws.amazon.com/IAM/latest/UserGuide/IAMBestPractices.html).

The following pseudocode shows the algorithm that converts an AWS secret access key to an SES SMTP password.

```
 1. // Modify this variable to include your AWS secret access key
 2. key = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY";
 3.             
 4. // Modify this variable to refer to the AWS Region that you want to use to send email.
 5. region = "us-west-2";
 6.             
 7. // The values of the following variables should always stay the same.
 8. date = "11111111";
 9. service = "ses";
10. terminal = "aws4_request";
11. message = "SendRawEmail";
12. version = 0x04;
13. 
14. kDate = HmacSha256(date, "AWS4" + key);
15. kRegion = HmacSha256(region, kDate);
16. kService = HmacSha256(service, kRegion);
17. kTerminal = HmacSha256(terminal, kService);
18. kMessage = HmacSha256(message, kTerminal);
19. signatureAndVersion = Concatenate(version, kMessage);
20. smtpPassword = Base64(signatureAndVersion);
```

Some programming languages include libraries that you can use to convert an IAM secret access key into an SMTP password. This section includes a code example that you can use to convert an AWS secret access key to an SES SMTP password using Python.

**Note**  
The following example uses **f-strings** that were introduced in Python 3.6; if using an older version, they won't work.
In the following example, the list of SMTP\$1REGIONS is simply an example—your actual list of regions could be shorter or longer depending on which regions you plan to send email in as you'll need SMTP credentials for each AWS Region.

------
#### [ Python ]

```
#!/usr/bin/env python3

import hmac
import hashlib
import base64
import argparse

SMTP_REGIONS = [
    "us-east-2",  # US East (Ohio)
    "us-east-1",  # US East (N. Virginia)
    "us-west-2",  # US West (Oregon)
    "ap-south-1",  # Asia Pacific (Mumbai)
    "ap-northeast-2",  # Asia Pacific (Seoul)
    "ap-southeast-1",  # Asia Pacific (Singapore)
    "ap-southeast-2",  # Asia Pacific (Sydney)
    "ap-northeast-1",  # Asia Pacific (Tokyo)
    "ca-central-1",  # Canada (Central)
    "eu-central-1",  # Europe (Frankfurt)
    "eu-west-1",  # Europe (Ireland)
    "eu-west-2",  # Europe (London)
    "eu-south-1",  # Europe (Milan)
    "eu-north-1",  # Europe (Stockholm)
    "sa-east-1",  # South America (Sao Paulo)
    "us-gov-west-1",  # AWS GovCloud (US)
    "us-gov-east-1",  # AWS GovCloud (US)
]

# These values are required to calculate the signature. Do not change them.
DATE = "11111111"
SERVICE = "ses"
MESSAGE = "SendRawEmail"
TERMINAL = "aws4_request"
VERSION = 0x04


def sign(key, msg):
    return hmac.new(key, msg.encode("utf-8"), hashlib.sha256).digest()


def calculate_key(secret_access_key, region):
    if region not in SMTP_REGIONS:
        raise ValueError(f"The {region} Region doesn't have an SMTP endpoint.")

    signature = sign(("AWS4" + secret_access_key).encode("utf-8"), DATE)
    signature = sign(signature, region)
    signature = sign(signature, SERVICE)
    signature = sign(signature, TERMINAL)
    signature = sign(signature, MESSAGE)
    signature_and_version = bytes([VERSION]) + signature
    smtp_password = base64.b64encode(signature_and_version)
    return smtp_password.decode("utf-8")


def main():
    parser = argparse.ArgumentParser(
        description="Convert a Secret Access Key to an SMTP password."
    )
    parser.add_argument("secret", help="The Secret Access Key to convert.")
    parser.add_argument(
        "region",
        help="The AWS Region where the SMTP password will be used.",
        choices=SMTP_REGIONS,
    )
    args = parser.parse_args()
    print(calculate_key(args.secret, args.region))


if __name__ == "__main__":
    main()
```

To obtain your SMTP password by using this script, save the preceding code as `smtp_credentials_generate.py`. Then, at the command line, run the following command:

```
python path/to/smtp_credentials_generate.py wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY us-east-1
```

In the preceding command, do the following:
+ Replace *path/to/* with the path to the location where you saved `smtp_credentials_generate.py`.
+ Replace *wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY* with the secret access key that you want to convert into an SMTP password.
+ Replace *us-east-1* with the AWS Region in which you want to use the SMTP credentials.

When this script runs successfully, the only output is your SMTP password.

------

## Migrating a SMTP user from an existing inline policy to a group policy (security recommendation)
<a name="migrate-inline-policy-to-group"></a>

**Important**  
If you created SES SMTP credentials before September 6, 2024, an inline policy and a tag have been attached to your SMTP user. SES is moving away from inline policies and encourages you to do the same as a security recommendation.

Before migrating a SMTP user off of an existing inline policy to a group policy, you must first create an IAM user group with the SES permissions policy to take the place of the inline policy. If you've already created this IAM user group, or it was automatically created for SMTP credentials you created from September 6, 2024 onward, you can skip directly to *step 10* in the following procedures.

**To migrate from an existing inline policy to a managed group**

1. Sign in to the AWS Management Console and open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/).

1. Under **Access management**, choose **Polices** followed by **Create policy**.

1. In the **Policy editor**, select **JSON** and remove any example code in the editor.

1. Paste to the following permissions policy into the editor:

------
#### [ JSON ]

****  

   ```
   {
   "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
   "Effect": "Allow",
               "Action": "ses:SendRawEmail",
               "Resource": "*"
           }
       ]
   }
   ```

------

1. Select **Next** and enter `AmazonSesSendingAccess` in the **Policy name** field followed by **Create policy**.

1. Under **Access management**, choose **User groups** followed by **Create group**.

1. Enter `AWSSESSendingGroupDoNotRename` in the **User group name** field.

1. Add SMTP users to the group by selecting them from the **Add users to the group** table.

1. Attach the `AmazonSesSendingAccess` policy created previously by selecting it from the **Attach permissions policies** table followed by **Create user group**.

   Now that you've created the IAM user group with the SES permissions policy, you can migrate a SMTP user from their current inline policy to this group policy as explained in the remaining steps.

1. Under **Access management**, choose **Users** followed by selecting the SMTP user you want to migrate.

1. Select the **Groups** tab and choose **Add user to groups**.

1. Select the `AWSSESSendingGroupDoNotRename` group followed by **Add user to group(s)**.

1. Select the **Permissions** tab and confirm that there are two rows listed with `AmazonSesSendingAccess` the in the **Policy name** column, one with *Inline* and one with *Group `AWSSESSendingGroupDoNotRename`* listed in the **Attached via** column.

1. Select only the row that contains `AmazonSesSendingAccess` in the **Policy name** column and *Inline* in the **Attached via** column followed by **Remove** and confirm with **Remove policy**.

   Verify the row with *Group `AWSSESSendingGroupDoNotRename`* in the **Attached via** column remains.

1. Select the **Tags** tab followed by **Manage tags**.

1. Select **Remove** next to the row that contains *InvokedBy* in the **Key** column and *SESConsole* in the **Value** column followed by **Save changes**.

**Important**  
The `AmazonSesSendingAccess` policy (either as an inline or group policy or both) must remain attached to the SMTP user to make sure their sending is not impacted. Only remove the inline policy after the group policy is attached to your user. 

# Connecting to an Amazon SES SMTP endpoint
<a name="smtp-connect"></a>

To send email using the Amazon SES SMTP interface, you connect to an SMTP endpoint. For a complete list of Amazon SES SMTP endpoints, see [Amazon Simple Email Service endpoints and quotas](https://docs.aws.amazon.com/general/latest/gr/ses.html) in the *AWS General Reference*.

The Amazon SES SMTP endpoint requires that all connections be encrypted using Transport Layer Security (TLS). (Note that TLS is often referred to by the name of its predecessor protocol, SSL.) Amazon SES supports two mechanisms for establishing a TLS-encrypted connection: STARTTLS and TLS Wrapper. Check the documentation for your software to determine whether it supports STARTTLS, TLS Wrapper, or both.

Amazon Elastic Compute Cloud (Amazon EC2) throttles email traffic over port 25 by default. To avoid timeouts when sending email through the SMTP endpoint from EC2, submit a [Request to Remove Email Sending Limitations](https://aws-portal.amazon.com/gp/aws/html-forms-controller/contactus/ec2-email-limit-rdns-request) to remove the throttle. Alternatively, you can send email using a different port, or use an [Amazon VPC endpoint](send-email-set-up-vpc-endpoints.md).

For SMTP connection issues, see [SMTP issues](troubleshoot-smtp.md).

## STARTTLS
<a name="smtp-connect-starttls"></a>

STARTTLS is a means of upgrading an unencrypted connection to an encrypted connection. There are versions of STARTTLS for a variety of protocols; the SMTP version is defined in [RFC 3207](https://www.ietf.org/rfc/rfc3207.txt).

To set up a STARTTLS connection, the SMTP client connects to the Amazon SES SMTP endpoint on port 25, 587, or 2587, issues an EHLO command, and waits for the server to announce that it supports the STARTTLS SMTP extension. The client then issues the STARTTLS command, initiating TLS negotiation. When negotiation is complete, the client issues an EHLO command over the new encrypted connection, and the SMTP session proceeds normally.

## TLS Wrapper
<a name="smtp-connect-tlswrapper"></a>

TLS Wrapper (also known as SMTPS or the Handshake Protocol) is a means of initiating an encrypted connection without first establishing an unencrypted connection. With TLS Wrapper, the Amazon SES SMTP endpoint doesn't perform TLS negotiation: it's the client's responsibility to connect to the endpoint using TLS, and to continue using TLS for the entire conversation. TLS Wrapper is an older protocol, but many clients still support it.

To set up a TLS Wrapper connection, the SMTP client connects to the Amazon SES SMTP endpoint on port 465 or 2465. The server presents its certificate, the client issues an EHLO command, and the SMTP session proceeds normally.

# Sending email through Amazon SES using software packages
<a name="send-email-smtp-software-package"></a>

There are a number of commercial and open source software packages that support sending email through SMTP. Here are some examples:
+ Blogging platforms
+ RSS aggregators
+ List management software
+ Workflow systems

You can configure any such SMTP-enabled software to send email through the Amazon SES SMTP interface. For instructions on how to configure SMTP for a particular software package, see the documentation for that software.

The following procedure shows how to set up Amazon SES sending in JIRA, a popular issue-tracking solution. With this configuration, JIRA can notify users through email whenever there is a change in the status of a software issue.

**To configure JIRA to send email using Amazon SES**

1. Using your web browser, log in to JIRA with administrator credentials.

1. In the browser window, choose **Administration**.

1. On the **System** menu, choose **Mail**.

1. On the **Mail administration** page, choose **Mail Servers**.

1. Choose **Configure new SMTP mail server**.

1. On the **Add SMTP Mail Server** form, fill in the following fields:

   1. **Name**—A descriptive name for this server.

   1. **From address**—The address from which email will be sent. You must verify this email address with Amazon SES before you can send from it. For more information about verification, see [Verified identities in Amazon SES](verify-addresses-and-domains.md).

   1. **Email prefix**—A string that JIRA prepends to each subject line prior to sending.

   1. **Protocol**—Choose **SMTP**.
**Note**  
If you can't connect to Amazon SES using this setting, try **SECURE\$1SMTP**.

   1. **Hostname**—See [Connecting to an Amazon SES SMTP endpoint](smtp-connect.md) for a list of Amazon SES SMTP endpoints. For example, if you want to use the Amazon SES endpoint in the US West (Oregon) Region, the hostname would be *email-smtp.us-west-2.amazonaws.com*.

   1. **SMTP port**—25, 587, or 2587 (to connect using STARTTLS), or 465 or 2465 (to connect using TLS Wrapper).

   1. **TLS**—Select this check box.

   1. **User name**—Your SMTP user name.

   1. **Password**—Your SMTP password.

   You can see the settings for TLS Wrapper in the following image.  
![\[SMTP email configuration for JIRA\]](http://docs.aws.amazon.com/ses/latest/dg/images/SMTP_jira.png)

1. Choose **Test Connection**. If the test email that JIRA sends through Amazon SES arrives successfully, then your configuration is complete.

# Sending emails programmatically through the Amazon SES SMTP interface
<a name="send-using-smtp-programmatically"></a>

To send an email using the Amazon SES SMTP interface, you can use an SMTP-enabled programming language, email server, or application. Before you start, complete the tasks in [Setting up Amazon Simple Email Service](setting-up.md). You also need to get the following information: 
+ Your Amazon SES SMTP credentials, which enable you to connect to the Amazon SES SMTP endpoint. To get your Amazon SES SMTP credentials, see [Obtaining Amazon SES SMTP credentials](smtp-credentials.md). 
**Important**  
Your SMTP credentials are different from your AWS credentials. For more information about credentials, see [Types of Amazon SES credentials](send-email-concepts-credentials.md).
+ The SMTP endpoint address. For a list of Amazon SES SMTP endpoints, see [Connecting to an Amazon SES SMTP endpoint](smtp-connect.md).
+ The Amazon SES SMTP interface port number, which depends on the connection method. For more information, see [Connecting to an Amazon SES SMTP endpoint](smtp-connect.md).

## Code examples
<a name="send-email-smtp-code-examples"></a>

You can access the Amazon SES SMTP interface by using an SMTP-enabled programming language. You provide the Amazon SES SMTP hostname and port number along with your SMTP credentials and then use the programming language's generic SMTP functions to send the email.

Amazon Elastic Compute Cloud (Amazon EC2) restricts email traffic over port 25 by default. To avoid timeouts when sending email through the SMTP endpoint from Amazon EC2, you can request that these restrictions be removed. For more information, see [How do I remove the restriction on port 25 from my Amazon EC2 instance or AWS Lambda function?](https://aws.amazon.com/premiumsupport/knowledge-center/ec2-port-25-throttle/) in the AWS Knowledge Center.

The code examples in this section for Java and PHP use port 587 to avoid this issue. 

**Note**  
In these tutorials, you send an email to yourself so that you can check to see if you received it. For further experimentation or load testing, use the Amazon SES mailbox simulator. Emails that you send to the mailbox simulator do not count toward your sending quota or your bounce and complaint rates. For more information, see [Using the mailbox simulator manually](send-an-email-from-console.md#send-email-simulator).

**Select a programing language to view the example for that language:**

**Warning**  
Amazon SES does not recommend using static credentials. Refer to [AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html) to learn how to improve your security posture by removing hard-coded credentials from your source code. This tutorial is only provided for the purpose of testing the Amazon SES SMTP interface in a non-production environment.

------
#### [ Java ]

This example uses the [Eclipse IDE](http://www.eclipse.org/) and the [JavaMail API](https://github.com/javaee/javamail/releases) to send email through Amazon SES using the SMTP interface.

Before you perform the following procedure, complete the tasks in [Setting up Amazon Simple Email Service](setting-up.md).

**To send an email using the Amazon SES SMTP interface with Java**

1. In a web browser, go to the [JavaMail GitHub page](https://github.com/javaee/javamail/releases). Under **Assets**, choose **javax.mail.jar** to download the latest version of JavaMail.
**Important**  
This tutorial requires JavaMail version 1.5 or later. These procedures were tested using JavaMail version 1.6.1.

1. In a web browser, go to the [Jakarta Activation GitHub page](https://github.com/eclipse-ee4j/jaf/releases), and under [JavaBeans Activation Framework 1.2.1 Final Release](https://github.com/eclipse-ee4j/jaf/releases/tag/1.2.1), download the **jakarta.activation.jar**

1. Create a project in Eclipse by performing the following steps:

   1. Start Eclipse.

   1. In Eclipse, choose **File**, choose **New**, and then choose **Java Project**.

   1. In the **Create a Java Project** dialog box, type a project name and then choose **Next.**

   1. In the **Java Settings** dialog box, choose the **Libraries** tab.

   1. Select **Classpath** and add the two external jar files **javax.mail.jar** and **jakarta.activation.jar** using the **Add External JARs** button.

   1. Choose **Add External JARs**.

   1. Browse to the folder in which you downloaded JavaMail. Choose the file `javax.mail.jar`, and then choose **Open**.

   1. In the **Java Settings** dialog box, choose **Finish**.

1. In Eclipse, in the **Package Explorer** window, expand your project.

1. Under your project, right-click the **src** directory, choose **New**, and then choose **Class**.

1. In the **New Java Class** dialog box, in the **Name** field, type `AmazonSESSample` and then choose **Finish**.

1. Replace the entire contents of **AmazonSESSample.java** with the following code:

   ```
     1. import java.util.Properties;
     2. 
     3. import javax.mail.Message;
     4. import javax.mail.Session;
     5. import javax.mail.Transport;
     6. import javax.mail.internet.InternetAddress;
     7. import javax.mail.internet.MimeMessage;
     8. 
     9. public class AmazonSESSample {
    10. 
    11.     // Replace sender@example.com with your "From" address.
    12.     // This address must be verified.
    13.     static final String FROM = "sender@example.com";
    14.     static final String FROMNAME = "Sender Name";
    15.     
    16.     // Replace recipient@example.com with a "To" address. If your account 
    17.     // is still in the sandbox, this address must be verified.
    18.     static final String TO = "recipient@example.com";
    19.     
    20.     // Replace smtp_username with your Amazon SES SMTP user name.
    21.     static final String SMTP_USERNAME = "smtp_username";
    22.       
    23.     // The name of the Configuration Set to use for this message.
    24.     // If you comment out or remove this variable, you will also need to
    25.     // comment out or remove the header below.
    26.     static final String CONFIGSET = "ConfigSet";
    27.     
    28.     // Amazon SES SMTP host name. This example uses the US West (Oregon) region.
    29.     // See https://docs.aws.amazon.com/ses/latest/DeveloperGuide/regions.html#region-endpoints
    30.     // for more information.
    31.     static final String HOST = "email-smtp.us-west-2.amazonaws.com";
    32.     
    33.     // The port you will connect to on the Amazon SES SMTP endpoint. 
    34.     static final int PORT = 587;
    35.     
    36.     static final String SUBJECT = "Amazon SES test (SMTP interface accessed using Java)";
    37.     
    38.     static final String BODY = String.join(
    39.             System.getProperty("line.separator"),
    40.             "<h1>Amazon SES SMTP Email Test</h1>",
    41.             "<p>This email was sent with Amazon SES using the ", 
    42.             "<a href='https://github.com/javaee/javamail'>Javamail Package</a>",
    43.             " for <a href='https://www.java.com'>Java</a>."
    44.         );
    45. 
    46.     public static void main(String[] args) throws Exception {
    47. 
    48.         // Create a Properties object to contain connection configuration information.
    49.         Properties props = System.getProperties();
    50.         props.put("mail.transport.protocol", "smtp");
    51.         props.put("mail.smtp.port", PORT); 
    52.         props.put("mail.smtp.starttls.enable", "true");
    53.         props.put("mail.smtp.auth", "true");
    54. 
    55.         // Create a Session object to represent a mail session with the specified properties. 
    56.         Session session = Session.getDefaultInstance(props);
    57. 
    58.         // Create a message with the specified information. 
    59.         MimeMessage msg = new MimeMessage(session);
    60.         msg.setFrom(new InternetAddress(FROM,FROMNAME));
    61.         msg.setRecipient(Message.RecipientType.TO, new InternetAddress(TO));
    62.         msg.setSubject(SUBJECT);
    63.         msg.setContent(BODY,"text/html");
    64.         
    65.         // Add a configuration set header. Comment or delete the 
    66.         // next line if you are not using a configuration set
    67.         msg.setHeader("X-SES-CONFIGURATION-SET", CONFIGSET);
    68.             
    69.         // Create a transport.
    70.         Transport transport = session.getTransport();
    71. 
    72.         // Get the password 
    73.         String SMTP_PASSWORD = fetchSMTPPasswordFromSecureStorage();
    74.                     
    75.         // Send the message.
    76.         try
    77.         {
    78.             System.out.println("Sending...");
    79.             
    80.             // Connect to Amazon SES using the SMTP username and password you specified above.
    81.             transport.connect(HOST, SMTP_USERNAME, SMTP_PASSWORD);
    82.             
    83.             // Send the email.
    84.             transport.sendMessage(msg, msg.getAllRecipients());
    85.             System.out.println("Email sent!");
    86.         }
    87.         catch (Exception ex) {
    88.             System.out.println("The email was not sent.");
    89.             System.out.println("Error message: " + ex.getMessage());
    90.         }
    91.         finally
    92.         {
    93.             // Close and terminate the connection.
    94.             transport.close();
    95.         }
    96.     }
    97. 
    98.     static String fetchSMTPPasswordFromSecureStorage() {
    99.         /* IMPLEMENT THIS METHOD */
   100.         // For example, you might fetch it from a secure location or AWS Secrets Manager: https://aws.amazon.com/secrets-manager/
   101.     }
   102. }
   ```

1. In **AmazonSESSample.java**, replace the following email addresses with your own values:
**Important**  
The email addresses are case-sensitive. Make sure that the addresses are exactly the same as the ones you verified.
   + *sender@example.com* – Replace with your "From" email address. You must verify this address before you run this program. For more information, see [Verified identities in Amazon SES](verify-addresses-and-domains.md).
   + *recipient@example.com* – Replace with your "To" email address. If your account is still in the sandbox, you must verify this address before you use it. For more information, see [Request production access (Moving out of the Amazon SES sandbox)](request-production-access.md).

1. In **AmazonSESSample.java** replace the following with your own values:
   + *smtp\$1username* – Replace with your SMTP user name credential. Note that your SMTP user name credential is a 20-character string of letters and numbers, not an intelligible name.
   + *smtp\$1password* – Implement ``fetchSMTPPasswordFromSecureStorage`` to fetch the password.

1. (Optional) If you want to use an Amazon SES SMTP endpoint in an AWS Region other than *email-smtp.us-west-2.amazonaws.com*, change the value of the variable `HOST` to the endpoint you want to use. For a list of regions where Amazon SES is available, see [Amazon Simple Email Service (Amazon SES)](https://docs.aws.amazon.com/general/latest/gr/rande.html#ses_region) in the *AWS General Reference*.

1. (Optional) If you want to use a configuration set when sending this email, change the value of the variable *ConfigSet* to the name of the configuration set. For more information about configuration sets, see [Using configuration sets in Amazon SES](using-configuration-sets.md).

1. Save **AmazonSESSample.java**.

1. To build the project, choose **Project** and then choose **Build Project**. (If this option is disabled, then you may have automatic building enabled.)

1. To start the program and send the email, choose **Run** and then choose **Run** again.

1. Review the output. If the email was successfully sent, the console displays *"Email sent\$1"* Otherwise, it displays an error message.

1. Sign into the email client of the recipient address. You will see the message that you sent.

------
#### [ PHP  ]

This example uses the PHPMailer class to send email through Amazon SES using the SMTP interface. 

Before you perform the following procedure you must complete the tasks in [Setting up Amazon Simple Email Service](setting-up.md). In addition to setting up Amazon SES you must complete the following prerequisites to sending email with PHP:

**Prerequisites:**
+ **Install PHP** – PHP is available at [http://php.net/downloads.php](https://php.net/downloads.php). After you install PHP, add the path to PHP in your environment variables so that you can run PHP from any command prompt.
+ **Install the Composer dependency manager** – After you install the Composer dependency manager, you can download and install the PHPMailer class and its dependencies. To install Composer, follow the installation instructions at [https://getcomposer.org/download](https://getcomposer.org/download).
+ **Install the PHPMailer class** – After you install Composer, run the following command to install PHPMailer: 

  ```
  path/to/composer require phpmailer/phpmailer
  ```

  In the preceding command, replace *path/to/* with the path where you installed Composer.

**To send an email using the Amazon SES SMTP interface with PHP**

1. Create a file named **amazon-ses-smtp-sample.php**. Open the file with a text editor and paste in the following code:

   ```
    1. <?php
    2. 
    3. // Import PHPMailer classes into the global namespace
    4. // These must be at the top of your script, not inside a function
    5. use PHPMailer\PHPMailer\PHPMailer;
    6. use PHPMailer\PHPMailer\Exception;
    7. 
    8. // If necessary, modify the path in the require statement below to refer to the
    9. // location of your Composer autoload.php file.
   10. require 'vendor/autoload.php';
   11. 
   12. // Replace sender@example.com with your "From" address.
   13. // This address must be verified with Amazon SES.
   14. $sender = 'sender@example.com';
   15. $senderName = 'Sender Name';
   16. 
   17. // Replace recipient@example.com with a "To" address. If your account
   18. // is still in the sandbox, this address must be verified.
   19. $recipient = 'recipient@example.com';
   20. 
   21. // Replace smtp_username with your Amazon SES SMTP user name.
   22. $usernameSmtp = 'smtp_username';
   23. 
   24. // Specify a configuration set. If you do not want to use a configuration
   25. // set, comment or remove the next line.
   26. $configurationSet = 'ConfigSet';
   27. 
   28. // If you're using Amazon SES in a region other than US West (Oregon),
   29. // replace email-smtp.us-west-2.amazonaws.com with the Amazon SES SMTP
   30. // endpoint in the appropriate region.
   31. $host = 'email-smtp.us-west-2.amazonaws.com';
   32. $port = 587;
   33. 
   34. // The subject line of the email
   35. $subject = 'Amazon SES test (SMTP interface accessed using PHP)';
   36. 
   37. // The plain-text body of the email
   38. $bodyText =  "Email Test\r\nThis email was sent through the
   39.     Amazon SES SMTP interface using the PHPMailer class.";
   40. 
   41. // The HTML-formatted body of the email
   42. $bodyHtml = '<h1>Email Test</h1>
   43.     <p>This email was sent through the
   44.     <a href="https://aws.amazon.com/ses">Amazon SES</a> SMTP
   45.     interface using the <a href="https://github.com/PHPMailer/PHPMailer">
   46.     PHPMailer</a> class.</p>';
   47. 
   48. $mail = new PHPMailer(true);
   49. 
   50. try {
   51.     // Specify the SMTP settings.
   52.     $mail->isSMTP();
   53.     $mail->setFrom($sender, $senderName);
   54.     $mail->Username   = $usernameSmtp;
   55.     $mail->Password   = fetchSMTPPasswordFromSecureStorage();
   56.     $mail->Host       = $host;
   57.     $mail->Port       = $port;
   58.     $mail->SMTPAuth   = true;
   59.     $mail->SMTPSecure = 'tls';
   60.     $mail->addCustomHeader('X-SES-CONFIGURATION-SET', $configurationSet);
   61. 
   62.     // Specify the message recipients.
   63.     $mail->addAddress($recipient);
   64.     // You can also add CC, BCC, and additional To recipients here.
   65. 
   66.     // Specify the content of the message.
   67.     $mail->isHTML(true);
   68.     $mail->Subject    = $subject;
   69.     $mail->Body       = $bodyHtml;
   70.     $mail->AltBody    = $bodyText;
   71.     $mail->Send();
   72.     echo "Email sent!" , PHP_EOL;
   73. } catch (phpmailerException $e) {
   74.     echo "An error occurred. {$e->errorMessage()}", PHP_EOL; //Catch errors from PHPMailer.
   75. } catch (Exception $e) {
   76.     echo "Email not sent. {$mail->ErrorInfo}", PHP_EOL; //Catch errors from Amazon SES.
   77. }
   78. function fetchSMTPPasswordFromSecureStorage() {
   79. /* IMPLEMENT THIS METHOD */
   80. // For example, you might fetch it from a secure location or AWS Secrets Manager: https://aws.amazon.com/secrets-manager/
   81. }
   82. 
   83. ?>
   ```

1. In **amazon-ses-smtp-sample.php**, replace the following with your own values:
   + *sender@example.com* – Replace with an email address that you have verified with Amazon SES. For more information, see [Verified identities](verify-addresses-and-domains.md). Email addresses in Amazon SES are case-sensitive. Make sure that the address you enter is exactly the same as the one you verified.
   + *recipient@example.com* – Replace with the address of the recipient. If your account is still in the sandbox, you must verify this address before you use it. For more information, see [Request production access (Moving out of the Amazon SES sandbox)](request-production-access.md). Make sure that the address you enter is exactly the same as the one you verified.
   + *smtp\$1username* – Replace with your SMTP user name credential, which you obtained from the [SMTP Settings](https://console.aws.amazon.com/ses/home?#smtp-settings:) page of the Amazon SES console. This is **not** the same as your AWS access key ID. Note that your SMTP user name credential is a 20-character string of letters and numbers, not an intelligible name.
   + *smtp\$1password* – Implement ``fetchSMTPPasswordFromSecureStorage`` to fetch the password.
   + (Optional) *ConfigSet* – If you want to use a configuration set when sending this email, replace this value with the name of the configuration set. For more information about configuration sets, see [Using configuration sets in Amazon SES](using-configuration-sets.md).
   + (Optional) *email-smtp.us-west-2.amazonaws.com* – If you want to use an Amazon SES SMTP endpoint in a Region other than US West (Oregon), replace this with the Amazon SES SMTP endpoint in the Region you want to use. For a list of SMTP endpoint URLs for the AWS Regions where Amazon SES is available, see [Amazon Simple Email Service (Amazon SES)](https://docs.aws.amazon.com/general/latest/gr/rande.html#ses_region) in the *AWS General Reference*.

1. Save **amazon-ses-smtp-sample.php**.

1. To run the program, open a command prompt in the same directory as **amazon-ses-smtp-sample.php**, and then type **php amazon-ses-smtp-sample.php**.

1. Review the output. If the email was successfully sent, the console displays *"Email sent\$1"* Otherwise, it displays an error message.

1. Sign in to the email client of the recipient address. You will see the message that you sent.

------

# Integrating Amazon SES with your existing email server
<a name="send-email-smtp-existing-server"></a>

If you currently administer your own email server, you can use the Amazon SES SMTP endpoint to send all of your outgoing email to Amazon SES. There is no need to modify your existing email clients and applications; the changeover to Amazon SES will be transparent to them.

Several mail transfer agents (MTAs) support sending email through SMTP relays. This section provides general guidance on how to configure some popular MTAs to send email using Amazon SES SMTP interface.

The Amazon SES SMTP endpoint requires that all connections be encrypted using Transport Layer Security (TLS).

**Topics**
+ [Integrating Amazon SES with Postfix](postfix.md)
+ [Integrating Amazon SES with Sendmail](send-email-sendmail.md)
+ [Integrating Amazon SES with Microsoft Windows Server IIS SMTP](send-email-windows-server.md)

# Integrating Amazon SES with Postfix
<a name="postfix"></a>

Postfix is an alternative to the widely used Sendmail Message Transfer Agent (MTA). For information about Postfix, go to [http://www.postfix.org](http://www.postfix.org). The procedures in this topic will work with Linux, macOS, or Unix.

**Note**  
Postfix is a third-party application, and isn't developed or supported by Amazon Web Services. The procedures in this section are provided for informational purposes only, and are subject to change without notice.

## Prerequisites
<a name="send-email-postfix-prereqs"></a>

Before you complete the procedures in this section, you have to perform the following tasks:
+ Uninstall the Sendmail application if it's installed on your system. The procedure for completing this step varies depending on the operating system you use.
**Important**  
Following references to *sendmail* refer to the Postfix command `sendmail`, not to be confused with the Sendmail application.
+ Install Postfix. The procedure for completing this step varies depending on the operating system you use.
+ Install a SASL authentication package. The procedure for completing this step varies depending on the operating system you use. For example, if you use a RedHat-based system, you should install the `cyrus-sasl-plain` package. If you use a Debian- or Ubuntu-based system, you should install the `libsasl2-modules` package.
+ Verify an email address or domain to use for sending email. For more information, see [Creating an email address identity](creating-identities.md#verify-email-addresses-procedure).
+ If your account is still in the sandbox, you can only send email to verified email addresses. For more information, see [Request production access (Moving out of the Amazon SES sandbox)](request-production-access.md).

## Configuring Postfix
<a name="send-email-postfix"></a>

Complete the following procedures to configure your mail server to send email through Amazon SES using Postfix.

**To configure Postfix**

1. At the command line, type the following command:

   ```
   sudo postconf -e "relayhost = [email-smtp.us-west-2.amazonaws.com]:587" \
   "smtp_sasl_auth_enable = yes" \
   "smtp_sasl_security_options = noanonymous" \
   "smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd" \
   "smtp_use_tls = yes" \
   "smtp_tls_security_level = secure" \
   "smtp_tls_note_starttls_offer = yes"
   ```
**Note**  
If you use Amazon SES in an AWS Region other than US West (Oregon), replace *email-smtp.us-west-2.amazonaws.com* in the preceding command with the SMTP endpoint of the appropriate Region. For more information, see [Regions and Amazon SES](regions.md).

1. In a text editor, open the file `/etc/postfix/master.cf`. Search for the following entry:

   ```
   -o smtp_fallback_relay=
   ```

   If you find this entry, comment it out by placing a `#` (hash) character at the beginning of the line. Save and close the file.

   Otherwise, if this entry isn't present, continue to the next step.

1. In a text editor, open the file `/etc/postfix/sasl_passwd`. If the file doesn't already exist, create it.

1. Add the following line to `/etc/postfix/sasl_passwd`:

   ```
   [email-smtp.us-west-2.amazonaws.com]:587 SMTPUSERNAME:SMTPPASSWORD
   ```
**Note**  
Replace *SMTPUSERNAME* and *SMTPPASSWORD* with your SMTP sign-in credentials. Your SMTP sign-in credentials aren't the same as your AWS access key ID and secret access key. For more information about credentials, see [Obtaining Amazon SES SMTP credentials](smtp-credentials.md).  
If you use Amazon SES in an AWS Region other than US West (Oregon), replace *email-smtp.us-west-2.amazonaws.com* in the preceding example with the SMTP endpoint of the appropriate Region. For more information, see [Regions and Amazon SES](regions.md).

   Save and close `sasl_passwd`.

1. At a command prompt, type the following command to create a hashmap database file containing your SMTP credentials:

   ```
   sudo postmap hash:/etc/postfix/sasl_passwd
   ```

1. (Optional) The `/etc/postfix/sasl_passwd` and `/etc/postfix/sasl_passwd.db` files you created in the previous steps aren't encrypted. Because these files contain your SMTP credentials, we recommend that you modify the files' ownership and permissions in order to restrict access to them. To restrict access to these files:

   1. At a command prompt, type the following command to change the ownership of the files:

      ```
      sudo chown root:root /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db
      ```

   1. At a command prompt, type the following command to change the permissions of the files so that only the root user can read or write to them:

      ```
      sudo chmod 0600 /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db
      ```

1. Tell Postfix where to find the CA certificate (needed to verify the Amazon SES server certificate). The command you use in this step varies based on your operating system.
   + If you use Amazon Linux, Red Hat Enterprise Linux, or a related distribution, type the following command: 

     ```
     sudo postconf -e 'smtp_tls_CAfile = /etc/ssl/certs/ca-bundle.crt'
     ```
   + If you use Ubuntu or a related distribution, type the following command:

     ```
     sudo postconf -e 'smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt'
     ```
   + If you use macOS, you can generate the certificate from your system keychain. To generate the certificate, type the following command at the command line:

     ```
     sudo security find-certificate -a -p /System/Library/Keychains/SystemRootCertificates.keychain | sudo tee /etc/ssl/certs/ca-bundle.crt > /dev/null
     ```

     After you generate the certificate, type the following command:

     ```
     sudo postconf -e 'smtp_tls_CAfile = /etc/ssl/certs/ca-bundle.crt'
     ```

1. Type the following command to start the Postfix server (or to reload the configuration settings if the server is already running):

   ```
   sudo postfix start; sudo postfix reload
   ```

1. Send a test email by typing the following at a command line, pressing Enter after each line. Replace *sender@example.com* with your From email address. The From address has to be verified for use with Amazon SES. Replace *recipient@example.com* with the destination address. If your account is still in the sandbox, the recipient address also has to be verified. Finally, the final line of the message has to contain a single period (.) with no other content.

   ```
   sendmail -f sender@example.com recipient@example.com
   From: Sender Name <sender@example.com>
   Subject: Amazon SES Test                
   This message was sent using Amazon SES.                
   .
   ```

1. Check the mailbox associated with the recipient address. If the email doesn't arrive, check your junk mail folder. If you still can't locate the email, check the mail log on the system that you used to send the email (typically located at `/var/log/maillog`) for more information.

## Advanced usage example
<a name="send-email-postfix-advanced"></a>

This example shows how to send an email that uses a [configuration set](using-configuration-sets.md), and that uses MIME-multipart encoding to send both a plain text and an HTML version of the message, along with an attachment. It also includes a [link tag](faqs-metrics.md#sending-metric-faqs-clicks-q5), which can be used for categorizing click events. The content of the email is specified in an external file, so that you do not have to manually type the commands in the Postfix session.

**To send a multipart MIME email using Postfix**

1. In a text editor, create a new file called `mime-email.txt`.

1. In the text file, paste the following content, replacing the values in red with the appropriate values for your account:

   ```
   X-SES-CONFIGURATION-SET: ConfigSet
   From:Sender Name <sender@example.com>
   Subject:Amazon SES Test
   MIME-Version: 1.0
   Content-Type: multipart/mixed; boundary="YWVhZDFlY2QzMGQ2N2U0YTZmODU"
   
   --YWVhZDFlY2QzMGQ2N2U0YTZmODU
   Content-Type: multipart/alternative; boundary="3NjM0N2QwMTE4MWQ0ZTg2NTYxZQ"
   
   --3NjM0N2QwMTE4MWQ0ZTg2NTYxZQ
   Content-Type: text/plain; charset=UTF-8
   Content-Transfer-Encoding: quoted-printable
   
   Amazon SES Test
   
   This message was sent from Amazon SES using the SMTP interface.
   
   For more information, see:
   http://docs.aws.amazon.com/ses/latest/DeveloperGuide/send-email-smtp.html
   
   --3NjM0N2QwMTE4MWQ0ZTg2NTYxZQ
   Content-Type: text/html; charset=UTF-8
   Content-Transfer-Encoding: quoted-printable
   
   <html>
     <head>
   </head>
     <body>
       <h1>Amazon SES Test</h1>
         <p>This message was sent from Amazon SES using the SMTP interface.</p>
         <p>For more information, see
         <a ses:tags="samplekey0:samplevalue0;samplekey1:samplevalue1;" 
         href="http://docs.aws.amazon.com/ses/latest/DeveloperGuide/send-email-smtp.html">
         Using the Amazon SES SMTP Interface to Send Email</a> in the <em>Amazon SES
         Developer Guide</em>.</p>
     </body>
   </html>
   --3NjM0N2QwMTE4MWQ0ZTg2NTYxZQ--
   --YWVhZDFlY2QzMGQ2N2U0YTZmODU
   Content-Type: application/octet-stream
   MIME-Version: 1.0
   Content-Transfer-Encoding: base64
   Content-Disposition: attachment; filename="customers.txt"
   
   SUQsRmlyc3ROYW1lLExhc3ROYW1lLENvdW50cnkKMzQ4LEpvaG4sU3RpbGVzLENh
   bmFkYQo5MjM4OSxKaWUsTGl1LENoaW5hCjczNCxTaGlybGV5LFJvZHJpZ3VleixV
   bml0ZWQgU3RhdGVzCjI4OTMsQW5heWEsSXllbmdhcixJbmRpYQ==
   --YWVhZDFlY2QzMGQ2N2U0YTZmODU--
   ```

   Save and close the file.

1. At the command line, type the following command. Replace *sender@example.com* with your email address, and replace *recipient@example.com* with the recipient's email address.

   ```
   sendmail -f sender@example.com recipient@example.com < mime-email.txt
   ```

   If the command runs successfully, it exits without providing any output.

1. Check your inbox for the email. If the message wasn't delivered, check your system's mail log.

# Integrating Amazon SES with Sendmail
<a name="send-email-sendmail"></a>

Sendmail was released in the early 1980s, and has been continuously improved ever since. It's a flexible and configurable message transfer agent (MTA) with a large community of users. Sendmail was acquired by Proofpoint in 2013, but Proofpoint continues to offer an open source version of Sendmail. You can download the [open source version of Sendmail](https://www.proofpoint.com/us/open-source-email-solution) from the Proofpoint website, or through the package managers of most Linux distributions.

The procedure in this section shows you how to configure Sendmail to send email through Amazon SES. This procedure was tested on a server running Ubuntu 18.04.2 LTS.

**Note**  
Sendmail is a third-party application, and isn't developed or supported by Amazon Web Services. The procedures in this section are provided for informational purposes only, and are subject to change without notice.

## Prerequisites
<a name="send-email-sendmail-prerequisites"></a>

Before you complete the procedure in this section, you should complete the following steps:
+ Install the Sendmail package on your server. 
**Note**  
Depending on which operating system distribution you use, you might also need to install the following packages: `sendmail-cf`, `m4`, and `cyrus-sasl-plain`.
+ Verify an identity to use as your From address. For more information, see [Creating an email address identity](creating-identities.md#verify-email-addresses-procedure).

  If your account is in the Amazon SES sandbox, you must also verify the addresses that you send email to. For more information, see [Request production access (Moving out of the Amazon SES sandbox)](request-production-access.md).

If you're using Amazon SES to send email from an Amazon EC2 instance, you should also complete the following steps:
+ You may need to assign an Elastic IP Address to your Amazon EC2 instance in order for receiving email providers to accept your email. For more information, see [Amazon EC2 Elastic IP addresses](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/elastic-ip-addresses-eip.html) in the *Amazon EC2 User Guide*.
+ Amazon Elastic Compute Cloud (Amazon EC2) restricts email traffic over port 25 by default. To avoid timeouts when sending email through the SMTP endpoint from Amazon EC2, you can request that these restrictions be removed. For more information, see [How do I remove the restriction on port 25 from my Amazon EC2 instance or AWS Lambda function?](https://aws.amazon.com/premiumsupport/knowledge-center/ec2-port-25-throttle/) in the AWS Knowledge Center.

  Alternatively, you can modify the procedure in this section to use port 587 rather than port 25.

## Configuring Sendmail
<a name="send-email-sendmail-procedure"></a>

Complete the steps in this section to configure Sendmail to send email by using Amazon SES.

**Important**  
The procedure in this section assumes that you want to use Amazon SES in the US West (Oregon) AWS Region. If you want to use a different Region, replace all instances of *email-smtp.us-west-2.amazonaws.com* in this procedure with the SMTP endpoint of the desired Region. For a list of SMTP endpoint URLs for the AWS Regions where Amazon SES is available, see [Amazon Simple Email Service (Amazon SES)](https://docs.aws.amazon.com/general/latest/gr/rande.html#ses_region) in the *AWS General Reference*.

**To configure Sendmail**

1. In a file editor, open the file `/etc/mail/authinfo`. If the file doesn't exist, create it.

   Add the following line to */etc/mail/authinfo*:

   ```
   AuthInfo:email-smtp.us-west-2.amazonaws.com "U:root" "I:smtpUsername" "P:smtpPassword" "M:PLAIN"
   ```

   In the preceding example, make the following changes:
   + Replace *email-smtp.us-west-2.amazonaws.com* with the Amazon SES SMTP endpoint that you want to use.
   + Replace *smtpUsername* with your Amazon SES SMTP user name.
   + Replace *smtpPassword* with your Amazon SES SMTP password.
**Note**  
Your SMTP sign-in credentials are different from your AWS Access Key ID and Secret Access Key. For more information about obtaining your SMTP sign-in credentials, see [Obtaining Amazon SES SMTP credentials](smtp-credentials.md).

   When you finish, save `authinfo`.

1. At the command line, enter the following command to generate the `/etc/mail/authinfo.db` file:

   ```
   sudo sh -c 'makemap hash /etc/mail/authinfo.db < /etc/mail/authinfo'
   ```

1. At the command line, type the following command to add support for relaying to the Amazon SES SMTP endpoint.

   ```
   sudo sh -c 'echo "Connect:email-smtp.us-west-2.amazonaws.com RELAY" >> /etc/mail/access'
   ```

   In the preceding command, replace *email-smtp.us-west-2.amazonaws.com* with the address of the Amazon SES SMTP endpoint that you want to use.

1. At the command line, type the following command to regenerate */etc/mail/access.db*:

   ```
   sudo sh -c 'makemap hash /etc/mail/access.db < /etc/mail/access'
   ```

1. At the command line, type the following command to create backups of the `sendmail.cf` and `sendmail.mc` files:

   ```
   sudo sh -c 'cp /etc/mail/sendmail.cf /etc/mail/sendmail_cf.backup && cp /etc/mail/sendmail.mc /etc/mail/sendmail_mc.backup'
   ```

1. Add the following lines to the */etc/mail/sendmail.mc* file before any `MAILER()` definitions.

   ```
   define(`SMART_HOST', `email-smtp.us-west-2.amazonaws.com')dnl
   define(`RELAY_MAILER_ARGS', `TCP $h 25')dnl
   define(`confAUTH_MECHANISMS', `LOGIN PLAIN')dnl
   FEATURE(`authinfo', `hash -o /etc/mail/authinfo.db')dnl
   MASQUERADE_AS(`example.com')dnl
   FEATURE(masquerade_envelope)dnl
   FEATURE(masquerade_entire_domain)dnl
   ```

   In the preceding text, do the following:
   + Replace *email-smtp.us-west-2.amazonaws.com* with the Amazon SES SMTP endpoint that you want to use.
   + Replace *example.com* with the domain that you want to use to send email.

   When you finish, save the file.
**Note**  
Amazon EC2 restricts communications over port 25 by default. If you're using Sendmail in an Amazon EC2 instance, you should complete the [Request to Remove Email Sending Limitations](https://aws-portal.amazon.com/gp/aws/html-forms-controller/contactus/ec2-email-limit-rdns-request).

1. At the command line, type the following command to make *sendmail.cf* writeable:

   ```
   sudo chmod 666 /etc/mail/sendmail.cf
   ```

1. At the command line, type the following command to regenerate *sendmail.cf*:

   ```
   sudo sh -c 'm4 /etc/mail/sendmail.mc > /etc/mail/sendmail.cf'
   ```
**Note**  
If you encounter errors such as "Command not found" and "No such file or directory," make sure that the `m4` and `sendmail-cf` packages are installed on your system.

1. At the command line, type the following command to reset the permissions of *sendmail.cf* to read only:

   ```
   sudo chmod 644 /etc/mail/sendmail.cf
   ```

1. At the command line, type the following command to restart Sendmail:

   ```
   sudo /etc/init.d/sendmail restart
   ```

   *Depending on the version of Linux or Sendmail, if the above doesn't work, try the following:*

   ```
   sudo su service sendmail restart
   ```

1. Complete the following steps to send a test email:

   1. At the command line, enter the following command.

      ```
      /usr/sbin/sendmail -vf sender@example.com recipient@example.com
      ```

      Replace *sender@example.com* with your From email address. Replace *recipient@example.com* with the To address. When you finish, press Enter.

   1. Enter the following message content. Press Enter at the end of each line.

      ```
      From: sender@example.com
      To: recipient@example.com
      Subject: Amazon SES test email
      
      This is a test message sent from Amazon SES using Sendmail.
      ```

      When you finish entering the content of the email, press Ctrl\$1D to send it.

1. Check the recipient email's client for the email. If you can't find the email, check the junk mail folder. If you still can't find the email, check the Sendmail log on your mail server. The log is often located at */var/log/mail.log* or */var/log/maillog*. 

# Integrating Amazon SES with Microsoft Windows Server IIS SMTP
<a name="send-email-windows-server"></a>

You can configure Microsoft Windows Server's IIS SMTP server to send email through Amazon SES. These instructions were written using Microsoft Windows Server 2022 on an Amazon EC2 instance. You can use the same configuration on Microsoft Windows Server 2016.

**Note**  
Windows Server is a third-party application, and isn't developed or supported by Amazon Web Services. The procedures in this section are provided for informational purposes only, and are subject to change without notice.

**To integrate the Microsoft Windows Server IIS SMTP server with Amazon SES**

1. First, set up Microsoft Windows Server 2022 using the following instructions.

   1. From the [Amazon EC2 management console](https://console.aws.amazon.com/ec2/home), launch a new Microsoft Windows Server 2022 Base Amazon EC2 instance.

   1. Connect to the instance and log into it using Remote Desktop by following the instructions in [Getting Started with Amazon EC2 Windows Instances](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/EC2Win_GetStarted.html).

   1. Launch the Server Manager Dashboard.

   1. Install the **Web Server** role. Be sure to include the **IIS 10 Management Compatibility tools** (an option under the **Web Server** check box).

   1. Install the **SMTP Server** feature.

1. Next, configure the IIS SMTP service using the following instructions.

   1. Return to the Server Manager Dashboard.

   1. From the **Tools** menu, choose **Internet Information Services (IIS) 10.0 Manager**.

   1. Right-click **SMTP Virtual Server \$11** and then select **Properties**.

   1. On the **Access** tab, under **Relay Restrictions**, choose **Relay**.

   1. In the **Relay Restrictions** dialog box, choose **Add**.

   1. Under **Single Computer**, enter **127.0.0.1** for the IP address. You have now granted access for this server to relay email to Amazon SES through the IIS SMTP service.

      In this procedure, we assume that your emails are generated on this server. If the application that generates the email runs on a separate server, you must grant relaying access for that server in IIS SMTP.
**Note**  
To extend the SMTP relay to private subnets, for **Relay Restriction**, use **Single Computer** 127.0.0.1 and **Group of Computers** 172.1.1.0 - 255.255.255.0 (in the netmask section). For **Connection**, use **Single Computer** 127.0.0.1 and **Group of Computers** 172.1.1.0 - 255.255.255.0 (in the netmask section).

1. Finally, configure the server to send email through Amazon SES using the following instructions.

   1. Return to the **SMTP Virtual Server \$11 Properties** dialog box and then choose the **Delivery** tab.

   1. On the **Delivery** tab, choose **Outbound Security**.

   1. Select **Basic Authentication** and then enter your Amazon SES SMTP credentials. You can obtain these credentials from the Amazon SES console using the procedure in [Obtaining Amazon SES SMTP credentials](smtp-credentials.md).
**Important**  
Your SMTP credentials are not the same as your AWS access key ID and secret access key. Do not attempt to use your AWS credentials to authenticate yourself against the SMTP endpoint. For more information about credentials, see [Types of Amazon SES credentials](send-email-concepts-credentials.md).

   1. Ensure that **TLS encryption** is selected.

   1. Return to the **Delivery** tab.

   1. Choose **Outbound Connections**.

   1. In the **Outbound Connections** dialog box, ensure that the port is 25 or 587. 

   1. Choose **Advanced**.

   1. For the **Smart host** name, enter the Amazon SES endpoint that you will use (for example, *email-smtp.us-west-2.amazonaws.com*). For a list of endpoint URLs for the AWS Regions where Amazon SES is available, see [Amazon Simple Email Service (Amazon SES)](https://docs.aws.amazon.com/general/latest/gr/rande.html#ses_region) in the *AWS General Reference*.

   1. Return to the Server Manager Dashboard.

   1. On the Server Manager Dashboard, right-click **SMTP Virtual Server \$11** and then restart the service to pick up the new configuration.

   1. Send an email through this server. You can examine the message headers to confirm that it was delivered through Amazon SES.

# Testing your connection to the Amazon SES SMTP interface using the command line
<a name="send-email-smtp-client-command-line"></a>

You can use the methods described in this section from the command line to test your connection to the Amazon SES SMTP endpoint, validate your SMTP credentials, and troubleshoot connection issues. These procedures use tools and libraries that are included with most common operating systems.

For additional information about troubleshooting SMTP connection problems, see [Amazon SES SMTP issues](troubleshoot-smtp.md).

## Prerequisites
<a name="send-email-smtp-client-command-line-prereqs"></a>

When you connect to the Amazon SES SMTP interface, you have to provide a set of SMTP credentials. These SMTP credentials are different from your standard AWS credentials. The two types of credentials aren't interchangeable. For more information about obtaining your SMTP credentials, see [Obtaining Amazon SES SMTP credentials](smtp-credentials.md).

## Testing your connection to the Amazon SES SMTP interface
<a name="send-email-smtp-client-command-line-testing"></a>

You can use the command line to test your connection to the Amazon SES SMTP interface without authenticating or sending any messages. This procedure is useful for troubleshooting basic connectivity issues. If your test connection fails, see [SMTP issues](troubleshoot-smtp.md).

This section includes procedures for testing your connection using both OpenSSL (which is included with most Linux, macOS, and Unix distributions, and is also available for Windows) and the `Test-NetConnection` cmdlet in PowerShell (which is included with most recent versions of Windows).

------
#### [ Linux, macOS, or Unix ]

There are two ways to connect to the Amazon SES SMTP interface with OpenSSL: using explicit SSL over port 587, or using implicit SSL over port 465.

**To connect to the SMTP interface using explicit SSL**
+ At the command line, enter the following command to connect to the Amazon SES SMTP server:

  ```
  openssl s_client -crlf -quiet -starttls smtp -connect email-smtp.us-west-2.amazonaws.com:587
  ```

  In the preceding command, replace *email-smtp.us-west-2.amazonaws.com* with the URL of the Amazon SES SMTP endpoint for your AWS Region. For more information, see [Regions and Amazon SES](regions.md).

  If the connection was successful, you see output similar to the following:

  ```
  depth=2 C = US, O = Amazon, CN = Amazon Root CA 1
  verify return:1
  depth=1 C = US, O = Amazon, OU = Server CA 1B, CN = Amazon
  verify return:1
  depth=0 CN = email-smtp.us-west-2.amazonaws.com
  verify return:1
  250 Ok
  ```

  The connection automatically closes after about 10 seconds of inactivity.

Alternatively, you can use implicit SSL to connect to the SMTP interface over port 465.

**To connect to the SMTP interface using implicit SSL**
+ At the command line, enter the following command to connect to the Amazon SES SMTP server:

  ```
  openssl s_client -crlf -quiet -connect email-smtp.us-west-2.amazonaws.com:465
  ```

  In the preceding command, replace *email-smtp.us-west-2.amazonaws.com* with the URL of the Amazon SES SMTP endpoint for your AWS Region. For more information, see [Regions and Amazon SES](regions.md).

  If the connection was successful, you see output similar to the following:

  ```
  depth=2 C = US, O = Amazon, CN = Amazon Root CA 1
  verify return:1
  depth=1 C = US, O = Amazon, OU = Server CA 1B, CN = Amazon
  verify return:1
  depth=0 CN = email-smtp.us-west-2.amazonaws.com
  verify return:1
  220 email-smtp.amazonaws.com ESMTP SimpleEmailService-d-VCSHDP1YZ A1b2C3d4E5f6G7h8I9j0
  ```

  The connection automatically closes after about 10 seconds of inactivity.

------
#### [ PowerShell ]

You can use the [Test-NetConnection](https://docs.microsoft.com/en-us/powershell/module/nettcpip/test-netconnection) cmdlet in PowerShell to connect to the Amazon SES SMTP server.

**Note**  
The `Test-NetConnection` cmdlet can determine whether your computer can connect to the Amazon SES SMTP endpoint. However, it doesn't test whether your computer can make an implicit or explicit SSL connection to the SMTP endpoint. To test an SSL connection, you can install OpenSSL for Windows to send a test email.

**To connect to the SMTP interface using the `Test-NetConnection` cmdlet**
+ In PowerShell, enter the following command to connect to the Amazon SES SMTP server:

  ```
  Test-NetConnection -Port 587 -ComputerName email-smtp.us-west-2.amazonaws.com
  ```

  In the preceding command, replace *email-smtp.us-west-2.amazonaws.com* with the URL of the Amazon SES SMTP endpoint for your AWS Region, and replace *587* with the port number. For more information about regional endpoints in Amazon SES, see [Regions and Amazon SES](regions.md).

  If the connection was successful, you see output that resembles the following example:

  ```
  ComputerName     : email-smtp.us-west-2.amazonaws.com
  RemoteAddress    : 198.51.100.126
  RemotePort       : 587
  InterfaceAlias   : Ethernet
  SourceAddress    : 203.0.113.46
  TcpTestSucceeded : True
  ```

------

## Using the command line to send email using the Amazon SES SMTP interface
<a name="send-email-using-openssl"></a>

You can also use the command line to send messages using the Amazon SES SMTP interface. This procedure is useful for testing SMTP credentials and for testing the ability of specific recipients to receive messages that you send by using Amazon SES.

------
#### [ Linux, macOS, or Unix ]

When an email sender connects to an SMTP server, the client issues a standard set of requests, and the server replies to each request with a standard response. This series of requests and responses is called an *SMTP conversation*. When you connect to the Amazon SES SMTP server using OpenSSL, the server expects an SMTP conversation to occur.

When you use OpenSSL to connect to the SMTP interface, you have to encode your SMTP credentials using base64 encoding. This section includes procedures for encoding your credentials using base64.

**To send an email from the command line using the SMTP interface**

1. Enter the following at the command line and replace *email-smtp.us-west-2.amazonaws.com* with the URL of the Amazon SES SMTP endpoint for your AWS Region. For more information, see [Regions and Amazon SES](regions.md).:

   ```
    1. #!/bin/bash
    2. 
    3. # Prompt user to provide following information
    4. read -p "Configuration set: " CONFIGSET
    5. read -p "Enter SMTP username: " SMTPUsername
    6. read -p "Enter SMTP password: " SMTPPassword
    7. read -p "Sender email address: " MAILFROM
    8. read -p "Receiver email address: " RCPT
    9. read -p "Email subject: " SUBJECT
   10. read -p "Message to send: " DATA
   11. 
   12. echo
   13. 
   14. # Encode SMTP username and password using base64
   15. EncodedSMTPUsername=$(echo -n "$SMTPUsername" | openssl enc -base64)
   16. EncodedSMTPPassword=$(echo -n "$SMTPPassword" | openssl enc -base64)
   17. 
   18. # Construct the email
   19. Email="EHLO example.com
   20. AUTH LOGIN
   21. $EncodedSMTPUsername
   22. $EncodedSMTPPassword
   23. MAIL FROM: $MAILFROM
   24. RCPT TO: $RCPT
   25. DATA
   26. X-SES-CONFIGURATION-SET: $CONFIGSET
   27. From: $MAILFROM
   28. To: $RCPT
   29. Subject: $SUBJECT
   30. 
   31. $DATA
   32. .
   33. QUIT"
   34. 
   35. echo "$Email" | openssl s_client -crlf -quiet -starttls smtp -connect email-smtp.us-west-2.amazonaws.com:587
   ```

1. At the prompt for each variable, enter your values.

1. 
   + To send using implicit SSL over port 465, use:

     ```
     openssl s_client -crlf -quiet -connect email-smtp.us-west-2.amazonaws.com:465
     ```

   If the message was accepted by Amazon SES, you see output that resembles the following example:

   ```
   250 Ok 01010160d7de98d8-21e57d9a-JZho-416c-bbe1-8ebaAexample-000000
   ```

   The string of numbers and text that follows `250 Ok` is the message ID of the email.
**Note**  
The connection closes automatically after about 10 seconds of inactivity.

------
#### [ PowerShell ]

You can use the [Net.Mail.SmtpClient](https://docs.microsoft.com/en-us/dotnet/api/system.net.mail.smtpclient?view=netframework-4.8) class to send email using explicit SSL over port 587.

**Note**  
The `Net.Mail.SmtpClient` class is officially obsolete, and Microsoft recommends that you use third-party libraries. This code is intended for testing purposes only, and shouldn't be used for production workloads.

**To send an email through PowerShell using explicit SSL**

1. In a text editor, create a new file. Paste the following code into the file:

   ```
   function SendEmail($Server, $Port, $Sender, $Recipient, $Subject, $Body) {
       $Credentials = [Net.NetworkCredential](Get-Credential)
   
       $SMTPClient = New-Object Net.Mail.SmtpClient($Server, $Port)
       $SMTPClient.EnableSsl = $true
       $SMTPClient.Credentials = New-Object System.Net.NetworkCredential($Credentials.Username, $Credentials.Password);
   
       try {
           Write-Output "Sending message..."
           $SMTPClient.Send($Sender, $Recipient, $Subject, $Body)
           Write-Output "Message successfully sent to $($Recipient)"
       } catch [System.Exception] {
           Write-Output "An error occurred:"
           Write-Error $_
       }
   }
   
   function SendTestEmail(){
       $Server = "email-smtp.us-west-2.amazonaws.com"
       $Port = 587
   
       $Subject = "Test email sent from Amazon SES"
       $Body = "This message was sent from Amazon SES using PowerShell (explicit SSL, port 587)."
   
       $Sender = "sender@example.com"
       $Recipient = "recipient@example.com"
   
       SendEmail $Server $Port $Sender $Recipient $Subject $Body
   }
   
   SendTestEmail
   ```

   When you finish, save the file as `SendEmail.ps1`.

1. Make the following changes to the file that you created in the previous step:
   + Replace *sender@example.com* with the email address that you want to send the message from.
   + Replace *recipient@example.com* with the email address that you want to send the message to.
   + Replace *email-smtp.us-west-2.amazonaws.com* with the URL of the Amazon SES SMTP endpoint for your AWS Region. For more information, see [Regions and Amazon SES](regions.md).

1. In PowerShell, enter the following command:

   ```
   .\path\to\SendEmail.ps1
   ```

   In the preceding command, replace *path\$1to\$1SendEmail.ps1* with the path to the file that you created in step 1.

1. When prompted, enter your SMTP user name and password.

Alternatively, you can use the [System.Web.Mail.SmtpMail](https://docs.microsoft.com/en-us/dotnet/api/system.web.mail.smtpmail?view=netframework-4.8) class to send email using implicit SSL over port 465.

**Note**  
The `System.Web.Mail.SmtpMail` class is officially obsolete, and Microsoft recommends that you use third-party libraries. This code is intended for testing purposes only, and shouldn't be used for production workloads.

**To send an email through PowerShell using implicit SSL**

1. In a text editor, create a new file. Paste the following code into the file:

   ```
   [System.Reflection.Assembly]::LoadWithPartialName("System.Web") > $null
   
   function SendEmail($Server, $Port, $Sender, $Recipient, $Subject, $Body) {
       $Credentials = [Net.NetworkCredential](Get-Credential)
   
       $mail = New-Object System.Web.Mail.MailMessage
       $mail.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpserver", $Server)
       $mail.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpserverport", $Port)
       $mail.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpusessl", $true)
       $mail.Fields.Add("http://schemas.microsoft.com/cdo/configuration/sendusername", $Credentials.UserName)
       $mail.Fields.Add("http://schemas.microsoft.com/cdo/configuration/sendpassword", $Credentials.Password)
       $mail.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout", $timeout / 1000)
       $mail.Fields.Add("http://schemas.microsoft.com/cdo/configuration/sendusing", 2)
       $mail.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate", 1)
   
       $mail.From = $Sender
       $mail.To = $Recipient
       $mail.Subject = $Subject
       $mail.Body = $Body
   
       try {
           Write-Output "Sending message..."
           [System.Web.Mail.SmtpMail]::Send($mail)
           Write-Output "Message successfully sent to $($Recipient)"
       } catch [System.Exception] {
           Write-Output "An error occurred:"
           Write-Error $_
       }
   }
   
   function SendTestEmail(){
       $Server = "email-smtp.us-west-2.amazonaws.com"
       $Port = 465
       
       $Subject = "Test email sent from Amazon SES"
       $Body = "This message was sent from Amazon SES using PowerShell (implicit SSL, port 465)."
   
       $Sender = "sender@example.com"
       $Recipient = "recipient@example.com"
   
       SendEmail $Server $Port $Sender $Recipient $Subject $Body
   }
   
   SendTestEmail
   ```

   When you finish, save the file as `SendEmail.ps1`.

1. Make the following changes to the file that you created in the previous step:
   + Replace *sender@example.com* with the email address that you want to send the message from.
   + Replace *recipient@example.com* with the email address that you want to send the message to.
   + Replace *email-smtp.us-west-2.amazonaws.com* with the URL of the Amazon SES SMTP endpoint for your AWS Region. For more information, see [Regions and Amazon SES](regions.md).

1. In PowerShell, enter the following command:

   ```
   .\path\to\SendEmail.ps1
   ```

   In the preceding command, replace *path\$1to\$1SendEmail.ps1* with the path to the file that you created in step 1.

1. When prompted, enter your SMTP user name and password.

------

# Using the Amazon SES API to send email
<a name="send-email-api"></a>

To send production email through Amazon SES, you can use the Simple Mail Transfer Protocol (SMTP) interface or the Amazon SES API. For more information about the SMTP interface, see [Using the Amazon SES SMTP interface to send email](send-email-smtp.md). This section describes how to send email by using the API. 

When you send an email using the Amazon SES API, you specify the content of the message, and Amazon SES assembles a MIME email for you. Alternatively, you can assemble the email yourself so that you have complete control over the content of the message. For more information about the API, see the [Amazon Simple Email Service API Reference](https://docs.aws.amazon.com/ses/latest/APIReference/). For a list of endpoint URLs for the AWS Regions where Amazon SES is available, see [Amazon Simple Email Service endpoints and quotas](https://docs.aws.amazon.com/general/latest/gr/ses.html) in the *AWS General Reference*.

You can call the API in the following ways:
+ **Make direct HTTPS requests—**This is the most advanced method, because you have to manually handle authentication and signing of your requests, and then manually construct the requests. For information about the Amazon SES API, see the [Welcome](https://docs.aws.amazon.com/ses/latest/APIReference-V2/Welcome.html) page in the *API v2 Reference*.
+ **Use an AWS SDK—**AWS SDKs make it easy to access the APIs for several AWS services, including Amazon SES. When you use an SDK, it takes care of authentication, request signing, retry logic, error handling, and other low-level functions so that you can focus on building applications that delight your customers.
+ **Use a command line interface—**The [AWS Command Line Interface](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html) is the command line tool for Amazon SES. We also offer the [AWS Tools for PowerShell](https://aws.amazon.com/powershell/) for those who script in the PowerShell environment.

Regardless of whether you access the Amazon SES API directly or indirectly through an AWS SDK, the AWS Command Line Interface or the AWS Tools for PowerShell, the Amazon SES API provides two different ways for you to send an email, depending on how much control you want over the composition of the email message:
+ **Formatted—**Amazon SES composes and sends a properly formatted email message. You need only supply "From:" and "To:" addresses, a subject, and a message body. Amazon SES takes care of all the rest. For more information, see [Sending formatted email using the Amazon SES API](send-email-formatted.md).
+ **Raw—**You manually compose and send an email message, specifying your own email headers and MIME types. If you're experienced in formatting your own email, the raw interface gives you more control over the composition of your message. For more information, see [Sending raw email using the Amazon SES API v2](send-email-raw.md).

**Topics**
+ [Sending formatted email using the Amazon SES API](send-email-formatted.md)
+ [Sending raw email using the Amazon SES API v2](send-email-raw.md)
+ [Using templates to send personalized email with the Amazon SES API](send-personalized-email-api.md)
+ [Sending email through Amazon SES using an AWS SDK](send-an-email-using-sdk-programmatically.md)
+ [Content encodings supported by Amazon SES](content-encodings.md)

# Sending formatted email using the Amazon SES API
<a name="send-email-formatted"></a>

You can send a formatted email by using the AWS Management Console or by calling the Amazon SES API through an application directly, or indirectly through an AWS SDK, the AWS Command Line Interface, or the AWS Tools for Windows PowerShell.

The Amazon SES API provides the `SendEmail` action, which lets you compose and send a formatted email. `SendEmail` requires a From: address, To: address, message subject, and message body—text, HTML, or both. For more information, see [SendEmail](https://docs.aws.amazon.com/ses/latest/APIReference/API_SendEmail.html) (API Reference) or [SendEmail](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_SendEmail.html) (API v2 Reference).

**Note**  
The email address string must be 7-bit ASCII. If you want to send to or from email addresses that contain Unicode characters in the domain part of an address, you must encode the domain using Punycode. For more information, see [RFC 3492](https://tools.ietf.org/html/rfc3492).

For examples of how to compose a formatted message using various programming languages, see [Code examples](send-an-email-using-sdk-programmatically.md#send-an-email-using-sdk-programmatically-examples).

For tips on how to increase your email sending speed when you make multiple calls to `SendEmail`, see [Increasing throughput with Amazon SES](troubleshoot-throughput-problems.md).

# Sending raw email using the Amazon SES API v2
<a name="send-email-raw"></a>

You can use the Amazon SES API v2 `SendEmail` operation with the content type specified as `raw` to send customized messages to your recipients using the raw email format.

## About email header fields
<a name="send-email-raw-headers"></a>

Simple Mail Transfer Protocol (SMTP) specifies how email messages are to be sent by defining the mail envelope and some of its parameters, but it does not concern itself with the content of the message. Instead, the Internet Message Format ([RFC 5322](https://www.ietf.org/rfc/rfc5322.txt)) defines how the message is to be constructed.

With the Internet Message Format specification, every email message consists of a header and a body. The header consists of message metadata, and the body contains the message itself. For more information about email headers and bodies, see [Email format in Amazon SES](send-email-concepts-email-format.md).

## Using raw email MIME message construction
<a name="send-email-raw-mime"></a>

The SMTP protocol was originally designed to send email messages that only contained 7-bit ASCII characters. This specification makes SMTP insufficient for non-ASCII text encodings (such as Unicode), binary content, or attachments. The Multipurpose Internet Mail Extensions standard (MIME) was developed to make it possible to send many other kinds of content using SMTP.

The MIME standard works by breaking the message body into multiple parts and then specifying what is to be done with each part. For example, one part of an email message body might be plain text, while another might be HTML. In addition, MIME allows email messages to contain one or more attachments. Message recipients can view the attachments from within their email clients, or they can save the attachments.

The message header and content are separated by a blank line. Each part of the email is separated by a boundary, a string of characters that denotes the beginning and ending of each part.

The multipart message in the following example contains a text and an HTML part, and an attachment. The attachment should be placed just below the [attachment headers](#send-email-mime-encoding-files) and is most often encoded in `base64` as shown in this example.

```
 1. From: "Sender Name" <sender@example.com>
 2. To: recipient@example.com
 3. Subject: Customer service contact info
 4. Content-Type: multipart/mixed;
 5.     boundary="a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a"
 6. 
 7. --a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a
 8. Content-Type: multipart/alternative;
 9.     boundary="sub_a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a"
10. 
11. --sub_a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a
12. Content-Type: text/plain; charset=iso-8859-1
13. Content-Transfer-Encoding: quoted-printable
14. 
15. Please see the attached file for a list of customers to contact.
16. 
17. --sub_a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a
18. Content-Type: text/html; charset=iso-8859-1
19. Content-Transfer-Encoding: quoted-printable
20. 
21. <html>
22. <head></head>
23. <body>
24. <h1>Hello!</h1>
25. <p>Please see the attached file for a list of customers to contact.</p>
26. </body>
27. </html>
28. 
29. --sub_a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a--
30. 
31. --a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a
32. Content-Type: text/plain; name="customers.txt"
33. Content-Description: customers.txt
34. Content-Disposition: attachment;filename="customers.txt";
35.     creation-date="Sat, 05 Aug 2017 19:35:36 GMT";
36. Content-Transfer-Encoding: base64
37. 
38. SUQsRmlyc3ROYW1lLExhc3ROYW1lLENvdW50cnkKMzQ4LEpvaG4sU3RpbGVzLENhbmFkYQo5MjM4
39. OSxKaWUsTGl1LENoaW5hCjczNCxTaGlybGV5LFJvZHJpZ3VleixVbml0ZWQgU3RhdGVzCjI4OTMs
40. QW5heWEsSXllbmdhcixJbmRpYQ==
41. 
42. --a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a--
```

The content type for the message is `multipart/mixed`, which indicates that the message has many parts (in this example, a body and an attachment), and the receiving client must handle each part separately.

Nested within the body section is a second part that uses the `multipart/alternative` content type. This content type indicates that each part contains alternative versions of the same content (in this case, a text version and an HTML version). If the recipient's email client can display HTML content, then it shows the HTML version of the message body. If the recipient's email client can't display HTML content, then it shows the plain text version of the message body.

Both versions of the message also contain an attachment (in this case, a short text file that contains some customer names).

When you nest a MIME part within another part, as in this example, the nested part must use a `boundary` parameter that is distinct from the `boundary` parameter in the parent part. These boundaries should be unique strings of characters. To define a boundary between MIME parts, type two hyphens (--) followed by the boundary string. At the end of a MIME part, place two hyphens at both the beginning and the end of the boundary string.

**Note**  
A message cannot have more than 500 MIME parts.

### MIME Encoding
<a name="send-email-mime-encoding"></a>

To maintain compatibility with older systems, Amazon SES honors the 7-bit ASCII limitation of SMTP as defined in [RFC 2821](https://tools.ietf.org/html/rfc2821). If you want to send content that contains non-ASCII characters, you must encode those characters into a format that uses 7-bit ASCII characters.

#### Email addresses
<a name="send-email-mime-encoding-addresses"></a>

The email address string must be 7-bit ASCII. If you want to send to or from email addresses that contain Unicode characters in the domain part of an address, you must encode the domain using Punycode. Punycode is not permitted in the local part of the email address (the part before the @ sign) nor in the "friendly from" name. If you want to use Unicode characters in the "friendly from" name, you must encode the "friendly from" name using MIME encoded-word syntax, as described in this section. For more information about Punycode, see [RFC 3492](http://tools.ietf.org/html/rfc3492).

**Note**  
This rule only applies to email addresses that you specify in the message envelope, not the message headers. When you use the Amazon SES API v2 `SendEmail` operation, the addresses you specify in the `Source` and `Destinations` parameters define the envelope sender and recipients, respectively.

#### Email headers
<a name="send-email-mime-encoding-headers"></a>

To encode a message header, use MIME encoded-word syntax. MIME encoded word syntax uses the following format:

```
=?charset?encoding?encoded-text?=
```

The value of `encoding` can be either `Q` or `B`. If the value of encoding is `Q`, then the value `encoded-text` has to use Q-encoding. If the value of encoding is `B`, then the value of `encoded-text` has to use base64 encoding.

For example, if you want to use the string "Як ти поживаєш?" in the subject line of an email, you can use either of the following encodings:
+ **Q-encoding**

  ```
  =?utf-8?Q?=D0=AF=D0=BA_=D1=82=D0=B8_=D0=BF=D0=BE=D0=B6=D0=B8=D0=B2=D0=B0=D1=94=D1=88=3F?=
  ```
+ **Base64 encoding**

  ```
  =?utf-8?B?0K/QuiDRgtC4INC/0L7QttC40LLQsNGU0Yg/?=
  ```

For more information about Q-encoding, see [RFC 2047](https://tools.ietf.org/html/rfc2047). For more information about base64 encoding, see [RFC 2045](https://tools.ietf.org/html/rfc2045).

#### Message body
<a name="send-email-mime-encoding-body"></a>

To encode the body of a message, you can use quoted-printable encoding or base64 encoding. Then, use the `Content-Transfer-Encoding` header to indicate which encoding scheme you used.

For example, assume the body of your message contains the following text: 

१९७२ मे रे टॉमलिंसन ने पहला ई-मेल संदेश भेजा \$1 रे टॉमलिंसन ने ही सर्वप्रथम @ चिन्ह का चयन किया और इन्ही को ईमेल का आविष्कारक माना जाता है

If you choose to encode this text using base64 encoding, first specify the following header:

```
Content-Transfer-Encoding: base64
```

Then, in the body section of the email, include the base64-encoded text:

```
4KWn4KWv4KWt4KWoIOCkruClhyDgpLDgpYcg4KSf4KWJ4KSu4KSy4KS/4KSC4KS44KSoIOCkqOCl
hyDgpKrgpLngpLLgpL4g4KSILeCkruClh+CksiDgpLjgpILgpKbgpYfgpLYg4KSt4KWH4KSc4KS+
IHwg4KSw4KWHIOCkn+ClieCkruCksuCkv+CkguCkuOCkqCDgpKjgpYcg4KS54KWAIOCkuOCksOCl
jeCkteCkquCljeCksOCkpeCkriBAIOCkmuCkv+CkqOCljeCkuSDgpJXgpL4g4KSa4KSv4KSoIOCk
leCkv+Ckr+CkviDgpJTgpLAg4KSH4KSo4KWN4KS54KWAIOCkleCliyDgpIjgpK7gpYfgpLIg4KSV
4KS+IOCkhuCkteCkv+Ckt+CljeCkleCkvuCksOCklSDgpK7gpL7gpKjgpL4g4KSc4KS+4KSk4KS+
IOCkueCliAo=
```

**Note**  
In some cases, you can use the 8bit `Content-Transfer-Encoding` in messages that you send using Amazon SES. However, if Amazon SES has to make any changes to your messages (for example, when you use [open and click tracking](faqs-metrics.md)), 8-bit-encoded content might not appear correctly when it arrives in recipients' inboxes. For this reason, you should always encode content that isn't 7-bit ASCII.

#### File attachments
<a name="send-email-mime-encoding-files"></a>

To attach a file to an email, you have to encode the attachment using base64 encoding. Attachments are typically placed in dedicated MIME message parts, which include the following headers:
+ **Content-Type** – The file type of the attachment. The following are examples of common MIME Content-Type declarations:
  + **Plain text file** – `Content-Type: text/plain; name="sample.txt"`
  + **Microsoft Word Document** – `Content-Type: application/msword; name="document.docx"`
  + **JPG image** – `Content-Type: image/jpeg; name="photo.jpeg"`
+ **Content-Disposition** – Specifies how the recipient's email client should handle the content. For attachments, this value is `Content-Disposition: attachment`.
+ **Content-Transfer-Encoding** – The scheme that was used to encode the attachment. For file attachments, this value is almost always `base64`.
+ **The encoded attachment** – You must encode the actual attachment and include it in the body below the attachment headers as [shown in the example](#send-email-raw-mime).

Amazon SES accepts most common file types. For a list of file types that Amazon SES doesn't accept, see [SES unsupported attachment types](attachments.md#mime-types).

## Sending raw email using the Amazon SES API v2
<a name="send-email-raw-api"></a>

The Amazon SES API v2 provides the `SendEmail` action, which lets you compose and send an email message in the format that you specify when you set the content type to either simple, raw, or templated. For a complete description, see [https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_SendEmail.html](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_SendEmail.html). The following example will specify the content type as `raw` to send a messages using the raw email format.

**Note**  
For tips on how to increase your email sending speed when you make multiple calls to `SendEmail`, see [Increasing throughput with Amazon SES](troubleshoot-throughput-problems.md).

The message body must contain a properly formatted, raw email message, with appropriate header fields and message body encoding. Although it's possible to construct the raw message manually within an application, it's much easier to do so using existing mail libraries. 

------
#### [ Java ]

The following code example shows how to use the [JavaMail](https://javaee.github.io/javamail/) library and the [AWS SDK for Java](https://aws.amazon.com/sdk-for-java) to compose and send a raw email.

```
  1. package com.amazonaws.samples;
  2. 
  3. import java.io.ByteArrayOutputStream;
  4. import java.io.IOException;
  5. import java.io.PrintStream;
  6. import java.nio.ByteBuffer;
  7. import java.util.Properties;
  8. 
  9. // JavaMail libraries. Download the JavaMail API 
 10. // from https://javaee.github.io/javamail/
 11. import javax.activation.DataHandler;
 12. import javax.activation.DataSource;
 13. import javax.activation.FileDataSource;
 14. import javax.mail.Message;
 15. import javax.mail.MessagingException;
 16. import javax.mail.Session;
 17. import javax.mail.internet.AddressException;
 18. import javax.mail.internet.InternetAddress;
 19. import javax.mail.internet.MimeBodyPart;
 20. import javax.mail.internet.MimeMessage;
 21. import javax.mail.internet.MimeMultipart;
 22. 
 23. // AWS SDK libraries. Download the AWS SDK for Java 
 24. // from https://aws.amazon.com/sdk-for-java
 25. import com.amazonaws.regions.Regions;
 26. import com.amazonaws.services.simpleemail.AmazonSimpleEmailService;
 27. import com.amazonaws.services.simpleemail.AmazonSimpleEmailServiceClientBuilder;
 28. import com.amazonaws.services.simpleemail.model.RawMessage;
 29. import com.amazonaws.services.simpleemail.model.SendRawEmailRequest;
 30. 
 31. public class AmazonSESSample {
 32. 
 33. 	// Replace sender@example.com with your "From" address.
 34. 	// This address must be verified with Amazon SES.
 35. 	private static String SENDER = "Sender Name <sender@example.com>";
 36. 
 37. 	// Replace recipient@example.com with a "To" address. If your account 
 38. 	// is still in the sandbox, this address must be verified.
 39. 	private static String RECIPIENT = "recipient@example.com";
 40. 
 41. 	// Specify a configuration set. If you do not want to use a configuration
 42. 	// set, comment the following variable, and the 
 43. 	// ConfigurationSetName=CONFIGURATION_SET argument below.
 44. 	private static String CONFIGURATION_SET = "ConfigSet";
 45. 
 46. 	// The subject line for the email.
 47. 	private static String SUBJECT = "Customer service contact info";
 48. 
 49. 	// The full path to the file that will be attached to the email.
 50. 	// If you're using Windows, escape backslashes as shown in this variable.
 51. 	private static String ATTACHMENT = "C:\\Users\\sender\\customers-to-contact.xlsx";
 52. 
 53. 	// The email body for recipients with non-HTML email clients.
 54. 	private static String BODY_TEXT = "Hello,\r\n"
 55.                                         + "Please see the attached file for a list "
 56.                                         + "of customers to contact.";
 57. 
 58. 	// The HTML body of the email.
 59. 	private static String BODY_HTML = "<html>"
 60.                                         + "<head></head>"
 61.                                         + "<body>"
 62.                                         + "<h1>Hello!</h1>"
 63.                                         + "<p>Please see the attached file for a "
 64.                                         + "list of customers to contact.</p>"
 65.                                         + "</body>"
 66.                                         + "</html>";
 67. 
 68.     public static void main(String[] args) throws AddressException, MessagingException, IOException {
 69.             	
 70.     	Session session = Session.getDefaultInstance(new Properties());
 71.         
 72.         // Create a new MimeMessage object.
 73.         MimeMessage message = new MimeMessage(session);
 74.         
 75.         // Add subject, from and to lines.
 76.         message.setSubject(SUBJECT, "UTF-8");
 77.         message.setFrom(new InternetAddress(SENDER));
 78.         message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(RECIPIENT));
 79. 
 80.         // Create a multipart/alternative child container.
 81.         MimeMultipart msg_body = new MimeMultipart("alternative");
 82.         
 83.         // Create a wrapper for the HTML and text parts.        
 84.         MimeBodyPart wrap = new MimeBodyPart();
 85.         
 86.         // Define the text part.
 87.         MimeBodyPart textPart = new MimeBodyPart();
 88.         textPart.setContent(BODY_TEXT, "text/plain; charset=UTF-8");
 89.                 
 90.         // Define the HTML part.
 91.         MimeBodyPart htmlPart = new MimeBodyPart();
 92.         htmlPart.setContent(BODY_HTML,"text/html; charset=UTF-8");
 93.                 
 94.         // Add the text and HTML parts to the child container.
 95.         msg_body.addBodyPart(textPart);
 96.         msg_body.addBodyPart(htmlPart);
 97.         
 98.         // Add the child container to the wrapper object.
 99.         wrap.setContent(msg_body);
100.         
101.         // Create a multipart/mixed parent container.
102.         MimeMultipart msg = new MimeMultipart("mixed");
103.         
104.         // Add the parent container to the message.
105.         message.setContent(msg);
106.         
107.         // Add the multipart/alternative part to the message.
108.         msg.addBodyPart(wrap);
109.         
110.         // Define the attachment
111.         MimeBodyPart att = new MimeBodyPart();
112.         DataSource fds = new FileDataSource(ATTACHMENT);
113.         att.setDataHandler(new DataHandler(fds));
114.         att.setFileName(fds.getName());
115.         
116.         // Add the attachment to the message.
117.         msg.addBodyPart(att);
118. 
119.         // Try to send the email.
120.         try {
121.             System.out.println("Attempting to send an email through Amazon SES "
122.                               +"using the AWS SDK for Java...");
123. 
124.             // Instantiate an Amazon SES client, which will make the service 
125.             // call with the supplied AWS credentials.
126.             AmazonSimpleEmailService client = 
127.                     AmazonSimpleEmailServiceClientBuilder.standard()
128.                     // Replace US_WEST_2 with the AWS Region you're using for
129.                     // Amazon SES.
130.                     .withRegion(Regions.US_WEST_2).build();
131.             
132.             // Print the raw email content on the console
133.             PrintStream out = System.out;
134.             message.writeTo(out);
135. 
136.             // Send the email.
137.             ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
138.             message.writeTo(outputStream);
139.             RawMessage rawMessage = 
140.             		new RawMessage(ByteBuffer.wrap(outputStream.toByteArray()));
141. 
142.             SendRawEmailRequest rawEmailRequest = 
143.             		new SendRawEmailRequest(rawMessage)
144.             		    .withConfigurationSetName(CONFIGURATION_SET);
145.             
146.             client.sendRawEmail(rawEmailRequest);
147.             System.out.println("Email sent!");
148.         // Display an error if something goes wrong.
149.         } catch (Exception ex) {
150.           System.out.println("Email Failed");
151.             System.err.println("Error message: " + ex.getMessage());
152.             ex.printStackTrace();
153.         }
154.     }
155. }
```

------
#### [ Python ]

The following code example shows how to use the [Python email.mime](https://docs.python.org/3.8/library/email.mime.html) packages and the [AWS SDK for Python (Boto)](https://aws.amazon.com/sdk-for-python) to compose and send a raw email.

```
 1. import json
 2. import boto3
 3. from botocore.exceptions import ClientError
 4. from email.mime.multipart import MIMEMultipart
 5. from email.mime.text import MIMEText
 6. from email.mime.application import MIMEApplication
 7. import os
 8. 
 9. def boto3_rawemailv2():
10.     SENDER = "Sender <sender@example.com>"
11.     RECIPIENT = "recipient@example.com"
12.     CONFIGURATION_SET = "ConfigSet"
13.     AWS_REGION = "us-east-1"
14.     SUBJECT = "Customer service contact info"
15.     ATTACHMENT = "path/to/customers-to-contact.xlsx"
16.     BODY_TEXT = "Hello,\r\nPlease see the attached file for a list of customers to contact."
17. 
18.     # The HTML body of the email.
19.     BODY_HTML = """\
20.     <html>
21.     <head/>
22.     <body>
23.     <h1>Hello!</h1>
24.     <p>Please see the attached file for a list of customers to contact.</p>
25.     </body>
26.     </html>
27.     """
28. 
29.     # The character encoding for the email.
30.     CHARSET = "utf-8"
31.     msg = MIMEMultipart('mixed')
32.     # Add subject, from and to lines.
33.     msg['Subject'] = SUBJECT 
34.     msg['From'] = SENDER 
35.     msg['To'] = RECIPIENT
36.     
37.     # Create a multipart/alternative child container.
38.     msg_body = MIMEMultipart('alternative')
39.     
40.     # Encode the text and HTML content and set the character encoding. This step is
41.     # necessary if you're sending a message with characters outside the ASCII range.
42.     textpart = MIMEText(BODY_TEXT.encode(CHARSET), 'plain', CHARSET)
43.     htmlpart = MIMEText(BODY_HTML.encode(CHARSET), 'html', CHARSET)
44.     
45.     # Add the text and HTML parts to the child container.
46.     msg_body.attach(textpart)
47.     msg_body.attach(htmlpart)
48.     
49.     # Define the attachment part and encode it using MIMEApplication.
50.     att = MIMEApplication(open(ATTACHMENT, 'rb').read())
51.     
52.     # Add a header to tell the email client to treat this part as an attachment,
53.     # and to give the attachment a name.
54.     att.add_header('Content-Disposition','attachment',filename=os.path.basename(ATTACHMENT))
55.     
56.     # Attach the multipart/alternative child container to the multipart/mixed
57.     # parent container.
58.     msg.attach(msg_body)
59.     msg.attach(att)
60. 
61.     #changes start from here
62.     strmsg = str(msg)
63.     body = bytes (strmsg, 'utf-8')
64. 
65. 
66. 
67.     
68.     client = boto3.client('sesv2')
69.     response = client.send_email(
70.     FromEmailAddress=SENDER,
71.     Destination={
72.         'ToAddresses': [RECIPIENT]
73.     },
74.     Content={
75.         'Raw': {
76.             'Data': body
77.         }
78.     }
79.     )
80.     print(response)
81. boto3_rawemailv2 ()
```

------

# Using templates to send personalized email with the Amazon SES API
<a name="send-personalized-email-api"></a>

In Amazon SES you can send templated email either by using a *stored template* or by using an *inline template*.
+ **Stored template** – Refers to the [https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_Template.html](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_Template.html) resource that is created and saved in SES by using the `CreateEmailTemplate` operation in the Amazon SES v2 API. The template contains the subject and body of the email containing variables (placeholders) inline with the written content. The name of the stored template and the dynamic data to the placeholder variables in the template are provided when calling either the `SendEmail` or `SendBulkEmail` v2 API operations.

  *Stored templates* can be easily reused and can save you time and effort when sending similar types of emails. Instead of creating each email from scratch, you only need to create the base structure and design once, then simply update the dynamic content within the template.
+ **Inline template** – The `Template` resource is not used, but rather, the subject and body of the email containing variables (placeholders) inline with the written content along with the values for those placeholder variables are provided when calling either the `SendEmail` or `SendBulkEmail` v2 API operations.

  *Inline templates* streamline the process for sending bulk email by eliminating the need to manage template resources in your SES account and simplify the integration process by allowing you to include template content directly within your application logic. They do not count against the 20,000-template limit per AWS Region.

The following limits apply when using *stored templates*:
+ You can create up to 20,000 email templates in each AWS Region.
+ Each template can be up to 500 KB in size, including both the text and HTML parts.

The following limit applies when using *inline templates*:
+ Each input JSON file can be up to 1 MB in size, including both the text and HTML parts.

The following applies to both *stored* and *inline templates*:
+ There are no limits to the number of replacement variables that can be used.
+ You can send email to up to 50 destination objects in each call to the `SendBulkEmail` operation. The [https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_Destination.html](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_Destination.html) object can contain multiple recipients defined in **ToAddresses**, **CcAddresses**, and **BccAddresses**. The number of destinations you can contact in a single call to the v2 API may be limited by your account's maximum sending rate. For more information, see [Managing your Amazon SES sending limits](manage-sending-quotas.md).

This chapter includes procedures with examples for using both *stored templates* and *inline templates*.

**Note**  
The procedures in this section assume that you've already installed and configured the AWS CLI. For more information about installing and configuring the AWS CLI, see the [AWS Command Line Interface User Guide](https://docs.aws.amazon.com/cli/latest/userguide/).

## (Optional) Part 1: Set up Rendering Failure event notifications
<a name="send-personalized-email-set-up-notifications"></a>

 If you send an email that contains invalid personalization content, Amazon SES might accept the message, but won't be able to deliver it. For this reason, if you plan to send personalized email, you should configure SES to send Rendering Failure event notifications through Amazon SNS. When you receive a Rendering Failure event notification, you can identify which message contained the invalid content, fix the issues, and send the message again.

The procedure in this section is optional, but highly recommended.

**To configure Rendering Failure event notifications**

1. Create an Amazon SNS topic. For procedures, see [Create a Topic](https://docs.aws.amazon.com/sns/latest/dg/sns-create-subscribe-endpoint-to-topic.html) in the *Amazon Simple Notification Service Developer Guide*.

1. Subscribe to the Amazon SNS topic. For example, if you want to receive Rendering Failure notifications by email, subscribe an email endpoint (that is, your email address) to the topic.

   For procedures, see [Subscribe to a Topic](https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html) in the *Amazon Simple Notification Service Developer Guide*.

1. Complete the procedures in [Set up an Amazon SNS event destination for event publishing](event-publishing-add-event-destination-sns.md) to set up your configuration sets to publish Rendering Failure events to your Amazon SNS topic.

## (Optional) Part 2: Create an email template
<a name="send-personalized-email-create-template"></a>

If you intend on using a *stored template*, this section will show you how to use the [https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_CreateEmailTemplate.html](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_CreateEmailTemplate.html) SES v2 API operation to create the template. You can skip this step if you want to use an *inline template*.

This procedure assumes that you've already installed and configured the AWS CLI. For more information about installing and configuring the AWS CLI, see the [AWS Command Line Interface User Guide](https://docs.aws.amazon.com/cli/latest/userguide/).

**To create the template**

1. In a text editor, create a new file and paste the following code customizing it as you need.

   ```
   {
       "TemplateName": "MyTemplate",
       "TemplateContent": {
           "Subject": "Greetings, {{name}}!",
           "Text": "Dear {{name}},\r\nYour favorite animal is {{favoriteanimal}}.",
           "Html": "<h1>Hello {{name}},</h1><p>Your favorite animal is {{favoriteanimal}}.</p>"
       }
   }
   ```

   This code contains the following properties:
   + **TemplateName** – The name of the `Template` resource. When you send the email, you refer to this name.
   + **TemplateContent** – A container for the following attributes:
     + **Subject** – The subject line of the email. This property may contain replacement tags. These tags use the following format: `{{tagname}}`. When you send the email, you can specify a value for `tagname` for each destination.
     + **Html** – The HTML body of the email. This property may contain replacement tags. The preceding example includes two tags: `{{name}}` and `{{favoriteanimal}}`.
     + **Text** – The text body of the email. Recipients whose email clients don't display HTML content will see this version of the email. This property may also contain replacement tags.

1. Customize the preceding example to fit your needs, and then save the file as *mytemplate.json*.

1. At the command line, type the following command to create a new template using the [https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_CreateEmailTemplate.html](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_CreateEmailTemplate.html) v2 API operation:

   ```
   aws sesv2 create-email-template --cli-input-json file://mytemplate.json
   ```

## Part 3: Sending the personalized email
<a name="send-personalized-email-api-operations"></a>

You can use the following two SES v2 API operations to send emails using either *stored templates* or *inline templates*:
+ The [https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_SendEmail.html](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_SendEmail.html) operation is useful for sending a customized email to a single destination object. The v2 API [https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_Destination.html](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_Destination.html) object can contain the *ToAddresses*, *CcAddresses*, and *BccAddresses* properties. These can be used in any combination and can contain one or more email addresses that will receive the same email.
+ The [https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_SendBulkEmail.html](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_SendBulkEmail.html) operation is useful for sending unique emails to multiple destination objects in a single call to the v2 API.

This section provides examples of how to use the AWS CLI to send templated email using both of these send operations.

### Sending templated email to a single destination object
<a name="send-templated-email-single-destination"></a>

You can use the [https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_SendEmail.html](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_SendEmail.html) operation to send an email to one or more recipients defined in a single destination object. All of the recipients in the [https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_Destination.html](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_Destination.html) object will receive the same email.

**To send a templated email to a single destination object**

1. Depending on whether you want to use a *stored template* or *inline template*, select the respective code example to paste into a text editor, customizing it as you need.

------
#### [ Stored template code example ]

   Notice that the template you created in the previous step, *MyTemplate*, is being referenced as the value for the `TemplateName` parameter.

   ```
   {
       "FromEmailAddress": "Mary Major <mary.major@example.com>",
       "Destination": {
           "ToAddresses": [
               "alejandro.rosalez@example.com", "jimmy.jet@example.com"
           ]
       },
       "Content": {
           "Template": {
               "TemplateName": "MyTemplate",
               "TemplateData": "{ \"name\":\"Alejandro\", \"favoriteanimal\": \"alligator\" }"
           }
       },
       "ConfigurationSetName": "ConfigSet"
   }
   ```

   This code contains the following properties:
   + **FromEmailAddress** – The email address of the sender.
   + **Destination** – An object containing the email recipients defined in the *ToAddresses*, *CcAddresses*, and *BccAddresses* properties. These can be used in any combination and can contain one or more email addresses that will receive the same email.
   + **TemplateName** – The name of the `Template` resource to apply to the email.
   + **TemplateData** – An escaped JSON string that contains key-value pairs. The keys correspond to the variables defined in the `TemplateContent` properties in the stored template, for example, `{{name}}`. The values represent the content that replaces the variables.
   + **ConfigurationSetName** – The name of the configuration set to use when sending the email.
**Note**  
We recommend that you use a configuration set that is configured to publish Rendering Failure events to Amazon SNS. For more information, see [(Optional) Part 1: Set up Rendering Failure event notifications](#send-personalized-email-set-up-notifications).

------
#### [ Inline template code example ]

   Notice that the `TemplateContent` properties (that would normally be defined in a *stored template*), are being defined *inline* along with the `TemplateData` property which makes this an *inline template*.

   ```
   {
       "FromEmailAddress": "Mary Major <mary.major@example.com>",
       "Destination": {
           "ToAddresses": [
               "alejandro.rosalez@example.com", "jimmy.jet@example.com"
           ]
       },
       "Content": {
           "Template": {
               "TemplateContent": {
                   "Subject": "Greetings, {{name}}!",
                   "Text": "Dear {{name}},\r\nYour favorite animal is {{favoriteanimal}}.",
                   "Html": "<h1>Hello {{name}},</h1><p>Your favorite animal is {{favoriteanimal}}.</p>"
               },
               "TemplateData": "{ \"name\":\"Alejandro\", \"favoriteanimal\": \"alligator\" }"
           }
       },
       "ConfigurationSetName": "ConfigSet"
   }
   ```

   This code contains the following properties:
   + **FromEmailAddress** – The email address of the sender.
   + **Destination** – An object containing the email recipients defined in the *ToAddresses*, *CcAddresses*, and *BccAddresses* properties. These can be used in any combination and can contain one or more email addresses that will receive the same email.
   + **TemplateContent** – A container for the following attributes:
     + **Subject** – The subject line of the email. This property may contain replacement tags. These tags use the following format: `{{tagname}}`. When you send the email, you can specify a value for `tagname` for each destination.
     + **Html** – The HTML body of the email. This property may contain replacement tags. The preceding example includes two tags: `{{name}}` and `{{favoriteanimal}}`.
     + **Text** – The text body of the email. Recipients whose email clients don't display HTML content will see this version of the email. This property may also contain replacement tags.
   + **TemplateData** – An escaped JSON string that contains key-value pairs. The keys correspond to the variables defined in the `TemplateContent` properties in this file, for example, `{{name}}`. The values represent the content that replaces the variables.
   + **ConfigurationSetName** – The name of the configuration set to use when sending the email.
**Note**  
We recommend that you use a configuration set that is configured to publish Rendering Failure events to Amazon SNS. For more information, see [(Optional) Part 1: Set up Rendering Failure event notifications](#send-personalized-email-set-up-notifications).

------

1. Customize the preceding example to fit your needs, and then save the file as *myemail.json*.

1. At the command line, type the following v2 API command to send the email:

   ```
   aws sesv2 send-email --cli-input-json file://myemail.json
   ```

### Sending templated email to multiple destination objects
<a name="send-templated-email-multiple-destinations"></a>

You can use the [https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_SendBulkEmail.html](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_SendBulkEmail.html) operation to send an email to multiple destination objects in a single call to the SES v2 API. SES sends a unique email to the recipient or recipients in each [https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_Destination.html](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_Destination.html) object.

**To send a templated email to multiple destination objects**

1. Depending on whether you want to use a *stored template* or *inline template*, select the respective code example to paste into a text editor, customizing it as you need.

------
#### [ Stored template code example ]

   Notice that the template you created in the previous step, *MyTemplate*, is being referenced as the value for the `TemplateName` parameter.

   ```
   {
       "FromEmailAddress": "Mary Major <mary.major@example.com>",
       "DefaultContent": {
           "Template": {
               "TemplateName": "MyTemplate",
               "TemplateData": "{ \"name\":\"friend\", \"favoriteanimal\":\"unknown\" }"
           }
       },
       "BulkEmailEntries": [
           {
               "Destination": {
                   "ToAddresses": [
                       "anaya.iyengar@example.com"
                   ]
               },
               "ReplacementEmailContent": {
                   "ReplacementTemplate": {
                       "ReplacementTemplateData": "{ \"name\":\"Anaya\", \"favoriteanimal\":\"angelfish\" }"
                   }
               }
           },
           {
               "Destination": {
                   "ToAddresses": [
                       "liu.jie@example.com"
                   ]
               },
               "ReplacementEmailContent": {
                   "ReplacementTemplate": {
                       "ReplacementTemplateData": "{ \"name\":\"Liu\", \"favoriteanimal\":\"lion\" }"
                   }
               }
           },
           {
               "Destination": {
                   "ToAddresses": [
                       "shirley.rodriguez@example.com"
                   ]
               },
               "ReplacementEmailContent": {
                   "ReplacementTemplate": {
                       "ReplacementTemplateData": "{ \"name\":\"Shirley\", \"favoriteanimal\":\"shark\" }"
                   }
               }
           },
           {
               "Destination": {
                   "ToAddresses": [
                       "richard.roe@example.com"
                   ]
               },
               "ReplacementEmailContent": {
                   "ReplacementTemplate": {
                       "ReplacementTemplateData": "{}"
                   }
               }
           }
       ],
       "ConfigurationSetName": "ConfigSet"
   }
   ```

   This code contains the following properties:
   + **FromEmailAddress** – The email address of the sender.
   + **DefaultContent** – A JSON object that contains the `TemplateName` and `TemplateData` objects. 
   + **TemplateName** – The name of the `Template` resource to apply to the email.
   + **TemplateData** – Contains key-value pairs that will be used if the `ReplacementEmailContent` object contains an empty JSON object, `{}`, in the `ReplacementTemplateData` property.
   + **BulkEmailEntries** – An array that contains one or more `Destination` objects.
   + **Destination** – An object containing the email recipients defined in the *ToAddresses*, *CcAddresses*, and *BccAddresses* properties. These can be used in any combination and can contain one or more email addresses that will receive the same email.
   + **ReplacementTemplateData** – An escaped JSON string that contains key-value pairs. The keys correspond to the variables in the template, for example, `{{name}}`. The values represent the content that replaces the variables in the email. (If the JSON string here is empty, indicated by `{}`, the key-value pairs defined in the `TemplateData` property within the `DefaultContent` object will be used.)
   + **ConfigurationSetName** – The name of the configuration set to use when sending the email.
**Note**  
We recommend that you use a configuration set that is configured to publish Rendering Failure events to Amazon SNS. For more information, see [(Optional) Part 1: Set up Rendering Failure event notifications](#send-personalized-email-set-up-notifications).

------
#### [ Inline template code example ]

   Notice that the `TemplateContent` properties (that would normally be defined in a *stored template*), are being defined *inline* along with the `TemplateData` property which makes this an *inline template*.

   ```
   {
       "FromEmailAddress": "Mary Major <mary.major@example.com>",
       "DefaultContent": {
           "Template": {
               "TemplateContent": {
                   "Subject": "Greetings, {{name}}!",
                   "Text": "Dear {{name}},\r\nYour favorite animal is {{favoriteanimal}}.",
                   "Html": "<h1>Hello {{name}},</h1><p>Your favorite animal is {{favoriteanimal}}.</p>"
               },
               "TemplateData": "{ \"name\":\"friend\", \"favoriteanimal\":\"unknown\" }"
           }
       },
       "BulkEmailEntries": [
           {
               "Destination": {
                   "ToAddresses": [
                       "anaya.iyengar@example.com"
                   ]
               },
               "ReplacementEmailContent": {
                   "ReplacementTemplate": {
                       "ReplacementTemplateData": "{ \"name\":\"Anaya\", \"favoriteanimal\":\"angelfish\" }"
                   }
               }
           },
           {
               "Destination": {
                   "ToAddresses": [
                       "liu.jie@example.com"
                   ]
               },
               "ReplacementEmailContent": {
                   "ReplacementTemplate": {
                       "ReplacementTemplateData": "{ \"name\":\"Liu\", \"favoriteanimal\":\"lion\" }"
                   }
               }
           },
           {
               "Destination": {
                   "ToAddresses": [
                       "shirley.rodriguez@example.com"
                   ]
               },
               "ReplacementEmailContent": {
                   "ReplacementTemplate": {
                       "ReplacementTemplateData": "{ \"name\":\"Shirley\", \"favoriteanimal\":\"shark\" }"
                   }
               }
           },
           {
               "Destination": {
                   "ToAddresses": [
                       "richard.roe@example.com"
                   ]
               },
               "ReplacementEmailContent": {
                   "ReplacementTemplate": {
                       "ReplacementTemplateData": "{}"
                   }
               }
           }
       ],
       "ConfigurationSetName": "ConfigSet"
   }
   ```

   This code contains the following properties:
   + **FromEmailAddress** – The email address of the sender.
   + **DefaultContent** – A JSON object that contains the `TemplateContent` and `TemplateData` objects. 
   + **TemplateContent** – A container for the following attributes:
     + **Subject** – The subject line of the email. This property may contain replacement tags. These tags use the following format: `{{tagname}}`. When you send the email, you can specify a value for `tagname` for each destination.
     + **Html** – The HTML body of the email. This property may contain replacement tags. The preceding example includes two tags: `{{name}}` and `{{favoriteanimal}}`.
     + **Text** – The text body of the email. Recipients whose email clients don't display HTML content will see this version of the email. This property may also contain replacement tags.
   + **TemplateData** – Contains key-value pairs that will be used if the `ReplacementEmailContent` object contains an empty JSON object, `{}`, in the `ReplacementTemplateData` property.
   + **BulkEmailEntries** – An array that contains one or more `Destination` objects.
   + **Destination** – An object containing the email recipients defined in the *ToAddresses*, *CcAddresses*, and *BccAddresses* properties. These can be used in any combination and can contain one or more email addresses that will receive the same email.
   + **ReplacementTemplateData** – An escaped JSON string that contains key-value pairs. The keys correspond to the variables defined in the `TemplateContent` properties in this file, for example, `{{name}}`. The values represent the content that replaces the variables in the email. (If the JSON string here is empty, indicated by `{}`, the key-value pairs defined in the `TemplateData` property within the `DefaultContent` object will be used.)
   + **ConfigurationSetName** – The name of the configuration set to use when sending the email.
**Note**  
We recommend that you use a configuration set that is configured to publish Rendering Failure events to Amazon SNS. For more information, see [(Optional) Part 1: Set up Rendering Failure event notifications](#send-personalized-email-set-up-notifications).

------

1. Change the values in the code in the previous step to meet your needs, and then save the file as *mybulkemail.json*.

1. At the command line, type the following v2 API command to send the bulk email:

   ```
   aws sesv2 send-bulk-email --cli-input-json file://mybulkemail.json
   ```

# Advanced email personalization
<a name="send-personalized-email-advanced"></a>

 If you're using a *stored template*, that is, you've created a [https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_Template.html](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_Template.html) resource in Amazon SES by using the `CreateEmailTemplate` operation with the SES v2 API, you can take advantage of the Handlebars system to create templates that include advanced features, such as nested attributes, array iteration, basic conditional statements, and the creation of inline partials. This section provides examples of these features.

Handlebars includes additional features beyond those documented in this section. For more information, see [Built-In Helpers](https://handlebarsjs.com/guide/builtin-helpers.html) at [handlebarsjs.com](http://handlebarsjs.com).

**Note**  
SES doesn't escape HTML content when rendering the HTML template for a message. This means if you're including user inputted data, such as from a contact form, you will need to escape it on the client side.

**Topics**
+ [Parsing nested attributes](#send-personalized-email-advanced-nested)
+ [Iterating through lists](#send-personalized-email-advanced-iterating)
+ [Using basic conditional statements](#send-personalized-email-advanced-conditionals)
+ [Creating inline partials](#send-personalized-email-advanced-inline-partials)

## Parsing nested attributes
<a name="send-personalized-email-advanced-nested"></a>

Handlebars includes support for nested paths, which makes it easy to organize complex customer data, and then refer to that data in your email templates.

For example, you can organize recipient data into several general categories. Within each of those categories, you can include detailed information. The following code example shows an example of this structure for a single recipient:

```
{
  "meta":{
    "userId":"51806220607"
  },
  "contact":{
    "firstName":"Anaya",
    "lastName":"Iyengar",
    "city":"Bengaluru",
    "country":"India",
    "postalCode":"560052"
  },
  "subscription":[
    {
      "interest":"Sports"
    },
    {
      "interest":"Travel"
    },
    {
      "interest":"Cooking"
    }
  ]
}
```

In your email templates, you can refer to nested attributes by providing the name of the parent attribute, followed by a period (.), followed by the name of the attribute for which you want to include the value. For example, if you use the data structure shown in the preceding example, and you want to include each recipient's first name in the email template, include the following text in your email template: `Hello {{contact.firstName}}!`

Handlebars can parse paths that are nested several levels deep, which means you have flexibility in how you structure your template data.

## Iterating through lists
<a name="send-personalized-email-advanced-iterating"></a>

The `each` helper function iterates through items in an array. The following code is an example of an email template that uses the `each` helper function to create an itemized list of each recipient's interests.

```
{
  "Template": {
    "TemplateName": "Preferences",
    "SubjectPart": "Subscription Preferences for {{contact.firstName}} {{contact.lastName}}",
    "HtmlPart": "<h1>Your Preferences</h1>
                 <p>You have indicated that you are interested in receiving 
                   information about the following subjects:</p>
                 <ul>
                   {{#each subscription}}
                     <li>{{interest}}</li>
                   {{/each}}
                 </ul>
                 <p>You can change these settings at any time by visiting 
                    the <a href=https://www.example.com/prefererences/i.aspx?id={{meta.userId}}>
                    Preference Center</a>.</p>",
    "TextPart": "Your Preferences\n\nYou have indicated that you are interested in 
                 receiving information about the following subjects:\n
                 {{#each subscription}}
                   - {{interest}}\n
                 {{/each}}
                 \nYou can change these settings at any time by 
                 visiting the Preference Center at 
                 https://www.example.com/prefererences/i.aspx?id={{meta.userId}}"
  }
}
```

**Important**  
In the preceding code example, the values of the `HtmlPart` and `TextPart` attributes include line breaks to make the example easier to read. The JSON file for your template can't contain line breaks within these values. If you copied and pasted this example into your own JSON file, remove the line breaks and extra spaces from the `HtmlPart` and `TextPart` sections before proceeding.

After you create the template, you can use the `SendEmail` or the `SendBulkEmail` operation to send email to recipients using this template. As long as each recipient has at least one value in the `Interests` object, they receive an email that includes an itemized list of their interests. The following example shows a JSON file that can be used to send email to multiple recipients using the preceding template:

```
{
  "Source":"Sender Name <sender@example.com>",
  "Template":"Preferences",
  "Destinations":[
    {
      "Destination":{
        "ToAddresses":[
          "anaya.iyengar@example.com"
        ]
      },
      "ReplacementTemplateData":"{\"meta\":{\"userId\":\"51806220607\"},\"contact\":{\"firstName\":\"Anaya\",\"lastName\":\"Iyengar\"},\"subscription\":[{\"interest\":\"Sports\"},{\"interest\":\"Travel\"},{\"interest\":\"Cooking\"}]}"
      },
    {
      "Destination":{ 
        "ToAddresses":[
          "shirley.rodriguez@example.com"
        ]
      },
      "ReplacementTemplateData":"{\"meta\":{\"userId\":\"1981624758263\"},\"contact\":{\"firstName\":\"Shirley\",\"lastName\":\"Rodriguez\"},\"subscription\":[{\"interest\":\"Technology\"},{\"interest\":\"Politics\"}]}"
    }
  ],
  "DefaultTemplateData":"{\"meta\":{\"userId\":\"\"},\"contact\":{\"firstName\":\"Friend\",\"lastName\":\"\"},\"subscription\":[]}"
}
```

When you send an email to the recipients listed in the preceding example using the `SendBulkEmail` operation, they receive a message that resembles the example shown in the following image:

![\[Preferences notification listing Sports, Travel, and Cooking as selected interests.\]](http://docs.aws.amazon.com/ses/latest/dg/images/send-personalized-email-advanced-condition-interest.png)


## Using basic conditional statements
<a name="send-personalized-email-advanced-conditionals"></a>

This section builds on the example described in the previous section. The example in the previous section uses the `each` helper to iterate through a list of interests. However, recipients for whom no interests are specified receive an email that contains an empty list. By using the `{{if}}` helper, you can format the email differently if a certain attribute is present in the template data. The following code uses the `{{if}}` helper to display the bulleted list from the preceding section if the `Subscription` array contains any values. If the array is empty, a different block of text is displayed.

```
{
  "Template": {
    "TemplateName": "Preferences2",
    "SubjectPart": "Subscription Preferences for {{contact.firstName}} {{contact.lastName}}",
    "HtmlPart": "<h1>Your Preferences</h1>
                 <p>Dear {{contact.firstName}},</p>
                 {{#if subscription}}
                   <p>You have indicated that you are interested in receiving 
                     information about the following subjects:</p>
                     <ul>
                     {{#each subscription}}
                       <li>{{interest}}</li>
                     {{/each}}
                     </ul>
                     <p>You can change these settings at any time by visiting 
                       the <a href=https://www.example.com/prefererences/i.aspx?id={{meta.userId}}>
                       Preference Center</a>.</p>
                 {{else}}
                   <p>Please update your subscription preferences by visiting 
                     the <a href=https://www.example.com/prefererences/i.aspx?id={{meta.userId}}>
                     Preference Center</a>.
                 {{/if}}",
    "TextPart": "Your Preferences\n\nDear {{contact.firstName}},\n\n
                 {{#if subscription}}
                   You have indicated that you are interested in receiving 
                   information about the following subjects:\n
                   {{#each subscription}}
                     - {{interest}}\n
                   {{/each}}
                   \nYou can change these settings at any time by visiting the 
                   Preference Center at https://www.example.com/prefererences/i.aspx?id={{meta.userId}}.
                 {{else}}
                   Please update your subscription preferences by visiting the 
                   Preference Center at https://www.example.com/prefererences/i.aspx?id={{meta.userId}}.
                 {{/if}}"
  }
}
```

**Important**  
In the preceding code example, the values of the `HtmlPart` and `TextPart` attributes include line breaks to make the example easier to read. The JSON file for your template can't contain line breaks within these values. If you copied and pasted this example into your own JSON file, remove the line breaks and extra spaces from the `HtmlPart` and `TextPart` sections before proceeding.

The following example shows a JSON file that can be used to send email to multiple recipients using the preceding template:

```
{
  "Source":"Sender Name <sender@example.com>",
  "Template":"Preferences2",
  "Destinations":[
    {
      "Destination":{
        "ToAddresses":[
          "anaya.iyengar@example.com"
        ]
      },
      "ReplacementTemplateData":"{\"meta\":{\"userId\":\"51806220607\"},\"contact\":{\"firstName\":\"Anaya\",\"lastName\":\"Iyengar\"},\"subscription\":[{\"interest\":\"Sports\"},{\"interest\":\"Cooking\"}]}"
      },
    {
      "Destination":{ 
        "ToAddresses":[
          "shirley.rodriguez@example.com"
        ]
      },
      "ReplacementTemplateData":"{\"meta\":{\"userId\":\"1981624758263\"},\"contact\":{\"firstName\":\"Shirley\",\"lastName\":\"Rodriguez\"}}"
    }
  ],
  "DefaultTemplateData":"{\"meta\":{\"userId\":\"\"},\"contact\":{\"firstName\":\"Friend\",\"lastName\":\"\"},\"subscription\":[]}"
}
```

In this example, the recipient whose template data included a list of interests receives the same email as the example shown in the previous section. The recipient whose template data did not include any interests, however, receives an email that resembles the example shown in the following image:

![\[Email message with header "Your Preferences" and text about updating subscription preferences.\]](http://docs.aws.amazon.com/ses/latest/dg/images/send-personalized-email-advanced-condition-nointerest.png)


## Creating inline partials
<a name="send-personalized-email-advanced-inline-partials"></a>

You can use inline partials to simplify templates that include repeated strings. For example, you could create an inline partial that includes the recipient's first name, and, if it's available, their last name by adding the following code to the beginning of your template:

```
{{#* inline \"fullName\"}}{{firstName}}{{#if lastName}} {{lastName}}{{/if}}{{/inline}}\n
```

**Note**  
The newline character (`\n`) is required to separate the `{{inline}}` block from the content in your template. The newline isn't rendered in the final output.

After you create the `fullName` partial, you can include it anywhere in your template by preceding the name of the partial with a greater-than (>) sign followed by a space, as in the following example: `{{> fullName}}`. Inline partials are not transferred between parts of the email. For example, if you want to use the same inline partial in both the HTML and the text version of the email, you must define it in both the `HtmlPart` and the `TextPart` sections.

You can also use inline partials when iterating through arrays. You can use the following code to create a template that uses the `fullName` inline partial. In this example, the inline partial applies to both the recipient's name and to an array of other names:

```
{
  "Template": {
    "TemplateName": "Preferences3",
    "SubjectPart": "{{firstName}}'s Subscription Preferences",
    "HtmlPart": "{{#* inline \"fullName\"}}
                   {{firstName}}{{#if lastName}} {{lastName}}{{/if}}
                 {{/inline~}}\n
                 <h1>Hello {{> fullName}}!</h1>
                 <p>You have listed the following people as your friends:</p>
                 <ul>
                 {{#each friends}}
                   <li>{{> fullName}}</li>
                 {{/each}}</ul>",
    "TextPart": "{{#* inline \"fullName\"}}
                   {{firstName}}{{#if lastName}} {{lastName}}{{/if}}
                 {{/inline~}}\n
                 Hello {{> fullName}}! You have listed the following people 
                 as your friends:\n
                 {{#each friends}}
                   - {{> fullName}}\n
                 {{/each}}"
  }
}
```

**Important**  
In the preceding code example, the values of the `HtmlPart` and `TextPart` attributes include line breaks to make the example easier to read. The JSON file for your template can't contain line breaks within these values. If you copied and pasted this example into your own JSON file, remove the line breaks and extra spaces from these sections.

# Managing email templates
<a name="send-personalized-email-manage-templates"></a>

In addition to [creating email templates](send-personalized-email-api.md), you can also use the Amazon SES v2 API to update or delete existing templates, to list all of your existing templates, or to view the contents of a template. 

This section contains procedures for using the AWS CLI to perform tasks related to SES templates.

**Note**  
The procedures in this section assume that you've already installed and configured the AWS CLI. For more information about installing and configuring the AWS CLI, see the [AWS Command Line Interface User Guide](https://docs.aws.amazon.com/cli/latest/userguide/).

## Viewing a list of email templates
<a name="send-personalized-email-manage-templates-list"></a>

You can use the [https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_ListEmailTemplate.html](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_ListEmailTemplate.html) SES v2 API operation to view a list of all of your existing email templates.

**To view a list of email templates**
+ At the command line, enter the following command:

  ```
  aws sesv2 list-email-templates
  ```

  If there are existing email templates in your SES account in the current Region, this command returns a response that resembles the following example:

  ```
  {
      "TemplatesMetadata": [
          {
              "Name": "SpecialOffers",
              "CreatedTimestamp": "2020-08-05T16:04:12.640Z"
          },
          {
              "Name": "NewsAndUpdates",
              "CreatedTimestamp": "2019-10-03T20:03:34.574Z"
          }
      ]
  }
  ```

  If you haven't created any templates, the command returns a `TemplatesMetadata` object with no members.

## Viewing the contents of a specific email template
<a name="send-personalized-email-manage-templates-get"></a>

You can use the [https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_GetEmailTemplate.html](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_GetEmailTemplate.html) SES v2 API operation to view the contents of a specific email template.

**To view the contents of an email template**
+ At the command line, enter the following command:

  ```
  aws sesv2 get-email-template --template-name MyTemplate
  ```

  In the preceding command, replace *MyTemplate* with the name of the template that you want to view.

  If the template name that you provided matches a template that exists in your SES account, this command returns a response that resembles the following example:

  ```
  {
      "Template": {
          "TemplateName": "TestMessage",
          "SubjectPart": "Amazon SES Test Message",
          "TextPart": "Hello! This is the text part of the message.",
          "HtmlPart": "<html>\n<body>\n<h2>Hello!</h2>\n<p>This is the HTML part of the message.</p></body>\n</html>"
      }
  }
  ```

  If the template name that you provided doesn't match a template that exists in your SES account, the command returns a `NotFoundException` error.

## Deleting an email template
<a name="send-personalized-email-manage-templates-delete"></a>

You can use the [https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_DeleteEmailTemplate.html](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_DeleteEmailTemplate.html) SES v2 API operation to delete a specific email template.

**To delete an email template**
+ At the command line, enter the following command:

  ```
  aws sesv2 delete-email-template --template-name MyTemplate
  ```

  In the preceding command, replace *MyTemplate* with the name of the template that you want to delete.

  This command doesn't provide any output. You can verify that the template was deleted by using the [GetTemplate](#send-personalized-email-manage-templates-get) operation.

## Updating an email template
<a name="send-personalized-email-manage-templates-update"></a>

You can use the [https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_UpdateEmailTemplate.html](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_UpdateEmailTemplate.html) SES v2 API operation to update an existing email template. For example, this operation is helpful if you want to change the subject line of the email template, or if you need to modify the body of the message itself.

**To update an email template**

1. Use the `GetEmailTemplate` command to retrieve the existing template by entering the following command on the command line:

   ```
   aws sesv2 get-email-template --template-name MyTemplate
   ```

   In the preceding command, replace *MyTemplate* with the name of the template that you want to update.

   If the template name that you provided matches a template that exists in your SES account, this command returns a response that resembles the following example:

   ```
   {
       "Template": {
           "TemplateName": "TestMessage",
           "SubjectPart": "Amazon SES Test Message",
           "TextPart": "Hello! This is the text part of the message.",
           "HtmlPart": "<html>\n<body>\n<h2>Hello!</h2>\n<p>This is the HTML part of the message.</p></body>\n</html>"
       }
   }
   ```

1. In a text editor, create a new file. Paste the output of the previous command into the file.

1. Modify the template as needed. Any lines that you omit are removed from the template. For example, if you only want to change the `SubjectPart` of the template, you still need to include the `TextPart` and `HtmlPart` properties.

   When you finish, save the file as `update_template.json`.

1. At the command line, enter the following command:

   ```
   aws sesv2 update-email-template --cli-input-json file://path/to/update_template.json
   ```

   In the preceding command, replace *path/to/update\$1template.json* with the path to the `update_template.json` file that you created in the previous step.

   If the template is updated successfully, this command doesn't provide any output. You can verify that the template was updated by using the [https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_GetEmailTemplate.html](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_GetEmailTemplate.html) operation.

   If the template that you specified doesn't exist, this command returns a `TemplateDoesNotExist` error. If the template doesn't contain either the `TextPart` or `HtmlPart` property (or both), this command returns an `InvalidParameterValue` error. 

# Sending email through Amazon SES using an AWS SDK
<a name="send-an-email-using-sdk-programmatically"></a>

You can use an AWS SDK to send email through Amazon SES. AWS SDKs are available for several programming languages. For more information, see [Tools for Amazon Web Services](https://aws.amazon.com/tools/#sdk).

## Prerequisites
<a name="send-an-email-using-sdk-programmatically-prereqs"></a>

The following prerequisites must be completed in order to complete any of the code samples in the next section:
+ If you haven't already done so, complete the tasks in [Setting up Amazon Simple Email Service](setting-up.md).
+ **Verify your email address with Amazon SES**—Before you can send an email with Amazon SES, you must verify that you own the sender's email address. If your account is still in the Amazon SES sandbox, you must also verify the recipient email address. We recommend you use the Amazon SES console to verify email addresses. For more information, see [Creating an email address identity](creating-identities.md#verify-email-addresses-procedure). 
+ **Get your AWS credentials**—You need an AWS access key ID and AWS secret access key to access Amazon SES using an SDK. You can find your credentials by using the [Security Credentials](https://console.aws.amazon.com/iam/home?#security_credential) page in the AWS Management Console. For more information about credentials, see [Types of Amazon SES credentials](send-email-concepts-credentials.md).
+ **Create a shared credentials file**—For the sample code in this section to function properly, you must create a shared credentials file. For more information, see [Creating a shared credentials file to use when sending email through Amazon SES using an AWS SDK](create-shared-credentials-file.md).

## Code examples
<a name="send-an-email-using-sdk-programmatically-examples"></a>

**Important**  
In the following tutorials, you send an email to yourself so that you can check to see if you received it. For further experimentation or load testing, use the Amazon SES mailbox simulator. Emails that you send to the mailbox simulator do not count toward your sending quota or your bounce and complaint rates. For more information, see [Using the mailbox simulator manually](send-an-email-from-console.md#send-email-simulator).

**Topics**

------
#### [ .NET ]

The following procedure shows you how to send an email through Amazon SES using [Visual Studio](https://www.visualstudio.com/) and the AWS SDK for .NET.

This solution was tested using the following components:
+ Microsoft Visual Studio Community 2017, version 15.4.0.
+ Microsoft .NET Framework version 4.6.1.
+ The AWSSDK.Core package (version 3.3.19), installed using NuGet.
+ The AWSSDK.SimpleEmail package (version 3.3.6.1), installed using NuGet.

**Before you begin, perform the following tasks:**
+ **Install Visual Studio**—Visual Studio is available at [https://www.visualstudio.com/](https://www.visualstudio.com/).

**To send an email using the AWS SDK for .NET**

1. Create a new project by performing the following steps:

   1. Start Visual Studio.

   1. On the **File** menu, choose **New**, **Project**.

   1. On the **New Project** window, in the panel on the left, expand **Installed**, and then expand **Visual C\$1**.

   1. In the panel on the right, choose **Console App (.NET Framework)**.

   1. For **Name**, type **AmazonSESSample**, and then choose **OK**.

1. Use NuGet to include the Amazon SES packages in your solution by completing the following steps:

   1. In the **Solution Explorer** pane, right-click your project, and then choose **Manage NuGet Packages**.

   1. On the **NuGet: AmazonSESSample** tab, choose **Browse**.

   1. In the search box, type **AWSSDK.SimpleEmail**. 

   1. Choose the **AWSSDK.SimpleEmail** package, and then choose **Install**.

   1. On the **Preview Changes** window, choose **OK**.

1. On the **Program.cs** tab, paste the following code:

   ```
    1. using Amazon;
    2. using System;
    3. using System.Collections.Generic;
    4. using Amazon.SimpleEmail;
    5. using Amazon.SimpleEmail.Model;
    6. 
    7. namespace AmazonSESSample 
    8. {
    9.     class Program
   10.     {
   11.         // Replace sender@example.com with your "From" address.
   12.         // This address must be verified with Amazon SES.
   13.         static readonly string senderAddress = "sender@example.com";
   14. 
   15.         // Replace recipient@example.com with a "To" address. If your account
   16.         // is still in the sandbox, this address must be verified.
   17.         static readonly string receiverAddress = "recipient@example.com";
   18. 
   19.         // The configuration set to use for this email. If you do not want to use a
   20.         // configuration set, comment out the following property and the
   21.         // ConfigurationSetName = configSet argument below. 
   22.         static readonly string configSet = "ConfigSet";
   23. 
   24.         // The subject line for the email.
   25.         static readonly string subject = "Amazon SES test (AWS SDK for .NET)";
   26. 
   27.         // The email body for recipients with non-HTML email clients.
   28.         static readonly string textBody = "Amazon SES Test (.NET)\r\n" 
   29.                                         + "This email was sent through Amazon SES "
   30.                                         + "using the AWS SDK for .NET.";
   31.         
   32.         // The HTML body of the email.
   33.         static readonly string htmlBody = @"<html>
   34. <head></head>
   35. <body>
   36.   <h1>Amazon SES Test (SDK for .NET)</h1>
   37.   <p>This email was sent with
   38.     <a href='https://aws.amazon.com/ses/'>Amazon SES</a> using the
   39.     <a href='https://aws.amazon.com/sdk-for-net/'>
   40.       AWS SDK for .NET</a>.</p>
   41. </body>
   42. </html>";
   43. 
   44.         static void Main(string[] args)
   45.         {
   46.             // Replace USWest2 with the AWS Region you're using for Amazon SES.
   47.             // Acceptable values are EUWest1, USEast1, and USWest2.
   48.             using (var client = new AmazonSimpleEmailServiceClient(RegionEndpoint.USWest2))
   49.             {
   50.                 var sendRequest = new SendEmailRequest
   51.                 {
   52.                     Source = senderAddress,
   53.                     Destination = new Destination
   54.                     {
   55.                         ToAddresses =
   56.                         new List<string> { receiverAddress }
   57.                     },
   58.                     Message = new Message
   59.                     {
   60.                         Subject = new Content(subject),
   61.                         Body = new Body
   62.                         {
   63.                             Html = new Content
   64.                             {
   65.                                 Charset = "UTF-8",
   66.                                 Data = htmlBody
   67.                             },
   68.                             Text = new Content
   69.                             {
   70.                                 Charset = "UTF-8",
   71.                                 Data = textBody
   72.                             }
   73.                         }
   74.                     },
   75.                     // If you are not using a configuration set, comment
   76.                     // or remove the following line 
   77.                     ConfigurationSetName = configSet
   78.                 };
   79.                 try
   80.                 {
   81.                     Console.WriteLine("Sending email using Amazon SES...");
   82.                     var response = client.SendEmail(sendRequest);
   83.                     Console.WriteLine("The email was sent successfully.");
   84.                 }
   85.                 catch (Exception ex)
   86.                 {
   87.                     Console.WriteLine("The email was not sent.");
   88.                     Console.WriteLine("Error message: " + ex.Message);
   89. 
   90.                 }
   91.             }
   92. 
   93.             Console.Write("Press any key to continue...");
   94.             Console.ReadKey();
   95.         }
   96.     }
   97. }
   ```

1. In the code editor, do the following:
   + Replace *sender@example.com* with the "From:" email address. This address must be verified. For more information, see [Verified identities in Amazon SES](verify-addresses-and-domains.md).
   + Replace *recipient@example.com* with the "To:" address. If your account is still in the sandbox, this address must also be verified.
   + Replace *ConfigSet* with the name of the configuration set to use when sending this email.
   + Replace *USWest2* with the name of the AWS Region endpoint you use to send email using Amazon SES. For a list of regions where Amazon SES is available, see [Amazon Simple Email Service (Amazon SES)](https://docs.aws.amazon.com/general/latest/gr/rande.html#ses_region) in the *AWS General Reference*.

   When you finish, save `Program.cs`.

1. Build and run the application by completing the following steps:

   1. On the **Build** menu, choose **Build Solution**.

   1. On the **Debug** menu, choose **Start Debugging**. A console window appears.

1. Review the output of the console. If the email was successfully sent, the console displays "`The email was sent successfully.`" 

1. If the email was successfully sent, sign in to the email client of the recipient address. You will see the message that you sent.

------
#### [ Java ]

The following procedure shows you how to use [Eclipse IDE for Java EE Developers](http://www.eclipse.org/) and [AWS Toolkit for Eclipse](https://docs.aws.amazon.com/toolkit-for-jetbrains/latest/userguide/welcome.html) to create an AWS SDK project and modify the Java code to send an email through Amazon SES. 

**Before you begin, perform the following tasks:**
+ **Install Eclipse**—Eclipse is available at [https://www.eclipse.org/downloads](https://www.eclipse.org/downloads). The code in this tutorial was tested using Eclipse Neon.3 (version 4.6.3), running version 1.8 of the Java Runtime Environment.
+ **Install the AWS Toolkit for Eclipse**—Instructions for adding the AWS Toolkit for Eclipse to your Eclipse installation are available at [https://aws.amazon.com/eclipse](https://aws.amazon.com/eclipse). The code in this tutorial was tested using version 2.3.1 of the AWS Toolkit for Eclipse.

**To send an email using the AWS SDK for Java**

1. Create an AWS Java Project in Eclipse by performing the following steps:

   1. Start Eclipse.

   1. On the **File** menu, choose **New**, and then choose **Other**. On the **New** window, expand the **AWS** folder, and then choose **AWS Java Project**.

   1. In the **New AWS Java Project** dialog box, do the following:

      1. For **Project name**, type a project name.

      1. Under **AWS SDK for Java Samples**, select **Amazon Simple Email Service JavaMail Sample**.

      1. Choose **Finish**.

1. In Eclipse, in the **Package Explorer** pane, expand your project.

1. Under your project, expand the `src/main/java` folder, expand the `com.amazon.aws.samples` folder, and then double-click `AmazonSESSample.java`.

1. Replace the entire contents of `AmazonSESSample.java` with the following code:

   ```
    1. package com.amazonaws.samples;
    2. 
    3. import java.io.IOException;
    4. 
    5. import com.amazonaws.regions.Regions;
    6. import com.amazonaws.services.simpleemail.AmazonSimpleEmailService;
    7. import com.amazonaws.services.simpleemail.AmazonSimpleEmailServiceClientBuilder;
    8. import com.amazonaws.services.simpleemail.model.Body;
    9. import com.amazonaws.services.simpleemail.model.Content;
   10. import com.amazonaws.services.simpleemail.model.Destination;
   11. import com.amazonaws.services.simpleemail.model.Message;
   12. import com.amazonaws.services.simpleemail.model.SendEmailRequest; 
   13. 
   14. public class AmazonSESSample {
   15. 
   16.   // Replace sender@example.com with your "From" address.
   17.   // This address must be verified with Amazon SES.
   18.   static final String FROM = "sender@example.com";
   19. 
   20.   // Replace recipient@example.com with a "To" address. If your account
   21.   // is still in the sandbox, this address must be verified.
   22.   static final String TO = "recipient@example.com";
   23. 
   24.   // The configuration set to use for this email. If you do not want to use a
   25.   // configuration set, comment the following variable and the 
   26.   // .withConfigurationSetName(CONFIGSET); argument below.
   27.   static final String CONFIGSET = "ConfigSet";
   28. 
   29.   // The subject line for the email.
   30.   static final String SUBJECT = "Amazon SES test (AWS SDK for Java)";
   31.   
   32.   // The HTML body for the email.
   33.   static final String HTMLBODY = "<h1>Amazon SES test (AWS SDK for Java)</h1>"
   34.       + "<p>This email was sent with <a href='https://aws.amazon.com/ses/'>"
   35.       + "Amazon SES</a> using the <a href='https://aws.amazon.com/sdk-for-java/'>" 
   36.       + "AWS SDK for Java</a>";
   37. 
   38.   // The email body for recipients with non-HTML email clients.
   39.   static final String TEXTBODY = "This email was sent through Amazon SES "
   40.       + "using the AWS SDK for Java.";
   41. 
   42.   public static void main(String[] args) throws IOException {
   43. 
   44.     try {
   45.       AmazonSimpleEmailService client = 
   46.           AmazonSimpleEmailServiceClientBuilder.standard()
   47.           // Replace US_WEST_2 with the AWS Region you're using for
   48.           // Amazon SES.
   49.             .withRegion(Regions.US_WEST_2).build();
   50.       SendEmailRequest request = new SendEmailRequest()
   51.           .withDestination(
   52.               new Destination().withToAddresses(TO))
   53.           .withMessage(new Message()
   54.               .withBody(new Body()
   55.                   .withHtml(new Content()
   56.                       .withCharset("UTF-8").withData(HTMLBODY))
   57.                   .withText(new Content()
   58.                       .withCharset("UTF-8").withData(TEXTBODY)))
   59.               .withSubject(new Content()
   60.                   .withCharset("UTF-8").withData(SUBJECT)))
   61.           .withSource(FROM)
   62.           // Comment or remove the next line if you are not using a
   63.           // configuration set
   64.           .withConfigurationSetName(CONFIGSET);
   65.       client.sendEmail(request);
   66.       System.out.println("Email sent!");
   67.     } catch (Exception ex) {
   68.       System.out.println("The email was not sent. Error message: " 
   69.           + ex.getMessage());
   70.     }
   71.   }
   72. }
   ```

1. In `AmazonSESSample.java`, replace the following with your own values:
**Important**  
The email addresses are case-sensitive. Make sure that the addresses are exactly the same as the ones you verified.
   + `SENDER@EXAMPLE.COM`—Replace with your "From" email address. You must verify this address before you run this program. For more information, see [Verified identities in Amazon SES](verify-addresses-and-domains.md).
   + `RECIPIENT@EXAMPLE.COM`—Replace with your "To" email address. If your account is still in the sandbox, you must verify this address before you use it. For more information, see [Request production access (Moving out of the Amazon SES sandbox)](request-production-access.md).
   + **(Optional) `us-west-2`**—If you want to use Amazon SES in a Region other than US West (Oregon), replace this with the Region you want to use. For a list of Regions where Amazon SES is available, see [Amazon Simple Email Service (Amazon SES)](https://docs.aws.amazon.com/general/latest/gr/rande.html#ses_region) in the *AWS General Reference*.

1. Save `AmazonSESSample.java`.

1. To build the project, choose **Project** and then choose **Build Project**.
**Note**  
If this option is disabled, automatic building may be enabled; if so, skip this step.

1. To start the program and send the email, choose **Run** and then choose **Run** again.

1. Review the output of the console pane in Eclipse. If the email was successfully sent, the console displays "`Email sent!`" Otherwise, it displays an error message.

1. If the email was successfully sent, sign in to the email client of the recipient address. You will see the message that you sent.

------
#### [ PHP ]

This topic shows how to use the [AWS SDK for PHP](https://aws.amazon.com/sdk-for-php/) to send an email through Amazon SES. 

**Before you begin, perform the following tasks:**
+ **Install PHP**—PHP is available at [http://php.net/downloads.php](http://php.net/downloads.php). This tutorial requires PHP version 5.5 or higher. After you install PHP, add the path to PHP in your environment variables so that you can run PHP from any command prompt. The code in this tutorial was tested using PHP 7.2.7.
+ **Install the AWS SDK for PHP version 3**—For download and installation instructions, see the [AWS SDK for PHP documentation](https://docs.aws.amazon.com/aws-sdk-php/v3/guide/getting-started/installation.html). The code in this tutorial was tested using version 3.64.13 of the SDK. 

**To send an email through Amazon SES using the AWS SDK for PHP**

1. In a text editor, create a file named `amazon-ses-sample.php`. Paste the following code:

   ```
    1. <?php
    2. 
    3. // If necessary, modify the path in the require statement below to refer to the 
    4. // location of your Composer autoload.php file.
    5. require 'vendor/autoload.php';
    6. 
    7. use Aws\Ses\SesClient;
    8. use Aws\Exception\AwsException;
    9. 
   10. // Create an SesClient. Change the value of the region parameter if you're 
   11. // using an AWS Region other than US West (Oregon). Change the value of the
   12. // profile parameter if you want to use a profile in your credentials file
   13. // other than the default.
   14. $SesClient = new SesClient([
   15.     'profile' => 'default',
   16.     'version' => '2010-12-01',
   17.     'region'  => 'us-west-2'
   18. ]);
   19. 
   20. // Replace sender@example.com with your "From" address.
   21. // This address must be verified with Amazon SES.
   22. $sender_email = 'sender@example.com';
   23. 
   24. // Replace these sample addresses with the addresses of your recipients. If
   25. // your account is still in the sandbox, these addresses must be verified.
   26. $recipient_emails = ['recipient1@example.com','recipient2@example.com'];
   27. 
   28. // Specify a configuration set. If you do not want to use a configuration
   29. // set, comment the following variable, and the
   30. // 'ConfigurationSetName' => $configuration_set argument below.
   31. $configuration_set = 'ConfigSet';
   32. 
   33. $subject = 'Amazon SES test (AWS SDK for PHP)';
   34. $plaintext_body = 'This email was sent with Amazon SES using the AWS SDK for PHP.' ;
   35. $html_body =  '<h1>AWS Amazon Simple Email Service Test Email</h1>'.
   36.               '<p>This email was sent with <a href="https://aws.amazon.com/ses/">'.
   37.               'Amazon SES</a> using the <a href="https://aws.amazon.com/sdk-for-php/">'.
   38.               'AWS SDK for PHP</a>.</p>';
   39. $char_set = 'UTF-8';
   40. 
   41. try {
   42.     $result = $SesClient->sendEmail([
   43.         'Destination' => [
   44.             'ToAddresses' => $recipient_emails,
   45.         ],
   46.         'ReplyToAddresses' => [$sender_email],
   47.         'Source' => $sender_email,
   48.         'Message' => [
   49.           'Body' => [
   50.               'Html' => [
   51.                   'Charset' => $char_set,
   52.                   'Data' => $html_body,
   53.               ],
   54.               'Text' => [
   55.                   'Charset' => $char_set,
   56.                   'Data' => $plaintext_body,
   57.               ],
   58.           ],
   59.           'Subject' => [
   60.               'Charset' => $char_set,
   61.               'Data' => $subject,
   62.           ],
   63.         ],
   64.         // If you aren't using a configuration set, comment or delete the
   65.         // following line
   66.         'ConfigurationSetName' => $configuration_set,
   67.     ]);
   68.     $messageId = $result['MessageId'];
   69.     echo("Email sent! Message ID: $messageId"."\n");
   70. } catch (AwsException $e) {
   71.     // output error message if fails
   72.     echo $e->getMessage();
   73.     echo("The email was not sent. Error message: ".$e->getAwsErrorMessage()."\n");
   74.     echo "\n";
   75. }
   ```

1. In `amazon-ses-sample.php`, replace the following with your own values:
   + **`path_to_sdk_inclusion`**—Replace with the path required to include the AWS SDK for PHP in the program. For more information, see the [AWS SDK for PHP documentation](https://docs.aws.amazon.com/aws-sdk-php/v3/guide/getting-started/basic-usage.html). 
   + **`sender@example.com`**—Replace with an email address that you have verified with Amazon SES. For more information, see [Verified identities](verify-addresses-and-domains.md). Email addresses in Amazon SES are case-sensitive. Make sure that the address you enter is exactly the same as the one you verified.
   + **`recipient1@example.com`, `recipient2@example.com`**—Replace with the addresses of your recipients. If your account is still in the sandbox, your recipients' addresses must also be verified. For more information, see [Request production access (Moving out of the Amazon SES sandbox)](request-production-access.md). Make sure that the address you enter is exactly the same as the one you verified.
   + **(Optional) `ConfigSet`**—If you want to use a configuration set when sending this email, replace this value with the name of the configuration set. For more information about configuration sets, see [Using configuration sets in Amazon SES](using-configuration-sets.md).
   + **(Optional) `us-west-2`**—If you want to use Amazon SES in a Region other than US West (Oregon), replace this with the Region you want to use. For a list of Regions where Amazon SES is available, see [Amazon Simple Email Service (Amazon SES)](https://docs.aws.amazon.com/general/latest/gr/rande.html#ses_region) in the *AWS General Reference*.

1. Save `amazon-ses-sample.php`.

1. To run the program, open a command prompt in the same directory as `amazon-ses-sample.php`, and then type the following command:

   ```
   $ php amazon-ses-sample.php
   ```

1. Review the output. If the email was successfully sent, the console displays "`Email sent!`" Otherwise, it displays an error message.
**Note**  
If you encounter a "cURL error 60: SSL certificate problem" error when you run the program, download the latest CA bundle as described in the [AWS SDK for PHP documentation](https://docs.aws.amazon.com/aws-sdk-php/v3/guide/faq.html#what-do-i-do-about-a-curl-ssl-certificate-error). Then, in `amazon-ses-sample.php`, add the following lines to the `SesClient::factory` array, replace `path_of_certs` with the path to the CA bundle you downloaded, and re-run the program.  

   ```
   1. 'http' => [
   2.    'verify' => 'path_of_certs\ca-bundle.crt'
   3. ]
   ```

1. Sign in to the email client of the recipient address. You will see the message that you sent.

------
#### [ Ruby ]

This topic shows how to use the [AWS SDK for Ruby](https://aws.amazon.com/sdk-for-ruby/) to send an email through Amazon SES. 

**Before you begin, perform the following tasks:**
+ **Install Ruby**—Ruby is available at [https://www.ruby-lang.org/en/downloads/](https://www.ruby-lang.org/en/downloads/). The code in this tutorial was tested using Ruby 1.9.3. After you install Ruby, add the path to Ruby in your environment variables so that you can run Ruby from any command prompt.
+ **Install the AWS SDK for Ruby**—For download and installation instructions, see [Installing the AWS SDK for Ruby](https://docs.aws.amazon.com/sdk-for-ruby/latest/developer-guide/setup-install.html) in the *AWS SDK for Ruby Developer Guide*. The sample code in this tutorial was tested using version 2.9.36 of the AWS SDK for Ruby.
+ **Create a shared credentials file**—For the sample code in this section to function properly, you must create a shared credentials file. For more information, see [Creating a shared credentials file to use when sending email through Amazon SES using an AWS SDK](create-shared-credentials-file.md).

**To send an email through Amazon SES using the AWS SDK for Ruby**

1. In a text editor, create a file named `amazon-ses-sample.rb`. Paste the following code into the file:

   ```
    1. require 'aws-sdk'
    2. 
    3. # Replace sender@example.com with your "From" address.
    4. # This address must be verified with Amazon SES.
    5. sender = "sender@example.com"
    6. 
    7. # Replace recipient@example.com with a "To" address. If your account 
    8. # is still in the sandbox, this address must be verified.
    9. recipient = "recipient@example.com"
   10. 
   11. # Specify a configuration set. If you do not want to use a configuration
   12. # set, comment the following variable and the 
   13. # configuration_set_name: configsetname argument below. 
   14. configsetname = "ConfigSet"
   15.   
   16. # Replace us-west-2 with the AWS Region you're using for Amazon SES.
   17. awsregion = "us-west-2"
   18. 
   19. # The subject line for the email.
   20. subject = "Amazon SES test (AWS SDK for Ruby)"
   21. 
   22. # The HTML body of the email.
   23. htmlbody =
   24.   '<h1>Amazon SES test (AWS SDK for Ruby)</h1>'\
   25.   '<p>This email was sent with <a href="https://aws.amazon.com/ses/">'\
   26.   'Amazon SES</a> using the <a href="https://aws.amazon.com/sdk-for-ruby/">'\
   27.   'AWS SDK for Ruby</a>.'
   28. 
   29. # The email body for recipients with non-HTML email clients.  
   30. textbody = "This email was sent with Amazon SES using the AWS SDK for Ruby."
   31. 
   32. # Specify the text encoding scheme.
   33. encoding = "UTF-8"
   34. 
   35. # Create a new SES resource and specify a region
   36. ses = Aws::SES::Client.new(region: awsregion)
   37. 
   38. # Try to send the email.
   39. begin
   40. 
   41.   # Provide the contents of the email.
   42.   resp = ses.send_email({
   43.     destination: {
   44.       to_addresses: [
   45.         recipient,
   46.       ],
   47.     },
   48.     message: {
   49.       body: {
   50.         html: {
   51.           charset: encoding,
   52.           data: htmlbody,
   53.         },
   54.         text: {
   55.           charset: encoding,
   56.           data: textbody,
   57.         },
   58.       },
   59.       subject: {
   60.         charset: encoding,
   61.         data: subject,
   62.       },
   63.     },
   64.   source: sender,
   65.   # Comment or remove the following line if you are not using 
   66.   # a configuration set
   67.   configuration_set_name: configsetname,
   68.   })
   69.   puts "Email sent!"
   70. 
   71. # If something goes wrong, display an error message.
   72. rescue Aws::SES::Errors::ServiceError => error
   73.   puts "Email not sent. Error message: #{error}"
   74. 
   75. end
   ```

1. In `amazon-ses-sample.rb`, replace the following with your own values:
   + **`sender@example.com`**—Replace with an email address that you have verified with Amazon SES. For more information, see [Verified identities](verify-addresses-and-domains.md). Email addresses in Amazon SES are case-sensitive. Make sure that the address you enter is exactly the same as the one you verified.
   + **`recipient@example.com`**—Replace with the address of the recipient. If your account is still in the sandbox, you must verify this address before you use it. For more information, see [Request production access (Moving out of the Amazon SES sandbox)](request-production-access.md). Make sure that the address you enter is exactly the same as the one you verified.
   + **(Optional) `us-west-2`**—If you want to use Amazon SES in a Region other than US West (Oregon), replace this with the Region you want to use. For a list of Regions where Amazon SES is available, see [Amazon Simple Email Service (Amazon SES)](https://docs.aws.amazon.com/general/latest/gr/rande.html#ses_region) in the *AWS General Reference*.

1. Save `amazon-ses-sample.rb`.

1. To run the program, open a command prompt in the same directory as `amazon-ses-sample.rb`, and type **ruby amazon-ses-sample.rb**

1. Review the output. If the email was successfully sent, the console displays "`Email sent!`" Otherwise, it displays an error message.

1. Sign in to the email client of the recipient address. You will find the message that you sent.

------
#### [ Python ]

This topic shows how to use the [AWS SDK for Python (Boto)](https://aws.amazon.com/sdk-for-python/) to send an email through Amazon SES. 

**Before you begin, perform the following tasks:**
+ **Verify your email address with Amazon SES**—Before you can send an email with Amazon SES, you must verify that you own the sender's email address. If your account is still in the Amazon SES sandbox, you must also verify the recipient email address. We recommend you use the Amazon SES console to verify email addresses. For more information, see [Creating an email address identity](creating-identities.md#verify-email-addresses-procedure). 
+ **Get your AWS credentials**—You need an AWS access key ID and AWS secret access key to access Amazon SES using an SDK. You can find your credentials by using the [Security Credentials](https://console.aws.amazon.com/iam/home?#security_credential) page of the AWS Management Console. For more information about credentials, see [Types of Amazon SES credentials](send-email-concepts-credentials.md).
+ **Install Python**—Python is available at [https://www.python.org/downloads/](https://www.python.org/downloads/). The code in this tutorial was tested using Python 2.7.6 and Python 3.6.1. After you install Python, add the path to Python in your environment variables so that you can run Python from any command prompt.
+ **Install the AWS SDK for Python (Boto)**—For download and installation instructions, see the [AWS SDK for Python (Boto) documentation](https://boto3.readthedocs.io/en/latest/guide/quickstart.html#installation). The sample code in this tutorial was tested using version 1.4.4 of the SDK for Python.

**To send an email through Amazon SES using the SDK for Python**

1. In a text editor, create a file named `amazon-ses-sample.py`. Paste the following code into the file:

   ```
    1. import boto3
    2. from botocore.exceptions import ClientError
    3. 
    4. # Replace sender@example.com with your "From" address.
    5. # This address must be verified with Amazon SES.
    6. SENDER = "Sender Name <sender@example.com>"
    7. 
    8. # Replace recipient@example.com with a "To" address. If your account 
    9. # is still in the sandbox, this address must be verified.
   10. RECIPIENT = "recipient@example.com"
   11. 
   12. # Specify a configuration set. If you do not want to use a configuration
   13. # set, comment the following variable, and the 
   14. # ConfigurationSetName=CONFIGURATION_SET argument below.
   15. CONFIGURATION_SET = "ConfigSet"
   16. 
   17. # If necessary, replace us-west-2 with the AWS Region you're using for Amazon SES.
   18. AWS_REGION = "us-west-2"
   19. 
   20. # The subject line for the email.
   21. SUBJECT = "Amazon SES Test (SDK for Python)"
   22. 
   23. # The email body for recipients with non-HTML email clients.
   24. BODY_TEXT = ("Amazon SES Test (Python)\r\n"
   25.              "This email was sent with Amazon SES using the "
   26.              "AWS SDK for Python (Boto)."
   27.             )
   28.             
   29. # The HTML body of the email.
   30. BODY_HTML = """<html>
   31. <head></head>
   32. <body>
   33.   <h1>Amazon SES Test (SDK for Python)</h1>
   34.   <p>This email was sent with
   35.     <a href='https://aws.amazon.com/ses/'>Amazon SES</a> using the
   36.     <a href='https://aws.amazon.com/sdk-for-python/'>
   37.       AWS SDK for Python (Boto)</a>.</p>
   38. </body>
   39. </html>
   40.             """            
   41. 
   42. # The character encoding for the email.
   43. CHARSET = "UTF-8"
   44. 
   45. # Create a new SES resource and specify a region.
   46. client = boto3.client('ses',region_name=AWS_REGION)
   47. 
   48. # Try to send the email.
   49. try:
   50.     #Provide the contents of the email.
   51.     response = client.send_email(
   52.         Destination={
   53.             'ToAddresses': [
   54.                 RECIPIENT,
   55.             ],
   56.         },
   57.         Message={
   58.             'Body': {
   59.                 'Html': {
   60.                     'Charset': CHARSET,
   61.                     'Data': BODY_HTML,
   62.                 },
   63.                 'Text': {
   64.                     'Charset': CHARSET,
   65.                     'Data': BODY_TEXT,
   66.                 },
   67.             },
   68.             'Subject': {
   69.                 'Charset': CHARSET,
   70.                 'Data': SUBJECT,
   71.             },
   72.         },
   73.         Source=SENDER,
   74.         # If you are not using a configuration set, comment or delete the
   75.         # following line
   76.         ConfigurationSetName=CONFIGURATION_SET,
   77.     )
   78. # Display an error if something goes wrong.	
   79. except ClientError as e:
   80.     print(e.response['Error']['Message'])
   81. else:
   82.     print("Email sent! Message ID:"),
   83.     print(response['MessageId'])
   ```

1. In `amazon-ses-sample.py`, replace the following with your own values:
   + **`sender@example.com`**—Replace with an email address that you have verified with Amazon SES. For more information, see [Verified identities](verify-addresses-and-domains.md). Email addresses in Amazon SES are case sensitive. Make sure that the address you enter is exactly the same as the one you verified.
   + **`recipient@example.com`**—Replace with the address of the recipient. If your account is still in the sandbox, you must verify this address before you use it. For more information, see [Request production access (Moving out of the Amazon SES sandbox)](request-production-access.md). Make sure that the address you enter is exactly the same as the one you verified.
   + **(Optional) `us-west-2`**—If you want to use Amazon SES in a Region other than US West (Oregon), replace this with the Region you want to use. For a list of Regions where Amazon SES is available, see [Amazon Simple Email Service (Amazon SES)](https://docs.aws.amazon.com/general/latest/gr/rande.html#ses_region) in the *AWS General Reference*.

1. Save `amazon-ses-sample.py`.

1. To run the program, open a command prompt in the same directory as `amazon-ses-sample.py`, and then type **python amazon-ses-sample.py**.

1. Review the output. If the email was successfully sent, the console displays "`Email sent!`" Otherwise, it displays an error message.

1. Sign in to the email client of the recipient address. You will see the message that you sent.

------

# Creating a shared credentials file to use when sending email through Amazon SES using an AWS SDK
<a name="create-shared-credentials-file"></a>

The following procedure shows how to create a shared credentials file in your home directory. For the SDK sample code to function properly, you must create this file.

1. In a text editor, create a new file. In the file, paste the following code:

   ```
   1. [default]
   2. aws_access_key_id = YOUR_AWS_ACCESS_KEY_ID
   3. aws_secret_access_key = YOUR_AWS_SECRET_ACCESS_KEY
   ```

1. In the text file you just created, replace `YOUR_AWS_ACCESS_KEY` with your unique AWS access key ID, and replace `YOUR_AWS_SECRET_ACCESS_KEY` with your unique AWS secret access key.

1. Save the file. The following table shows the correct location and file name for your operating system.    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ses/latest/dg/create-shared-credentials-file.html)
**Important**  
Don't include a file extension when saving the credentials file.

# Content encodings supported by Amazon SES
<a name="content-encodings"></a>

The following is provided for reference.

Amazon SES supports the following content encodings:
+ `deflate`
+ `gzip`
+ `identity`

Amazon SES also supports the following Accept-Encoding header format, according to the [RFC 7231](https://tools.ietf.org/html/rfc7231#section-5.3.4) specification:
+ `Accept-Encoding:deflate,gzip`
+ `Accept-Encoding:`
+ `Accept-Encoding:*`
+ `Accept-Encoding:deflate;q=0.5,gzip;q=1.0`
+ `Accept-Encoding:gzip;q=1.0,identity;q=0.5,*;q=0`

# Amazon SES and security protocols
<a name="security-protocols"></a>

This topic describes the security protocols that you can use when you connect to Amazon SES, and when Amazon SES delivers an email to a receiver.

## Email sender to Amazon SES
<a name="security-client-to-ses"></a>

The security protocol that you use to connect to Amazon SES depends on whether you are using the Amazon SES API or the Amazon SES SMTP interface, as described next.

### HTTPS
<a name="security-client-to-ses-api"></a>

If you're using the Amazon SES API (either directly or through an AWS SDK), then all communications are encrypted by TLS through the Amazon SES HTTPS endpoint. The Amazon SES HTTPS endpoint supports TLS 1.2 and TLS 1.3.

### SMTP interface
<a name="security-client-to-ses-smtp"></a>

If you are accessing Amazon SES through the SMTP interface, you're required to encrypt your connection using Transport Layer Security (TLS). Note that TLS is often referred to by the name of its predecessor protocol, Secure Sockets Layer (SSL).

Amazon SES supports two mechanisms for establishing a TLS-encrypted connection: STARTTLS and TLS Wrapper.
+ **STARTTLS**—STARTTLS is a means of upgrading an unencrypted connection to an encrypted connection. There are versions of STARTTLS for a variety of protocols; the SMTP version is defined in [RFC 3207](https://www.ietf.org/rfc/rfc3207.txt). For STARTTLS connections, Amazon SES supports TLS 1.2 and TLS 1.3.
+ **TLS Wrapper**—TLS Wrapper (also known as SMTPS or the Handshake Protocol) is a means of initiating an encrypted connection without first establishing an unencrypted connection. With TLS Wrapper, the Amazon SES SMTP endpoint does not perform TLS negotiation: it is the client's responsibility to connect to the endpoint using TLS, and to continue using TLS for the entire conversation. TLS Wrapper is an older protocol, but many clients still support it. For TLS Wrapper connections, Amazon SES supports TLS 1.2 and TLS 1.3.

For information about connecting to the Amazon SES SMTP interface using these methods, see [Connecting to an Amazon SES SMTP endpoint](smtp-connect.md).

## Amazon SES to receiver
<a name="security-ses-to-receiver"></a>

 While TLS 1.3 is our default delivery method, SES can deliver email to mail servers using earlier versions of TLS. 

By default, Amazon SES uses *opportunistic TLS*. Opportunistic TLS in SES always uses STARTTLS and does not include the TLS Wrapper. The flow involves establishing an initial plaintext connection, followed by upgrading to a TLS-encrypted session if both the client and server support STARTTLS. If SES can't establish a secure connection, it sends the message unencrypted.

You can change this behavior by using configuration sets. Use the [PutConfigurationSetDeliveryOptions](https://docs.aws.amazon.com/ses/latest/APIReference/API_PutConfigurationSetDeliveryOptions.html) API operation to set the `TlsPolicy` property for a configuration set to `Require`. You can use the [AWS CLI](https://aws.amazon.com/cli) to make this change.

**To configure Amazon SES to require TLS connections for a configuration set**
+ At the command line, enter the following command:

  ```
  aws sesv2 put-configuration-set-delivery-options --configuration-set-name MyConfigurationSet --tls-policy REQUIRE
  ```

  In the preceding example, replace *MyConfigurationSet* with the name of your configuration set.

  When you send an email using this configuration set, Amazon SES only sends the message to the receiving email server if it can establish a secure connection. If Amazon SES can't make a secure connection to the receiving email server, it drops the message.

## End-to-end encryption
<a name="security-end-to-end"></a>

You can use Amazon SES to send messages that are encrypted using S/MIME or PGP. Messages that use these protocols are encrypted by the sender. Their contents can only be viewed by recipients who possess the private keys that are required to decrypt the messages.

Amazon SES supports the following MIME types, which you can use to send S/MIME encrypted email:
+ `application/pkcs7-mime`
+ `application/pkcs7-signature`
+ `application/x-pkcs7-mime`
+ `application/x-pkcs7-signature`

Amazon SES also supports the following MIME types, which you can use to send PGP-encrypted email:
+ `application/pgp-encrypted`
+ `application/pgp-keys`
+ `application/pgp-signature`

# Amazon SES header fields
<a name="header-fields"></a>

Amazon SES can accept all email headers that follow the format described in [RFC 822](https://www.rfc-editor.org/rfc/rfc822.html).

The following fields can't appear more than once in the header section of a message:
+ `Accept-Language`
+ `acceptLanguage`
+ `Archived-At`
+ `Auto-Submitted`
+ `Bounces-to`
+ `Comments`
+ `Content-Alternative`
+ `Content-Base`
+ `Content-Class`
+ `Content-Description`
+ `Content-Disposition`
+ `Content-Duration`
+ `Content-ID`
+ `Content-Language`
+ `Content-Length`
+ `Content-Location`
+ `Content-MD5`
+ `Content-Transfer-Encoding`
+ `Content-Type`
+ `Date`
+ `Delivered-To `
+ `Disposition-Notification-Options`
+ `Disposition-Notification-To`
+ `DKIM-Signature`
+ `DomainKey-Signature`
+ `Errors-To`
+ `From`
+ `Importance`
+ `In-Reply-To`
+ `Keywords`
+ `List-Archive`
+ `List-Help`
+ `List-Id`
+ `List-Owner`
+ `List-Post`
+ `List-Subscribe`
+ `List-Unsubscribe`
+ `List-Unsubscribe-Post`
+ `Message-Context`
+ `Message-ID`
+ `MIME-Version`
+ `Organization`
+ `Original-From`
+ `Original-Message-ID`
+ `Original-Recipient`
+ `Original-Subject`
+ `Precedence`
+ `Priority`
+ `References`
+ `Reply-To`
+ `Return-Path`
+ `Return-Receipt-To`
+ `Sender`
+ `Solicitation`
+ `Sensitivity`
+ `Subject`
+ `Thread-Index`
+ `Thread-Topic`
+ `User-Agent`
+ `VBR-Info`

**Considerations**
+ The `acceptLanguage` field is non-standard. If possible, you should use the `Accept-Language` header instead.
+ If you specify a `Date` header, Amazon SES overrides it with a timestamp that corresponds to the date and time in the UTC time zone when Amazon SES accepted the message.
+ If you provide a `Message-ID` header, Amazon SES overrides the header with its own value.
+ If you specify a `Return-Path` header, Amazon SES sends bounce and complaint notifications to the address that you specified. However, the message that your recipients receive contains a different value for the `Return-Path` header.
+ If you use the Amazon SES API v2 `SendEmail` operation with either *Simple* or *Templated* content, or use the `SendBulkEmail` operation, you cannot set custom header content for headers that are set by SES; therefore, the following headers are disallowed as custom headers:
  + `BCC`, `CC`, `Content-Disposition`, `Content-Type`, `Date`, `From`, `Message-ID`, `MIME-Version`, `Reply-To`, `Return-Path`, `Subject`, `To`

# Working with email attachments in SES
<a name="attachments"></a>

Email attachments in SES are files that you can include with your email messages when using the SES API v2 `SendEmail` and `SendBulkEmail` operations. This feature enables you to enrich your email content by including documents such as PDFs, Word files, images, or other file types that comply with SES supported MIME types. You can also include inline images that render directly in the email content without requiring recipients to download them separately. You can include multiple attachments per email, up to the 40MB total message size limit.

**Note**  
[https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_SendEmail.html](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_SendEmail.html) SES API v2 with `Raw` content type, SMTP interface, and SES API v1 continue to handle attachments through [raw email MIME message construction](send-email-raw.md#send-email-raw-mime).

## How attachments work in SES
<a name="how-attachments-work"></a>

There are two different types of encoding that happen at different stages when sending an email with attachments:

Stage 1 – Sending data to SES:
+ When you want to send an attachment to SES, the binary data (like a PDF or image) needs to be converted into a format that can be transmitted safely.
+ This is where base64-encoding comes in—it's required because you can't send raw binary data in a JSON request.
+ If you're using the AWS SDK, it handles this encoding automatically.
+ If you're using the AWS CLI, you need to base64-encode the attachment yourself before sending it.

Stage 2 – SES creating the email:
+ Once SES receives your data, it needs to create an actual email with the attachment.
+ This is where the [ContentTransferEncoding](#attachment-structure) setting comes into play.
+ SES will use whatever encoding method you specify in ContentTransferEncoding to automatically format the attachment in the final email.

Think of it like this—it's similar to sending a package through the mail. First, you need to get the package to the post office (Stage 1 - Base64-encoding required), then the post office will package it appropriately for final delivery (Stage 2 - ContentTransferEncoding).

## Attachment object structure
<a name="attachment-structure"></a>

When you send an email with attachments through SES, the service handles the complex MIME message construction automatically. You simply need to provide the attachment content and metadata through the following the SES API v2 [https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_Attachment.html](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_Attachment.html) object structure:
+ `FileName` (Required) – The file name displayed to recipients (must include file extension). If not provided, SES will derive a `ContentType` from the extension of the `FileName`.
+ `ContentType` (Optional) – [IANA-compliant media type identifier](https://www.iana.org/assignments/media-types/media-types.xhtml).
+ `ContentDisposition` (Optional) – Specifies how the attachment should be rendered: `ATTACHMENT` *(default)* or `INLINE`.
+ `ContentDescription` (Optional) – Short description of the content.
+ `RawContent` (Required) – The actual content of the attachment.
+ `ContentTransferEncoding` (Optional) – Specifies how the attachment payload is encoded when it's assembled into the email's mime message: `SEVEN_BIT` *(default)*, `BASE64` or `QUOTED_PRINTABLE`.

All attached content must be encoded to base64 before transferring to the SES endpoint for sending. If you're using the AWS SDK client to make API calls, this is automatically handled for you. If you're using the AWS CLI, or have implemented your own client, you will have to do the encoding yourself, such as:
+ Plain text content: `Text attachment sample content.`
+ Base64 encoded: `VGV4dCBhdHRhY2htZW50IHNhbXBsZSBjb250ZW50Lg==`

The following examples show how to use the attachment object structure when specifying attachments with the SES API v2 [https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_SendEmail.html](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_SendEmail.html) and [https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_SendBulkEmail.html](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_SendBulkEmail.html) operations using the AWS CLI referencing a JSON file containing attachment object elements.

**Example – SendEmail with simple content**  

```
aws sesv2 send-email --cli-input-json file://request-send-email-simple.json
```
**request-send-email-simple.json**  

```
{
    "FromEmailAddress": "sender@example.com",
    "Destination": {
        "ToAddresses": [
            "recipient@example.com"
        ]
    },
    "Content": {
        "Simple": {
            "Subject": {
                "Data": "Email with attachment"
            },
            "Body": {
                "Text": {
                    "Data": "Please see attached document."
                },
                "Html": {
                    "Data": "Please see attached <b>document</b>."
                }
            },
            "Attachments": [
                {
                    "RawContent": "<base64-encoded-content>",
                    "ContentDisposition": "ATTACHMENT",
                    "FileName": "document.pdf",
                    "ContentDescription": "PDF Document Attachment",
                    "ContentTransferEncoding": "BASE64"
                }
            ]
        }
    }
}
```

**Example – SendEmail with simple content and inline attachment**  

```
aws sesv2 send-email --cli-input-json file://request-send-email-simple-inline-attachment.json
```
**request-send-email-simple-inline-attachment.json**  

```
{
    "FromEmailAddress": "sender@example.com",
    "Destination": {
        "ToAddresses": [
            "recipient@example.com"
        ]
    },
    "Content": {
        "Simple": {
            "Subject": {
                "Data": "Email with attachment"
            },
            "Body": {
                "Html": {
                    "Data": "<html><body>Our logo:<br><img src=\"cid:logo123\" alt=\"Company Logo\"></body></html>"
                }
            },
            "Attachments": [
                {
                    "RawContent": "<base64-encoded-content>",
                    "ContentDisposition": "INLINE",
                    "FileName": "logo.png",
                    "ContentId": "logo123",
                    "ContentTransferEncoding": "BASE64"
                }
            ]
        }
    }
}
```

**Example – SendEmail with template content**  

```
aws sesv2 send-email --cli-input-json file://request-send-email-template.json
```
**request-send-email-template.json**  

```
{
    "FromEmailAddress": "sender@example.com",
    "Destination": {
        "ToAddresses": [
            "recipient@example.com"
        ]
    },
    "Content": {
        "Template": {
            "TemplateName": "MyTemplate",
            "TemplateData": "{\"name\":\"John\"}",
            "Attachments": [
                {
                    "RawContent": "<base64-encoded-content>",
                    "ContentDisposition": "ATTACHMENT",
                    "FileName": "document.pdf",
                    "ContentDescription": "PDF Document Attachment",
                    "ContentTransferEncoding": "BASE64"
                }
            ]
        }
    }
}
```

**Example – SendBulkEmail with attachment content**  

```
aws sesv2 send-bulk-email --cli-input-json file://request-send-bulk-email.json
```
**request-send-bulk-email.json**  

```
{
    "FromEmailAddress": "sender@example.com",
    "DefaultContent": {
        "Template": {
            "TemplateName": "MyTemplate",
            "TemplateData": "{}",
            "Attachments": [
                {
                    "RawContent": "<base64-encoded-content>",
                    "ContentDisposition": "ATTACHMENT",
                    "FileName": "document.pdf",
                    "ContentDescription": "PDF Document Attachment",
                    "ContentTransferEncoding": "BASE64"
                }
            ]
        }
    },
    "BulkEmailEntries": [
        {
            "Destination": {
                "ToAddresses": [
                    "recipient@example.com"
                ]
            },
            "ReplacementEmailContent": {
                "ReplacementTemplate": {
                    "ReplacementTemplateData": "{\"name\":\"John\"}"
                }
            }
        }
    ]
}
```

## Best practices
<a name="attachments-best-practices"></a>
+ Keep total message size (including attachments) under 40MB.
+ Let SES auto-detect content types based on file extensions when possible.
+ Explicitly specify content types only when they fall outside of the [common MIME types](https://developer.mozilla.org/en-US/docs/Web/HTTP/MIME_types/Common_types).
+ Consider using inline images for better email rendering.
+ SES supports a wide range of MIME types for attachments, except for those listed in [Unsupported attachment types](#mime-types).

## SES unsupported attachment types
<a name="mime-types"></a>

You can send messages with attachments through Amazon SES by using the Multipurpose Internet Mail Extensions (MIME) standard. Amazon SES accepts all file attachment types *except* for attachments with the file extensions in the following list.


|  |  |  |  |  | 
| --- |--- |--- |--- |--- |
| .ade .adp .app .asp .bas .bat .cer .chm .cmd .com .cpl .crt .csh .der .exe .fxp .gadget .hlp  | .hta .inf .ins .isp .its .js .jse .ksh .lib .lnk .mad .maf .mag .mam .maq .mar .mas .mat  | .mau .mav .maw .mda .mdb .mde .mdt .mdw .mdz .msc .msh .msh1 .msh2 .mshxml .msh1xml .msh2xml .msi .msp  | .mst .ops .pcd .pif .plg .prf .prg .reg .scf .scr .sct .shb .shs .sys .ps1 .ps1xml .ps2 .ps2xml  | .psc1 .psc2 .tmp .url .vb .vbe .vbs .vps .vsmacros .vss .vst .vsw .vxd .ws .wsc .wsf .wsh .xnk  | 

Some ISPs have further restrictions (such as restrictions regarding archived attachments), so we recommend testing your email sending through major ISPs before you send your production email.