Customer.io Pipelines API

With the Pipelines API (shown in the UI as the Customer.io API source), you can send data from anywhere directly to Customer.io and other downstream integrations without using an SDK. See our API documentation for more information about the Pipelines APIs.

Examples on this page use our US region

If you’re in our EU region, you’ll use endpoints beginning with https://cdp-eu.customer.io/v1/ instead.

Connect a Customer.io Pipelines API source

  1. Go to Integrations and click Add integration.
  2. Find the Customer.io API integration.
    the integrations page, showing the Customer.io API integration
  3. Give the integration a name. The name helps you find and differentiate between different API credentials; you might name them for users, environments, or the services you use them for.
  4. Under Configure your API call, copy the API key. This is the key you’ll use to authenticate with Customer.io. The page also shows you a ready-made curl request with your key already filled in, so you can paste that straight into a terminal instead of building the request yourself.
  5. Send a test call with your key. Your key is the username and the password is blank, so pass it to curl with a trailing colon and let curl encode the credentials for you. Here’s an example:
    curl --request POST \
      --url https://cdp.customer.io/v1/identify \
      --user '<your api key>:' \
      --header 'content-type: application/json' \
      -d '
      {
        "userId": "97980cfea0067",
        "traits": {
          "name": "Cool Person",
          "email": "cool.person@example.com"
        }
      }'

    A 200 response doesn't always mean we accepted your data

    If your credentials are wrong, we still return 200, but we drop the request. Add the header X-Strict-Mode: 1 to your call and we’ll return an error instead, which makes an authentication problem much easier to spot.

  6. Click Test connection. We check whether we’ve received data from your source. Sending the call isn’t enough on its own; you have to run this check for us to record that your source is connected.
  7. Click Complete setup.

After you’ve added your source, you can start making your own calls and add a destination to work with your new source.

Enable automatic geolocation support

You can automatically geolocate profiles when you identify them and pass their IP addresses in the context.ip field in your identify requests. This helps you gather information about your audience’s location and time zone so you can schedule messages at the right times or send messages relevant to their communities.

If you’ve already set up your integration to capture IP addresses, and you’ve enabled the workspace-level Automatic Geolocation Data Collection setting, you can enable geolocation for your integration.

After you enable the Customer.io API source, go to your integration’s Settings tab and turn on the Enable Geolocation setting.

settings for a server-side integration showing the Enable Geolocation setting

Make sure you capture your users' IP addresses

If you don’t set the context.ip in your requests, we won’t be able to capture geolocation data for your users.

Identify

You should call identify when your customers create an account, log in, or otherwise identify themselves. The identify method tells you who the current website or app visitor is and lets you set or update unique traits to a profile.

You can send an identify call with an anonymous ID and/or user ID. To associate anonymous activity with an identified profile, send both IDs in a single call.

  • Anonymous ID only: This assigns traits to a profile before you know who they are.
  • User ID only: Identifies a user and sets traits.
  • Both user ID and anonymous ID: Associates the data sent in previous anonymous page, track, and identify calls with the person you identify by user ID.
One of:
  • userIdstringrequired
    The unique identifier for a person. This value should be unique across systems, so you recognize the same person in your sources _and_ destinations.
  • anonymousIdstring
    A unique substitute for a User ID in cases when you don’t have an absolutely unique identifier. Our libraries generate this value automatically to help you track people before they sign up, log in, provide their email, etc.
  • A dictionary of context about a source call/event, like the user’s IP address or locale. Context is automatically collected by our source libraries.
  • Contains a list of booleans indicating the integrations that are enabled (true) or disabled (false). By default, all integrations are enabled (returning an empty object). Set "All": false to reverse this behavior.
  • messageIdstring
    A unique identifier for a Data Pipelines call, ensuring that each individual event is unique. This is set by Customer.io
  • originalTimestampstring(date-time)
    In general, you can use timestamp rather than this field if you want to back-date events. This is the timestamp on the client device you invoke a call or the timestamp value you manually passed in a server-side library call.
  • sentAtstring(date-time)
    The ISO-8601 timestamp when a library sends an event to Data Pipelines.
  • timestampstring(date-time)
    The ISO-8601 timestamp when the event originally took place. This is mostly useful when you backfill past events. If you're not backfilling data, you can leave this field empty and we'll use the current time or server time.
  • Additional properties that you know about a person. We've listed some common/reserved traits below, but you can add any traits that you might use in another system.

