Amazon - Simple Email Service


Questions & Answers
Email Verification
Amazon SES Scripts

45millions messages every night in 6 hours (Amazon)
75 - 250 millions per day / 20TB of mail per day.

What is Amazon SES?

Amazon SES provides a relatively easy way to deliver emails, while reducing the likelihood of legitimate email being classified by ISPs as spam. Amazon SES can send a broad range of transactional, marketing, and subscription messages, and scales to handle large volumes of email. You can use either the Amazon SES SMTP interface or the Amazon SES API to send mail.

What are the basic steps to get started with SES?

  1. Sign up for SES
  2. Get you AWS Access Keys
  3. Verify your email address
  4. Verify your domain
  5. Configure SPF, Sender ID, DKIM
  6. Send an email message using the management console
  7. Configure SMTP credentials and SMTP sending
  8. Configure your account to handle feedback notifications for bounces, complaints, out-of-office, etc
  9. Test your application using SMTP and those simulator addresses to see how your application behave
  10. Request production access
  11. Monitor your usage statistics
  12. Improve delivery

How can we sign up for SES?

  1. Go to, and click Create an AWS Account.
  2. Follow the on-screen instructions.

How can we get our AWS Access Keys?

Now that you're signed up for Amazon SES, you'll need to obtain your AWS access key identifiers. These identifiers consist of an Access Key ID and a Secret Access Key. Your Secret Access Key is a secret and only you and AWS should know it. It is important to keep it confidential to protect your account. Never include it in your requests to AWS, and never email it to anyone. Do not share it outside your organization, even if an inquiry appears to come from AWS or No one who legitimately represents Amazon will ever ask you for your Secret Access Key.

  1. Go to, click Account, and then click Security Credentials.
  2. Navigate to the Access Credentials section of the page, and click the Access Keys tab. Your access ID is displayed. To view your secret key, under Secret Access Key, click Show

How can we verify our email address?

Before you can send your first email, Amazon SES requires that you verify your email address or domain. Amazon SES requires you to verify ownership of the email addresses or domains from which email will be sent from. You must also verify the email addresses or domains of recipients. However, you do not have to verify the email addresses provided by Amazon SES mailbox simulator. Amazon SES also restricts usage until you granted production access. Until you have production access, you must also verify the email address of every recipient, except for the recipients provided by the mailbox simulator. You must verify each email address that will be used as a "From" or "Return-Path" address.

  1. Go to the AWS Management Console. Log in with the email address and password you used when you signed up for Amazon SES.
  2. In the Amazon SES console, click Verified Senders and choose the Email Addresses tab. If you are a new Amazon SES user, the list should be empty.
  3. To start the verification process, click Verify a New Email Address.
  4. In the Verify a New Email Address dialog box, type your email address in the indicated field, then click Verify This Email Address.
  5. Sign in to your email client, and then find the message from Amazon SES asking you to confirm that you are the owner of this email address.
  6. To verify your email address, click the link in the email. The link in the verification message expires 24 hours after your original verification request.

How can we send an email message using the management console?

  1. See How to send a test message via management console

How can we verify a domain?

  1. Go to the AWS Management Console and log in with the email address and password you used when you signed up for Amazon SES
  2. In the navigation page, click Verified Senders
  3. In the content pane, choose the Domains tab.
  4. Click the Verify a New Domain button
  5. In the Verify a New Domain dialog box, enter the domain name, then click Verify This Domain button.
  6. In the resulting TXT Record Information dialog box, you will see a TXT Name and a TXT Value (this information will also be available from the Domains tab)
  7. To complete the verification, you must update the domain's DNS settings with the TXT Name and TXT Value
  8. It may takes up to 72 hours for AWS to verify that the TXT Name and TXT Value have been added to your DNS record. When verification is complete, you will receive a email.
  9. You can now use Amazon SES to send mail from any address in the verified domain. To send a test email, check the box next to the verified domain, and click Send a Test Email

How can we configure SPF, Sender ID, and DKIM?

  1. See authentication

How can we configure SMTP credentials and SMTP sending?

  1. See SMTP

How can we configure our account to handle feedback notifications for bounces, complaints, and out-of-office?

