In this article, we will take a look at how to send emails with the SendGrid API directly from our code. Sending emails from within our applications is a common scenario that we face as developers. Let’s look at a couple of use cases where we may need to do this.

To download the source code for this article, you can visit our GitHub repository.

Let’s imagine we are working on an application, and we want to provide our users with a way to email error logs to our support team with just the click of a button. This is a situation where it would be nice to send an email directly from within our application. Another very common use case is found within the context of E-commerce. Say we have a storefront app written in ASP.NET Core. When a user visits our page and makes a purchase, we need to email them a purchase confirmation. This is another candidate for sending an email directly from our code.

What Is SendGrid

SendGrid is an email service that provides flexibility, as well as reliability when sending emails. They provide a wide range of statistics and metrics that can help users in planning and organizing email campaigns. The service provides simple signup and one-click unsubscribe links, making it easy for customers to both register for and unsubscribe from email lists.

Support Code Maze on Patreon to get rid of ads and get the best discounts on our products!
Become a patron at Patreon!

As developers, the standout feature of SendGrid is their Web API, which provides an easy and intuitive way to send emails. With their API, we don’t have to worry about the hassles of setting up some sort of OAuth authentication, SMTP configuration, or any other details. We simply send a POST request to the Web API endpoint and our email is on its way.

With that in mind, let’s jump right in and see how we can use the SendGrid API to send emails from within our application.

Getting Started With the SendGrid API

In this article, we will focus on using the SendGrid Web API to send emails. We will look at how to use the Web API directly via HttpClient, and after that, we will see how to use the official SendGrid NuGet package. To follow along with the remainder of the article, we will need to register for a SendGrid account. No need to worry, the free tier account is sufficient for our exercise. Now we need to log into our account and create our Web API key. This key is required for authorizing our requests to the SendGrid REST endpoint. With our key in hand, we can continue with the article. 

Send Emails With the SendGrid API Using HttpClient

Since the SendGrid Web API is simply expecting a JSON payload in our POST request, we can quickly get up and running sending emails using only HttpClient. If you are unfamiliar with using the HttpClient, you can check out our tutorial series here.

First, we need to create and initialize our HttpClient:

var httpClient = new HttpClient()
{
    BaseAddress = new Uri(@"https://api.sendgrid.com"),
};
httpClient.DefaultRequestHeaders.Add("authorization", $"Bearer <SendGridWebApiKey>");

Here we create a new HttpClient. Next, we set the BaseAddress to point to the SendGrid API endpoint https://api.sendgrid.com. Finally, we use the Web API key, which we generated earlier, to set up our authorization header. We need to be sure to replace the <SendGridWebApiKey> value with our own Web API key.

Preparing the JSON Body

Now, let’s create our message content. This is a simple JSON body containing all the information for our email (this JSON body has been formatted for readability, in practice we would remove all unnecessary whitespace before posting):

{
  "personalizations":[
    {
      "to":[
        {
          "email":"[email protected]",
          "name":"John Smith"
        }
      ]
    }
  ],
  "from":{
    "email":"[email protected]",
    "name":"Jane Doe"
  },
  "subject":"Sending Email via SendGrid Web API!",
  "content":[
    {
      "type":"text/plain",
      "value":"Sending email is fun!"
    },
    {
      "type":"text/html",
      "value":"Sending email is <strong>fun</strong>!"
    }
  ]
}

Let’s briefly examine this JSON body. First, we set the to, and the from (i.e. the sender), both of which are mandatory. Next, we set the subject, and lastly, the content. Regarding the email body, we can set plain text, HTML, or both, since the content field is an array.

All that’s left is to send our email:

using var content = new StringContent(messageContent, Encoding.UTF8, "application/json");
using var response = await httpClient.PostAsync("/v3/mail/send", content).ConfigureAwait(false);

Assuming that we assigned our JSON to a variable called messageContent, we can then create a StringContent object with it. Then all we need to do is POST the StringContent to the SendGrid endpoint /v3/mail/send. If we have done everything correctly, the response.StatusCode will be 202 Accepted.

Adding an Attachment

Now, let’s take our example a step further and look at how we could do something a little more complicated. For example, what if we wish to send an email containing a file attachment? Let’s take a look at the JSON body for such an email (for brevity, the Base64 encoding of the Word document has been removed):

{
  // JSON content from simple email - removed for brevity
  "attachments":[
    {
      "content":"<<Bas64EncodedFileContentsRemovedForBrevity>>",
      "type":"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
      "filename":"MeetingOutline.docx"
    }
  ]
}

We just add this block to our previous JSON body and follow the same steps as before, creating the StringContent and posting it to the Web API endpoint. So far, this has all seemed pretty simple and straightforward, but as our emails become more complicated, and as we add in more of the SendGrid features, such as scheduling, customized subjects and message bodies, template replacements, etc., hand coding JSON bodies for our messages will become very unwieldy. Not only that, but our codebase will become difficult to maintain. Thankfully, there is a better way.

Send Emails With the SendGrid API Using the Official NuGet Package

First, we need to add the SendGrid NuGet package to our project. For our article, we are using the latest version of the library: v9.2.8.1. Now that we have the library added to our project, let’s go ahead and take a look at how we can use it to send emails.

Now, we need to initialize the SendGridClient with our API key (be sure to replace <SendGridWebApiKey> with our own):

var sendGridClient = new SendGridClient("<SendGridWebApiKey>");

Using the MailHelper Class

The SendGrid library provides a MailHelper class that makes it quick and easy to get up and running with simple email generation. Let’s take a look at it in action. First, let’s create some variables to hold our email details:

var from = new EmailAddress("[email protected]", "Jane Doe");
var to = new EmailAddress("[email protected]", "John Smith");
var subject = "Sending Email via SendGrid Web API!";
var plainText = "Sending email is fun!";
var htmlContent = "Sending email is <strong>fun</strong>!"

Now, let’s send the email:

var message = MailHelper.CreateSingleEmail(from, to, subject, plainText, htmlContent);
var response = await sendGridClient.SendEmailAsync(message);

Notice how the MailHelper class handles creating the SendGridMessagefor us from just a few parameters. We pass in from (the sender), to (our recipient), subject and finally both our contents: plainText and htmlContent. We can set both the plain text and the HTML content directly through the helper method. If we only want to set the plain text, then all we need to do is pass null or the empty string as htmlContent. We can also do it the other way around if we only want HTML content. With our message created, we simply pass it to the SendEmailAsync method of our client and await the response. If all goes as planned, the response status code will be 202 Accepted.

Customizing Our Email Via SendGridMessage

While the MailHelper class is nice for quickly creating a simple email, if we want to customize the behavior, we need to work with the SendGridMessage object directly. We can still employ the MailHelper class to create our message, but for the purposes of our example, let’s go ahead and create one directly. This way, we can see the level of flexibility and customizability it provides.

To make the code a little cleaner, we will define a couple of helper extension methods (some code has been removed for brevity, for the full example, please see our GitHub repository):

private static List<EmailAddress> ToList(this EmailAddress address) => new(new[] {address});
private static long ToUnixTime(this DateTime dateTime) => new DateTimeOffset(dateTime).ToUnixTimeSeconds();

First, we have a helper method to convert an EmailAddressinto a List<EmailAddress>, as all the TO, CC and BCC fields require this. Our second helper will convert a DateTime to a Unix timestamp, which we need when scheduling emails.

Create the Personalizations

Next, we create a list to hold all of our email personalizations:

var personalizations = new List<Personalization>();

Now we need to create the Personalization for our email:

new Personalization
{
    Tos = to.ToList(),
    Ccs = cc?.ToList(),
    Bccs = bcc?.ToList(),
};

The Personalization object provides an extreme amount of flexibility for configuring different recipient groups for our emails. Here we can override the email subject, change the FROM field, add email template replacement values, and even add custom headers. It is through the Personalization class that we add CC and BCC recipients to our email. All recipient properties take a List<EmailAddress>and in the case of the CC and BCC we can ignore it or just set it to nullif we are only including recipients in the TO field of our email.

Create the SendGridMessage

Now, we are ready to create our message:

var message = new SendGridMessage
{
    Personalizations = personalizations,
    Subject = subject,
    From = from,
    SendAt = sendAt.ToUnixTime(),
    PlainTextContent = plainTextContent,
    HtmlContent = htmlContent,
};

In examining the code, we see that message creation is pretty straightforward. We set our Personalizations, add a Subject, set the From field, etc. For the email body, just like when creating the JSON manually, we can set any or all of the content properties: PlainTextContent and HtmlContent.

Another property that we are setting is the SendAt time. SendAt requires a Unix timestamp. Valid times are from the current time up to 72 hours in the future. With the SendAt time, we can also set a batch ID, which allows us to cancel sending. There are several other settings that allow for further email customization that are outside the scope of this article. We can read more about them at the SendGrid GitHub repository.

Send the Email Via the SendGrid API

Now we are ready to send our message:

var response = await sendGridClient.SendEmailAsync(message);

Assuming we have done everything correctly, then we expect response.StatusCode to be 202 Accepted. 

Error Handling When Sending Emails With the SendGrid API

As developers, we always hope that our code works flawlessly, and without errors, but, unfortunately, this is not the case. This means we need to be prepared to deal with errors.

When working with the SendGrid Web API, whether we are using HttpClient directly or the official library, we always have to check the response from our request, so we can handle potential errors in a smart way. With that in mind, here are a few common response codes that we need to be sure to handle appropriately:

  • 401 - Unauthorized: We have passed an incorrect or invalid Web API key in our authorization header
  • 400 - Bad Request: Something is incorrect or malformed in our JSON body
  • 429 - Too many requests/Rate limit exceeded: Wait and retry
  • 500 - Internal server error: Beyond our control, wait and retry 

Along with the status codes, the content portion of the Web API response includes additional information that will help us track down the error. For example, if we made a 400 - Bad Request, the content body will contain information related to what was wrong with the request.

One nice feature provided by the SendGrid Web API is the ability to send a sandbox message. Sandbox mode validates the body of our JSON payload without sending a message. If everything is valid, we will get a 200 - OK response.

If we are using HttpClient, then we access the sandbox feature by adding a mail_settings section to our JSON and enabling sandbox_mode:

{
  // JSON content from simple email - removed for brevity

  "mail_settings":{
    "sandbox_mode":{
      "enable":true
    }
}   

If we are using the SendGridClient, then all that is needed is to set one additional property on our SendGridMessage, SetSandBoxMode:

message.SetSandBoxMode(true);

Conclusion

In this article, we saw how to send an email with the SendGrid API. We first looked at sending an email via a POST request to the SendGrid Web API endpoint using HttpClient. Second, we looked at using the official SendGrid C# library. Third, we looked briefly at some common error responses and how to deal with them. Finally, we saw how to validate our message payload using sandbox mode, to help us prevent potential errors.

Liked it? Take a second to support Code Maze on Patreon and get the ad free reading experience!
Become a patron at Patreon!