Merge anonymous activity into a profile

Unlike our client-side JavaScript library, server-side libraries and the API don’t assign an anonymous ID automatically. You assign an anonymous ID to track a person’s anonymous track and page calls. Then when you identify the user, you pass the anonymous ID with their user ID and Customer.io will merge the last 30 days of anonymous activity with the identified profile.

You can’t reuse an anonymous ID after it’s merged into a profile. Once an identify call links an anonymous ID to a user ID, Customer.io merges that ID’s anonymous activity into the profile and marks the anonymous ID as used—any events sent under the same anonymous ID afterward stay anonymous and won’t link to the profile.

If a person generates new anonymous activity after you’ve identified them—for example, they log out and keep browsing before logging back in—assign a new anonymous ID for that activity, then send another identify call with their user ID and the new anonymous ID to merge it into the same profile.

However, there is a 5 minute window after you merge anonymous activity into a profile where you can still merge anonymous activity using the same anonymous ID. This allows you to merge anonymous activity in a batch or in rapid succession without worrying about the order of your calls.

Track

The track method tells us about actions profiles take—the events profiles perform—on your site. Every track call represents an event.

You should track your audience’s activities with events both as performance indicators and so you can respond to your audience’s activities with automations in Journeys. For example, if your audience performs a Video Viewed or Item Purchased event, you might respond with other videos or products the profile might enjoy.

You can send events with an anonymousId or a userId. Calls that you make with an anonymousId are associated with a userId when you identify someone by their userId.

Track calls require an event name describing what a person did. And they generally include a series of properties, providing additional information about the event. Beyond that, we’ve provided a complete schema for writable event fields below, and you can find more information in our API documentation.

One of:
  • eventstringrequired
    The name of the event
  • userIdstringrequired
    The unique identifier for a person. This value should be unique across systems, so you recognize the same person in your sources _and_ destinations.
  • contextone of
    A dictionary of context about a source call/event, like the user’s IP address or locale. Context is automatically collected by our source libraries.
    One of:
    A dictionary of context about a source call/event, like the user’s IP address or locale. Context is automatically collected by our source libraries.
    • activeboolean
      Whether a user is active.

      This is usually used when you send an .identify() call to update the traits independently of when you've “last seen” a user.

    • Contains information about the campaign that resulted in the API call, gathered from, or mapping to, UTM parameters (e.g. utm_source).
    • channelstring
      The channel the event originated from.
      Accepted values: browser, server, mobile
    • ipstring
      The user's IP address. This isn't captured by our libraries, but by our servers when we receive client-side events (like from our JavaScript source).
    • localestring
      The locale string for the current user, e.g. en-US.
    • Contains information about the current page in the browser. This is automatically collected by our JavaScript source.
    • userAgentstring
      The user agent of the device making the request
  • integrationsobject
    Contains a list of booleans indicating the integrations that are enabled (true) or disabled (false). By default, all integrations are enabled (returning an empty object). Set "All": false to reverse this behavior.
    • Enabled/Disabled integrations *boolean
  • messageIdstring
    A unique identifier for a Data Pipelines call, ensuring that each individual event is unique. This is set by Customer.io
  • originalTimestampstring(date-time)
    In general, you can use timestamp rather than this field if you want to back-date events. This is the timestamp on the client device you invoke a call or the timestamp value you manually passed in a server-side library call.
  • propertiesobject
    Additional properties for your event.
    • Event Properties *any type
      Additional properties that you want to capture in the event. These can take any JSON shape.
  • sentAtstring(date-time)
    The ISO-8601 timestamp when a library sends an event to Data Pipelines.
  • timestampstring(date-time)
    The ISO-8601 timestamp when the event originally took place. This is mostly useful when you backfill past events. If you're not backfilling data, you can leave this field empty and we'll use the current time or server time.

Page

The Page method records page views on your website, along with optional extra information about the page a person visited.

