Reporting Webhooks

Reporting Webhooks


Reporting Webhooks send real-time message activity events (e.g. sends, opens, clicks) as JSON in an HTTP POST.

They're useful in many cases, including analyzing message activity outside of Customer.io.

Looking to send a custom webhook to a specific API?

Check out Webhook Actions, instead.

Setup

  1. Log in and choose Integrations from the left panel.
  2. Select the Data Management category.
  3. Find and select Reporting Webhooks.
  4. Select Add Reporting Webhook.
  5. Enter the URL for the Webhook Endpoint at which you would like to receive events. The URL can be either HTTP or HTTPs (HTTPs is recommended to protect customer information).
  6. Select the events you want to receive, then choose Save and Enable Webhook at the bottom right of the page.

Add New Webhook

Disabling & Enabling

If you want to stop webhook events from being sent, you can disable the webhook.

  • Select "Disable" from the dropdown menu on the index page.
    Disable Toggle
  • Or toggle the state while editing a Webhook Endpoint, then click save.
    Disable Toggle 2

To re-enable, select "Enable" from the list dropdown menu shown above, or edit your webhook and make the change there.

Testing

To inspect Webhook Events before pointing them at your own servers, use a service like webhook.site.

Warning
Enabling a webhook endpoint could cause sensitive data to send. We recommend creating a test/sandbox Customer.io workspace for webhook testing purposes. That way, no sensitive data can leak to a potentially unsecured endpoint.

To send a test event, press Send Test while editing your Webhook Endpoint.

image.png

Events

The following events are available via webhook:

Name Description
customer_subscribed A person's "unsubscribed" attribute was explicitly set to "false"
customer_unsubscribed A person's "unsubscribed" attribute was explicitly set to "true"
email_drafted An email draft was created
email_attempted An email that couldn't be sent to the delivery provider will be retried
email_deferred An email that the delivery provider couldn't send will be retried by the delivery provider
email_sent An email was sent from Customer.io to the delivery provider
email_delivered The delivery provider reported the email was delivered to an inbox
email_opened An email was opened
email_clicked A tracked link in an email was clicked
email_converted A person matched a conversion goal attributed to an email
email_unsubscribed A person unsubscribed via a particular email
email_bounced The delivery provider was unable to deliver the email
email_dropped An email wasn't sent because it was addressed to a person who was suppressed
email_spammed An email was marked as spam by the recipient
email_failed An email couldn't be sent to the delivery provider
push_drafted A push notification draft was created
push_attempted A push notification that couldn't be sent to the delivery provider will be retried
push_sent A push notification was sent from Customer.io to the delivery provider
push_delivered The app on a person's device reported the push notification was delivered
push_opened The app on a person's device reported the push notification was opened
push_clicked A tracked link in a push notification has been clicked
push_converted A person matched a conversion goal attributed to a push notification
push_bounced The delivery provider reported at least one invalid device token
push_dropped A push notification wasn't sent because at least one device token previously bounced
push_failed A push notification couldn't be sent to the delivery provider
sms_drafted An SMS draft was created
sms_attempted An SMS that couldn't be sent to the delivery provider will be retried
sms_sent An SMS was sent from Customer.io to the delivery provider
sms_delivered The delivery provider reported the SMS was delivered
sms_clicked A tracked link in an SMS has been clicked
sms_converted A person matched a conversion goal attributed to an SMS
sms_bounced The delivery provider was unable to deliver the SMS
sms_failed An SMS couldn't be sent to the delivery provider
slack_drafted A slack draft was created
slack_attempted A slack message that couldn't be sent will be retried
slack_sent A slack message was sent from Customer.io to slack
slack_clicked A tracked link in a slack message has been clicked
slack_failed A slack message couldn't be sent to slack
webhook_drafted A webhook draft was created
webhook_attempted A webhook that couldn't be sent will be retried
webhook_sent A webhook was sent from Customer.io to the specified Webhook URL
webhook_clicked A tracked link in a webhook payload has been opened
webhook_failed A webhook couldn't be sent to the specified Webhook URL

To only receive specific events, select just those that interest you:
Webhook Events

If you have a specific request for an event not listed here that you would like to be notified of, please contact us.

Webhook Attributes

