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.
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.
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 SendGridMessage
for 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 EmailAddress
into 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 null
if 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 header400 - Bad Request
: Something is incorrect or malformed in our JSON body429 - Too many requests/Rate limit exceeded
: Wait and retry500 - 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.