One of:
  • userIdstringrequired
    The unique identifier for a person. This value should be unique across systems, so you recognize the same person in your sources _and_ destinations.
  • contextobject
    A dictionary of context about a source call/event, like the user’s IP address or locale. Context is automatically collected by our source libraries.
    • activeboolean
      Whether a user is active.

      This is usually used when you send an .identify() call to update the traits independently of when you've “last seen” a user.

    • Contains information about the campaign that resulted in the API call, gathered from, or mapping to, UTM parameters (e.g. utm_source).
    • channelstring
      The channel the event originated from.
      Accepted values: browser, server, mobile
    • ipstring
      The user's IP address. This isn't captured by our libraries, but by our servers when we receive client-side events (like from our JavaScript source).
    • localestring
      The locale string for the current user, e.g. en-US.
    • Contains information about the current page in the browser. This is automatically collected by our JavaScript source.
    • userAgentstring
      The user agent of the device making the request
  • integrationsobject
    Contains a list of booleans indicating the integrations that are enabled (true) or disabled (false). By default, all integrations are enabled (returning an empty object). Set "All": false to reverse this behavior.
    • Enabled/Disabled integrations *boolean
  • messageIdstring
    A unique identifier for a Data Pipelines call, ensuring that each individual event is unique. This is set by Customer.io
  • namestring
    The name of the page.
  • originalTimestampstring(date-time)
    In general, you can use timestamp rather than this field if you want to back-date events. This is the timestamp on the client device you invoke a call or the timestamp value you manually passed in a server-side library call.
  • propertiesobject
    Additional page properties. Analytics.js automatically collects url, title, referrer, path, and search properties. But, if you use our other sources or you write your own integration, you should consider sending these properties yourself. Destination actions that take page events often rely on the url and title properties.
    • categorystring
      The category of the page. This might be useful if you have a single page routes or have a flattened URL structure.
    • pathstring
      The path of the page. This defaults to location.pathname, but can be overridden.
    • referrerstring
      The referrer of the page, if applicable. This defaults to document.referrer, but can be overridden.
    • searchstring
      The search query in the URL, if present. This defaults to location.search, but can be overridden.
    • titlestring
      The title of the page. This defaults to document.title, but can be overridden.
    • urlstring
      The URL of the page. This defaults to a canonical url if available, and falls back to document.location.href.
    • Page Properties *any type
  • sentAtstring(date-time)
    The ISO-8601 timestamp when a library sends an event to Data Pipelines.
  • timestampstring(date-time)
    The ISO-8601 timestamp when the event originally took place. This is mostly useful when you backfill past events. If you're not backfilling data, you can leave this field empty and we'll use the current time or server time.

Screen

The Screen method sends screen view events for mobile devices. These help you understand the screens that profiles use in your app.

One of:
  • userIdstringrequired
    The unique identifier for a person. This value should be unique across systems, so you recognize the same person in your sources _and_ destinations.
  • contextobject
    A dictionary of context about a source call/event, like the user’s IP address or locale. Context is automatically collected by our source libraries.
    • activeboolean
      Whether a user is active.

      This is usually used when you send an .identify() call to update the traits independently of when you've “last seen” a user.

    • Contains information about the mobile app the event originated from, automatically collected by our mobile libraries when possible.
    • channelstring
      The channel the event originated from.
      Accepted values: browser, server, mobile
    • Contains information about the device the event originated from.
    • ipstring
      The user's IP address. This isn't captured by our libraries, but by our servers when we receive client-side events (like from our JavaScript source).
    • localestring
      The locale string for the current user, e.g. en-US.
    • Information about the current network connection, containing bluetooth, carrier, cellular, and wifi. If the context.network.cellular and context.network.wifi fields are empty, then the user is offline.
    • Dictionary of information about the operating system, containing name and version.
    • userAgentstring
      The user agent of the device making the request
  • integrationsobject
    Contains a list of booleans indicating the integrations that are enabled (true) or disabled (false). By default, all integrations are enabled (returning an empty object). Set "All": false to reverse this behavior.
    • Enabled/Disabled integrations *boolean
  • messageIdstring
    A unique identifier for a Data Pipelines call, ensuring that each individual event is unique. This is set by Customer.io
  • namestring
    The name of the screen the person visited.
  • originalTimestampstring(date-time)
    In general, you can use timestamp rather than this field if you want to back-date events. This is the timestamp on the client device you invoke a call or the timestamp value you manually passed in a server-side library call.
  • propertiesobject
    Additional properties for your screen.
    • Screen Properties *any type
  • sentAtstring(date-time)
    The ISO-8601 timestamp when a library sends an event to Data Pipelines.
  • timestampstring(date-time)
    The ISO-8601 timestamp when the event originally took place. This is mostly useful when you backfill past events. If you're not backfilling data, you can leave this field empty and we'll use the current time or server time.