Attribute Description
action_id If the delivery was created as part of a Campaign or API Triggered Broadcast workflow, this is the ID for the unique workflow item that caused the delivery to be created. It can be used to retrieve full message details, including content, via the Campaign endpoint of our API.
broadcast_id If applicable, the ID of the API Triggered Broadcast that generated the message. It can be used to retrieve full message details, including content, via the Campaign endpoint of our API.
campaign_id If applicable, the ID of the Event-triggered, Segment-triggered, or Date-triggered Campaign that generated the message.
content_id If the message was part of a newsletter split test, this is the ID of the split test variation.
customer_id The ID of the person the webhook event occurred to. Blank if the person in question has been deleted.
delivery_id The unique ID of the delivery record associated with the message.
device_id Only on push-related events, the ID of the associated mobile device.
device_platform Only on push-related events, the platform of the associated mobile device.
email_address Only on customer_subscribed and customer_unsubscribed events, this is the email address of the person.
event_id The unique ID of the reporting webhook event being sent. This can be useful for deduplicating purposes.
event_type The type of event sent (e.g. email_sent, sms_drafted).
href Only on "clicked" events, the fully rendered URL of the link that was clicked.
journey_id The ID for the path a person went through in a Campaign or API Triggered Broadcast workflow. In our Data Warehouse Sync, this is referred to as subject_id.
link_id Only on "clicked" events, the ID of the tracked link that was clicked.
newsletter_id If applicable, the ID of the Newsletter that generated the message. It can be used to retrieve full message details, including content, via the Newsletters endpoint of our API.
recipient The address of the message recipient. This could be an email address, a phone number, a mobile device ID, a Webhook URL, or a Slack username or channel.
subject For email events, this is the subject of the email.
failure_message If applicable, the reason a message failed to send.
timestamp The timestamp at which the event being reported took place.

Format

Customer.io Webhooks are HTTP POST requests encoded in JSON. The requests have a User Agent header containing "Customer.io Web Hooks x.x" where "x.x" is the version number.

The JSON body contains a general top-level section included in all webhook requests, as well as a "data" attribute, which contains data specific to the type of event.

Below is an example of an HTTP request for an email-related event:

User-Agent: Customer.io Web Hooks 1.0
Host: webhook.site
Content-Type: application/json
Accept-Encoding: gzip
Cf-Connecting-Ip: 167.114.157.9
X-Request-Id: 	7e6f46cd-480e-4354-93ce-74b770015c7f
Connect-Time: 1
Content-Length: 1100
Cf-Visitor: {"scheme":"http"}
Total-Route-Time: 0
Cf-Ipcountry: CA
Cf-Ray: 2b62237a83a12507-ORD
Connection: close
Via: 1.1 vegur

RAW BODY

{
  "data": {
    "action_id": 36,
    "broadcast_id": 9,
    "customer_id": "1",
    "delivery_id": "RPILAgABcRhIBqSp7kiPekGBIeVh",
    "recipient": "test@example.com",
    "subject": "hello"
  },
  "event_id": "01E4C8AY5K21N2QNRBD9YXJ13Z",
  "object_type": "email",
  "metric": "clicked",
  "timestamp": 1585254331
}

For examples for each of our webhook events, please click here.

Timeouts and Failures

We have a 4 second timeout and if we don't get a successful (2xx) response during those 4 seconds, Customer.io will retry sending the notification over a period of 7 days with an exponential backoff. We will not move past a failing webhook until we get a successful (2xx) response or until 7 days have expired. Subsequent webhooks will be backlogged and will get processed after the success or failure of the webhook that failed and triggered the backlog.

If you wish to temporarily block our servers, you can look up the current set of IP addresses we use via this API endpoint.

Securely Verifying Requests

For security purposes, every email webhook is delivered with an X-CIO-Signature header. This signature is generated by combining your webhook signing key with the body of webhook request using a standard HMAC-SHA256 hash. You can find the signing key on the Email Activity Webhook integration page in your account settings. (This is the same page where you enter your webhook endpoint.)

To validate a signed request, first you'll need to retrieve the X-CIO-Timestamp header sent with the webhook request, and the body of the request. Combine the version number, timestamp and body delimited by colons to form a string in the form v0:<timestamp>:<body> (the version number is always v0). Using HMAC SHA256, hash the string using your webhook signing secret as the hash key. Compare this value to the value of the X-CIO-Signature header sent with the request to confirm that the request originated with Customer.io.

Here's an example of a validation function in Golang.

import (
	"encoding/hex"
	"crypto/hmac"
	"crypto/sha256"
	"strconv"
	"fmt"
)

func CheckSignature(WebhookSigningSecret, XCIOSignature string, XCIOTimestamp int, RequestBody []byte) (bool, error) {
  signature, err := hex.DecodeString(XCIOSignature)
  if err != nil {
    return false, err
  }

  mac := hmac.New(sha256.New, []byte(WebhookSigningSecret))

  if _, err := mac.Write([]byte("v0:" + strconv.Itoa(XCIOTimestamp) + ":")); err != nil {
    return false, err
  }
  if _, err := mac.Write(RequestBody); err != nil {
    return false, err
  }

  computed := mac.Sum(nil)

  if !hmac.Equal(computed, signature) {
    fmt.Println("Signature didn't match")
    return false, nil
  }

  fmt.Println("Signature matched!")
  return true, nil
}

