Sendgrid

https://sendgrid.com/docs/User_Guide/Settings/Whitelabel/index.html
https://api.sendgrid.com/docs/API_Reference/Web_API_v3/IP_Management/ip_addresses.html
https://sendgrid.com/docs/Classroom/Send/v3_Mail_Send/index.html
https://sendgrid.com/docs/Integrate/Code_Examples/v3_Mail/java.html
https://sendgrid.com/docs/Classroom/Send/v3_Mail_Send/curl_examples.html
https://sendgrid.com/docs/API_Reference/SMTP_API/index.html#-The-XSMTPAPI-Header
https://stackoverflow.com/questions/7825465/best-practices-for-sending-email-to-lots-of-recipients-rails-sendgrid
https://github.com/sendgrid/sendgrid-php#sending-to-1000s-of-emails-in-one-batch
https://github.com/sendgrid/sendgrid-java
https://sendgrid.com/docs/API_Reference/Web_API_v3/Transactional_Templates/versions.html#-POST
https://docs.microsoft.com/en-us/azure/store-sendgrid-java-how-to-send-email

What is the relationship between section tag and substitution tag?

Section tags are similar to substitution tags in how they’re built, but are specific to the message, not the recipient. You have to have a substitution tag value for each recipient, but you can have any number of section tags. Section tags can then contain Substitution tags for the recipient if needed. Section tags have to be contained within a Substitution tag, since SendGrid needs to know which data to populate for the recipient.

It is possible & acceptable to use only Substition tags. However, that method is not DRY, and you may come against message size limitations. The format of the SMTP API section tag has the form:

{
  "section": {
    ":sectionName1": "section 1 text",
    ":sectionName2": "section 2 text"
  }
}

How you flag your section tags may depend on the library you use to create your SMTP connection, the language you are writing your code in, or any intermediate mail servers that your servers will send mail through. In some cases -subVal- may be the best choice while in other cases, %subVal%, #subVal#, or :subVal may make more sense. The flag doesn’t matter, as long as it’s a unique string.

Do not use spaces inside your section or substitution tags! e.g. %first name% The space breaks the string. Consider the following scenario:

Message body sent to SendGrid:

<html>
 <body>
   Hi :salutation,<br />
   Thanks so much for joining us at our event!

   <p>You have registered for the following event:<br />
    :event_details.</p>

   Thanks,<br />
   The SendGrid Team
 </body>
</html>

The accompanying X-SMTPAPI JSON header would look like:

{
  "to": [
    "alice@foo.com",
    "bob@bar.com",
    "casey@baz.com"
  ],
  "sub": {
    ":salutation": [
      ":female",
      ":male",
      ":neutral"
    ],
    ":name": [
      "Alice",
      "Bob",
      "Casey"
    ],
    ":event_details": [
      ":event1",
      ":event2",
      ":event1"
    ],
    ":event_date": [
      "Jan 1",
      "Feb 14",
      "Aug 11"
    ]
  },
  "section": {
    ":male": "Mr. :name",
    ":female": "Ms. :name",
    ":neutral": ":name",
    ":event1": "New User Event on :event_date",
    ":event2": "Veteran User Appreciation on :event_date"
  }
}

Alice receives:

<html>
 <body>
   Hi Ms. Alice,<br />
   Thanks so much for joining us at our event!

   <p>You have registered for the following event:<br />
    New User Event on Jan 1.</p>

   Thanks,<br />
   The SendGrid Team
 </body>
</html>

Bob receives:

<html>
 <body>
   Hi Mr. Bob,<br />
   Thanks so much for joining us at our event!

   <p>You have registered for the following event:<br />
    Veteran User Appreciation on Feb 14.</p>

   Thanks,<br />
   The SendGrid Team
 </body>
</html>

Casey receives:

<html>
 <body>
   Hi Casey,<br />
   Thanks so much for joining us at our event!

   <p>You have registered for the following event:<br />
    New User Event on Aug 11.</p>

   Thanks,<br />
   The SendGrid Team
 </body>
</html>

Substitution tags allow you to easily generate dynamic content for each recipient on your list. When you send to a list of recipients over SMTP API you can specify substitution tags specific to each recipient. For example, a first name that will then be inserted into an opening greeting like the following, where each recipient sees -firstName- replaced with their first name. For example:

"Dear -firstName-"

These tags can also be used in more complex scenarios. For example, you could use a -customerID- to build a custom URL that is specific to that user. A customer specific ID can replace -customerID- in the URL within your email.

<a href="http://example.com/customerOffer?id=-customerID-">Claim your offer!</a>

