Available to all accounts except Lite.

SendGrid’s Event Webhook will notify a URL of your choice via HTTP POST with information about events that occur as SendGrid processes your email. Common uses of this data are to remove unsubscribes, react to spam reports, determine unengaged recipients, identify bounced email addresses, or create advanced analytics of your email program. With Unique Arguments and Category parameters, you can insert dynamic data that will help build a sharp, clear image of your mailings.

If you’d like to see how one of our customers uses the Event Webhook, check out Leveraging SendGrid’s Event Webhook.

There are a number of pre-made integrations for the SendGrid Event Webhook that make processing events easy. You can find them in the Library Index.

Setup

To setup the Event Webhook via our web interface, login and go to the settings page, click on Show Disabled Apps, click the Event Notification app, then click on settings. Check the boxes next to the type of events that you want posted to your web server, then enter in the URL you have setup to receive POSTs from our servers when an event occurs.

The Event Webhook may also be setup by using our Filter Settings Endpoint.

We support basic HTTP authentication in our Event Webhook. Those who wish to implement can provide credentials in the post event url field on the app settings page. Below is an example of the post url with authentication included.

1
http(s)://username:password@domain/foo.php

If you wish to receive encrypted posts, we require that your callback URL support TLS 1.2.

Requests

You will receive a HTTP POST containing a JSON array of multiple events in one request after a very short delay. These POSTs will be sent to the URL you have defined in the Event Notification app options.

Events currently post every 1 second or when the batch size reaches 1MB (one megabyte), whichever occurs first. This is per server, so the webhook URL may receive tens of posts per second.

Event POST Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[
  {
    "sg_message_id":"sendgrid_internal_message_id",
    "email": "john.doe@sendgrid.com",
    "timestamp": 1337197600,
    "smtp-id": "<4FB4041F.6080505@sendgrid.com>",
    "event": "processed"
  },
  {
    "sg_message_id":"sendgrid_internal_message_id",
    "email": "john.doe@sendgrid.com",
    "timestamp": 1337966815,
    "category": "newuser",
    "event": "click",
    "url": "https://sendgrid.com"
  },
  {
    "sg_message_id":"sendgrid_internal_message_id",
    "email": "john.doe@sendgrid.com",
    "timestamp": 1337969592,
    "smtp-id": "<20120525181309.C1A9B40405B3@Example-Mac.local>",
    "event": "group_unsubscribe",
    "asm_group_id": 42
  }
]

You can test your endpoint by clicking the “Test Your Integration” button on the setup screen. SendGrid will send a simulated POST of events to your callback url. At this time, our testing tool does not support HTTP basic authentication, so you must disable auth on your app while debugging.

SendGrid expects a 2xx HTTP response to the POST, otherwise the event notification will be retried. If your URL returns a non-2xx 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. 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 a lot of events, the incoming data can easily overload a web server if not configured properly. 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, Recipient List over Package Quota
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 message’s subscription management link.
Group Unsubscribe Recipient unsubscribed from specific group, by either direct link or updating preferences.
Group Resubscribe Recipient resubscribes to specific group by updating preferences.

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

Default Parameters for Delivery Events

The following parameters are sent with delivery events: bounce, deferred, delivered, dropped, and processed events. Some events may include additional parameters.

Parameter Description
event One of: bounce, deferred, delivered, dropped, processed
email Email address of the intended recipient
smtp-id An id attached to the message by the originating system

Default Parameters for Engagement Events

The following parameters are sent with engagement events: click, open, spamreport, and unsubscribe events. Some events may include additional parameters.

Parameter Description
event One of: click, 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

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 userid and the email template, you would submit them in the SMTP API header or parameter, as described on the Unique Arguments documentation page, they would then be returned in the events like this:

Unique arguments will show in-line with the other key-value pairs in the Webhook response.

1
2
3
4
5
6
7
8
9
10
11
[
  {
    "sg_message_id":"sendgrid_internal_message_id",
    "email": "john.doe@sendgrid.com",
    "timestamp": 1337966815,
    "event": "click",
    "url": "https://sendgrid.com",
    "userid": "1123",
    "template": "welcome"
  }
]

You can create unique arguments with the same keys as reserved words, such as “event” or “email”. In this case, SendGrid will default to the reserved key and NOT your unique argument. An example of this is below.

Reserved Keys in Unique Arguments

1
2
3
4
5
6
7
8
9
10
//for this example, assume we're sending to john.doe@sendgrid.com
{
  "unique_args": {
    "customerAccountNumber": "55555",
    "activationAttempt": "1",
    "New Argument 1": "New Value 1",
    "email": "jane.doe@sendgrid.com",
    "event": "SendEmail"
  }
}

The resulting webhook call

1
2
3
4
5
6
7
8
9
10
[
  {
    "event": "Processed",
    "timestamp":"123456789",
    "customerAccountNumber": "55555",
    "activationAttempt": "1",
    "New Argument 1": "New Value 1",
    "email": "john.doe@sendgrid.com"
  }
]