Frequently Asked Questions

  1. Do webhooks contain the message body? No, only the attributes mentioned in the "Webhook Attributes" section above are sent.
  1. How can I secure webhooks? It's possible to add basic authentication in the Webhook Endpoint URL field (e.g. http://username:password@example.com).

  2. How do you identify each message that is going out? Each message sent from Customer.io has a delivery_id unique identifier that is also part of the default unsubscribe link:

https://track.customer.io/unsubscribe/MjYyMTI6Fs_YAmQAAnMAFeEaAU2YoV7tFRoYVh6HYAFzOjIyOTkwMQA=
 
To view a particular message in the UI, select Deliveries & Drafts from the left panel, click under the "Action" column for any message in the list, then replace the end of the URL in your browser with the delivery_id you're interested in. For example:

https://fly.customer.io/env/26212/outbox/deliveries/MjYyMTI6Fs_YAmQAAnMAFeEaAU2YoV7tFRoYVh6HYAFzOjIyOTkwMQA=

The delivery_id is also displayed under the Metadata details in the right-hand column of the page.

  1. Can I specify which campaign(s) get forwarded to an external webhook? No. If you need to monitor only a specific campaign, however, it's possible to handle the logic on your end to filter out unwanted webhook events based on campaign_id.

  2. Can I get a webhook when a customer gets added to a segment? No. But if you want to pull a list of people in a given segment, you can do so using the /segments/:id/membership endpoint of our API. Alternatively, you could create a segment-triggered campaign based on the segment you're interested in, set the email inside to "Queue Draft" and then monitor the email_drafted events for that campaign_id.

  3. Do you send an event for each click performed by a user? By default, only the first click event is sent. If you wish to have each click recorded, you can set the Send Frequency on your Webhook Endpoint accordingly:
    Webhook Send Frequency

  4. Can Reporting Webhooks be rate limited? By default, we only send one event per action (sent, opened, clicked, etc.) to limit the output. No further rate limiting is available.

  5. Is it possible to host a webhook endpoint in Customer.io? No. For incoming data, you'll need to use our REST API or our Segment integration.

Webhook Event Examples

customer_subscribed

{
  "data": {
    "customer_id": "1",
    "email_address": "test@example.com"
  },
  "event_id": "01E4C4CT6YDC7Y5M7FE1GWWPQJ",
  "object_type": "customer",
  "metric": "subscribed",
  "timestamp": 1585250199
}

customer_unsubscribed

{
  "data": {
    "customer_id": "1",
    "email_address": "test@example.com"
  },
  "event_id": "01E4C4C6P79C12J5A6KPE6XNFD",
  "object_type": "customer",
  "metric": "unsubscribed",
  "timestamp": 1585250179
}

email_drafted

{
  "data": {
    "action_id": 36,
    "broadcast_id": 9,
    "customer_id": "1",
    "delivery_id": "RPILAgABcRhIBqSp7kiPekGBIeVh"
  },
  "event_id": "01E4C4G1S0AMNG0XVF2M7RPH5S",
  "object_type": "email",
  "metric": "drafted",
  "timestamp": 1585250305
}

email_attempted

{
  "data": {
    "action_id": 36,
    "broadcast_id": 9,
    "customer_id": "1",
    "delivery_id": "RPILAgABcRhIBqSp7kiPekGBIeVh",
    "failure_message": "from address can't be blank"
  },
  "event_id": "01E4C4HDQ7GH7M19ZKS39BDB73",
  "object_type": "email",
  "metric": "attempted",
  "timestamp": 1585250350
}

email_sent

{
  "data": {
    "action_id": 36,
    "broadcast_id": 9,
    "customer_id": "1",
    "delivery_id": "RPILAgABcRhIBqSp7kiPekGBIeVh",
    "recipient": "test@example.com",
    "subject": "hello"
  },
  "event_id": "01E4C8AY5K21N2QNRBD9YXJ13Z",
  "object_type": "email",
  "metric": "sent",
  "timestamp": 1585254331
}

email_delivered