Substitution tags will work in the Subject line as well as the body of the email. How you format your substitution tags may depend on the library you use to create your SMTP connection, the language you are writing your code in, or any intermediate mail servers that your servers will send mail through. In some cases -subVal- may be the best choice while in other %subVal% or #subVal# may make more sense. It is best to avoid characters that have special meaning in html, such as <,>, and &. These might end up encoded and will not be properly substituted. Do not use spaces inside your substitution tags, e.g. %first name%

Consider the following scenario:

Email HTML content:

<html>
  <head></head>
  <body>
    <p>Hello -name-,<br>
       Thank you for your interest in our products. I have set up an appointment
             to call you at -time- EST to discuss your needs in more detail. If you would
             like to reschedule this call please visit the following link:
             <a href="http://example.com/reschedule?id=-customerID-">reschedule</a>

                Regards,

                -salesContact-
                -contactPhoneNumber-<br>
    </p>
  </body>
</html>

An accompanying SMTP API JSON header might look something like this:

{
  "to": [
    "john.doe@gmail.com",
    "jane.doe@hotmail.com"
  ],
  "sub": {
    "-name-": [
      "John",
      "Jane"
    ],
    "-customerID-": [
      "1234",
      "5678"
    ],
    "-salesContact-": [
      "Jared",
      "Ben"
    ],
    "-contactPhoneNumber-": [
      "555.555.5555",
      "777.777.7777"
    ],
    "-time-": [
      "3:00pm",
      "5:15pm"
    ]
  }
}

The resulting email for John would look like this:

<html>
  <head></head>
  <body>
    <p>Hello John,<br>
       Thank you for your interest in our products. I have set up an appointment
             to call you at 3:00pm EST to discuss your needs in more detail. If you would
             like to reschedule this call please visit the following link:
             <a href="http://example.com/reschedule?id=1234">reschedule</a>

                Regards,

                Jared
                555.555.5555<br>
    </p>
  </body>
</html>

In contrast, the resulting email for Jane will look like the following, with her specific values replaced in for each tag:

<html>
  <head></head>
  <body>
    <p>Hello Jane,<br>
       Thank you for your interest in our products. I have set up an appointment
             to call you at 5:15pm EST to discuss your needs in more detail. If you would
             like to reschedule this call please visit the following link:
             <a href="http://example.com/reschedule?id=5678">reschedule</a>

                Regards,

                Ben
                777.777.7777<br>
    </p>
  </body>
</html>

How can we send email using the Java mail/send helper?

import com.sendgrid.*;
import java.io.IOException;

public class Example {
  public static void main(String[] args) throws IOException {
    Email from = new Email("test@example.com");
    String subject = "Sending with SendGrid is Fun";
    Email to = new Email("test@example.com");
    Content content = new Content("text/plain", "and easy to do anywhere, even with Java");
    Mail mail = new Mail(from, subject, to, content);

    SendGrid sg = new SendGrid(System.getenv("SENDGRID_API_KEY"));
    Request request = new Request();
    try {
      request.setMethod(Method.POST);
      request.setEndpoint("mail/send");
      request.setBody(mail.build());
      Response response = sg.api(request);
      System.out.println(response.getStatusCode());
      System.out.println(response.getBody());
      System.out.println(response.getHeaders());
    } catch (IOException ex) {
      throw ex;
    }
  }
}
import com.sendgrid.*;

public class SendGridExample {
  public static void main(String[] args) {
    SendGrid sendgrid = new SendGrid("SENDGRID_APIKEY");

    SendGrid.Email email = new SendGrid.Email();

    email.addTo("test@sendgrid.com");
    email.setFrom("you@youremail.com");
    email.setSubject("Sending with SendGrid is Fun");
    email.setHtml("and easy to do anywhere, even with Java");

    SendGrid.Response response = sendgrid.send(email);
  }
}

How can we send email using the raw object?

import com.sendgrid.*;
import java.io.IOException;

