v1.0.0
OpenAPI 3.1.0

Reporting webhooks

Customer.io lets you subscribe to reporting webhooks. This page details the events that we report back to your webhook URL.

Set up webhooks to inform an external service about Customer.io events. Webhooks can notify you immediately when customer attributes change or when people open your messages.

Set up webhooks

  1. Log in and go to Data & Integrations > Integrations.

  2. Find and select Reporting Webhooks.

  3. Click Add Reporting Webhook.

  4. Enter the Webhook Endpoint—the URL where you want to receive events. The URL can be either HTTP or HTTPs, but we recommended HTTPS to protect customer information.

  5. Select the events you want to receive.

  6. (Optional) Select the Send Frequency and Body Content options.

    • Send Frequency: This determines whether you receive events the first time they happen or every time they happen.
    • Body Content: Enable this to include message body content in all of the "Sent" events we send to you.
  7. Click Save and Enable Webhook.

We may add fields to payloads

As we release new features, we might add fields to existing webhook payloads. Any event type can gain new fields, and we won't announce these additions in advance. Existing fields keep their names and types, so any additions will be backward compatible.

You should build your endpoint to ignore fields it doesn't recognize. If you validate incoming payloads against a schema, make sure the schema accepts unknown keys. In JSON Schema, for example, don't set additionalProperties: false or your endpoint will reject events when we add a field.

Timeouts and failures

We have a 4 second timeout for calls to your webhook endpoint. If we don't get a successful (2xx) response during those 4 seconds, we retry the webhook over a period of seven days with an exponential backoff. We backlog subsequent webhook calls and won't continue processing them until the timed-out webhook call returns a successful response or the seven day retry period expires.

If your webhook server responds with any of the following status codes, we'll wait for one hour before we retry the failed call. As with timeouts, we use the same exponential backoff for retries and we'll backlog subsequent webhook calls until the failed call returns a successful response.

  • Error codes: 400, 401, 402, 403, 404, 405, 410, 429, 500, 502, 521.
  • Error responses: EOF, server misbehaving, connect: connection refused, read: connection reset by peer, tls: failed to verify certificate: x509:

If you have issues with your webhook server and you want 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.

Client Libraries

Reporting Webhooks

Create a reporting webhook

Create a new webhook configuration.

Body
application/json
  • endpoint
    Type: stringFormat: url
    required

    The webhook URL.

  • events
    Type: array string[] 1…enum
    required

    Specifies the types of events you want to report to your webhook. See our reporting webhooks reference for more information about event types and the information they return.

    values
    • customer_subscribed
    • customer_unsubscribed
    • customer_subscription_preferences_changed
    • email_drafted
    • email_attempted
  • name
    Type: string
    required

    The name of your webhook.

  • disabled
    Type: boolean

    Set to true to quit sending events to the webhook URL. Set to false to enable the webhook.

  • full_resolution
    Type: boolean

    Set to false to send unique open and click events to the webhook. Set to true to send all events.

  • with_content
    Type: boolean

    Set to true to include the message body in _sent events.

Responses
  • application/json
  • 400

    The request was malformed.

  • application/json
Request Example for post/v1/reporting_webhooks
curl https://api.customer.io/v1/reporting_webhooks \
  --request POST \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_SECRET_TOKEN' \
  --data '{
  "name": "my cool webhook",
  "endpoint": "https://example.com/webhook",
  "disabled": false,
  "full_resolution": true,
  "with_content": false,
  "events": [
    "email_failed",
    "webhook_failed"
  ]
}'
{
  "name": "my cool webhook",
  "id": 4,
  "type": "webhook",
  "endpoint": "https://example.com/webhook",
  "disabled": false,
  "full_resolution": true,
  "with_content": false,
  "events": [
    "email_failed",
    "webhook_failed"
  ]
}

List reporting webhooks

Return a list of all of your reporting webhooks

Responses
  • application/json
  • application/json
Request Example for get/v1/reporting_webhooks
curl https://api.customer.io/v1/reporting_webhooks \
  --header 'Authorization: Bearer YOUR_SECRET_TOKEN'
{
  "reporting_webhooks": [
    {
      "name": "my cool webhook",
      "id": 4,
      "type": "webhook",
      "endpoint": "https://example.com/webhook",
      "disabled": false,
      "full_resolution": true,
      "with_content": false,
      "events": [
        "email_failed",
        "webhook_failed"
      ]
    }
  ]
}

Get a reporting webhook

Returns information about a specific reporting webhook.

Path Parameters
  • webhook_id
    Type: integer
    required

    The identifier of a webhook.

Responses
  • application/json
  • 404

    The webhook ID does not exist.

  • application/json
