V1 and V2 of this webhook are being deprecated. Version 3 is the recommended option and the only option available to new users.

Requests

You have the option to receive a HTTP POST request for each event (“Version 1”) or to receive a batch of multiple events in one request after a very short delay (“Version 2”). These POSTs will be sent to the URL you have defined in the Event Notification app options.

SendGrid expects a 200 HTTP response to the POST, otherwise the event notification will be retried. If your URL returns a non-200 HTTP code it will be deferred and retried for 24 hours. The maximum number of deferred POSTs in the retry queue is 100,000. If the queue is full, the oldest request in the queue will be removed to make room for the newest deferred POST. This means that if you use batched events these events will drop due to 24 hours before the queue can max out. Events that cannot be submitted within the maximum retry period or events removed from the defer queue will be lost.

If your email traffic generates lots of events, the incoming amount of data can easily overload a web server if not configured properly for scalability. To reduce the number of requests to your server, enable the batched events option.

Keep in mind that even with batched events enabled, your servers can potentially see a large number of POSTs from the webhook as we POST batches from multiple servers. You can load test your endpoints with loader.io for free.

Event Types

The following lists the events generated by SendGrid.

Event Criteria
Processed Message has been received and is ready to be delivered.
Dropped You may see the following drop reasons:
  • Invalid SMTPAPI header
  • Spam Content (if spam checker app enabled)
  • Unsubscribed Address
  • Bounced Address
  • Spam Reporting Address
  • Invalid
Delivered Message has been successfully delivered to the receiving server.
Deferred Recipient’s email server temporarily rejected message.
Bounce Receiving server could not or would not accept message.
Open Recipient has opened the HTML message.
Click Recipient clicked on a link within the message.
Spam Report Recipient marked message as spam.
Unsubscribe Recipient clicked on messages’s subscription management link.

The following image shows where events can be generated as email is being processed:

Default Parameters

The following parameters are always passed with each event. Some events include additional parameters. Also a category name and custom argument may be passed. Please see the Custom Parameters and Categories section below for more information.

Parameter Description
event One of: bounce, click, deferred, delivered, dropped, processed, open, spamreport, unsubscribe
email Email address of the intended recipient
useragent The user agent responsible for the event, e.g. “Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36”
ip The IP Address where the event originated.
sg_event_id A unique id for the event. This is a 23 byte string.

Unique Arguments and Categories

Events generated by SendGrid can also include unique arguments. To define and receive custom parameters in your URL the SMTP API must be used when sending emails using the unique_args argument. For example, if you have an application and want to receive custom parameters such as the user id and the email template name, include the following in your SMTP headers as X-SMTPAPI or as the xsmtpapi parameter of your Web API call:

1
2
3
4
5
6
{
  "unique_args": {
    "userid": "1123",
    "template": "welcome"
  }
}

Either of those emails will generate the following HTTP POST request to your application when the email is opened:

1
email=emailrecipient@domain.com&event=open&userid=1123&template=welcome

Categories

If a category is used over the SMTP API to get detailed statistics for user signups in addition to custom parameter, include the following in your SMTP headers as X-SMTPAPI or as the xsmtpapi parameter of your Web API call:

1
2
3
4
5
6
7
{
  "unique_args": {
    "userid": "1123",
    "template": "welcome"
  },
  "category": "user_signup"
}

Either of those emails will generate the following HTTP POST request to your application when the email is opened:

1
email=emailrecipient@domain.com&event=open&userid=1123&template=welcome&category=user_signup
If you apply multiple categories to any of your outgoing messages, the returned data will be in the form of an array.

Batched Events (Version 2)

Batched event POSTs have a content-type header of application/json, and contain exactly one JSON string per line, with each line representing one event. Please note that currently the POST headers define this post as application/json, though it’s not; each line is a valid JSON string, but the overall POST body is not. For example:

1
2
{"email":"foo@bar.com","timestamp":1322000095,"unique_arg":"my unique arg","event":"delivered"}
{"email":"foo@bar.com","timestamp":1322000096,"unique_arg":"my unique arg","event":"open"}
Batched events currently post every 1 second, or when the batch size reaches 1MB (one megabyte), whichever occurs first.
Batching your events is recommended to reduce server load and reduce the number of open connections.

Examples

The following examples will use PHP language, the Web API to send email using curl, and the SMTP API for the X-SMTPAPI parameter when sending email. Many times is useful to see all parameters that are being POSTed. The following example receives a batched POST and dumps the parameters to a log file located at /tmp/dump.log:
1
2
3
4
5
6
7
8
9
<?php
$fh = fopen('/tmp/dump.log', 'a+');
if ( $fh )
{
// Dump body
fwrite($fh, print_r($HTTP_RAW_POST_DATA, true));
fclose($fh);
}
?> ok
If you’re not batching, the code would look like:
1
2
3
4
5
6
7
8
9
<?php
$fh = fopen('/tmp/dump.log', 'a+');
if ( $fh )
{
// Dump parameters
fwrite($fh, print_r($_POST, true));
fclose($fh);
}
?> ok
If you are using a hosting service, you don’t have direct access to the server’s file system. In that case, you need to modify the path for the dump log to be somewhere you do have access to. In most cases, the second line in the code above…
1
2
3
<?php
$fh = fopen('/tmp/dump.log', 'a+');
?>
should be changed to…
1
2
3
<?php
$fh = fopen('~/dump.log', 'a+');
?>

Parameter Details

The following shows each type of event that can be posted along with the specific parameters that go along with the event.

You can use the SMTP API to specify additional custom parameters including categories and unique args. Each unique arg is posted as a separate post parameter, similar to the category listed below, but with a custom name specified by you.

Processed

event email category
processed Message recipient The category you assigned

Deferred

event email response attempt category
deferred Message recipient Full reponse from MTA Delivery attempt # The category you assigned

Delivered

event email response category
delivered Message recipient Full reponse from MTA The category you assigned

Open

event email category
open Message recipient The category you assigned

Click

event email url category
click Message recipient URL Clicked The category you assigned

Bounce

event email status reason type category
bounce Message recipient 3-digit status code Bounce reason from MTA Bounce/Blocked/Expired The category you assigned

Drop

event email reason category
dropped Message recipient Drop reason The category you assigned

Spam Report

event email category
spamreport Message recipient The category you assigned

Unsubscribe

event email category
unsubscribe Message recipient The category you assigned

Troubleshooting

Ensure that your web server is returning a 200 response to our servers. Any other response type will result in our server retrying a POST until we receive a 200 response or the maximum time has expired. All events are retried at increasing intervals for up to three days after the event occurs. Make sure you are not blocking our IPs that are trying to POST to your server. Our IPs change often since we constantly add more machines. Also, you can try a test POST yourself from a terminal by running the following command. This will give you the full response your server is returning including the HTTP headers.

1
curl -i -d 'email=test@gmail.com&arg2=2&arg1=1&category=testing&event=processed'