public class Example {
  public static void main(String[] args) throws IOException {
    try {
      SendGrid sg = new SendGrid(System.getenv("SENDGRID_API_KEY"));
      Request request = new Request();
      request.setMethod(Method.POST);
      request.setEndpoint("mail/send");
      request.setBody("{\"personalizations\":[
        {\"to\":[{\"email\":\"test@example.com\"}],
          \"subject\":\"Sending with SendGrid is Fun\"}],
          \"from\":{\"email\":\"test@example.com\"},
          \"content\":[{\"type\":\"text/plain\",
          \"value\": \"and easy to do anywhere, even with Java\"}]}");
      Response response = sg.api(request);
      System.out.println(response.getStatusCode());
      System.out.println(response.getBody());
      System.out.println(response.getHeaders());
    } catch (IOException ex) {
      throw ex;
    }
  }
}
public class Example {
  public static void main(String[] args) throws IOException {
    try {
      SendGrid sg = new SendGrid(System.getenv("SENDGRID_API_KEY"));
      Request request = new Request();
      request.setMethod(Method.POST);
      request.setEndpoint("mail/send");
      request.setBody("{
        \"custom_args\":{
            \"New Argument 1\":\"New Value 1\",
            \"activationAttempt\":\"1\",
            \"customerAccountNumber\":\"[CUSTOMER ACCOUNT NUMBER GOES HERE]\"
        },
        \"from\":{\"email\":\"sam.smith@example.com\",\"name\":\"Sam Smith\"},
        \"attachments\":[{
            \"name\":\"file1\",
            \"filename\":\"file1.jpg\",
            \"content\":\"[BASE64 encoded content block here]\",
            \"disposition\":\"inline\",
            \"content_id\":\"ii_139db99fdb5c3704\",
            \"type\":\"jpg\"
        }],
        \"personalizations\":[{
            \"to\":[{\"email\":\"john.doe@example.com\",\"name\":\"John Doe\"}],
            \"cc\":[{\"email\":\"jane.doe@example.com\",\"name\":\"Jane Doe\"}],
            \"bcc\":[{\"email\":\"sam.doe@example.com\",\"name\":\"Sam Doe\"}],
            \"custom_args\":{
                \"New Argument 1\":\"New Value 1\",
                \"activationAttempt\":\"1\",
                \"customerAccountNumber\":\"[CUSTOMER ACCOUNT NUMBER GOES HERE]\"},
                \"headers\":{
                    \"X-Accept-Language\":\"en\",
                    \"X-Mailer\":\"MyApp\"
                },
                \"send_at\":1409348513,
                \"substitutions\":{\"type\":\"object\",\"id\":\"substitutions\"},
                \"subject\":\"Hello, World!\"
        }],
        \"subject\":\"Hello, World!\",
        \"ip_pool_name\":\"[YOUR POOL NAME GOES HERE]\",
        \"content\":[{
            \"type\":\"text/html\",
            \"value\":\"<html><p>Hello, world!</p><img src=[CID GOES HERE]></img></html>\"
        }],
        \"headers\":{},
        \"asm\":{\"groups_to_display\":[1,2,3],\"group_id\":1},
        \"batch_id\":\"[YOUR BATCH ID GOES HERE]\",
        \"tracking_settings\":{
            \"subscription_tracking\":{
                \"text\":\"If you would like to unsubscribe and stop receiveing these emails 
                <% click here %>.\",\"enable\":true,\"html\":\"If you would like to 
                unsubscribe and stop receiving these emails <% clickhere %>.
                \",\"substitution_tag\":\"<%click here%>\"
            },
            \"open_tracking\":{
                \"enable\":true,
                \"substitution_tag\":\"%opentrack\"
            },
            \"click_tracking\":{
                \"enable\":true,
                \"enable_text\":true
            },
            \"ganalytics\":{
                \"utm_campaign\":\"[NAME OF YOUR REFERRER SOURCE]\",
                \"enable\":true,
                \"utm_name\":\"[NAME OF YOUR CAMPAIGN]\",
                \"utm_term\":\"[IDENTIFY PAID KEYWORDS HERE]\",
                \"utm_content\":\"[USE THIS SPACE TO DIFFERENTIATE YOUR EMAIL FROM ADS]\",
                \"utm_medium\":\"[NAME OF YOUR MARKETING MEDIUM e.g. email]\"
            }
        },
        \"mail_settings\":{
            \"footer\":{
                \"text\":\"Thanks,/n The SendGrid Team\",
                \"enable\":true,
                \"html\":\"<p>Thanks</br>The SendGrid Team</p>\"
            },
            \"spam_check\":{
                \"threshold\":3,
                \"post_to_url\":\"http://example.com/compliance\",
                \"enable\":true
            },
            \"bypass_list_management\":{
                \"enable\":true
            },
            \"sandbox_mode\":{\"enable\":false},
            \"bcc\":{
                \"enable\":true,
                \"email\":\"ben.doe@example.com\"
            }
        },
        \"reply_to\":{
            \"email\":\"sam.smith@example.com\",
            \"name\":\"Sam Smith\"
        },
        \"sections\":{
            \"section\":{
                \":sectionName2\":\"section 2 text\",
                \":sectionName1\":\"section 1 text\"
            }
        },
        \"template_id\":\"[YOUR TEMPLATE ID GOES HERE]\",
        \"categories\":[
            \"category1\",\"category2\"
        ],
        \"send_at\":1409348513}");
      Response response = sg.api(request);
      System.out.println(response.getStatusCode());
      System.out.println(response.getBody());
      System.out.println(response.getHeaders());
    } catch (IOException ex) {
      throw ex;
    }
  }
}