Note: The event and the email are not overwritten, because “event” and “email” are reserved and SendGrid defaults to the reserved key for webhooks.

Categories

If categories are used over the SMTP API they will be returned by the Event Webhook as such:

Single Category

Will be returned as a string

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[
  {
    "email": "john.doe@sendgrid.com",
    "timestamp": 1337966815,
    "category": "newuser",
    "event": "open"
  },
  {
    "email": "jane.doe@sendgrid.com",
    "timestamp": 1337966815,
    "category": "olduser",
    "event": "open"
  }
]

Multiple Categories

Will be returned as an array

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[
  {
    "email": "john.doe@sendgrid.com",
    "timestamp": 1337966815,
    "category": [
      "newuser",
      "transactional"
    ],
    "event": "open"
  },
  {
    "email": "jane.doe@sendgrid.com",
    "timestamp": 1337966815,
    "category": "olduser",
    "event": "open"
  }
]

Example

The following example uses PHP to store webhook requests in /tmp/dump.log:

1
2
3
4
5
6
7
8
9
10
11
<?php
$fh = fopen('/tmp/dump.log', 'a+');
if ( $fh )
{
// Dump body
fwrite($fh, print_r($HTTP_RAW_POST_DATA, true));
fclose($fh);
}

echo "ok";
?>

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.

The examples provided below are a JSON array for a particular event. These will always be within an array on the actual POST. The fields are not ordered.

Processed

event email category
processed Message recipient The category you assigned
1
2
3
4
5
6
7
8
9
10
{
  "sg_event_id":"sendgrid_internal_event_id",
  "sg_message_id":"sendgrid_internal_message_id",
  "email":"email@example.com",
  "timestamp":1249948800,
  "smtp-id":"<original-smtp-id@domain.com>",
  "unique_arg_key":"unique_arg_value",
  "category":["category1", "category2"],
  "event":"processed"
}

Deferred

event email response attempt category
deferred Message recipient Full response from MTA Delivery attempt # The category you assigned
1
2
3
4
5
6
7
8
9
10
11
12
{
  "response":"400 Try again",
  "sg_event_id":"sendgrid_internal_event_id",
  "sg_message_id":"sendgrid_internal_message_id",
  "event":"deferred",
  "email":"email@example.com",
  "timestamp":1249948800,
  "smtp-id":"<original-smtp-id@domain.com>",
  "unique_arg_key":"unique_arg_value",
  "category":["category1", "category2"],
  "attempt":"10"
}

Delivered

event email response category
delivered Message recipient Full response from MTA The category you assigned
1
2
3
4
5
6
7
8
9
10
11
{
  "response":"250 OK",
  "sg_event_id":"sendgrid_internal_event_id",
  "sg_message_id":"sendgrid_internal_message_id",
  "event":"delivered",
  "email":"email@example.com",
  "timestamp":1249948800,
  "smtp-id":"<original-smtp-id@domain.com>",
  "unique_arg_key":"unique_arg_value",
  "category":["category1", "category2"]
}

Open

event email category
open Message recipient The category you assigned
1
2
3
4
5
6
7
8
9
10
11
{
  "email":"email@example.com",
  "timestamp":1249948800,
  "ip":"255.255.255.255",
  "sg_event_id":"sendgrid_internal_event_id",
  "sg_message_id":"sendgrid_internal_message_id",
  "useragent":"Mozilla/5.0 (Windows NT 5.1; rv:11.0) Gecko Firefox/11.0 (via ggpht.com GoogleImageProxy)",
  "event":"open",
  "unique_arg_key":"unique_arg_value",
  "category":["category1", "category2"]
}

Click

event email url category
click Message recipient URL Clicked The category you assigned
1
2
3
4
5
6
7
8
9
10
11
12
{
  "sg_event_id":"sendgrid_internal_event_id",
  "sg_message_id":"sendgrid_internal_message_id",
  "ip":"255.255.255.255",
  "useragent":"Mozilla/5.0 (iPhone; CPU iPhone OS 7_1_2 like Mac OS X) AppleWebKit/537.51.2 (KHTML, like Gecko) Version/7.0 Mobile/11D257 Safari/9537.53",
  "event":"click",
  "email":"email@example.com",
  "timestamp":1249948800,
  "url":"http://yourdomain.com/blog/news.html",
  "unique_arg_key":"unique_arg_value",
  "category":["category1", "category2"]
}

Bounce

event email status reason type category
bounce Message recipient Status code string, e.g. 5.5.0 Bounce reason from MTA Bounce/Blocked/Expired The category you assigned
1
2
3
4
5
6
7
8
9
10
11
12
13
{
  "status":"5.0.0",
  "sg_event_id":"sendgrid_internal_event_id",
  "sg_message_id":"sendgrid_internal_message_id",
  "event":"bounce",
  "email":"email@example.com",
  "timestamp":1249948800,
  "smtp-id":"<original-smtp-id@domain.com>",
  "unique_arg_key":"unique_arg_value",
  "category":["category1", "category2"],
  "reason":"500 No Such User",
  "type":"bounce"
}

