Journeys Track API

Download OpenAPI specification:Download

Our Track API provides ways to send real-time customer data to your Customer.io workspace.

Overview

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/ServerPurpose
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.

Use our Postman collection

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).

Authentication

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.

Tracking API Key

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

Track API limits

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.

Customer limits

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

Object and relationship limits

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

Track API Event limits

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

v2 API Limits

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.

Track v2 Overview

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

Make a single request

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.

Authorization:
Request Body: application/json
One of
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 id, email, or cio_id. You cannot pass multiple identifiers.

action
required
string

Indicates that the operation will identify the the item of the specified type.

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.

Responses

Request samples

Content type
application/json
Example
{
  • "type": "person",
  • "identifiers": {
    • "id": "42"
    },
  • "action": "identify",
  • "attributes": {
    • "cio_subscription_preferences": {
      }
    },
  • "cio_relationships": [
    • {
      }
    ]
}

Response samples

Content type
application/json
{
  • "errors": [
    • {
      }
    ]
}

Send multiple requests

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.

Authorization:
Request Body: application/json
Array of objects

A batch of requests, where each object is any individual entity payload—modifying a single person or object.

Responses

Request samples

Content type
application/json
{
  • "batch": [
    • {
      }
    ]
}

Response samples

Content type
application/json
{
  • "errors": [
    • {
      }
    ]
}

Person Schemas

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.

Identify a person

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 id, email, or cio_id. You cannot pass multiple identifiers.

action
required
string
Value: "identify"

Indicates that the operation will identify the the item of the specified type.

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": {
      }
    },
  • "cio_relationships": [
    • {
      }
    ]
}

Delete a person

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 id, email, or cio_id. You cannot pass multiple identifiers.

action
required
string
Value: "delete"

Indicates that the operation will delete the the item of the specified type.

{
  • "type": "person",
  • "identifiers": {
    • "id": "42"
    },
  • "action": "delete"
}

Send events for a person

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 id, email, or cio_id. You cannot pass multiple identifiers.

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
    }
}

Send page events for a person

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 id, email, or cio_id. You cannot pass multiple identifiers.

action
required
string
Value: "screen"

A web "pageview" event attributed to a person. Our screen and page event types are more specific than our standard event, and help you track and target people based on the pages people visit in your mobile app or website.

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
    }
}

Send screen events for a person

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 id, email, or cio_id. You cannot pass multiple identifiers.

action
required
string
Value: "screen"

A mobile "screenview" event attributed to a person. Our screen and page event types are more specific than our standard event, and help you track and target people based on the pages people visit in your mobile app or website.

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
    }
}

Add relationships to a person

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 id, email, or cio_id. You cannot pass multiple identifiers.

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": [
    • {
      }
    ]
}

Remove relationships from a person

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 id, email, or cio_id. You cannot pass multiple identifiers.

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": [
    • {
      }
    ]
}

Add a person's devices

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 id, email, or cio_id. You cannot pass multiple identifiers.

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 autoTrackDeviceAttributes setting. You can reference the properties outside the attributes object in segments.

{
  • "type": "person",
  • "identifiers": {
    • "id": "42"
    },
  • "action": "add_device",
  • "device": {
    • "token": "string",
    • "last_used": 0,
    • "platform": "ios",
    • "attributes": {
      }
    }
}

Delete a person's devices

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 id, email, or cio_id. You cannot pass multiple identifiers.

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"
    }
}

Merge duplicate people

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 id, email, or cio_id. This person receives information from the secondary person in the merge.

If email is disabled as an identifier in your workspace settings, then you must reference people by id or cio_id. Under How to Modify, id must be set to "Reference people by cio_id" for a successful merge.

required
object

The person that you want to delete after the merge, identified by one of id, email, or cio_id. This person's information is merged into the primary person's profile and then it is deleted.

If email is disabled as an identifier in your workspace settings, then you must reference people by id or cio_id. Under How to Modify, id must be set to "Reference people by cio_id" for a successful merge.

action
required
string
Value: "merge"

Merge two people. You'll merge the secondary person into the primary. The primary profile remains after the merge and the secondary is deleted. This operation is not reversible. See our page on merging duplicate people for more information.