If you send an email message that results in a bounce or a complaint, the intended recipient's ISP will send a notification message to Amazon SES. When this happens, Amazon SES rewrites the From header and forwards the notification to you. How Amazon SES forwards the notification depends on how you sent the original message. If you use the SMTP interface to send the message, then notifications go to the address specified in SMTP's required MAIL FROM command, which overrides any Return-Path header specified in the SMTP DATA. If you used the SendMail API to send the message, then if you specified SendMail's optional ReturnPath parameter, then notifications go to the specified address. Otherwise, notifications go to the address specified in SendMail's required Source parameter, which populates the From header of the message. If you used the SendRawEmail API to send the message, then if you specified SendRawEmail's optional Source parameter, then notifications go to that address, overriding any Return-Path header specified in the raw message. Otherwise, if the Return-Path header was specified in the raw message, then notifications go to that address. Otherwise, notifications go to the address in the From header of the raw message

You can use Amazon SNS to receive notifications about bounces and complaints. Once configured, you will receive bounce and complaint feedback notifications through Amazon SNS in machine-readable format, allowing you to process them programmatically. You can also disable feedback forwarding via email entirely if you configure Amazon SNS feedback notifications for both bounces and complaints. You can publish to any Amazon SNS topic which your login has permission. You do not need to be the topic owner in order to publish to it.

In the beginning, we may not want to configure Amazon SNS to handle bounce and complaint feedback notifications because we need to write a program to process these Amazon SNS events. However, over the long run, we will need to configure Amazon SNS to handle bounce and complaint feedback notifications so that we can automatically disable users that are no longer using our application (their email addresses are causing a hard bounce, or no longer valid)

Feedback notification settings are configured on a per-verified-identity basis. Each email address and domain that you verify has configurable feedback notification settings. You must specify separate feedback notification configurations for different senders because there is no global setting. If a configuration is specified for a domain, it will apply to all mail sent from email addresses in that domain except for those email addresses that are also verified. The configurations for email addresses are completely separated from the configuration for the domain, so changing the domain configuration will have no effect on the email address configuration. For example, if you verify only and set its feedback notification topics, feedback for email from moc.elpmaxe|rednes#moc.elpmaxe|rednes will use those topics. If you verify both and moc.elpmaxe|rednes#moc.elpmaxe|rednes, moc.elpmaxe|rednes#moc.elpmaxe|rednes will not use feedback settings for whether or not they are set. Each verified identity must have its own configuration.

If you want to configure Amazon SNS to handle feedback notifications for bounce and complaint, refer to page 62 of the Amazon SES Developer Guide

How can we request production access?

To request production access to Amazon SES, go to and then complete our brief request form. We will contact you by email after reviewing your request. Please allow one business day for processing.

How can we monitor your usage statistics?

Amazon SES encourage you to monitor your usage of Amazon SES to ensure that you operate within your sending limits. You also need to be aware of any bounces or complaints that occur, so that you can determine and resolve the root causes. As you successfully send more email, you should notice that Amazon SES is gradually adjusting your sending limits so that you can send more email, and at a faster per-second rate. To view your usage statistics:

  1. Go to the AWS Management Console and log in with the email address and password you used when you signed up for Amazon SES
  2. In the navigation pane, click Dashboard. Your usage statistics are shown under Your Amazon SES Metrics
  3. To view trend data for any metric, double-click the corresponding graph.
  4. To obtain this information via the API, use the GetSendQuota method / action.

How can we improve delivery?

  • Check the AWS Management Console each day, monitoring both sending limits and your sending statistics
  • Carefully monitor the number of emails you send per 24-hour period, and note how close you are to your sending limit. Keep your sending volume slightly less than what your quota allows and keep your sending rate a little bit slower than your maximum rate.
  • Watch for upward trends in complaints. If you notice that your complaint rate is increasing, take steps to resolve the situation. Complaint notifications will appear in your inbox. Be sure to remove the affected recipients from any email lists you setup.
  • Watch for upward trends in bounces. Bounce notifications will appear in your inbox. Be sure to remove invalid recipients from any email lists you set up.
  • Watch for upward trends in rejected emails. Amazon SES will generate a MessageRejected error for any message that cannot be queued for delivery. If you see a large number of rejections, make sure that none of your application are trying to send the same rejected message over and over

How can we submit an extended access request?