{
  "data": {
    "action_id": 12042,
    "campaign_id": 1424,
    "customer_id": "test-1",
    "delivery_id": "SA13dk35ja7s8d9kja3s2dASdasd==",
    "recipient": "test@example.com",
    "subject": "Thanks for joining!"
  },
  "event_id": "01ASDG7S9P6MAZPTJ78JND9GDC",
  "object_type": "email",
  "metric": "delivered",
  "timestamp": 1234567890
}

email_opened

{
  "data": {
    "action_id": 36,
    "broadcast_id": 9,
    "customer_id": "1",
    "delivery_id": "RPILAgABcRhIBqSp7kiPekGBIeVh",
    "recipient": "test@example.com",
    "subject": "hello"
  },
  "event_id": "01E4C8BES586H0A5PFK1ARB9JW",
  "object_type": "email",
  "metric": "opened",
  "timestamp": 1585254348
}

email_clicked

{
  "data": {
    "action_id": 36,
    "broadcast_id": 9,
    "customer_id": "1",
    "delivery_id": "RPILAgABcRhIBqSp7kiPekGBIeVh",
    "href": "http://google.com",
    "link_id": 1,
    "recipient": "test@example.com",
    "subject": "hello"
  },
  "event_id": "01E4C8BES5XT87ZWRJFTB35YJ3",
  "object_type": "email",
  "metric": "clicked",
  "timestamp": 1585254348
}

email_converted

{
  "data": {
    "action_id": 12042,
    "campaign_id": 1424,
    "customer_id": "test-1",
    "delivery_id": "SA13dk35ja7s8d9kja3s2dASdasd==",
    "recipient": "test@example.com",
    "subject": "Thanks for joining!"
  },
  "event_id": "01ASDG7S9P6MYWPTJ78JND9GDC",
  "object_type": "email",
  "metric": "converted",
  "timestamp": 1234567890
}

email_unsubscribed

{
  "data": {
    "action_id": 37,
    "broadcast_id": 6,
    "customer_id": "test-1",
    "delivery_id": "RAECAAFxEqBRJ6UXtUdDSeFe_L8=",
    "recipient": "test@example.com",
    "subject": "hello"
  },
  "event_id": "01E4S9V7WSQK80RJZC6ATRQX8B",
  "object_type": "email",
  "metric": "unsubscribed",
  "timestamp": 1585692122
}

email_bounced

{
  "data": {
    "content_id": 1146,
    "customer_id": "test-1",
    "delivery_id": "RMehBAAAAXE7r_ONUGXly9DBGkpq1JS31=",
    "failure_message": "550 5.5.0 Requested action not taken: mailbox unavailable",
    "newsletter_id": 736,
    "recipient": "test@example.com",
    "subject": "Thanks for joining!"
  },
  "event_id": 12ASDG7S9P6MAZPTJ78DAND9GDC",
  "object_type": "email",
  "metric": "bounced",
  "timestamp": 1234567890
}

email_dropped

{
  "data": {
    "content_id": 1146,
    "customer_id": "test-7",
    "delivery_id": "RMehBAAasdAAXE7r_ONUGXly9DBGkpq1JS31=",
    "failure_message": "Not delivering to previously bounced address",
    "newsletter_id": 736,
    "recipient": "test@example.com",
    "subject": "Thanks for joining!"
  },
  "event_id": "31ASDG7S9P6MAZPTJ78DAND9GDC",
  "object_type": "email",
  "metric": "dropped",
  "timestamp": 1234567890
}

email_spammed

{
  "data": {
    "action_id": 73,
    "broadcast_id": 52,
    "customer_id": "test-9",
    "delivery_id": "RObuBAXE4xnjV0vtJso_6xdRAas135",
    "recipient": "test-9@example.com",
    "subject": "Book now!"
  },
  "event_id": "31ASDG7SU6HSJ78DAND9GDC",
  "object_type": "email",
  "metric": "spammed",
  "timestamp": 1234567890
}

email_failed

{
  "data": {
    "action_id": 73,
    "broadcast_id": 52,
    "customer_id": "test-2",
    "delivery_id": "EFBAXE4xnjV0vtJso_6xdRAas135",
    "failure_message": "Customer is unsubscribed",
    "recipient": "test-2@example.com",
    "subject": "Book for vacation now!"
  },
  "event_id": "31ASDG7SU6JN78DAND9GDC",
  "object_type": "email",
  "metric": "failed",
  "timestamp": 1234567890
}

push_drafted

{
  "data": {
    "action_id": 37,
    "broadcast_id": 9,
    "customer_id": "1",
    "delivery_id": "RPILAgUBcRhIBqSfeiIwdIYJKxTY"
  },
  "event_id": "01E4C4G1S0HZ7C4220T6QNY8JX",
  "object_type": "push",
  "metric": "drafted",
  "timestamp": 1585250305
}