Drop

event email reason category
dropped Message recipient Drop reason The category you assigned
1
2
3
4
5
6
7
8
9
10
11
{
  "sg_event_id":"sendgrid_internal_event_id",
  "sg_message_id":"sendgrid_internal_message_id",
  "email":"email@example.com",
  "timestamp":1249948800,
  "smtp-id":"<original-smtp-id@domain.com>",
  "unique_arg_key":"unique_arg_value",
  "category":["category1", "category2"],
  "reason":"Bounced Address",
  "event":"dropped"
}

Spam Report

event email category
spamreport Message recipient The category you assigned
1
2
3
4
5
6
7
8
9
{
  "sg_event_id":"sendgrid_internal_event_id",
  "sg_message_id":"sendgrid_internal_message_id",
  "email":"email@example.com",
  "timestamp":1249948800,
  "unique_arg_key":"unique_arg_value",
  "category":["category1", "category2"],
  "event":"spamreport"
}

Unsubscribe

event email category
unsubscribe Message recipient The category you assigned
1
2
3
4
5
6
7
8
{
  "sg_message_id":"sendgrid_internal_message_id",
  "email":"email@example.com",
  "timestamp":1249948800,
  "unique_arg_key":"unique_arg_value",
  "category":["category1", "category2"],
  "event":"unsubscribe"
}

Group Unsubscribe

event email asm_group_id category
unsubscribe Message recipient The id of the unsubscribed asm group The category you assigned
1
2
3
4
5
6
7
8
9
10
11
{
  "sg_message_id":"sendgrid_internal_message_id",
  "email":"email@example.com",
  "timestamp":1249948800,
  "unique_arg_key":"unique_arg_value",
  "category":["category1", "category2"],
  "event":"group_unsubscribe",
  "asm_group_id":1,
  "useragent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36",
  "ip":"255.255.255.255"
}

Group Resubscribe

event email asm_group_id category
unsubscribe Message recipient The id of the resubscribed asm group The category you assigned
1
2
3
4
5
6
7
8
9
10
11
{
  "sg_message_id":"sendgrid_internal_message_id",
  "email":"email@example.com",
  "timestamp":1249948800,
  "unique_arg_key":"unique_arg_value",
  "category":["category1", "category2"],
  "event":"group_resubscribe",
  "asm_group_id":1,
  "useragent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36",
  "ip":"255.255.255.255"
}

Marketing Email Unsubscribes

For emails sent through our Marketing Email tool, unsubscribes will look like the following example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[
  {
    "email": "nick@sendgrid.com",
    "timestamp": 1380822437,
    "newsletter": {
      "newsletter_user_list_id": "10557865",
      "newsletter_id": "1943530",
      "newsletter_send_id": "2308608"
    },
    "category": [
      "Tests",
      "Newsletter"
    ],
    "event": "unsubscribe"
  }
]

IP Pools

For emails sent with a specified IP Pool, you can view the IP Pool used in the event post for a processed event.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[
    {
        "email": "john.doe@sendgrid.com",
        "smtp-id": "<14c583da911.2c36.1c804d@ismtpd-073>",
        "timestamp": 1427409578,
        "pool": {
            "name": "new_MY_test",
            "id": 210
        },
        "sg_event_id": "RHFZB1IrTD2Y9Q7bUdZxUw",
        "sg_message_id": "14c583da911.2c36.1c804d.filter-406.22375.55148AA99.0",
        "event": "processed"
    }
]

Troubleshooting

Ensure that your web server is returning a 2xx response to our servers. Any other response type will result in our server retrying a POST until we receive a 2xx response or the maximum time has expired. All events are retried at increasing intervals for up to 24 hours 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.

You can use the “Test Your Integration” button on the Event Notifications settings page to send simulated events to your callback URL. You can also send a POST from a shell using cURL. This will give you the full response your server is returning including the HTTP headers.

1
curl -X POST -H "Content-Type: application/json" -d '[{"email":"john.doe@sendgrid.com","timestamp":1337197600,"smtp-id":"<4FB4041F.6080505@sendgrid.com>","event":"processed"},{"email":"john.doe@sendgrid.com","timestamp":1337966815,"category":"newuser","event":"click","url":"https://sendgrid.com"},{"email":"john.doe@sendgrid.com","timestamp":1337969592,"smtp-id":"<20120525181309.C1A9B40405B3@Example-Mac.local>","event":"processed"}]'

Version Differences

The primary difference between v2 (no longer available) and v3 of the Event Webhook is that Version 3 delivers events as JSON arrays, whereas the previous version delivered batched JSON as JSON documents separated by line breaks. Furthermore, v3 provides more data with certain events. The previous version of the webhook’s documentation is still provided so you can compare them.