

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