Email Webhooks send email performance data from Customer.io to a URL you specify in order to receive information about events as they occur in real time. Customer.io sends the information as JSON in an HTTP POST.
To begin receiving HTTP calls from Customer.io:
- Log in and choose Integrations from the left panel.
- Look under Streaming Data Out.
- Press the Get Started button next to Email Activity Webhook.
- Provide the URL you would like to receive events at and click Update. The URL can be either an HTTP or HTTPs URL (HTTPs is generally preferred for protecting customer information).
You may use a service like requestb.in to inspect HTTP requests before pointing them at your own servers.
To send a test event to your webhook endpoint, press Test.
By registering a URL with Customer.io, you will be notified when the following events occur:
- email_drafted: email you asked for approval before sending is ready for approval
- email_sent: email has been sent from our servers
- email_delivered: email successfully delivered to the receiving server
- email_opened: email was opened by one of your customers
- email_clicked: customer clicked through a link in the email
- email_bounced: receiving server for email could not or would not accept the email
- email_spammed: email was marked as spam by the customer
- email_unsubscribed: the customer clicked the unsubscribe link on this email
- email_dropped: email was suppressed because customer bounced or reported your emails as spam previously
- email_failed: email had an error as we tried to render it for delivery. A common scenario is the matching customer is missing an attribute you’ve used in the email content.
- email_converted: customer entered/exited the segment set as conversion segment
- email_unsubscribed: customer clicked the unsubscribe link
- customer_unsubscribed: customer has been unsubscribed.
- customer_subscribed: customer has been re-subscribed.
To only receive specific events, select those that interest you:
If you have a specific request for an event not listed here that you would like to be notified of, please contact us.
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 any of the email related events:
An example of an HTTP request for any customer related events:
List of 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 user profile)
- 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
- attachments: specific to event-triggered emails with small attachments (e.g. .ics files)
- customer: all the attributes associated with your user
Timeouts and Failures
We have a 4 second timeout and if we don’t get a successful (200) response in that period, or if anything but a 200 success code is returned, Customer.io will retry sending the notification several times with exponential backoff. We keep retrying up to a max of 10 times over a period of approximately 7 hours.
Frequently Asked Questions
Do webhooks contain the email body? No, we only send the attributes mentioned above under “List of Webhook Attributes”.
How can I secure webhooks? To secure webhooks, you can add basic authentication in the link (e.g. http://username:firstname.lastname@example.org).
How do you identify each message that is going out? Each message sent from Customer.io has an
email_idunique identifier that is also part of the default unsubscribe link:
To view a particular message the UI, go to the Email Log page, open any email and then inside the URL replace the part after email_logs/ with the email_id you’re interested in. For example
The email_id is also displayed under the Metadata details in the right-hand column of the page.
Can I specify which campaign(s) get forwarded to an external webhook? If you want to monitor only a specific campaign, you’ll need to select webhook events based on the
Can I get a webhook when a customer gets added to a segment? From our end, there isn’t a direct way to retrieve segment membership. One solution, though, would be to create a campaign based on the segment you’re interested in, set the email inside to “Queue Draft” and then monitor the
email_draftedevents for that
campaign_idon your side.
Do you send an event for each click performed by a user? The
email_clickedevent is unique, so it only gets triggered the first time someone clicks your email.
Is there a way to rate limit webhooks? No, right now you always get one event per action (sent, opened, clicked, etc.). Unfortunately for larger mailing that can mean thousand of messages pretty quickly.