Request Example for get/v1/reporting_webhooks/{webhook_id}
curl https://api.customer.io/v1/reporting_webhooks/1 \
  --header 'Authorization: Bearer YOUR_SECRET_TOKEN'
{
  "name": "my cool webhook",
  "id": 4,
  "type": "webhook",
  "endpoint": "https://example.com/webhook",
  "disabled": false,
  "full_resolution": true,
  "with_content": false,
  "events": [
    "email_failed",
    "webhook_failed"
  ]
}

Update a webhook configuration

Update the configuration of a reporting webhook. Turn events on or off, change the webhook URL, etc.

Path Parameters
  • webhook_id
    Type: integer
    required

    The identifier of a webhook.

Body
application/json
  • endpoint
    Type: stringFormat: url
    required

    The webhook URL.

  • events
    Type: array string[] 1…enum
    required

    Specifies the types of events you want to report to your webhook. See our reporting webhooks reference for more information about event types and the information they return.

    values
    • customer_subscribed
    • customer_unsubscribed
    • customer_subscription_preferences_changed
    • email_drafted
    • email_attempted
  • name
    Type: string
    required

    The name of your webhook.

  • disabled
    Type: boolean

    Set to true to quit sending events to the webhook URL. Set to false to enable the webhook.

  • full_resolution
    Type: boolean

    Set to false to send unique open and click events to the webhook. Set to true to send all events.

  • with_content
    Type: boolean

    Set to true to include the message body in _sent events.

Responses
  • application/json
  • 400

    The request was malformed.

  • 404

    The webhook ID does not exist.

  • application/json
Request Example for put/v1/reporting_webhooks/{webhook_id}
curl https://api.customer.io/v1/reporting_webhooks/1 \
  --request PUT \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_SECRET_TOKEN' \
  --data '{
  "name": "my cool webhook",
  "endpoint": "https://example.com/webhook",
  "disabled": false,
  "full_resolution": true,
  "with_content": false,
  "events": [
    "email_failed",
    "webhook_failed"
  ]
}'
{
  "name": "my cool webhook",
  "id": 4,
  "type": "webhook",
  "endpoint": "https://example.com/webhook",
  "disabled": false,
  "full_resolution": true,
  "with_content": false,
  "events": [
    "email_failed",
    "webhook_failed"
  ]
}

Delete a reporting webhook

Delete a reporting webhook's configuration.

Path Parameters
  • webhook_id
    Type: integer
    required

    The identifier of a webhook.

Responses
  • 200

    A successful request has no response.

  • 404

    The webhook ID does not exist.

  • application/json
Request Example for delete/v1/reporting_webhooks/{webhook_id}
curl https://api.customer.io/v1/reporting_webhooks/1 \
  --request DELETE \
  --header 'Authorization: Bearer YOUR_SECRET_TOKEN'
No Body

Webhooks

Webhook

Reporting webhook format

Customer.io sends events to your webhook URL in the following format. Events are generally organized by object_type—representing the message or Customer.io action (i.e. email, sms, etc)—and the specific metric pertaining to the type (i.e. sent, bounced, etc).

Headers
  • x-cio-timestamp
    Type: integerFormat: unix timestamp
    required

    The timestamp when the request was sent.

  • x-cio-signature
    Type: string
    required

    A string combining your webhook signing key with the body of webhook request using an HMAC-SHA256 hash, used to help you securely verify requests.

Body
application/json
    • Events that occur when a customer subscribes or unsubscribes from your messages.

      • A person subscribed to messages from you—their unsubscribed attribute was set to false.

        • data
          Type: object
          required

          Contains information about the event, specific to the object_type and metric.

        • event_id
          Type: string
          required

          The unique ID of the reporting webhook event being sent.

        • metric
          enum
          const:  
          subscribed
          required

          The metric recorded by the event. For customer events, this is whether the customer explicitly subscribed or unsubscribed.

          values
          • subscribed
        • object_type
          Type: stringenum
          required

          The channel that triggered the subscription change. If the subscription change wasn't triggered from a message, or we can't determine which message triggered the change, the object_type is customer.

          values
          • customer
          • email
          • sms
          • push
          • in_app
          • slack
          • webhook
          • whatsapp
        • timestamp
          Type: integerFormat: unix timestamp
          required

          The unix timestamp when the event occurred.

Request Example for postreportingWebhook
{
  "metric": "subscribed",
  "event_id": "01E4C4CT6YDC7Y5M7FE1GWWPQJ",
  "object_type": "customer",
  "timestamp": 1613063089,
  "data": {
    "customer_id": "0200000001",
    "email_address": "test@example.com",
    "identifiers": {
      "id": "42",
      "email": "test@example.com",
      "cio_id": "d9c106000001"
    }
  }
}

Models