Group

The Group method associates an identified profile with a group—like a company, organization, project, online class or any other collective noun you come up with for the same concept. In Customer.io Journeys, we call groups objects.

Group calls are useful for integrations where you maintain relationships between profiles and larger organizations, like in Customer.io! In Customer.io Journeys, you can store groups as objects, and trigger automations based on a profile’s relationship to an object—like an account, online class, and so on.

Find more details about group, including the group payload, in our API spec.

Include objectTypeId when you send data to Customer.io

Customer.io supports different kinds of groups (called objects) where each object has an object type represented by an incrementing integer beginning at 1. If you send group calls to Customer.io, include traits.objectTypeId or we’ll assume that the object type is 1.

One of:
  • groupIdstringrequired
    ID of the group
  • contextone of
    A dictionary of context about a source call/event, like the user’s IP address or locale. Context is automatically collected by our source libraries.
    One of:
    A dictionary of context about a source call/event, like the user’s IP address or locale. Context is automatically collected by our source libraries.
    • activeboolean
      Whether a user is active.

      This is usually used when you send an .identify() call to update the traits independently of when you've “last seen” a user.

    • Contains information about the campaign that resulted in the API call, gathered from, or mapping to, UTM parameters (e.g. utm_source).
    • channelstring
      The channel the event originated from.
      Accepted values: browser, server, mobile
    • ipstring
      The user's IP address. This isn't captured by our libraries, but by our servers when we receive client-side events (like from our JavaScript source).
    • localestring
      The locale string for the current user, e.g. en-US.
    • Contains information about the current page in the browser. This is automatically collected by our JavaScript source.
    • userAgentstring
      The user agent of the device making the request
  • integrationsobject
    Contains a list of booleans indicating the integrations that are enabled (true) or disabled (false). By default, all integrations are enabled (returning an empty object). Set "All": false to reverse this behavior.
    • Enabled/Disabled integrations *boolean
  • messageIdstring
    A unique identifier for a Data Pipelines call, ensuring that each individual event is unique. This is set by Customer.io
  • originalTimestampstring(date-time)
    In general, you can use timestamp rather than this field if you want to back-date events. This is the timestamp on the client device you invoke a call or the timestamp value you manually passed in a server-side library call.
  • sentAtstring(date-time)
    The ISO-8601 timestamp when a library sends an event to Data Pipelines.
  • timestampstring(date-time)
    The ISO-8601 timestamp when the event originally took place. This is mostly useful when you backfill past events. If you're not backfilling data, you can leave this field empty and we'll use the current time or server time.
  • traitsobject
    Additional information about the group.
    • objectTypeIdstring
      If you use Customer.io Journeys as a destination, this value is the type of group/object your group belongs to; object type IDs are stringified integers. If you don't include this value, we assume the object type ID is 1. See objects in Customer.io Journeys for more information.
    • relationshipAttributesobject
      Attributes that you want to set for the relationship between the person and the group.
    • Group Traits *any type
  • userIdstring
    The unique identifier for a person. This value should be unique across systems, so you recognize the same person in your sources _and_ destinations.

Alias

The Alias method combines two previously unassociated user identities. Some integrations automatically reconcile profiles with different identifiers based on whether you send anonymousId, userId, or another trait that the integration expects to be unique. But for integrations that don’t, you may need to send alias requests to do this.

In general, you won’t need to use the alias call; we try to handle user identification gracefully so you don’t need to merge profiles. But you may need to send alias calls to manage user identities in some data-out integrations.

For example, in Mixpanel it’s used to associate an anonymous user with an identified user once they sign up.

  • previousIdstringrequired
    The anonymousId or userId value that you want to merge into the canonical profile.
  • userIdstringrequired
    The userId that you want to keep. This is required if you haven't already identified someone with one of our web or server-side libraries.
Updated September 1, 2026