What is the easiest way of integrating Sendgrid into an existing application?

If we are integrating Sendgrid with an existing application, setting up the application to use Sendgrid SMTP relay is the easiest way, because it only requires modifying our MTA (our mail server) configuration. Set the server host name to smtp.sendgrid.net. Use port 25 or 587 for plain/TLS connections and port 465 for SSL connections. For most users, Sendgrid recommend using port 587 to avoid rate-limits set by some hosting companies.

How many messages can we send with each connection using SMTP?

100.

What are some sample personalization?

{
  "personalizations": [{
      "to": [{
          "email": "john@example.com"
      }],
      "subject": "Hello, World!"
  }],
  "from": {
      "email": "John Doe"
  },
  "content": {
      "type": "text",
      "value": "Hello, World!"
  },
  "mail_settings": {
      "sandbox_mode": {
          "enable": true
      }
  }
}

The above personalization object will result in an error response:

{
  "errors": [
    {
      "field": "from",
      "message": "The from object must at least have an 'email' parameter 
            with a valid email address and may also contain a 'name' parameter. e.g. 
            {"email": "example@example.com"} or 
            {"email": "example@example.com", "name": "Example Recipient"}"
    }
  ]
}

How can we send a simple email using curl?

curl --request POST \
    --url https://api.sendgrid.com/v3/mail/send \
    --header 'Authorization: Bearer YOUR_API_KEY' \
    --header 'Content-Type: application/json' \
    --data '{
        "personalizations": [{
            "to": [{"email": "recipient@example.com"}]}],
            "from": {"email": "sender@example.com"},
            "subject": "Hello, World!",
            "content": [{
                "type": "text/plain", "value": "Heya!"
            }
        ]
    }'

How can we send a basic email to multiple recipients using the CC list via curl?

curl --request POST \
    --url https://api.sendgrid.com/v3/mail/send \
    --header 'authorization: Bearer YOUR_API_KEY' \
    --header 'Content-Type: application/json' \
    --data '{
        "personalizations": [{
            "to": [{"email": "recipient@example.com"}],
            "cc": [
                {"email":"recipient2@example.com"}, 
                {"email": "recipient3@example.com"}, 
                {"email":"recipient4@example.com"}]}], 
            "from": {"email": "sender@example.com"},
            "subject":"Hello, World!", 
            "content": [{
                "type": "text/plain", 
                "value": "Heya!"
            }]
        }'

How can we send a basic email using a template via curl?

curl --request POST \
    --url https://api.sendgrid.com/v3/mail/send \
    --header 'authorization: Bearer YOUR_API_KEY' \
    --header 'Content-Type: application/json' \
    --data '{
        "personalizations": [{
            "to": [{"email": "recipient@example.com"}]}],
            "from": {"email": "sender@example.com"},
            "subject":"Hello, World!",
            "content": [{
                "type": "text/plain",
                "value": "Heya!"
            }], 
            "template_id" : "YOUR_TEMPLATE_ID"
        }'

How can we send a basic email at a scheduled time via curl?

curl --request POST \
    --url https://api.sendgrid.com/v3/mail/send \
    --header 'authorization: Bearer YOUR_API_KEY' \
    --header 'Content-Type: application/json' \
    --data '{
        "personalizations": [{
            "to": [{"email": "recipient@example.com"}]}],
            "from": {"email": "sender@example.com"},
            "subject":"Hello, World!",
            "content": [{
                "type": "text/plain",
                "value": "Heya!"
            }], 
            "send_at" : "UNIX_TIMESTAMP_HERE"
        }'

How can we generate a batch ID via curl?

curl --request POST \
  --url https://api.sendgrid.com/v3/mail/batch \
  --header 'authorization: Bearer YOUR_API_KEY' \
  --header 'Content-Type: application/json' \

How can we schedule an email to be sent as part of a given batch ID via curl?