push_attempted

{
  "data": {
    "action_id": 38,
    "campaign_id": 6,
    "customer_id": "2",
    "delivery_id": "RAEABQFxN56fWzydfV4_EGvfobI=",
    "failure_message": "NoDevicesSynced"
  },
  "event_id": "01E4VSX8SZ0T9AQMH4Q16NRB89",
  "object_type": "push",
  "metric": "attempted",
  "timestamp": 1585776075
}

push_sent

{
  "data": {
    "action_id": 37,
    "broadcast_id": 9,
    "customer_id": "1",
    "delivery_id": "RPILAgUBcRhIBqSfeiIwdIYJKxTY",
    "recipients": [
      {
        "device_id": "eeC2XC_NVPo:APA91bEYRSgmu-dAZcOWi7RzKBbT9gdY3WJACOpLQEMAmAOsChJMAZWirvSlSF3EuHxb7qdwlYeOyCWtbsnR14Vyx5nwBmg5J3SyPxfNn-ey1tNgXIj5UOq8IBk2VwzMApk-xzD4JJof",
        "device_platform": "android"
      }
    ]
  },
  "event_id": "01E4C4HDQ7P1X9KTKF0ZX7PWHE",
  "object_type": "push",
  "metric": "sent",
  "timestamp": 1585250350
}

push_delivered

{
  "data": {
    "action_id": 13,
    "campaign_id": 5,
    "customer_id": "243",
    "delivery_id": "RPILAQUBboR6Y6Wtb0GDNd_20wZr",
    "recipients": [
      {
        "device_id": "fdFJKOIVhKk:APA91bE182bzKtLJm5wV9aOCsCGTEUOrjNKmkUF_PXByKSViWvHcn9_a05h-7ihnZnqwnUSA55FBr2CgNkZGF2q4KeXclyDhBpfeYZVr6OHHuSiw7hbCDtvar0HPfw0SzlVR9Jw7_0yL"
      }
    ]
  },
  "event_id": "01E4V2WVVHPB24FHC0PRR1E68G",
  "object_type": "push",
  "metric": "delivered",
  "timestamp": 1585751943
}

push_opened

{
  "data": {
    "action_id": 37,
    "broadcast_id": 9,
    "customer_id": "1",
    "delivery_id": "RPILAgUBcRhIBqSfeiIwdIYJKxTY"
  },
  "event_id": "01E4C4V2B3FW52RKEKP4QF2P74",
  "object_type": "push",
  "metric": "opened",
  "timestamp": 1585250665
}

push_clicked

{
  "data": {
    "action_id": 37,
    "broadcast_id": 9,
    "customer_id": "1",
    "delivery_id": "RPILAgUBcRhIBqSfeiIwdIYJKxTY",
    "href": "ciosas://product/2",
    "link_id": 1,
    "recipients": [
      {
        "device_id": "eeC2XC_NVPo:APA91bEYRSgmu-dAZcOWi7RzKBbT9gdY3WJACOpLQEMAmAOsChJMAZWirvSlSF3EuHxb7qdwlYeOyCWtbsnR14Vyx5nwBmg5J3SyPxfNn-ey1tNgXIj5UOq8IBk2VwzMApk-xzD4JJof"
      }
    ]
  },
  "event_id": "01E4V2SBHYK4TNTG8WKMP39G9R",
  "object_type": "push",
  "metric": "clicked",
  "timestamp": 1585751829
}

push_converted

{
  "data": {
    "action_id": 37,
    "broadcast_id": 9,
    "customer_id": "1",
    "delivery_id": "RPILAgUBcRiSO2rkbaiQ-5luSWXK",
    "recipients": [
      {
        "device_id": "eeC2XC_NVPo:APA91bEYRSgmu-dAZcOWi7RzKBbT9gdY3WJACOpLQEMAmAOsChJMAZWirvSlSF3EuHxb7qdwlYeOyCWtbsnR14Vyx5nwBmg5J3SyPxfNn-ey1tNgXIj5UOq8IBk2VwzMApk-xzD4JJof"
      }
    ]
  },
  "event_id": "01E4XWX0NB4DH73NWDRTT71NMT",
  "object_type": "push",
  "metric": "converted",
  "timestamp": 1585846320
}

push_bounced

{
  "data": {
    "action_id": 38,
    "campaign_id": 6,
    "customer_id": "1",
    "delivery_id": "RAEABQFxN55vrab8yVNNVNI2Hxc=",
    "recipients": [
      {
        "device_id": "my_android_device_id",
        "device_platform": "android",
        "failure_message": "FCM_INVALID_TOKEN"
      }
    ]
  },
  "event_id": "01E4VSWX38K3R96QJ3B9N37KJR",
  "object_type": "push",
  "metric": "bounced",
  "timestamp": 1585776063
}