{
  • "type": "person",
  • "action": "merge",
  • "primary": {
    • "id": "42"
    },
  • "secondary": {
    • "id": "42"
    }
}

Suppress a person

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 id, email, or cio_id. You cannot pass multiple identifiers.

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"
}

Unsuppress a person

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 id, email, or cio_id. You cannot pass multiple identifiers.

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"
}

Object Schemas

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.

Identify object

required
object

Represents an individual object, where the object_type_id represents the type of object and the object_id is the individual identifier for the object.

type
required
string
Value: "object"

The operation modifies a single object—non person data.

action
required
string
Value: "identify"

Indicates that the operation will identify the the item of the specified type.

attributes
object

The data that belongs to the object. This is information you might want to associate with people later (through cio_relationships). Passing null or an empty string removes the attribute from the object. Some attributes have special meaning. Please refer to the list of reserved attributes.

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": [
    • {
      }
    ]
}

Identify an object and relate it to anonymous people

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 object_type_id represents the type of object and the object_id is the individual identifier for the object.

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 identify the item of the specified type and relate it to an anonymous_id.

attributes
object

The data that belongs to the object. This is information you might want to associate with people later (through cio_relationships). Passing null or an empty string removes the attribute from the object. Some attributes have special meaning. Please refer to the list of reserved attributes.

Array of objects

The anonymous people you want to associate with an object. Each object in the array contains an anonymous_id representing a person you haven't yet identified by id or email.

{
  • "identifiers": {
    • "object_type_id": "1",
    • "object_id": "acme"
    },
  • "type": "object",
  • "action": "identify_anonymous",
  • "attributes": { },
  • "cio_relationships": [
    • {
      }
    ]
}

Delete object

required
object

Represents an individual object, where the object_type_id represents the type of object and the object_id is the individual identifier for the object.

type
required
string
Value: "object"

The operation modifies a single object—non person data.

action
required
string
Value: "delete"

Indicates that the operation will delete the the item of the specified type.

{
  • "identifiers": {
    • "object_type_id": "1",
    • "object_id": "acme"
    },
  • "type": "object",
  • "action": "delete"
}

Add relationships to an object

required
object

Represents an individual object, where the object_type_id represents the type of object and the object_id is the individual identifier for the object.

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": [
    • {
      }
    ]
}

Remove relationships from an object

required
object

Represents an individual object, where the object_type_id represents the type of object and the object_id is the individual identifier for the object.

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": [
    • {
      }
    ]
}

Track v1 Overview

Web SDK vs Backend Integrations

  <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.

Client libraries

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.

Account Region

Determine whether your account and data are hosted in the US or EU data center using your Track API Key.

Find your account region

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.

Authorization:

Responses

Request samples

curl --request GET \
  --url https://track.customer.io/api/v1/accounts/region

Response samples

Content type
application/json
{}

Customers

Add, modify, suppress, or unsuppress people (referred to as "customers" in our APIs). You can also use these endpoints to set attributes on people.

Add or update a customer

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.

Authorization:
path Parameters
required
string

The unique value representing a person. The values you use to identify a person may be an id, email address, or the cio_id (when updating people), depending on your workspace settings. When you reference people by cio_id, you must prefix the value with cio_.

Request Body: application/json
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 cio_id.

email
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 _update:true, and Customer.io will not create a new profile, even if the identifier in the path isn't found.

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 cio_subscription_preferences. Like subscription preferences, this attribute is automatically set or updated when a person clicks the "unsubscribe" link in your emails.

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 "cio_subscription_preferences.topics.topic_<topic ID>":<boolean>.

string or integer or boolean

Set attributes on customers. Attributes can have string, integer, or boolean values.

Responses

Request samples

Content type
application/json
{
  • "email": "customer@example.com",
  • "created_at": 1361205308,
  • "first_name": "Bob",
  • "plan": "basic",
  • "cio_relationships": {
    • "action": "add_relationships",
    • "relationships": [
      ]
    },
  • "cio_subscription_preferences": {
    • "topics": {
      }
    }
}

Delete a customer

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.

Authorization:
path Parameters
required
string