curl --request POST \
    --url https://api.sendgrid.com/v3/mail/send \
    --header 'authorization: Bearer YOUR_API_KEY' \
    --header 'Content-Type: application/json' \
    --data '{
        "personalizations": [{
            "to": [{"email": "recipient@example.com"}]}],
            "from": {"email": "sender@example.com"},
            "subject":"Hello, World!",
            "content": [{
                "type": "text/plain",
                "value": "Heya!"
            }], 
            "send_at" : "UNIX_TIMESTAMP_HERE", 
            "batch_id" : "YOUR_BATCH_ID"
        }'

How can we cancel a given batch ID via curl?

curl --request POST \
  --url https://api.sendgrid.com/v3/user/scheduled_sends \
  --header 'authorization: Bearer YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{"batch_id":"YOUR_BATCH_ID","status":"cancel"}'

How can we use Sendgrid with PHP?

$recip = new \SendGrid\Email($email->sender_name, $email->sender_email);
$personalization->addTo($recip);
$personalization->setSubject($email->subject);
$personalization->addSubstitution("%text_content%", "text");
$personalization->addSubstitution("%html_content%", "<p>htmltest</p>");                    
$mail->addPersonalization($personalization);            
$text_content = new \SendGrid\Content("text/plain", "%text_content%");
$mail->addContent($text_content);
$html_content = new \SendGrid\Content("text/html", "%html_content%");
$mail->addContent($html_content);                    
$reply_to = new \SendGrid\ReplyTo("test@example.com");
$mail->setReplyTo($reply_to);

$apiKey = $this->send_grid_key;

$sg = new \SendGrid($this->send_grid_secret);    
$response = $sg->client->mail()->send()->post($mail);                    

var_dump($response->headers());

How much data can we put into the personalization object?

10k bytes per personalization object. Your only allowed 10k bytes per personalization object. Which is actually a LOT of room, when your not putting entire blocks of HTML in them.

How can we send email with substitution?

SendGrid sendGrid = new SendGrid("username","password"));
SendGrid.Email email = new SendGrid.Email();

email.setTo(new String[] { "xyz_to@gmail.com"});
email.setFrom("xyz_from@gmail.com");
email.setSubject("...");
email.setText("...");
email.setHtml("...");

// Substitute template ID
email.addFilter(
    "templates",
    "template_id",
    "1231_1212_2323_3232");

//place holders in template, dynamically fill values in template
email.addSubstitution(
     ":firstName",
     new String[] { firstName });
email.addSubstitution(
     ":lastName",
     new String[] { lastName });

// send your email
Response response = sendGrid.send(email);

How can we request a batch ID via Java?

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import com.sendgrid.*;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

//////////////////////////////////////////////////////////////////
// Create a batch ID
// POST /mail/batch

public class Example {
  public static void main(String[] args) throws IOException {
    try {
      SendGrid sg = new SendGrid(System.getenv("SENDGRID_API_KEY"));
      Request request = new Request();
      request.setMethod(Method.POST);
      request.setEndpoint("mail/batch");
      Response response = sg.api(request);
      System.out.println(response.getStatusCode());
      System.out.println(response.getBody());
      System.out.println(response.getHeaders());
    } catch (IOException ex) {
      throw ex;
    }
  }
}

How can we validate a batch ID via Java?

// GET /mail/batch/{batch_id}

public class Example {
  public static void main(String[] args) throws IOException {
    try {
      SendGrid sg = new SendGrid(System.getenv("SENDGRID_API_KEY"));
      Request request = new Request();
      request.setMethod(Method.GET);
      request.setEndpoint("mail/batch/{batch_id}");
      Response response = sg.api(request);
      System.out.println(response.getStatusCode());
      System.out.println(response.getBody());
      System.out.println(response.getHeaders());
    } catch (IOException ex) {
      throw ex;
    }
  }
}

How can we use the X-SMTPAPI header?

This is a bit of a workaround, but you could batch different emails together into one request by using the substitution property of the X-SMTPAPI header. In your email body, include only the substitution token, e.g. %content%. Then pass your actual content in the header, e.g.

{
  "to": [
    "john.doe@gmail.com",
    "jane.doe@hotmail.com"
  ],
  "sub": {
    "%content%": [
      "Here is the content for the email to john.doe",
      "And this is some different content for jane.doe"
    ]
  }
}

When using a lot of data in the x-smtpapi header, you'll want to try to be efficient. If any part of your content is common to everyone, you can put that in the body as static text. If it's common to some people (or to everyone), you can also leverage Section Tags to keep your header DRYer.

Do we have to pre-create the template in Sendgrid before sending emails?

Probably not. Here is an example using the X-SMTPAPI header:

{
    "filters": {
        "template": {
            "settings": {
                "enable": 1,
                "text/html": "..."
            }
        }
    }
}
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License