push_dropped

{
  "data": {
    "action_id": 40,
    "broadcast_id": 7,
    "customer_id": "1",
    "delivery_id": "RAECBQFxN6HHbPKYTzCT4XAS20Y=",
    "recipients": [
      {
        "device_id": "my_android_device_id",
        "device_platform": "android",
        "failure_message": "FCM_INVALID_TOKEN"
      }
    ]
  },
  "event_id": "01E4VT612DR9BX6J1HXCBAYA1N",
  "object_type": "push",
  "metric": "dropped",
  "timestamp": 1585776361
}

push_failed

{
  "data": {
    "action_id": 38,
    "campaign_id": 6,
    "customer_id": "3",
    "delivery_id": "RAECAQFxNeUBx6LqfjqrN1j-BJc=",
    "failure_message": "Variable 'customer.test' is missing"
  },
  "event_id": "01E4VSWX38K3R96QJ3B9N37KJR",
  "object_type": "push",
  "metric": "failed",
  "timestamp": 1585747134
}

sms_drafted

{
  "data": {
    "action_id": 38,
    "broadcast_id": 9,
    "customer_id": "1",
    "delivery_id": "RPILAgIBcRhIBqSZNqzgZVFoivwW"
  },
  "event_id": "01E4C4G1S02P8D0G2JMY88KAFN",
  "object_type": "sms",
  "metric": "drafted",
  "timestamp": 1585250305
}

sms_attempted

{
  "data": {
    "action_id": 41,
    "campaign_id": 7,
    "customer_id": "test-21",
    "delivery_id": "ROk1AAIBcR4iT6mueuxiDtzO8HXv",
    "failure_message": "Twilio Error 21408: Permission to send an SMS has not been enabled for the region indicated by the 'To' number: +18008675309."
  },
  "event_id": "01E4F3DCS83P8HT7R3E6DWQN1X",
  "object_type": "sms",
  "metric": "attempted",
  "timestamp": 1234567890
}

sms_sent

{
  "data": {
    "action_id": 38,
    "broadcast_id": 9,
    "customer_id": "1",
    "delivery_id": "RPILAgIBcRhIBqSZNqzgZVFoivwW",
    "recipient": "+18008675309"
  },
  "event_id": "01E4C4HDQ7KZF7AFPG6N2YQDJ0",
  "object_type": "sms",
  "metric": "sent",
  "timestamp": 1585250350
}

sms_delivered

{
  "data": {
    "action_id": 38,
    "broadcast_id": 9,
    "customer_id": "1",
    "delivery_id": "RPILAgIBcRh6qzHz-8gKvscP2UZa",
    "recipient": "+18008675309"
  },
  "event_id": "01E4XXG43MDMG47Z43V3090AW5",
  "object_type": "sms",
  "metric": "delivered",
  "timestamp": 1585846946
}

sms_clicked

{
  "data": {
    "action_id": 38,
    "broadcast_id": 9,
    "customer_id": "1",
    "delivery_id": "RPILAgIBcRh6qzHz-8gKvscP2UZa",
    "href": "https://app.com/verify",
    "link_id": 1,
    "recipient": "+18008675309"
  },
  "event_id": "01E4XXPN42JDF4B1ATQKTZ8WHV",
  "object_type": "sms",
  "metric": "clicked",
  "timestamp": 1585847161
}

sms_converted

{
  "data": {
    "action_id": 38,
    "broadcast_id": 9,
    "customer_id": "1",
    "delivery_id": "RPILAgIBcRh6qzHz-8gKvscP2UZa",
    "recipient": "+18008675309"
  },
  "event_id": "01E4XXPN42JDF4B1ATQKTZ8WHV",
  "object_type": "sms",
  "metric": "converted",
  "timestamp": 1585847161
}

sms_bounced

{
  "data": {
    "action_id": 38,
    "broadcast_id": 9,
    "customer_id": "1",
    "delivery_id": "RPILAgIBcRhIBqSZNqzgZVFoivwW",
    "failure_message": "Twilio error code: 21704",
    "recipient": "+18008675309"
  },
  "event_id": "01E4C4HENVDANXW94RQHHQYYDM",
  "object_type": "sms",
  "metric": "bounced",
  "timestamp": 1585250351
}

sms_failed

