# Customer.io data out

## About this integration

Sending data into your Customer.io workspace lets you take advantage of various sources to gather customer data, personalize messages, and trigger complex workflows. You can send data to different workspaces, to gather data for different messaging use cases.

[Mode How we forward source data to the destination: through Customer.io's servers or directly from our JavaScript client.](/cdp/destinations/getting-started/#connection-mode)

[Web sources Indicates whether or not this integration supports our the JavaScript client.](/cdp/sources/getting-started/#types-of-sources)

[API sources Indicates whether or not this integration supports our server libraries (Go, NodeJS, Python), API, Mobile SDK, and other data sources.](/cdp/sources/getting-started/#types-of-sources)

[Supported calls The API methods this integration supports.](/cdp/sources/source-spec/source-events/)

[Integration name The name of this integration if you want to enable or disable it in the `integrations` object.](/cdp/sources/source-spec/common-fields/#the-integrations-object)

Standard

[identify](/api/cdp/#operation/identify), [track](/api/cdp/#operation/track), [page](/api/cdp/#operation/page), [screen](/api/cdp/#operation/screen), [group](/api/cdp/#operation/group), and [alias](/api/cdp/#operation/alias)

Actions Customerio

## Getting started[](#getting-started)

1.  Go to **[Data & Integrations > Integrations](https://fly.customer.io/workspaces/last/journeys/integrations/all/directory)** and select the **Customer.io** entry in the *Directory* tab.
    
2.  (Optional) Select the data sources that you want to connect to your outbound integration. You can always connect data sources later. We’ll only show you data sources that work with your integration.
    
3.  Configure your integration.
    
    1.  **Site Id**: Customer.io site ID. This can be found on your [API Credentials page](https://fly.customer.io/settings/api_credentials).
        
    2.  **Api Key**: Customer.io API key. This can be found on your [API Credentials page](https://fly.customer.io/settings/api_credentials).
        
    3.  **Account Region**: Learn about [Account Regions](https://docs.customer.io/data-centers/).
        
    4.  **Endpoint**: The URL of the Customer.io API
        
4.  Click **Enable Destination**.
    

## Actions[](#actions)

 Be careful when editing actions for your workspace

The [Customer.io integration](/integrations/data-out/connections/customerio) is how data gets into Customer.io—the people, events, and other data that you’ll use to send messages to your audience. It’s already configured with actionsThe source event and data that triggers an API call to your destination. For example, an incoming `identify` event from your sources *adds or updates a person* in our Customer.io Journeys destination. to support incoming data. You can edit these actions if you want to change how we handle incoming data, but take care not to inadvertently break integrations with Customer.io.

When you’re done setting things up, you can go to the *Actions* tab to see how we map incoming data to your integration.

[![The actions for your integration](https://docs.customer.io/images/cdp-customerio-cloud-destination-actions.png)](#4eab5f5a50d2bfb5049122876f122292-lightbox)

Action

Default Trigger

Description

Create or Update Device

`event = “Application Installed”` or  
`event = “Device Created` or  
`Updated”` or  
`event = “Application Opened”`

Create or update a person's device.

Delete Device

`event = “Application Uninstalled”` or  
`event = “Device Deleted”`

Delete a person's device.

Delete Relationship

`event = “Relationship Deleted”`

Delete a relationship between a person and an object in Customer.io

Delete Person

`event = “User Deleted”`

Delete a person in Customer.io.

Delete Object

`event = “Object Deleted”`

Delete an object in Customer.io.

Create or Update Person

`type = “identify”`

Create a person in Customer.io or update them if they exist.

Track Event

`type = "track"` and  
`event != "Relationship Deleted"` and  
`event != "User Deleted"` and  
`event != "User Suppressed"` and  
`event != "User Unsuppressed"` and  
`event != "Object Deleted"` and  
`event != "Report Delivery Event"` and  
`event != "Device Created` or  
`Updated"` `event != "Device Deleted"`

Track an event for a known or anonymous person.

Track Page View

`type = “page”`

Track a page view for a known or anonymous person.

Track Screen View

`type = “screen”`

Track a screen view for a known or anonymous person.

Create or Update Object

`type = “group”`

Create an object in Customer.io or update them if they exist.

Merge People

`type = “alias”`

Merge two customer profiles together.

Suppress Person

`event = “User Suppressed”`

Track a "User Suppressed" event to suppress a person.

Unsuppress Person

`event = “User Unsuppressed”`

Track a "User Unsuppressed" event to suppress a person.

Report Delivery Event

`event = “Report Delivery Event”`

Report delivery metrics for a message sent from the Customer.io Journeys product.

Report Content Event

`event = “Report Content Event”`

Report a Viewed or Clicked Content event.

### Create or update a person (identify)[](#identify)

Incoming `identify` calls add and update people in your workspace. We map traitsInformation that you know about a person, captured from `identify` events in Data Pipelines. Traits are analogous to *attributes* in Customer.io Journeys. in source calls to [attributesA key-value pair that you associate with a person or an object—like a person’s name, the date they were created in your workspace, or a company’s billing date etc. Use attributes to target people and personalize messages.](/journeys/attributes/) for people in your workspace. These are things you know about a person, like their first name, their interests, etc.

By default, we send this event when you `identify` a person—like when they submit their email address on your website requesting more information, or when they create an account with you.

You’ll typically set relationships between a person and an object and [information about the relationship](#relationship-attributes) with the `group` call. But you can also send this information in an `identify` call if you want. When you relate a person to an object through an `identify` call, you’ll place the group information in the `context` object.

```json
{
  "type": "identify",
  "traits": {
    "first_name": "cool",
    "last_name": "person",
    "email": "cool.person@example.com",
    "plan": "premium",
    // include if you want to set relationships/attributes
    "objectId": "math101-2024",
    "objectTypeId": "2",
    "relationshipAttributes": {
        "dues_paid": true,
        "class_complete": true,
        "grade": "A-"
    }
  },
  "userId": "97980cfea0067",
  "created_at": "1679407797",
}
```

#### Add and update people by ID or email[](#id-or-email)

In Customer.io, you can identify people by an `id` *or* an `email` address, which provides a way to work with people if they provide an email address but haven’t generated a backend ID (like when someone signs up as a lead but hasn’t yet become a paying customer). When you send `identify` events to this destination, they’ll add or update people in Customer.io depending whether or not the corresponding email or ID exists.

If an `identify` request contains *either* a `userId` or an `email` trait, and that **person doesn’t already exist**, we’ll create a person in Customer.io

If an `identify` request contains either a `userId` or an `email` trait, and that **person already exists**, we’ll update the person in Customer.io

If an `identify` request contains both a `userId` and an `email` trait, but one of those values wasn’t associated with the person, we’ll add the new identifierThe attributes you use to add, modify, and target people. Each unique identifier value represents an individual person in your workspace. to the person and update their profile.

### Customer.io Journeys doesn’t support anonymous identify calls yet[](#customerio-journeys-doesnt-support-anonymous-identify-calls-yet)

We’re working on support for anonymous profiles, but, for now, Journeys ignores anonymous `identify` calls.

**This doesn’t mean you shouldn’t send anonymous `identify` calls**—even if Journeys is your only destination. Anonymous still has value if:

*   You send data to other, non-Customer.io destinations, many of which support anonymous profiles.
*   You use our JavaScript source.

If you use our [JavaScript source](/integrations/data-in/connections/javascript/), anonymous `identify` calls store traits in local storage and attach them to subsequent `identify` calls. This means that when you formally identify a person later, you won’t need to capture all of a customer’s traits at the same time; the JavaScript source will automatically associate their anonymously gathered traits with their `userId`.

### Delete person[](#delete)

You’ll delete people in Customer.io Journeys by sending a `track` call called `User Deleted`. You can always change the name of the event in the **Actions** tab of your destination settings.

Deleting a person doesn’t necessarily require a `userId`. You can delete a person by their email address, for example. If you don’t include a `userId`, we can delete a profile by `properties.email`. If you include both, we’ll use the `userId`.

```json
{
  "type": "track",
  "event": "User Deleted",
  "userId": "97980cfea0067",
  "timestamp": "1679407797",
  "properties": {
    "reason": "user requested deletion"
  }
}
```

### Create or update an object (group)[](#group)

In Customer.io Journeys, we refer to groups as [objectsAn object is a non-person entity that you can associate with one or more people—like a company, account, or online course.](/journeys/objects/)—non-people entities like accounts, online classes, or recreational leagues.

The `group` call does two things:

*   It creates or updates an object, like an `identify` call does for people.
*   If you include a `userId`, it also relates a person to the object—including any [relationship attributesA key-value pair that you associate with a person or an object—like a person’s name, the date they were created in your workspace, or a company’s billing date etc. Use attributes to target people and personalize messages.](/journeys/attributes/) you pass in the call.

Note the `objectTypeId` field: objects in Customer.io Journeys have a type—an incrementing number beginning at 1. This lets you have different kinds of objects; if you run an edtech company, for example, you might have objects for online classes, departments of faculty members, clubs or study groups, and so on. If you *don’t* pass `traits.object_type_id` (or `objectTypeId`), we assume that the value is `1`.

Like people, objects and their relationships with people can also have `traits`—things you know about the object, like its name, industry, and so on. A relationship might have things you know about the relationship between the group and a person, like a person’s position in a company, whether they’re a primary contact for a company, and so on.

Items in the `traits` object apply to the object itself—except for the `relationshipAttributes` key. Anything you put in the `traits.relationshipAttributes` object applies to the relationship between a person and the object.

```json
{
  "messageId": "4vl6zh",
  "timestamp": "2022-11-24T22:56:14.144Z",
  "type": "group",
  "traits": {
    "class_code": "cio101",
    "class_name": "Customer.io Basics",
    "start_date": 1679410730,
    "object_type_id": 1,
    "relationshipAttributes": {
      "type": "student",
      "dues_paid": true,
      "class_completed": false
    }
  },
  "groupId": "cio101-spring2024",
  "userId": "97980cfea0067"
}
```

#### Object and relationship attributes[](#object-and-relationship-attributes)

Both objects and people have their own [attributesA key-value pair that you associate with a person or an object—like a person’s name, the date they were created in your workspace, or a company’s billing date etc. Use attributes to target people and personalize messages.](/journeys/attributes/). But relationships can have attributes too! In the way that attributes on a person describe the person and attributes on an object describe the object, attributes on a relationship describe the relationship between the person and the object.

In the example above, our object is an online class and we set relationship traits (attributes) for a student. We could just as easily define relationship traits for a teacher, a teaching assistant, and so on—anyone who might be related to the class. These attributes help you send campaigns that are relevant to the relationship between a person and an object.

### Delete relationship[](#delete-relationship)

In Journeys, people are related to groups (called [objectsAn object is a non-person entity that you can associate with one or more people—like a company, account, or online course.](/journeys/objects/)) You can relate people to one or more groups. In some cases, you may want to remove a relationship—like when someone finishes an online class or leaves an organization. You can do this with a `track` call called `Relationship Deleted`.

Your call must include:

*   `properties.objectId`: the ID of the object a person is related to.
*   `properties.objectTypeId`: the type of object the person is related to (defaults to `1`).
*   either `userId` or `properties.email`: the ID or email of the person you’re removing the relationship from. If you include both values, we’ll use the `userId`.

```json
{
  "messageId": "4vl6zh",
  "timestamp": "2022-11-24T22:56:14.144Z",
  "type": "track",
  "event": "Relationship Deleted",
  "properties": {
    "objectId": "example-company",
    "objectTypeId": 2
  },
  "userId": "97980cfea0067"
}
```

### Delete object[](#delete-object)

In Journeys, you can delete a group (called an [objectAn object is a non-person entity that you can associate with one or more people—like a company, account, or online course.](/journeys/objects/)) with a `track` call called `Object Deleted`. Deleting an object also removes all relationships between people and the object.

```json
{
  "messageId": "4vl6zh",
  "timestamp": "2022-11-24T22:56:14.144Z",
  "type": "track",
  "event": "Object Deleted",
  "properties": {
    "objectId": "example-company",
    "objectTypeId": 2
  },
  "userId": "97980cfea0067"
}
```

### Create or update a device[](#create-or-update-a-device)

When a person uses your mobile app or mobile website, you can capture and send device information to Customer.io. We capture this information with two specific events: `Application Installed` and `Application Opened`. These represent the times when you’ll typically register for a token and associate a device with a person.

```json
{
  "messageId": "i6yatl",
  "timestamp": "2022-11-24T22:48:17.593Z",
  "type": "track",
  "email": "cool.person@example.com",
  "properties": {
    "device_id": "cEFolG5uRDGPizsaUh4X4m:APA91bFsKwjW9zUaiuJMCGqa3fLRiJ8fv1riQ6U-1iI72aSFZx5wxiqGnqbL-S2g3kZ5RrRUUo3AAVh_LhpFbjDlSqEoC4rqHmH8Z1BGgqaD9jStahy63cGXueW-vOr6mTOekmXgWSww"
  },
  "userId": "97980cfea0067",
  "event": "Application Installed"
}
```

### Delete device[](#delete-device)

We automatically remove a device when we register an event called `Application Uninstalled`. Our SDK automatically sends this event when people uninstall your app.

However, device tokens are transient tokens can expire based on your push provider, and you’ll likely register for a new device token whenever someone closes and re-opens your app. We automatically prune devices from our messaging platform when tokens are invalidated, but we don’t do this as a part of event subscriptions. You may want to send additional calls to delete previous devices as we prune them from your *Journeys* tab.

```json
{
  "messageId": "i6yatl",
  "timestamp": "2022-11-24T22:48:17.593Z",
  "type": "track",
  "email": "cool.person@example.com",
  "properties": {
    "device_id": "long-device-token"
  },
  "userId": "97980cfea0067",
  "event": "Application Uninstalled"
}
```

### Track event[](#track-event)

The `track` call represents an activity someone performs—typically in your app or on your website. If you send this event and the person you reference in the event doesn’t exist, we’ll create them.

You’ll notice that the track event excludes several event names. The Customer.io Journeys API contains methods and endpoints that don’t map naturally to other source calls—like deleting people, suppressing people, and so on. We’ve mapped these calls to `track` events with specific names. You can always change the name of the event in the **Actions** tab of your destination settings. Events that don’t match the defined names act as standard track events in Customer.io.

```json
{
  "messageId": "i6yatl",
  "timestamp": "2022-11-24T22:48:17.593Z",
  "type": "track",
  "email": "cool.person@example.com",
  "properties": {
    "class_name": "Customer.io Basics",
    "class_code": "cio101",
    "start_date": 1679410730
  },
  "userId": "97980cfea0067",
  "event": "enrolled"
}
```

### Page views and screens[](#page-views-and-screens)

There are two special kinds of track events: `page` and `screen` calls. These represent the pages people visit on your website and the screens people visit in your mobile app respectively. You can use these events to monitor the places people do and don’t visit in your website or app. You might also use page and screen calls to follow up with people, to see if they were still interested in a particular product, online class, and so on.

 page event

#### page event[](#page event)

```json
{
  "messageId": "efxqsi",
  "timestamp": "2022-11-24T22:55:59.498Z",
  "type": "page",
  "email": "cool.person@example.com",
  "properties": {
    "session_started": 1679410730,
    "url": "https://www.example.com"
  },
  "userId": "97980cfea0067",
  "name": "home"
}
```

 screen event

#### screen event[](#screen event)

```json
{
  "messageId": "9zk6c",
  "timestamp": "2023-03-20T22:56:06.259Z",
  "type": "screen",
  "email": "cool.person@example.com",
  "properties": {
    "session_started": 1679410730
  },
  "userId": "97980cfea0067",
  "name": "home"
}
```

### Merge people[](#merge-people)

Customer.io lets you merge profiles. If you use your JavaScript SDK, we’ll automatically merge anonymous profiles with their identified counterparts when you identify them. But for any other case—if you’re not using our JavaScript SDK or you want to merge two non-anonymous profiles—you’ll want to set up a *Merge People* action.

This action uses on the `alias` call from your sources. You’ll set the `userId` and `previousId` values in the `alias` call, where:

*   `userId` is the ID of the profile that you want to remain in customer.io. If this profile doesn’t exist, the request won’t do anything.
*   `previousId` is the ID of the profile that you want to merge into the `userId` profile and remove.

The `userId` inherits [attributesA key-value pair that you associate with a person or an object—like a person’s name, the date they were created in your workspace, or a company’s billing date etc. Use attributes to target people and personalize messages.](/journeys/attributes/) from the `previousId` that are not already set on the `userId`; if the `userId` and the `previousId` both have an attribute, the `userId` takes precedence.

The `userId` also inherits events performed by the `anonymousId`. Note that events merged from the `previousId` person cannot trigger campaigns.

```json
{
  "previousId": "97980cfea0067",
  "id": "cool_person"
}
```

### Suppress and unsuppress people[](#suppress-and-unsuppress-people)

In Journeys, [suppressing a person](/journeys/deleting-users/#suppressing-profiles-via-the-api) deletes their profile and prevents you from reusing their ID or email—whichever identifier you pass in the event.

You can suppress or unsuppress users by sending events called `User Suppressed` and `User Unsuppressed` respectively.

In most cases, you’ll want to delete people without suppressing them. Suppressing people is typically a last resort—along the lines of GDPR “right to be forgotten” requests.

```json
{
  "messageId": "4vl6zh",
  "timestamp": "2022-11-24T22:56:14.144Z",
  "type": "track",
  "event": "User Suppressed",
  "userId": "97980cfea0067"
}
```

### Report content event[](#report-content-event)

[Premium This feature is available for Premium plans.](/accounts-and-workspaces/plan-features/)

The “Report content event” action tracks views and clicks for *anonymous* messages.

 Do not edit this action

This action automatically reports metrics to your Customer.io workspace. It’s not a standard event that you can use to trigger campaigns, etc. If you edit this action, you could potentially break the way we report metrics for your anonymous in-app messages.

Only premium and enterprise customers have access to [anonymous in-app messages](/journeys/anonymous-in-app/). Go to your [account settings](https://fly.customer.io/settings/billing/available-plans/journeys) to learn about upgrading!

### Conversion timestamps[](#conversion-timestamps)

If you want to convert ISO-8601 strings to timestamps, set *Convert Timestamps* when setting up actions. This converts attributes containing ISO-8601 strings (like `2023-05-18T22:58:45+00:00`) to Unix timestamps (like `1684475925`).

We’ll only convert valid ISO-8601 date-times down to millisecond precision. If you store your timestamps in another format, or store timestamps using nanosecond precision, we won’t convert them.

*   `2025-08-13T15:45:17.451Z` ✅ (milliseconds - will convert)
*   `2025-08-13T02:08:40.1418726Z` ❌ (nanoseconds - won’t convert)