The unique value representing a person. The values you use to identify a person may be an id, email address, or the cio_id (when updating people), depending on your workspace settings. When you reference people by cio_id, you must prefix the value with cio_.

Responses

Request samples

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);

Add or update a customer device

Customers can have more than one device. Use this method to add iOS and Android devices to, or update devices for, a customer profile.

Authorization:
path Parameters
required
string

The unique value representing a person. The values you use to identify a person may be an id, email address, or the cio_id (when updating people), depending on your workspace settings. When you reference people by cio_id, you must prefix the value with cio_.

Request Body: application/json
required
object

The properties representing an individual device. Our SDK's gather all the properties defined below automatically, unless you disable the autoTrackDeviceAttributes setting. You can reference the properties outside the attributes object in segments or in Liquid.

Responses

Request samples

Content type
application/json
{
  • "device": {
    • "id": "string",
    • "last_used": 0,
    • "platform": "ios",
    • "attributes": {
      }
    }
}

Response samples

Content type
application/json
{
  • "meta": {
    • "errors": [
      ]
    }
}

Delete a customer device

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.

Authorization:
path Parameters
required
string

The unique value representing a person. The values you use to identify a person may be an id, email address, or the cio_id (when updating people), depending on your workspace settings. When you reference people by cio_id, you must prefix the value with cio_.

device_id
required
string

The ID of the device you want to perform an operation against.

Responses

Request samples

curl --request DELETE \
  --url https://track.customer.io/api/v1/customers/{identifier}/devices/{device_id}

Response samples

Content type
application/json
{
  • "meta": {
    • "errors": [
      ]
    }
}

Suppress a customer profile

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.

Authorization:
path Parameters
required
string

The unique value representing a person. The values you use to identify a person may be an id, email address, or the cio_id (when updating people), depending on your workspace settings. When you reference people by cio_id, you must prefix the value with cio_.

Responses

Request samples

curl --request POST \
  --url https://track.customer.io/api/v1/customers/{identifier}/suppress

Unsuppress a customer profile

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.

Authorization:
path Parameters
required
string

The unique value representing a person. The values you use to identify a person may be an id, email address, or the cio_id (when updating people), depending on your workspace settings. When you reference people by cio_id, you must prefix the value with cio_.

Responses

Request samples

curl --request POST \
  --url https://track.customer.io/api/v1/customers/{identifier}/unsuppress

Custom unsubscribe handling

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.

path Parameters
delivery_id
required
string

The delivery resulting in a request to unsubscribe.

Request Body: application/json
unsubscribe
boolean

If true, a person's unsubscribed attribute is set to true and the unsubscription is attributed to the delivery.

Responses

Request samples

Content type
application/json
{
  • "unsubscribe": true
}

Merge duplicate people

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:

  • Attributes that are not set, or are empty, on the primary.
  • The most recent 30-days of event history. Events merged from the secondary person cannot trigger campaigns.
  • Manual segments that the primary person did not already belong to.
  • Message delivery history.
  • Campaign journeys that the primary person has not entered. If the secondary person has started a journey that the primary person has not, the primary person continues on that campaign journey after the merge. If the secondary person has completed journeys that the primary person has not, the primary person gains these historical journeys after the merge. This may be important for determining entry (or re-entry) criteria for subsequent campaigns, segments, etc.
Authorization:
Request Body: application/json
required
object

The person that you want to remain after the merge, identified by one of id, email, or cio_id. This person receives information from the secondary person in the merge.

If email is disabled as an identifier in your workspace settings, then you must reference people by id or cio_id. Under How to Modify, id must be set to "Reference people by cio_id" for a successful merge.

required
object

The person that you want to delete after the merge, identified by one of id, email, or cio_id. This person's information is merged into the primary person's profile and then it is deleted.

If email is disabled as an identifier in your workspace settings, then you must reference people by id or cio_id. Under How to Modify, id must be set to "Reference people by cio_id" for a successful merge.

Responses

Request samples

Content type
application/json
{
  • "primary": {
    • "email": "cool.person@company.com"
    },
  • "secondary": {
    • "email": "cperson@gmail.com"
    }
}

Response samples

Content type
application/json
{
  • "meta": {
    • "error": "string"
    }
}