{
  "data": {
    "action_id": 41,
    "campaign_id": 7,
    "customer_id": "test-21",
    "delivery_id": "ROk1AAIBcR4iT6mueuxiDtzO8HXv",
    "failure_message": "Twilio Error 21408: Permission to send an SMS has not been enabled for the region indicated by the 'To' number: +18008675309."
  },
  "event_id": "01E4F3DCS83P8HT7R3E6DWQN1X",
  "object_type": "sms",
  "metric": "failed",
  "timestamp": 1234567890
}

slack_drafted

{
  "data": {
    "action_id": 39,
    "broadcast_id": 9,
    "customer_id": "1",
    "delivery_id": "RPILAgQBcRhIBqRiZAc0fyQiLvkC"
  },
  "event_id": "01E4C4G1S0T3Y4V8W7F6MNFA8S",
  "object_type": "slack",
  "metric": "drafted",
  "timestamp": 1585250305
}

slack_attempted

{
  "data": {
    "action_id": 38,
    "campaign_id": 6,
    "customer_id": "test",
    "delivery_id": "RAECAQFxNeUBx6LqfjqrN1j-BJc=",
    "failure_message": "Variable 'customer.test' is missing"
  },
  "event_id": "01E4TYA2KA9T0XGHCRJ784B774",
  "object_type": "slack",
  "metric": "attempted",
  "timestamp": 1585747134
}

slack_sent

{
  "data": {
    "action_id": 39,
    "broadcast_id": 9,
    "customer_id": "1",
    "delivery_id": "RPILAgQBcRhNAufb0s30bmz5HD7Y",
    "recipient": "#signups"
  },
  "event_id": "01E4C4TQKD6KJ274870J5DE2HB",
  "object_type": "slack",
  "metric": "sent",
  "timestamp": 1585250655
}

slack_clicked

{
  "data": {
    "action_id": 39,
    "broadcast_id": 9,
    "customer_id": "1",
    "delivery_id": "RPILAgQBcRhocpCJE3mFfwvRzNe6",
    "href": "http://bing.com",
    "link_id": 1,
    "recipient": "#signups"
  },
  "event_id": "01E4C6HJTBNDX18XC4B88M3Y2G",
  "object_type": "slack",
  "metric": "clicked",
  "timestamp": 1585252451
}

slack_failed

{
  "data": {
    "action_id": 39,
    "broadcast_id": 9,
    "customer_id": "1",
    "delivery_id": "RPILAgQBcRhIBqRiZAc0fyQiLvkC",
    "failure_message": "value passed for channel was invalid"
  },
  "event_id": "01E4C4HDQ77BCN0X23Z3WBE764",
  "object_type": "slack",
  "metric": "failed",
  "timestamp": 1585250350
}

webhook_drafted

{
  "data": {
    "action_id": 40,
    "broadcast_id": 9,
    "customer_id": "1",
    "delivery_id": "RPILAgEBcRhIBqSrYcXDr2ks6Pj9"
  },
  "event_id": "01E4C4G1S04QCV1NASF4NWMQNR",
  "object_type": "webhook",
  "metric": "drafted",
  "timestamp": 1585250305
}

webhook_attempted

{
  "data": {
    "action_id": 38,
    "broadcast_id": 6,
    "customer_id": "test",
    "delivery_id": "RAECAQFxNeUBx6LqgjqrN1j-BJc=",
    "failure_message": "Variable 'customer.test' is missing"
  },
  "event_id": "01E4TYA2KA9T0XGHCRJ784B774",
  "object_type": "webhook",
  "metric": "attempted",
  "timestamp": 1585747134
}

webhook_sent

{
  "data": {
    "action_id": 40,
    "broadcast_id": 9,
    "customer_id": "1",
    "delivery_id": "RPILAgEBcRhNAufr2aU82jtDZEh6",
    "recipient": "https://test.example.com/process"
  },
  "event_id": "01E4C6EP0HCKRHKFARMZ5XEH7A",
  "object_type": "webhook",
  "metric": "sent",
  "timestamp": 1585252357
}

webhook_clicked

{
  "data": {
    "action_id": 40,
    "broadcast_id": 9,
    "customer_id": "1",
    "delivery_id": "RPILAgEBcRhNAufr2aU82jtDZEh6",
    "href": "http://bing.com",
    "link_id": 1,
    "recipient": "https://test.example.com/process"
  },
  "event_id": "01E4C6F5N1Y54TVGJTN64Y1ZS9",
  "object_type": "webhook",
  "metric": "clicked",
  "timestamp": 1585252373
}

webhook_failed

