Journeys Track API Source
UpdatedUse a native Data Pipelines Source where possible
If you’re new to Customer.io, you should integrate your iOS app, website, or server directly with Data Pipelines and take advantage of all of Customer.io’s features. This information is based around legacy integration methods, or for sources that don’t (yet) have a native Data Pipelines integration.
When should I use a Journeys API source?
If you’re new here, we suggest you use native Data Pipelines sources—not the Journeys API source. But here’s a handy chart to help you determine which integration source(s) you should use.
If you have a mobile app, you’ll note that you have to use the Journeys API to support Android, React Native (including Expo), and Flutter. Version 3.x and later of our iOS SDK supports Data Pipelines natively, but we’re still working on native sources for other platforms. (Coming soon!)
If you want to bring in data from a database, you’ll need to use one of the Data Pipelines Reverse ETL or Database sources. Our comparable Journeys integrations do not support Data Pipelines.
do you have?} a-.->|No|c{Can you replace your
existing integrations?} c-->|Yes|b b--->|Website|d(Use the
JavaScript source) b-->|Web Server|e{What language?} e-->|GoLang, Python, or NodeJS|f(Use the native Go,
Python, or NodeJS sources) e-->|Another language|l(Integrate with the
Data Pipelines API) b--->|Data Warehouse/Reverse ETL|m("Use a Data Warehouse/Reverse ETL
source (Snowflake, PostgreSQL, Redshift)") b-->|Mobile App|i{What platform?} i-->|iOS|j("Use the iOS
source (v3.x or later)") i-->|Android, React Native, or Flutter|k(Use the
Journeys API source) c-.->|No|k c-.->|If you have a Data Warehouse
or Reverse ETL Journeys integration,
you must move to a native
Database or Reverse ETL Source.|m
How it works
The Journeys API was how you sent data to Customer.io before we introduced Data Pipelines. Journeys API sources let you use Data Pipelines without changing your existing integrations by automatically translating incoming Journeys Track API calls to our Data Pipelines format. This means you can use our Journeys Web SDK, our non-iOS mobile SDKs, and our Track API as sourcesA source is a website or server that you want to capture data from—it’s a source of data! without doing any extra integration work.
Journeys API sources all appear as Journeys API in our source catalog. Each set of Journeys Track API credentials you create will appear as a separate source in your workspace. In general, we recommend that you integrate with other sources and only use the Journeys API source where a native Data Pipelines source isn’t available. But Journeys API sources can help you take advantage of Data Pipelines features if you can’t replace your existing integrations.
Our Track and Data Pipelines APIs share similar concepts, so there are very few (but important) differences between native Data Pipelines sources and data sources based on our Track API. Your Track identify
calls become Data Pipelines identify
calls, your Track page
calls become Data Pipelines page
calls, and so on.
track API call)-->c(Journeys) a-->b((Convert to Data
Pipelines Format))-->d[(Journeys API
Source)]-.->e(Destination 1) d-.->f(Destination 2)
What’s the difference between native sources and the Journeys API?
Again, we always recommend using native sources like our JavaScript library, iOS SDK, and server libraries where possible. But, if you need to use the Journeys API sources, you should be aware of some minor differences between the Journeys API and Data Pipelines.
- Your source will read as coming from the Track API: when you use a Customer.io Journeys-based integration with Data Pipelines, you’ll need to set up a Journeys Track API source. This means that all calls from your mobile app will read as coming from the Track API, not from your website, mobile app, server, etc.
- Journeys-based sources don’t collect
context
for each request. Native Data Pipelines collectcontext
for each call, with basic information about thedevice
,page
,locale
, etc of the person or object causing the call. Journeys API-based sources don’t collect this information. - The Journeys Web SDK doesn’t support all destinations. Unlike the Data Pipelines JavaScript source, the comparable Journeys source can’t send data to destinations that bypass Customer.io, commonly known as direct modeA direct destination (sometimes known as a web destination) receives data directly from your sources, bypassing Customer.io’s servers. Direct mode destinations only support our JavaScript source. destinations (like our Facebook Lead Ads destination).
Each set of Journeys API credentials is a source
We treat each set of Journeys API credentials as a separate source. This lets you route each set of credentials to specific destinations; you don’t have to forward all Journeys API calls to the same place(s).
Sources are organized by the Name you give to each set of credentials. You may have separate sets of credentials for your website, mobile app, testing, etc.
Enabling Track API/SDKs as a source
If you’re new to Customer.io, this integration is automatic: your Track API calls are automatically forwarded to Data Pipelines. But, if you’re new to Customer.io, we strongly recommend that you integrate with a native Data Pipelines source or the Data Pipelines API.
If you created your account before July 25th, 2023, you can tell Customer.io to forward your Track API calls to Data Pipelines with the Send People and Events from Journeys to Data Pipelines setting. This setting appears when you set up Data Pipelines or as a banner on the Data Pipelines Dashboard page.
Filtering destination calls
If you need to filter specific Track API calls/events to your Customer.io workspace (the Journeys destination) and other calls/events to other destinations, you’ll need to use separate credentials for each set of calls.
const xhr = new XMLHttpRequest();
const url='https://track.customer.io/api/' + id + '/events';
var event = {
name: 'purchased',
data: {
type: 'socks',
price: 10.99
}
};
if (isJourneysDestination) {
xhr.open('POST', url, true)
xhr.setRequestHeader('Authorization', 'Basic ' + btoa(siteId + ':' + apiKey))
xhr.send(event);
} else {
xhr.open('POST', url, true)
xhr.setRequestHeader('Authorization', 'Basic ' + btoa(nonJourneysSite + ':' + nonJourneysKey))
xhr.send(event);
}
Mapping Track API calls to Data Pipelines
The Journeys Track and Data Pipelines APIs are very similar. In many cases, they share the same “method” name—they both identify
people, track
events, and so on. This makes it easy to map calls from the Track API to Data Pipelines, but we discuss mappings in greater detail in the sections below.
The Journeys Track API doesn’t have a group
method; rather, it handles group calls with a cio_relationships
object in identify
calls. We discuss this in greater detail in the Group calls section below, but this means that the Journeys Track API identify
method with cio_relationships
in the payload will produce two calls to Data Pipelines: one identify
call and one group
call.
Data Pipelines Source call | Journeys Web SDK method | Track v1 API call | Track v2 API call |
---|---|---|---|
Identify | identify | /v1/identify/{customer_id} | Any object where "type": "person" and "action" is "identify" |
Track | track | /v1/customers/{customer_id}/event | Any object where"type": "person" and "action" is "event" , "add_device" , or "remove_device" |
Page | page | /v1/customers/{customer_id}/event where "type": "page" | Any object where "type": "person", "action": "page" |
Screen | N/A | /v1/customers/{customer_id}/event where "type": "screen" | Any object where "type": "person", "action": "screen" |
Group | N/A | /v1/identify/{customer_id} containing cio_relationships | Any object where type: "group" ,"action": "add_relationship" , or "action": "delete_relationship" |
Alias | N/A | /v1/merge_customers | "type": "identify", "action": "merge" |
Suppress | N/A | /v1/customers/{customer_id}/suppress | Any object where "type": "person", "action": "suppress" |
Unsuppress | N/A | /v1/customers/{customer_id}/unsuppress | Any object where "type": "person", "action": "unsuppress" |
Some Journeys Track API calls don’t map to Data Pipelines
We’re working to support all Track API calls in Data Pipelines in the future. But for now, we don’t forward the following calls to Data Pipelines:
- Form submissions
- Calls that add or remove people from manual segments
- Custom unsubscribe calls
Identifying people by email
In our Track API and associated Journeys SDKs, you can identify people by their email address alone. If you don’t provide an id
value in the same call, we’ll map a person’s email directly to the userId
in Data Pipelines.
But, while Journeys supports email
as an identifier, your Data Pipelines destinations may not operate this way. If you identify the same person by an email address and later by id
, you may end up with separate profiles in your destination representing the same person.
When you identify people by email address, we capture the email address as both context.journeys.identifiers.email
and userId
. If your integration identifies people by both email and ID, you may want to filter your destination actions where context.journeys.identifiers.email
equals userId
. This will prevent you from sending actions to people identified by email only.
{
"type": "identify",
"traits": {
"first_name": "Cool",
"last_name": "Person"
},
"userId": "cool.person@example.com",
"integrations": {
"All": true,
},
"sentAt": "2023-08-24T14:15:22Z",
"messageId": "01H95X6RDPC4P9DHPC0JX52YKE",
"timestamp": "2023-08-24T14:15:22Z",
"context": {
"journeys": {
"identifiers": {
"email": "cool.person@example.com"
}
}
}
}
Mapping Track v2 calls
The Track v1 API includes methods that generally map to Data Pipelines—they both have methods to identify
, track
, send page
events, etc.
The Track v2 API uses the type
and action
keys to dictate an action. We use these keys to map actions to Data Pipelines. For example, if the v2 action
is identify
and type
is person
, that represents a Data Pipelines identify
call. If the type
is object
, that represents a group
call.
Data Pipelines method | Track v2 API type | Track v2 API action |
---|---|---|
Identify | person | identify |
Group | object | identify or add_relationship |
Group | person | add_relationship |
Track | person | event |
Page | person | page |
Screen | person | screen |
Alias | person | merge |
Identify
The Track v1 API includes an identify
method that maps cleanly to the identify
method in Data Pipelines. We map Track v2 calls to the Data Pipelines identify
method when type
is person
and action
is identify
.
For a typical identify
call, we map any keys that aren’t identifiers to traits
. The lone exception is cio_relationships
: we don’t pass this key in identify
calls, but rather send a separate group
call to set relationships. See Group calls below for more information.
identify
API call)
a-->b(identify)
a-->c{"does call includecio_relationships
?"}
c-.->|Yes|d(group)Track v1 API Call | Data Pipelines Result |
---|---|
|
|
Track, page, and screen events
The Track v1 API includes a track
method that maps cleanly to Data Pipelines track
method. The Track v1 API doesn’t have methods for page
and screen
events. Rather, you’ll send standard track
events with a type
of page
or screen
. These map to the Data Pipelines page
and screen
methods respectively.
track
API call)
a-->b(type: page)-->c(page)
a-->d(type: screen)-->e(screen)
a-->f(type is event)-->g(track)
a-->h(type is not set)-->g
a-->i(type is notpage or screen)-->g
The Track v2 API works similarly. We map Track v2 calls to Data Pipelines track
, page
, and screen
methods when the incoming type
is person
and the action
is event
, page
, or screen
respectively.
The event name
maps directly to the event
key in Data Pipelines. The data
object in your event call maps to the properties
key in Data Pipelines. For page
calls, the event name
is typically the URL of the page a person viewed. For screen
calls, the event name
is typically the name of the screen in your app.
Track v1 API Call | Data Pipelines Result |
---|---|
|
|
Semantic Events
A number of default 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. in Data Pipelines are based on the event name in a track
call. We call these semantic events. If you send events with names and structures corresponding to our semantic events, you’ll be able to use our default actions in destinations without any extra work.
For example, we typically use an event name called Application Installed
to trigger the Add Device action in destinations.
Track API Call | Data Pipelines semantic event |
---|---|
|
|
Group calls (cio_relationships
)
Journeys calls groups objectsNot to be confused with a JSON object, an object in Customer.io is a non-person entity that you can associate with one or more people—like a company, account, or online course. You can use objects to message people based on changes to their company, account, or course itinerary., and doesn’t have a specific endpoint to create groups. Instead, we base “group” calls on payloads of the Track API:
- Track v1 API:
identify
method containingcio_relationships
. - Track v2 API: Where
type
isobject
or wheneveraction
isadd_relationship
.
Because the Journeys API revolves around people, the calls in which you set relationships will result in two calls to Data Pipelines.
While an identify
call including cio_relationships
will result in two Data Pipelines API calls (identify
and group
), we’ll just show the resulting group
call in the example below.
Track v1 API Call | Data Pipelines Result |
---|---|
|
|
Context from the Track API
Data Pipelines payloads contain a context
object that contains information about the source of the data. For data coming in through our Journeys Track API (including our mobile and web SDKs), the context
contains a child object called journeys
with identifiers from the original call. This can help you understand which calls were made from the Track API (or our associated libraries).
The context
object contains a journeys.identifiers
object with identity information for the person or group represented in the original call.
{
"context": {
"journeys": {
"identifiers": {
"object_type_id": "1",
"object_id": "acme",
"id": "42",
}
}
}
}