Download OpenAPI specification:Download
Our Track API provides ways to send real-time customer data to your Customer.io workspace.
You're looking at our US regional endpoints
The only difference in our US and European Union (EU) regions is the subdomain—track-eu
for the EU region rather than just track
; there are no other differences between the two regions. If your account is based in the European Union (EU) data center, click here to show EU endpoints in our code samples and documentation below. Note that if your account is in the EU region and you send traffic to our US endpoints, we'll redirect it accordingly but this traffic still passes through US servers and data could be logged in the US.
If you don't know your region, you can find your account region on your account's privacy page, or get your region using the API.
You're looking at our EU regional endpoints
The only difference in our US and European Union (EU) regions is the subdomain—track
for our US region rather than track-eu
; there are no other differences between the two regions. If your account is based in the European Union (EU) data center, you can click here to to show US endpoints in our code samples and documentation below.
Note that if your account is based in the United States (US) data center and you send requests to the EU region, your requests will fail. If you don't know your region, you can find your account region on your account's privacy page, or get your region using the API.
Customer.io hosts services in the United States (US) and European Union (EU, host subdomains are suffixed with -eu
). Select the appropriate region for server addresses that apply to your region.
Host/Server | Purpose |
---|---|
https://track.customer.io/api/ | Use the Track API to report customer attributes and track customer events/activity. You cannot retrieve data using this API. Track endpoints support minimal validation to ensure as close to real-time processing as possible. |
We've generated a Postman collection with all of our APIs—not just the ones on this page—with a starter environment (called "CIO Env") containing variables for authorization and path parameters.
If you fork this collection, you might want to disable the Watch original collection option. We automatically update our Postman collection whenever we release changes to our documentation, even if we don't change our APIs—which happens daily! Rather than being flooded with Postman notifications, you can check out our Release Notes for updates to our APIs.
NOTE: Postman endpoints default to our US APIs. If you're in our European (EU) region, you'll need to add -eu
server variables (track_api_url and app_api_url).
You can find all of your API authentication information in your Account Settings. Our Tracking API uses HTTP basic authorization. The App API uses bearer authorization, and you can generate tokens supporting different scopes. Each operation in this document references the authorization header it requires.
The Track API uses a basic authentication scheme. Your credentials are your Site ID and your API key, Base-64 encoded in the format site_id:api_key
.
You can find your Site ID and API key on the Track API Keys page.
Security Scheme Type | HTTP |
---|---|
HTTP Authorization Scheme | basic |
The Behavioral Tracking API (track.customer.io
) has a fair-use rate limit of 100/requests per second for both active data integrations and historical backfill scripts; these limits apply to both our v1 and v2 APIs. However, there is no strictly enforced rate limit at which point Customer.io will drop your data.
If track.customer.io calls unexpectedly exceed 100 requests per second, we may reach out to help you correct your integration. We also reserve the right to block your API calls if your integration exceeds this limit in a way that degrades performance for our other customers.
Below are the payload size limits for the Track API. If any of these limits are too restrictive for your needs, contact support to let us know your situation as we may be able to accommodate special circumstances.
These limits apply to people and their attributes, often referred to as "customers" in our APIs.
Data Type | Limit | Description |
---|---|---|
ID | 150 bytes | Max length of a person's ID value |
Attribute Name | 150 bytes | Max length of each attribute name |
Attribute Value | 1000 bytes | Max length of attribute values |
Unique attributes | 300 | Max number of attributes allowed per person or Identify call |
Objects (groups) and relationships between people and objects can have their own attributes. Their limits are similar to people (customers).
Data Type | Limit | Description |
---|---|---|
Object ID | 150 bytes | Max length of a object's ID |
Attribute Names | 150 bytes | Max length of each attribute name |
Attribute Values | 1000 bytes | Max length of attribute values |
Unique attributes | 300 | Max number of attributes allowed per object or relationship |
Total attribute size | 100 Kilobytes | Max size of all attributes associated with an object or relationship |
These limits apply to events that you'll send with the /v1/track
call.
Data Type | Limit | Description |
---|---|---|
Event Name | 100 bytes | Max length of each event name |
Event Data | 100000 bytes | Max length of each event data |
The v2 API has two endpoints, both of which have limits on the total size of requests.
/single
is limited to requests 32kb or smaller. /batch
is limited to requests 500kb or smaller.This new version of our edge API has only two endpoints, but supports the majority of our traditional v1 track operations and then some based on the type
and action
keys that you set in your request.
You can use the /batch
call to send multiple requests at the same time. Unlike the v1 API, you can also make requests affecting objects and deliveries. Objects are a grouping mechanism for people—like an account people belong to or an online course that they enroll in. Deliveries are events based on messages sent from Customer.io.
The chart below lists the type of action
you can perform for each type
. Our requests below are broken out by type
; use the action
dropdown to see the specific payload structure for each action.
Action | Person | Object | Delivery |
---|---|---|---|
identify | ✅ | ✅ | |
delete | ✅ | ✅ | |
event | ✅ | ✅ | |
screen | ✅ | ||
page | ✅ | ||
add_relationships | ✅ | ✅ | |
delete_relationships | ✅ | ✅ | |
add_device | ✅ | ||
delete_device | ✅ | ||
merge | ✅ | ||
suppress | ✅ | ||
unsuppress | ✅ |
This endpoint lets you create, update, or delete a single person or object—including managing relationships between objects and people.
An "object" is any kind of non-person entity that you want to associate with one or more people—like a company, an educational course that people signed up for, a product, etc.
Your request must be smaller than 32kb.
type required | string Value: "person" The operation modifies a person in Customer.io |
required | object The person you want to perform an action for—one of either |
action required | string Indicates that the operation will identify unsuppress suppress merge delete_device add_device delete_relationships add_relationships page screen event delete identify |
object Attributes that you want to add or update for this person. | |
Array of objects Each object in the array represents a relationship you want to add to, or remove from, a person. |
{- "type": "person",
- "identifiers": {
- "id": "42"
}, - "action": "identify",
- "attributes": {
- "cio_subscription_preferences": {
- "topics": {
- "topic_1": true,
- "topic_2": false,
- "topic_3": true
}
}
}, - "cio_relationships": [
- {
- "identifiers": {
- "object_type_id": "1",
- "object_id": "acme"
}, - "relationship_attributes": {
- "role": "admin"
}
}
]
}
{- "errors": [
- {
- "reason": "string",
- "field": "string",
- "message": "string"
}
]
}
This endpoint lets you batch requests for different people and objects in a single request. Each object in your array represents an individual "entity" operation—it represents a change for a person, an object, or a delivery.
You can mix types in this request; you are not limited to a batch containing only objects or only people. An "object" is a non-person entity that you want to associate with one or more people—like a company, an educational course that people enroll in, etc.
Your request must be smaller than 500kb.
Array of objects A batch of requests, where each object is any individual entity payload—modifying a single person or object. |
{- "batch": [
- {
- "type": "person",
- "identifiers": {
- "id": "42"
}, - "action": "identify",
- "attributes": {
- "cio_subscription_preferences": {
- "topics": {
- "topic_1": true,
- "topic_2": false,
- "topic_3": true
}
}
}, - "cio_relationships": [
- {
- "identifiers": {
- "object_type_id": "1",
- "object_id": "acme"
}, - "relationship_attributes": {
- "role": "admin"
}
}
]
}
]
}
{- "errors": [
- {
- "batch_index": 0,
- "reason": "string",
- "field": "string",
- "message": "string"
}
]
}
These schemas all use "type": "person"
. These are operations that reflect people, the data you know about them, the events they perform, and the objects they're related to.
type required | string Value: "person" The operation modifies a person in Customer.io |
required | object The person you want to perform an action for—one of either |
action required | string Value: "identify" Indicates that the operation will |
object Attributes that you want to add or update for this person. | |
Array of objects Each object in the array represents a relationship you want to add to, or remove from, a person. |
{- "type": "person",
- "identifiers": {
- "id": "42"
}, - "action": "identify",
- "attributes": {
- "cio_subscription_preferences": {
- "topics": {
- "topic_1": true,
- "topic_2": false,
- "topic_3": true
}
}
}, - "cio_relationships": [
- {
- "identifiers": {
- "object_type_id": "1",
- "object_id": "acme"
}, - "relationship_attributes": {
- "role": "admin"
}
}
]
}
type required | string Value: "person" The operation modifies a person in Customer.io |
required | object The person you want to perform an action for—one of either |
action required | string Value: "delete" Indicates that the operation will |
{- "type": "person",
- "identifiers": {
- "id": "42"
}, - "action": "delete"
}
type required | string Value: "person" The operation modifies a person in Customer.io |
required | object The person you want to perform an action for—one of either |
action required | string Value: "event" A custom event attributed to the specified person. |
name required | string The name of the event. This is how you'll find your event in Customer.io or select it when using events as campaign triggers. |
id | string <ULID> A valid ULID used to deduplicate events. Note - our Python and Ruby libraries do not pass this id. |
timestamp | integer The Unix timestamp when the event happened. |
object Additional information that you might want to reference in a message using liquid or use to set attributes on the identified person. |
{- "type": "person",
- "identifiers": {
- "id": "42"
}, - "action": "event",
- "id": "string",
- "name": "string",
- "timestamp": 0,
- "attributes": {
- "recipient": "user@example.com",
- "from_address": "user@example.com",
- "reply_to": "user@example.com",
- "liquid merge data1": null,
- "liquid merge data2": null
}
}
type required | string Value: "person" The operation modifies a person in Customer.io |
required | object The person you want to perform an action for—one of either |
action required | string Value: "screen" A web "pageview" event attributed to a person. Our |
name required | string The name of the page or page path that a person visited. This is how you'll find and select page view events in Customer.io. |
id | string <ULID> A valid ULID used to deduplicate events. Note - our Python and Ruby libraries do not pass this id. |
timestamp | integer The Unix timestamp when the event happened. |
object Additional information that you might want to reference in a message using liquid or use to set attributes on the identified person. |
{- "type": "person",
- "identifiers": {
- "id": "42"
}, - "action": "screen",
- "id": "string",
- "name": "string",
- "timestamp": 0,
- "attributes": {
- "liquid merge data1": null,
- "liquid merge data2": null
}
}
type required | string Value: "person" The operation modifies a person in Customer.io |
required | object The person you want to perform an action for—one of either |
action required | string Value: "screen" A mobile "screenview" event attributed to a person. Our |
name required | string The name of the screen a person visited. This is how you'll find and select screen view events in Customer.io. |
id | string <ULID> A valid ULID used to deduplicate events. Note - our Python and Ruby libraries do not pass this id. |
timestamp | integer The Unix timestamp when the event happened. |
object Additional information that you might want to reference in a message using liquid or use to set attributes on the identified person. |
{- "type": "person",
- "identifiers": {
- "id": "42"
}, - "action": "screen",
- "id": "string",
- "name": "string",
- "timestamp": 0,
- "attributes": {
- "liquid merge data1": null,
- "liquid merge data2": null
}
}
type required | string Value: "person" The operation modifies a person in Customer.io |
required | object The person you want to perform an action for—one of either |
action required | string Value: "add_relationships" This operation associates a person with one or more objects. |
required | Array of objects Each object in the array represents a relationship you want to add to, or remove from, a person. |
{- "type": "person",
- "identifiers": {
- "id": "42"
}, - "action": "add_relationships",
- "cio_relationships": [
- {
- "identifiers": {
- "object_type_id": "1",
- "object_id": "acme"
}, - "relationship_attributes": {
- "role": "admin"
}
}
]
}
type required | string Value: "person" The operation modifies a person in Customer.io |
required | object The person you want to perform an action for—one of either |
action required | string Value: "delete_relationships" This operation deletes an object relationship from one or more people. |
required | Array of objects Each object in the array represents a relationship you want to add to, or remove from, a person. |
{- "type": "person",
- "identifiers": {
- "id": "42"
}, - "action": "delete_relationships",
- "cio_relationships": [
- {
- "identifiers": {
- "object_type_id": "1",
- "object_id": "acme"
}, - "relationship_attributes": {
- "role": "admin"
}
}
]
}
type required | string Value: "person" The operation modifies a person in Customer.io |
required | object The person you want to perform an action for—one of either |
action required | string Value: "add_device" Add a mobile device to a person's profile. |
required | object The properties representing an individual device. Our SDK's gather all the properties defined below automatically, unless you disable the |
{- "type": "person",
- "identifiers": {
- "id": "42"
}, - "action": "add_device",
- "device": {
- "token": "string",
- "last_used": 0,
- "platform": "ios",
- "attributes": {
- "device_os": "string",
- "device_model": "string",
- "app_version": "string",
- "cio_sdk_version": "string",
- "_last_status": "",
- "device_locale": "string",
- "push_enabled": "true",
- "Custom Device Attributes1": "string",
- "Custom Device Attributes2": "string"
}
}
}
type required | string Value: "person" The operation modifies a person in Customer.io |
required | object The person you want to perform an action for—one of either |
action required | string Value: "delete_device" Delete a device from a person's profile. |
required | object The device you want to remove. |
{- "type": "person",
- "identifiers": {
- "id": "42"
}, - "action": "delete_device",
- "device": {
- "token": "string"
}
}
type required | string Value: "person" The operation modifies a person in Customer.io |
required | object The person that you want to remain after the merge, identified by one of If email is disabled as an identifier in your workspace settings, then you must reference people by |
required | object The person that you want to delete after the merge, identified by one of If email is disabled as an identifier in your workspace settings, then you must reference people by |
action required | string Value: "merge" Merge two people. You'll merge the |
{- "type": "person",
- "action": "merge",
- "primary": {
- "id": "42"
}, - "secondary": {
- "id": "42"
}
}
type required | string Value: "person" The operation modifies a person in Customer.io |
required | object The person you want to perform an action for—one of either |
action required | string Value: "suppress" Suppress a person's identifier(s) in Customer.io, so that you can't message a person or add their identifiers back to your workspace. This is separate from suppressions performed by your email provider. |
{- "type": "person",
- "identifiers": {
- "id": "42"
}, - "action": "suppress"
}
type required | string Value: "person" The operation modifies a person in Customer.io |
required | object The person you want to perform an action for—one of either |
action required | string Value: "unsuppress" Unsuppress a person's identifier(s) in Customer.io, so that you can message a person or add their identifiers back to your workspace. This does not unsuppress addresses that were previously suppressed by your email provider. |
{- "type": "person",
- "identifiers": {
- "id": "42"
}, - "action": "unsuppress"
}
These schemas all use "type": "object"
. An "object" is a way to group people and relate them to common data—like all the people who belong to an account or sign up for an online class. An object can store attributes and relationships to people, but it cannot perform events or be related to another object.
required | object Represents an individual object, where the |
type required | string Value: "object" The operation modifies a single object—non person data. |
action required | string Value: "identify" Indicates that the operation will |
attributes | object The data that belongs to the object. This is information you might want to associate with people later (through |
Array of objects The people you want to associate with an object. Each object in the array represents a person. |
{- "identifiers": {
- "object_type_id": "1",
- "object_id": "acme"
}, - "type": "object",
- "action": "identify",
- "attributes": { },
- "cio_relationships": [
- {
- "identifiers": {
- "id": "42"
}, - "relationship_attributes": {
- "role": "admin",
- "date_created": 1702480414
}
}
]
}
The identify_anonymous
action lets you create or update an object and associate it with one or more people by anonymous_id
. This helps you relate objects to people before you identify people by their id
or email
.
When you identify a person by id
or email
and pass their anonymous_id
, we'll merge their anonymous information—including any objects they're related to—with their identified profile.
required | object Represents an individual object, where the |
type required | string Value: "object" The operation modifies a single object—non person data. |
action required | string Value: "identify_anonymous" Indicates that the operation will |
attributes | object The data that belongs to the object. This is information you might want to associate with people later (through |
Array of objects The anonymous people you want to associate with an object. Each object in the array contains an |
{- "identifiers": {
- "object_type_id": "1",
- "object_id": "acme"
}, - "type": "object",
- "action": "identify_anonymous",
- "attributes": { },
- "cio_relationships": [
- {
- "identifiers": {
- "anonymous_id": "string"
}, - "relationship_attributes": { }
}
]
}
required | object Represents an individual object, where the |
type required | string Value: "object" The operation modifies a single object—non person data. |
action required | string Value: "delete" Indicates that the operation will |
{- "identifiers": {
- "object_type_id": "1",
- "object_id": "acme"
}, - "type": "object",
- "action": "delete"
}
required | object Represents an individual object, where the |
type required | string Value: "object" The operation modifies a single object—non person data. |
action required | string Value: "add_relationships" This operation associates an object with one or more people. |
required | Array of objects The people you want to associate with an object. Each object in the array represents a person. |
{- "identifiers": {
- "object_type_id": "1",
- "object_id": "acme"
}, - "type": "object",
- "action": "add_relationships",
- "cio_relationships": [
- {
- "identifiers": {
- "id": "42"
}, - "relationship_attributes": {
- "role": "admin",
- "date_created": 1702480414
}
}
]
}
required | object Represents an individual object, where the |
type required | string Value: "object" The operation modifies a single object—non person data. |
action required | string Value: "delete_relationships" This operation deletes an object relationship from one or more people. |
required | Array of objects The people you want to associate with an object. Each object in the array represents a person. |
{- "identifiers": {
- "object_type_id": "1",
- "object_id": "acme"
}, - "type": "object",
- "action": "delete_relationships",
- "cio_relationships": [
- {
- "identifiers": {
- "id": "42"
}, - "relationship_attributes": {
- "role": "admin",
- "date_created": 1702480414
}
}
]
}
<script type="text/javascript">
var _cio = _cio || [];
(function() {
var a,b,c;a=function(f){return function(){_cio.push([f].
concat(Array.prototype.slice.call(arguments,0)))}};b=["load","identify",
"sidentify","track","page"];for(c=0;c<b.length;c++){_cio[b[c]]=a(b[c])};
var t = document.createElement('script'),
s = document.getElementsByTagName('script')[0];
t.async = true;
t.id = 'cio-tracker';
t.setAttribute('data-site-id', 'YOUR_SITE_ID');
t.setAttribute('data-use-array-params', 'true');
t.src = 'https://assets.customer.io/assets/track.js';
s.parentNode.insertBefore(t, s);
})();
</script>
You can integrate with this API using a javascript snippet, by consuming the API directly, or both.
You can simply copy/paste the Javascript snippet to your site to track basic customer behaviors directly from your website. In many cases, using the Javascript snippet is easier to integrate with your app, but there are several reasons why you may want to send events from your backend systems:
Ad blockers are becoming more prevalent as people and browsers increasingly try to avoid 3rd-party JS trackers.
You don't plan to trigger emails based on how customers interact with your website (e.g. users who haven’t visited the site in X days).
You use the Javascript snippet, but have a few events you’d like to send from your backend system. They will work well together!
You would rather not have another Javascript snippet slowing down your frontend. Our snippet is asynchronous (doesn’t affect initial page load) and very small, but we understand.
You should base your decision to send events from your backend or a Javascript snippet on what works best for you. You can fully integrate with Customer.io using either approach.
Check out our Track API section if you're looking for information about the Javascript snippet.
We provide client libraries to support integrations with our Track and App APIs in whatever language you prefer. Take advantage of our client libraries to simplify your integration and take advantage of operations tailored to your language of choice.
NOTE: Where possible, code samples on this page for our Track and App APIs reflect an integration with a relevant library. Otherwise, our code samples show HTTP client operations.
Determine whether your account and data are hosted in the US or EU data center using your Track API Key.
This endpoint returns the appropriate region and URL for your Track API credentials. Use it to determine the URLs you should use to successfully complete other requests.
You can perform this operation against either of the track API regional URLs; it returns your region in either case.
This endpoint also returns an environment_id
, which represents the workspace the credentials are valid for.
curl --request GET \ --url https://track.customer.io/api/v1/accounts/region
{- "region": "us",
- "environment_id": 3
}
Add, modify, suppress, or unsuppress people (referred to as "customers" in our APIs). You can also use these endpoints to set attributes on people.
Adds or updates a person.
If your request does not include cio_id
and the identifiers in the request body do not belong to a person, your request adds a person.
If a person already exists with the identifier in the request path, your request updates that person. If the identifier in the path does not belong to a person but you use an identifier in your request body that does belong to a person, your request updates the person and assigns them the identifier in the path.
If the identifier in the path and request body belong to different people, your request may return 200 OK
but produce an Attribute Update Failure for the identifier in the payload.
If you want to update a person's identifiers after they are set, you must reference them using their cio_id
in the format cio_<cio_id_value>
—unless when updating an email
with the Allow updates to email using ID setting enabled. You can get the cio_id
value from the App API. If your request includes a cio_id
, we'll attempt to update that person, including any identifiers in the request. If the cio_id
does not exist or belongs to a person who was deleted, we'll drop the request.
For workspaces using email
as an identifier, email
is case-insensitive. The addresses person@example.com
and PERSON@example.com
would represent the same person.
required | string The unique value representing a person. The values you use to identify a person may be an |
id | string A customer's ID. You can set a person's ID if you identify them by email (in the path); you can update this value if you identify a person by |
string <email> The email address of the customer. | |
anonymous_id | string An identifier for an anonymous event, like a cookie. If set as an attribute on a person, any events bearing the same anonymous value are associated with this person. This value must be unique and is not reusable. |
created_at | integer The Unix timestamp when the user was created. |
_update | boolean If you perform multiple requests in rapid succession when you create a person, there's a danger that you could create multiple profiles. If you know that a profile already exists and you want to update it, set If the identifiers in your path or request don't belong to an existing person, the request produces a Failed Attribute Change event in your activity log. |
object Describes relationships to an entity—a non-person object in Customer.io, like a company, educational course, job board, etc. | |
unsubscribed | boolean If true, a person is unsubscribed from all messages. If false, or absent, a person is eligible to receive messages as determined by their |
object Stores your audience's subscription preferences if you enable our subscription center feature. These items are set automatically when people use the unsubscribe link in your messages, but you can set preferences outside the subscription flow. To update select topic preferences while preserving those set for other topics, use JSON dot notation | |
string or integer or boolean Set attributes on customers. Attributes can have string, integer, or boolean values. |
{- "email": "customer@example.com",
- "created_at": 1361205308,
- "first_name": "Bob",
- "plan": "basic",
- "cio_relationships": {
- "action": "add_relationships",
- "relationships": [
- {
- "identifiers": {
- "object_type_id": "1",
- "object_id": "01H5Q5SZVQDJ71SBME2SMDXS88"
}, - "relationship_attributes": {
- "role": "admin"
}
}, - {
- "identifiers": {
- "object_type_id": "2",
- "object_id": "1171SBME"
}, - "relationship_attributes": {
- "role": "viewer"
}
}
]
}, - "cio_subscription_preferences": {
- "topics": {
- "topic_1": true,
- "topic_2": true,
- "topic_3": false
}
}
}
Deleting a customer removes them, and all of their information, from Customer.io.
NOTE: Calls that update customers by ID can also create a customer. If you send data to Customer.io through other means (like the Javascript snippet), after you delete a customer, you may accidentally recreate the customer. You cannot delete a customer using the Javascript snippet alone.
required | string The unique value representing a person. The values you use to identify a person may be an |
const { TrackClient, RegionUS } = require('customerio-node'); let cio = new TrackClient(siteId, apiKey, { region: RegionUS }); // Depending on your workspace settings, the id (5) may be an email address. cio.destroy(5);
Customers can have more than one device. Use this method to add iOS and Android devices to, or update devices for, a customer profile.
required | string The unique value representing a person. The values you use to identify a person may be an |
required | object The properties representing an individual device. Our SDK's gather all the properties defined below automatically, unless you disable the |
{- "device": {
- "id": "string",
- "last_used": 0,
- "platform": "ios",
- "attributes": {
- "device_os": "string",
- "device_model": "string",
- "app_version": "string",
- "cio_sdk_version": "string",
- "device_locale": "string",
- "push_enabled": "true",
- "Custom Device Attributes1": "string",
- "Custom Device Attributes2": "string"
}
}
}
{- "meta": {
- "errors": [
- "string"
]
}
}
Remove a device from a customer profile. If you continue sending data about a device to Customer.io, you may inadvertently re-add the device to the customer profile.
required | string The unique value representing a person. The values you use to identify a person may be an |
device_id required | string The ID of the device you want to perform an operation against. |
curl --request DELETE \ --url https://track.customer.io/api/v1/customers/{identifier}/devices/{device_id}
{- "meta": {
- "errors": [
- "string"
]
}
}
Delete a customer profile and prevent the person's identifier(s) from being re-added to your workspace. Any future API calls or operations referencing the specified ID are ignored. If you suppress a person in a workspace set that identifies people by email or ID and both identifiers are set, both the person's email and ID are suppressed.
This API permanently deletes people
Suppressing a person way deletes their profile and suppresses the identifier you reference in the path of this call, preventing you from re-adding a person using the same identifier (until you unsuppress the identifier). You cannot recover a profile after you suppress it. In general, should use this API sparingly—for GDPR/CCPA requests, etc.
If you want to keep a record of a person but prevent them from receiving messages, you should set the person's unsubscribed attribute (or use other attributes to represent complex subscription preferences) instead.
required | string The unique value representing a person. The values you use to identify a person may be an |
curl --request POST \ --url https://track.customer.io/api/v1/customers/{identifier}/suppress
Unsuppressing a profile allows you to add the customer back to Customer.io. If you unsuppress a person in a workspace set that identifies people by email or ID and the suppressed person had both an email and ID, both the person's email and ID are unsuppressed.
Unsuppressing a profile does not recreate the profile that you previously suppressed. Rather, it just makes the identifier available again. Identifying a person after unsuppressing them creates a new profile, with none of the history of the previously suppressed identifier.
required | string The unique value representing a person. The values you use to identify a person may be an |
curl --request POST \ --url https://track.customer.io/api/v1/customers/{identifier}/unsuppress
This endpoint lets you set a global unsubscribed status outside of the subscription pathways native to Customer.io. If you use custom unsubscribe links, you can host a custom unsubscribe page and use this API to send unsubscribe data, associated with a particular delivery, to Customer.io.
NOTE: This endpoint requires a Content-type: application/json
header. This endpoint does not require an Authorization
header.
Your request sets a person's unsubscribed
attribute to true
, attributes their unsubscribe request to the individual email/delivery that they unsubscribed from, and lets you segment your audience based on email_unsubscribed
events when you use a custom subscription center.
If you use a custom subscription center (managing subscriptions to various types of messages with custom attributes), this request does not set a custom attribute. You must perform a separate request to update a person's custom subscription attributes.
delivery_id required | string The delivery resulting in a request to unsubscribe. |
unsubscribe | boolean If true, a person's |
{- "unsubscribe": true
}
Merge two customer profiles together. The payload contains primary
and secondary
profile objects. The primary profile remains after the merge and the secondary is deleted. This operation is not reversible.
The following information is merged into the primary profile from the secondary profile:
required | object The person that you want to remain after the merge, identified by one of If email is disabled as an identifier in your workspace settings, then you must reference people by |
required | object The person that you want to delete after the merge, identified by one of If email is disabled as an identifier in your workspace settings, then you must reference people by |
{- "primary": {
- "email": "cool.person@company.com"
}, - "secondary": {
- "email": "cperson@gmail.com"
}
}
{- "meta": {
- "error": "string"
}
}
Use customer events to trigger campaigns or add users to segments. You can attribute events directly to customers or send anonymous events and associate them with users later when you identify them.
Send an event associated with a person, referenced by the identifier in the path. There are three defined event type
values: page
, screen
and event
. Page and screen events represent website page views and mobile app screen views respectively; the name
for these event types is intended to be the page or screen a person visited or viewed. Any other event, is given the event
type.
We automatically trim leading and trailing spaces from event names.
Reserved Properties
There are a few important values which, if sent with the events that trigger campaigns, will override your campaign settings:
from_address
recipient
reply_to
When using the Javascript snippet to track events, you must call the Behavioral Tracking API call after identifying the customer or the event will not associate with the customer’s profile.
required | string The unique value representing a person. You may identify a person by |
name required | string The name of the event. This is how you'll reference the event in campaigns or segments. |
id | string <ulid> An identifier used to deduplicate events. This value must be a ULID. If an event has the same value as an event we previously received, we won't show or process the duplicate. Note - our Python and Ruby libraries do not pass this id. |
type | string Value: "event" Sets the event type. If your event isn't a |
timestamp | integer <unix timestamp> The unix timestamp when the event took place. If you don't provide this value, we use the date-time when we receive the event. NOTE: Events with a timestamp in the past 72 hours can trigger campaigns. |
object Additional information that you might want to reference in a message using liquid or use to set attributes on your customer (referenced by |
{- "name": "purchase",
- "data": {
- "price": 23.45,
- "product": "socks"
}
}
An anonymous event represents a person you haven't identified yet. When you identify a person, you can set their anonymous_id
attribute. If event merging is turned on in your workspace, and the attribute matches the anonymous_id
in one or more events that were logged within the last 30 days, we associate those events with the person. If you associate an event with a person within 72 hours of the timestamp on the event, you can trigger campaigns from the event.
There are three possible event type
values: page
, screen
and event
. Page and screen events represent website page views and mobile app screen views respectively; the name
for these event types is intended to be the page or screen a person visited or viewed. Any other event, is given the event
type.
Note: Avoid using names with leading or trailing spaces, because you can't reference event names with leading or trailing spaces in campaigns, etc. In workspaces created after September 21, 2021, we trim leading and trailing spaces from event names automatically to fix this issue.
name required | string The name of the event. This is how you'll reference the event in campaigns or segments. |
anonymous_id | string An identifier for an anonymous event, like a cookie. If set as an attribute on a person, any events bearing the same anonymous value are associated with this person. This value must be unique and is not reusable. |
id | string <ulid> An identifier used to deduplicate events. This value must be a ULID. If an event has the same value as an event we previously received, we won't show or process the duplicate. Note - our Python and Ruby libraries do not pass this id. |
type | string Enum: "event" "page" "screen" Sets the event type. If your event isn't a |
timestamp | integer <unix timestamp> The unix timestamp when the event took place. If you don't provide this value, we use the date-time when we receive the event. |
object Additional information that you might want to reference in a message using liquid or use to set attributes on your customer (referenced by |
{- "name": "watched_video",
- "anonymous_id": "abc123",
- "data": {
- "video": "intro-to-platform"
}
}
This endpoint helps you report metrics from channels that aren't native to Customer.io or don't rely on our SDKs. When we deliver a message, we include a CIO-Delivery-ID header. This is the delivery_id
in the payload. You can use it as a UTL and you can pass it as a UTM parameter in links, etc to track metrics when people click, convert, etc.
delivery_id required | string The CIO-Delivery-ID from the notification that you want to associate the |
metric required | string Enum: "bounced" "clicked" "converted" "deferred" "delivered" "dropped" … 2 more The email metric you want to report back to Customer.io. |
timestamp | integer <unix timestamp> The unix timestamp when the event occurred. |
recipient | string The email of the person who received the message. |
reason | string For metrics indicating a failure (like |
href | string For |
{- "delivery_id": "RPILAgUBcRhIBqSfeiIwdIYJKxTY",
- "timestamp": 1613063089,
- "metric": "bounced",
- "recipient": "string",
- "reason": "string",
- "href": "string"
}
While this endpoint still works, you should take advantage of our universal metrics endpoint. It supports channels besides push and lets you provide additional information with some metrics.
Use this endpoint to report device-side push metrics—opened, converted, and delivered—back to Customer.io, so you can track the effectiveness of your push notifications. Customer.io has no way of knowing about these metrics, or associating metrics with a specific message, unless you report them back to us.
When Customer.io delivers a push notification, we include CIO-Delivery-ID
and CIO-Delivery-Token
parameters. Reference these in your payload as the delivery_id
and device_id
respectively with the type of device-side event
metric that you want to associate with your push notification and the person represented by the device_id
.
delivery_id | string The CIO-Delivery-ID from the notification that you want to associate the |
event | string Enum: "opened" "converted" "delivered" The type of device-side event you want to report back to Customer.io. |
device_id | string The CIO-Delivery-Token representing the device that received the original notification. |
timestamp | integer <unix timestamp> The unix timestamp when the event occurred. |
{- "delivery_id": "RPILAgUBcRhIBqSfeiIwdIYJKxTY",
- "event": "opened",
- "device_id": "CIO-Delivery-Token from the notification",
- "timestamp": 1613063089
}
Connect forms to your workspace to identify people, apply form responses to people, and trigger campaigns for people who fill out forms on your website or in your app.
Submit a form response. If Customer.io does not recognize the form_id
we create a new form connection (found on the Data & Integrations > Integrations > Forms page). Form submissions with the same ID are treated as submissions from the same form.
The data
object must contain at least one of id
or email
(depending on the identifiers supported in your workspace)—or a field that is mapped to one of these identifiers—to identify the form respondent. If the person who submitted the form does not already exist, we create them (like an identify request).
Additional keys in the data
object represent form fields and values from the form that a person submitted. By default, we map form fields in your request directly to attributes, e.g. if you have a form field called first_name
, we map that field to the first_name
attribute.
NOTES:
data
) to this API, we'll include it in the form submission.email_address
rather than email
in your initial request, you'll receive a 400
, but we'll still add your form on the Data & Integrations > Integrations > Forms page. You can then re-map your email_address
field to email
, and your form will begin working normally.form_id
, form_name
, form_type
, form_url
, and form_url_param
keys. If your request includes these keys, Customer.io ignores them.form_id required | string The identifier for a form. If Customer.io does not recognize the |
required | object Represents your form data. By default, we assume that form fields map directly to attributes (e.g. if your form field is called Values for form fields must be formatted as strings. |
{- "data": {
- "email": "cool.person@example.com",
- "first_name": "cool",
- "last_name": "person",
- "fav_food": "pizza"
}
}
{- "meta": {
- "errors": [
- "string"
]
}
}
Manual segments are lists of people that you incorporate using the API or by uploading CSVs. You can add people to, or remove people from, manual segments with these endpoints. These endpoints do not let you modify data-driven segments.
NOTE: These endpoints do not yet support workspaces that use both email
and id
as identifiers.
A segment must exist before you can add people to it. You can create manual segments using the App API /segments
endpoints.
Add people to a manual segment by ID. You are limited to 1000 customer IDs per request.
This endpoint lets you add people to manual segments, but a segment must exist before you can add people to it. You can create and find manual segments using the App API.
When you call this API, you can pass an id_type
query parameter determining the type of identifier you want to use, id
, email
, or cio_id
; If you don't pass this parameter, it defaults to id
. The request body always uses ids
, even though it'll accept either IDs, emails, or cio_id
s depending on the query parameter. Everybody in the payload must use the same kind of identifier; we'll ignore values in the ids
array that don't match the id_type
parameter.
NOTE: You cannot add people to data-driven segments using the API. See our documentation on segments for more information about segments.
segment_id required | integer <int32> The identifier for a segment. You can find your segment's ID on its page in the dashboard—go to Segments, select your segment, and find the ID under Usage. Or you can find your segment using the App API. |
id_type | string Default: "id" Enum: "id" "email" "cio_id" The type of |
ids required | Array of strings [ 1 .. 1000 ] items The customer IDs you want to add to the segment. The type of value you pass in the array corresponds to the |
{- "ids": [
- "customer_id1",
- "customer_id2"
]
}
"Segment not found"
You can remove users from a manual segment by ID. You are limited to 1000 customer IDs per request.
This endpoint requires people to have id
attributes. If your workspace does not use id
as an identifier, or you have not assigned people id
values, you cannot remove people from manual segments using the API. Our user interface does not have this limitation. You can remove people from manual segments through the UI as a part of a campaign workflow.
NOTE: You cannot remove people from data-driven segments using the API. See our documentation on segments for more information about segments.
segment_id required | integer <int32> The identifier for a segment. You can find your segment's ID on its page in the dashboard—go to Segments, select your segment, and find the ID under Usage. Or you can find your segment using the App API. |
id_type | string Default: "id" Enum: "id" "email" "cio_id" The type of |
ids required | Array of strings [ 1 .. 1000 ] items The customer IDs you want to remove from the segment. |
{- "ids": [
- "customer_id1",
- "customer_id2"
]
}
"Segment not found"