{
  "data": {
    "action_id": 38,
    "broadcast_id": 6,
    "customer_id": "test",
    "delivery_id": "RAECAQFxNeK3bC4SYqhQqFGBQrQ=",
    "failure_message": "HTTP 404 Not Found []"
  },
  "event_id": "01E4TY5FVB0ZQ4KVDKRME0XSYZ",
  "object_type": "webhook",
  "metric": "failed",
  "timestamp": 1585746984
}


Legacy Email Webhook Format

On April 8, 2020, we streamlined our email webhook payloads, removing unneeded data in order to improve our processing speed and reliability.

For customers who had Reporting Webhooks enabled before April 8, however, the old email webhook payload remains unchanged.

The example below covers any of the email-related events:

User-Agent: Customer.io Web Hooks 1.0
Host: webhook.site
Content-Type: application/json
Accept-Encoding: gzip
Cf-Connecting-Ip: 167.114.157.9
X-Request-Id: 	7e6f46cd-480e-4354-93ce-74b770015c7f
Connect-Time: 1
Content-Length: 1100
Cf-Visitor: {"scheme":"http"}
Total-Route-Time: 0
Cf-Ipcountry: CA
Cf-Ray: 2b62237a83a12507-ORD
Connection: close
Via: 1.1 vegur

RAW BODY

{
"data": {
  "campaign_id": "1000002",
  "campaign_name": "Upgrade to Premium",
  "customer_id": "98513",
  "email_address": "customer@example.com",
  "email_id": "NTE4MzE6FwGLxwJkAAJkABcBIfcaAVVvdGukFUsYV2hY6QFlOjQ4YTZhODljLTM3MjktMTFlNi04MDQwLTYzNGY3NzAzM2NhNjozNDMwMzEA",
  "message_id": "1000013",
  "message_name": "First Upgrade Email",
  "subject": "Have any doubts?",
  "template_id": "343031",
  "variables": {
    "attachments": null,
    "customer": {
      "created_at": 1466453747,
      "email": "customer@example.com",
      "id": 98513,
      "name": "John Doe",
      "plan_name": "free"
    },
    "email_id": "NTE4MzE6FwGLxwJkAAJkABcBIfcaAVVvdGukFUsYV2hY6QFlOjQ4YTZhODljLTM3MjktMTFlNi04MDQwLTYzNGY3NzAzM2NhNjozNDMwMzEA",
    "event": {
      "page": "https://customer.io/pricing/"
    },
    "event_id": "48a6a89c-3729-11e6-8040-634f77033ca6",
    "event_name": "viewed_pricing_page",
    "from_address": null,
    "recipient": null,
    "reply_to": null
  }
},
"event_id": "b50cb221c60f87cdf06e",
"event_type": "email_drafted",
"timestamp": 1466456299
}

Legacy Email Webhook Attributes

  • campaign_id and campaign_name: refer to the transactional, segment-triggered or newsletter campaign that generated the email
  • customer_id: user id (can be retrieved from the person profile). Only present if the person is still active (not included if the person has been deleted).
  • email_address: "To" email address
  • email_id: unique message id (each individual message sent from Customer.io has a different "email_id"); can also be found in the unsubscribe link URL
  • event: specific to event-triggered campaigns; includes all the event attributes
  • event_id (data section): specific to event-triggered campaigns; id of the event that generated the message (not visible in the UI)
  • event_id: internal attribute; id associated with the email_type action
  • event_name: specific to event-triggered campaigns; name of the event that powers the campaign
  • event_type: type of event ("email_drafted", "email_sent", etc.)
  • from_address: specific to anonymous event-triggered campaigns; from_address set via the event
  • href and link_id: specific to "email_clicked" events
  • href: first URL clicked by the user
  • link_id: internal attribute (not visible in the UI)
  • message_id: campaign email id; can be found in the campaign URL after emails/ (e.g. https://fly.customer.io/env/51831/v2/composer/emails/225039)
  • message_name: the name of the campaign email
  • reason: specific to the "email_bounced" and "email_dropped" events, mentions the cause of the bounce/suppression (e.g.: Invalid)
  • recipient: specific to anonymous event-triggered campaigns; email address of a user that does not exist inside Customer.io
  • reply_to: specific to anonymous event-triggered campaigns; reply_to address set via the event
  • subject: email subject
  • template_id: internal attribute, each email inside a campaign can have multiple template ids depending on the changes made over time. You can view it in the UI by filtering for a specific email under Email Log. For example: https://fly.customer.io/env/51831/email_logs?campaign=139744&template=343216
  • timestamp: date and time when the event took place in unix (seconds since epoch) format
  • variables:
    • attachments: specific to event-triggered emails with small attachments (e.g. .ics files)
    • customer: all the attributes associated with your user
Was this article helpful?