One you have been granted production access, your sending limits will increase if you are sending high-quality content, and Amazon SES detect that your utilization is approaching your limits, Amazon SES will automatically increase your quota before you actually need it, and no further action on your part is required. If your existing quota is not adequate for your needs, and the system has not automatically increased your quota, you can submit an Extended Access Request to explain in detail your need for a higher limit, and Amazon SES will evaluate your request. Plan ahead. Be aware of your sending limits and try to stay within them. If you anticipate needing a higher quota than the system has allocated automatically, you can submit an Extended Access Request well prior to the date that you need it. If you anticipate needing to send more than one million emails per day, you must submit an Extended Access Request. Extended Access Requests are generally processed within one business day, but plan ahead and don't wait until your situation is critical to submit the request.

  1. Log into your AWS account
  2. Go to Extended Access Request
  3. Provides your first name, last name, email address, phone number, web site address, link to your opt-in page, link to your opt-out policy, link to your privacy policy, email message type (marketing, transactional, subscription, and / or system notification), anticipated maximum daily sending volume, use case detail

Where does AWS recommend that we store the SES command-line scripts?


Where can we download the SES scripts?

What are the difference between SendEmail and SendRawEmail?

The SendEmail API requires you to provide only a source address, destination address, message subject, and a message body. You can optionally provide "Reply-To" addresses. When you call this API, Amazon SES automatically assembles a properly formatted multi-part Multipurpose Internet Mail Extensions (MIME) email message optimized for display by email client software. For more information, see Sending Formatted Email Using the Amazon SES API.

The SendRawEmail API provides you the flexibility to format and send your own raw email message by specifying headers, MIME parts, and content types. SendRawEmail is typically used by advanced users. You need to provide the body of the message and all header fields that are specified as required in the Internet Message Format specification (RFC 5322). For more information, see Sending Raw Email Using the Amazon SES API.

How can we send email using Java?

import java.util.Properties;
import javax.mail.*;
import javax.mail.internet.*;

public class AmazonSESSample {

    static final String FROM = "SENDER@EXAMPLE.COM";   // Replace with your "From" address. This address must be verified.
    static final String TO = "RECIPIENT@EXAMPLE.COM";  // Replace with a "To" address. If your account is still in the 
                                                       // sandbox, this address must be verified.

    static final String BODY = "This email was sent through the Amazon SES SMTP interface by using Java.";
    static final String SUBJECT = "Amazon SES test (SMTP interface accessed using Java)";

    // Supply your SMTP credentials below. Note that your SMTP credentials are different from your AWS credentials.
    static final String SMTP_USERNAME = "YOUR_SMTP_USERNAME";  // Replace with your SMTP username.
    static final String SMTP_PASSWORD = "YOUR_SMTP_PASSWORD";  // Replace with your SMTP password.

    // Amazon SES SMTP host name. This example uses the US West (Oregon) Region.
    static final String HOST = "";    

    // The port you will connect to on the Amazon SES SMTP endpoint. We are choosing port 25 because we will use
    // STARTTLS to encrypt the connection.
    static final int PORT = 25;