Events

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.

Track a customer event

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.

Authorization:
path Parameters
required
string

The unique value representing a person. You may identify a person by id, email address, or the cio_id (when updating people), depending on your workspace settings.

Request Body: application/json
One of
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 page or screen type event, we automatically set this property to event.

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 customer_id).

Responses

Request samples

Content type
application/json
Example
{
  • "name": "purchase",
  • "data": {
    • "price": 23.45,
    • "product": "socks"
    }
}

Track an anonymous event

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.

Authorization:
Request Body: application/json
One of
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 page or screen type event, we automatically set this property to event.

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 customer_id). You can include from_address and reply_to, but the event can only trigger a campaign if it is associated with a person within 72 hours of its timestamp.

Responses

Request samples

Content type
application/json
Example
{
  • "name": "watched_video",
  • "anonymous_id": "abc123",
  • "data": {
    • "video": "intro-to-platform"
    }
}

Report metrics

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.

Request Body: application/json
One of
delivery_id
required
string

The CIO-Delivery-ID from the notification that you want to associate the event with.

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 bounced), this field provides the reason for the failure.

href
string

For clicked metrics, this is the link the recipient clicked.

Responses

Request samples

Content type
application/json
Example
{
  • "delivery_id": "RPILAgUBcRhIBqSfeiIwdIYJKxTY",
  • "timestamp": 1613063089,
  • "metric": "bounced",
  • "recipient": "string",
  • "reason": "string",
  • "href": "string"
}

Report push metrics Deprecated

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.

Request Body: application/json
delivery_id
string

The CIO-Delivery-ID from the notification that you want to associate the event with.

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.

Responses

Request samples

Content type
application/json
{
  • "delivery_id": "RPILAgUBcRhIBqSfeiIwdIYJKxTY",
  • "event": "opened",
  • "device_id": "CIO-Delivery-Token from the notification",
  • "timestamp": 1613063089
}

Forms

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

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:

  • You cannot disable fields that you send to this API. If you send a field (as data) to this API, we'll include it in the form submission.
  • If an identifier in your form is called something like 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.
  • Customer.io reserves form_id, form_name, form_type, form_url, and form_url_param keys. If your request includes these keys, Customer.io ignores them.
Authorization:
path Parameters
form_id
required
string

The identifier for a form. If Customer.io does not recognize the form_id, we create a new form connection (found on the Data & Integrations > Forms page). Use a value that makes sense to you, or something that you can trace to your backend system.

Request Body: application/json
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 name, we assume it represents an attribute called "name"). However, you can re-map form fields to attributes on the Forms page in your workspace.

Values for form fields must be formatted as strings.

Responses

Request samples

Content type
application/json
{
  • "data": {
    • "email": "cool.person@example.com",
    • "first_name": "cool",
    • "last_name": "person",
    • "fav_food": "pizza"
    }
}

Response samples

Content type
application/json
{
  • "meta": {
    • "errors": [
      ]
    }
}

Segments

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

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_ids 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.

Authorization:
path Parameters
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.

query Parameters
id_type
string
Default: "id"
Enum: "id" "email" "cio_id"

The type of ids you want to use. All of the values in the ids array must be of this type. If you don't provide this parameter, we assume that the ids array contains id values.

Request Body: application/json
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 id_type query parameter—id, email, or cio_id. Entries in the array that don't match the id_type are ignored.

Responses

Request samples

Content type
application/json
{
  • "ids": [
    • "customer_id1",
    • "customer_id2"
    ]
}

Response samples

Content type
application/json
"Segment not found"

Remove people from a manual segment

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.

Authorization:
path Parameters
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.

query Parameters
id_type
string
Default: "id"
Enum: "id" "email" "cio_id"

The type of ids you want to use. All of the values in the ids array must be of this type. If you don't provide this parameter, we assume that the ids array contains id values.

Request Body: application/json
ids
required
Array of strings [ 1 .. 1000 ] items

The customer IDs you want to remove from the segment.

Responses

Request samples

Content type
application/json
{
  • "ids": [
    • "customer_id1",
    • "customer_id2"
    ]
}

Response samples

Content type
application/json
"Segment not found"