    public static void main(String[] args) throws Exception {

        // Create a Properties object to contain connection configuration information.
        Properties props = System.getProperties();
        props.put("mail.transport.protocol", "smtps");
        props.put("mail.smtp.port", PORT); 

        // Set properties indicating that we want to use STARTTLS to encrypt the connection.
        // The SMTP session will begin on an unencrypted connection, and then the client
        // will issue a STARTTLS command to upgrade to an encrypted connection.
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.starttls.enable", "true");
        props.put("mail.smtp.starttls.required", "true");

        // Create a Session object to represent a mail session with the specified properties. 
        Session session = Session.getDefaultInstance(props);

        // Create a message with the specified information. 
        MimeMessage msg = new MimeMessage(session);
        msg.setFrom(new InternetAddress(FROM));
        msg.setRecipient(Message.RecipientType.TO, new InternetAddress(TO));

        // Create a transport.        
        Transport transport = session.getTransport();

        // Send the message.
            System.out.println("Attempting to send an email through the Amazon SES SMTP interface...");

            // Connect to Amazon SES using the SMTP username and password you specified above.
            transport.connect(HOST, SMTP_USERNAME, SMTP_PASSWORD);

            // Send the email.
            transport.sendMessage(msg, msg.getAllRecipients());
            System.out.println("Email sent!");
        catch (Exception ex) {
            System.out.println("The email was not sent.");
            System.out.println("Error message: " + ex.getMessage());
            // Close and terminate the connection.

import java.nio.ByteBuffer;
import java.util.Properties;
import java.util.UUID;

// These are from the JavaMail API, which you can download at 
// Be sure to include the mail.jar library in your project. In 
// the build order, mail.jar should precede the AWS SDK for Java library.
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.Address;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

// These are from the AWS SDK for Java, which you can 
// download at
// Be sure to include the AWS SDK for Java library in your project.
import com.amazonaws.AmazonClientException;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.regions.Region;
import com.amazonaws.regions.Regions;

public class ComposeAndSendMIMEEmail {

  // IMPORTANT: To successfully send an email, you must replace the values 
  // of the strings below with your own values.   

  // Replace with the sender's address. This address must be verified 
  // with Amazon SES.
  private static String EMAIL_FROM      = "SENDER@EXAMPLE.COM";    

  // Replace with the address replies should go to. This address must be 
  //verified with Amazon SES. 
  private static String EMAIL_REPLY_TO  = "REPLY-TO@EXAMPLE.COM";  

  // Replace with a recipient address. If your account is still in the sandbox,
  // this address must be verified with Amazon SES.  

  // Replace with the path of an attachment. Must be a valid path or 
  // this project will not build.
  // Remember to use two slashes in place of each slash.

  // IMPORTANT: Ensure that the region selected below is the one in which your identities are verified.  
  private static Regions AWS_REGION = Regions.US_WEST_2;           

  // Choose the AWS region of the Amazon SES endpoint you want to connect to. Note that your sandbox 
  // status, sending limits, and Amazon SES identity-related settings are specific to a given AWS 
  // region, so be sure to select an AWS region in which you set up Amazon SES. Here, we are using 
  // the US West (Oregon) region. Examples of other regions that Amazon SES supports are US_EAST_1 
  // and EU_WEST_1. For a complete list, see 

  private static String EMAIL_SUBJECT   = "Amazon SES email test";
  private static String EMAIL_BODY_TEXT = "This MIME email was sent through Amazon SES using SendRawEmail.";

    public static void main(String[] args) throws AddressException, MessagingException, IOException {
        Session session = Session.getDefaultInstance(new Properties());
        MimeMessage message = new MimeMessage(session);
        message.setSubject(EMAIL_SUBJECT, "UTF-8");

        message.setFrom(new InternetAddress(EMAIL_FROM));
        message.setReplyTo(new Address[]{new InternetAddress(EMAIL_REPLY_TO)});
        message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(EMAIL_RECIPIENT));

        // Cover wrap
        MimeBodyPart wrap = new MimeBodyPart();

        // Alternative TEXT/HTML content
        MimeMultipart cover = new MimeMultipart("alternative");
        MimeBodyPart html = new MimeBodyPart();


        MimeMultipart content = new MimeMultipart("related");

        String[] attachmentsFiles = new String[]{

        // This is just for testing HTML embedding of different type of attachments.
        StringBuilder sb = new StringBuilder();

        for (String attachmentFileName : attachmentsFiles) {
            String id = UUID.randomUUID().toString();
            sb.append("<img src=\"cid:");
            sb.append("\" alt=\"ATTACHMENT\"/>\n");

            MimeBodyPart attachment = new MimeBodyPart();

            DataSource fds = new FileDataSource(attachmentFileName);
            attachment.setDataHandler(new DataHandler(fds));
            attachment.setHeader("Content-ID", "<" + id + ">");


        html.setContent("<html><body><h1>HTML</h1>\n" + 
          EMAIL_BODY_TEXT + "</body></html>", "text/html");

        try {
            System.out.println("Attempting to send an email through Amazon 
              SES by using the AWS SDK for Java...");

             * The ProfileCredentialsProvider will return your [default]
             * credential profile by reading from the credentials file located at
             * (~/.aws/credentials).
             * TransferManager manages a pool of threads, so we create a
             * single instance and share it throughout our application.
            AWSCredentials credentials = null;
            try {
                credentials = new ProfileCredentialsProvider().getCredentials();
            } catch (Exception e) {
                throw new AmazonClientException(
                        "Cannot load the credentials from the credential profiles file. " +
                        "Please make sure that your credentials file is at the correct " +
                        "location (~/.aws/credentials), and is in valid format.",

            // Instantiate an Amazon SES client, which will make the service 
            // call with the supplied AWS credentials.
            AmazonSimpleEmailServiceClient client = new AmazonSimpleEmailServiceClient(credentials);
            Region REGION = Region.getRegion(AWS_REGION);

            // Print the raw email content on the console
            PrintStream out = System.out;

            // Send the email.
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            RawMessage rawMessage = new RawMessage(ByteBuffer.wrap(outputStream.toByteArray()));

            SendRawEmailRequest rawEmailRequest = new SendRawEmailRequest(rawMessage);
            System.out.println("Email sent!");

        } catch (Exception ex) {
          System.out.println("Email Failed");
            System.err.println("Error message: " + ex.getMessage());
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License