Customer.io Pipelines API

The Customer.io Pipelines (CDP) API is the Segment-spec data ingestion interface Customer.io recommends for new integrations — identify, track, page, screen, group, alias and batch, all POST-only, with deletes and other state changes expressed as semantic events rather than HTTP verbs. This entry points at the OpenAPI 3.1.0 document Customer.io publishes itself. Authorization is HTTP basic with the CDP API key as the username and a blank password.

OpenAPI Specification

customer-io-pipelines-api-openapi.json Raw ↑
{
  "openapi": "3.1.0",
  "info": {
    "version": "1.0.0",
    "title": "Pipelines API",
    "description": "# Overview\nIn general, you'll consume this API through one of our source libraries—our JavaScript client library or any of our server packages. But you can also integrate directly with our REST API if you don't want to install one of our libraries or you want to support a source that we don't have a native integration with.\n\n# Server addresses: US and EU\nCustomer.io hosts services in the United States (US) and European Union. Select the appropriate server address for your region.\n\n| Region | Server Address |\n| :-- | :-- |\n| US | https://cdp.customer.io |\n| EU | https://cdp-eu.customer.io |\n\nIf you're in our EU region, you'll need to specify the EU URL when you initialize our server-side libraries. If you use our JavaScript client library, we'll set your region and route data/calls automatically.\n\n# Get an API key\n\n1. Go to the <svg class=\"icon\"><use href=\"#connection\" /></svg> tab and click **Sources**.\n1. Click **Add Source**, pick **HTTP**, and click **Next**.\n1. Give the source a *Name* and copy your *API Key*. You'll use this key to authenticate with our API. If you don't copy the key now, you can always get it later from the *Settings* tab when you're done setting up your source.\n1. (Optional) Test your connection by sending a test call. You can copy your API key into an app like Postman or send a CURL request. If your request is successful, and then you click *Test Connection* we'll let you know if your request was successful and you've set up your HTTP implementation successfully.\n1. Click **Submit**.\n\nNow you can use the key as a username with a blank password to authenticate and send requests to our API.\n\n# Authentication & rate limits\n\nOur API uses basic authorization with an API Key provided when you set up a source. If you use Postman or another platform that helps you send API calls, this API key is the *Username*, and the *Password* is blank.\n\nOur sources are all authenticated using a **API Key** that we generate when you create a source.\n\n\n## Rate and payload limits\n\nA request is limited to 32KB. A batch request is limited to 500KB total and 32KB per call in the request. If a request exceeds these limits, you will receive a 200 response, but the request will not go through.\n\nThe Data Pipelines API has a rate limit of 3000 requests per 3 seconds for both active data integrations and historical backfill scripts. This limit applies to both our v1 and v2 APIs.\n\nWhile this rate is not strictly enforced, consistently exceeding it may lead to throttling or dropped data, especially during periods of high system load. If we detect a sustained high volume that could impact other customers, we may contact you to help adjust your integration or, in rare cases, temporarily block requests.\n\n<div class=\"fly-panel fly-light regionUS\">\n<div class=\"fly-panel-body us-server\">\n<p class=\"text--bold\">Warning</p>\n<p>Rate limits are subject to change. We may adjust these thresholds to ensure stable performance for all customers.</p>\n</div></div>\n\n# Try out our postman collection\n\nWe've generated a Postman collection with all of the endpoints organized as you'll find them on this page, with a starter environment (mainly to contain your API key). For our API endpoints, **your API key is your username and your password is blank**.\n\nYou'll notice that payloads on this page can contain significantly more information than the payloads that appear in our collection. We've limited our collections to the fields that you'll _typically_ use when you send calls to our APIs and libraries, so it's easier to get started. But you can add additional fields to payloads—like `context`, `integrations`, and so on—if you want.\n\nIf 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](/release-notes/) for updates to our APIs.\n\n[<img src=\"https://run.pstmn.io/button.svg\" alt=\"Run In Postman\" style=\"width: 128px; height: 32px;\">](https://god.gw.postman.com/run-collection/23697545-287dd370-3d8b-4a71-80fe-75d6b7c7ff61?action=collection%2Ffork&source=rip_markdown&collection-url=entityId%3D23697545-287dd370-3d8b-4a71-80fe-75d6b7c7ff61%26entityType%3Dcollection%26workspaceId%3D35e4a70d-66bd-4b3e-8a0c-57f9e32080dc#?env%5BCustomer.io%20Data%20Pipelines%20API%20Environment%5D=W3sia2V5IjoiY2RwX2FwaV91cmwiLCJ0eXBlIjoiZGVmYXVsdCIsInZhbHVlIjoiY2RwLmN1c3RvbWVyLmlvIiwiZW5hYmxlZCI6dHJ1ZX0seyJrZXkiOiJ3cml0ZV9rZXkiLCJ0eXBlIjoic2VjcmV0IiwidmFsdWUiOiIiLCJlbmFibGVkIjp0cnVlfV0=)\n\n# Deletions, suppressions, and other semantic events\n\nYou'll notice that this API only contains `POST` calls; we don't have `DELETE` operations. For delete operations, and other operations that don't have bespoke endpoints, we use *semantic events*.\n\nWhen you need to do things like deleting people, removing relationships, and other sorts of things, you'll send a request to the `/track` endpoint with a specific event `name` parameter. The `name` tells us what to do with the request.\n\nFor example, you can send a `track` event with the name `Delete Person` to remove a person from your workspace.\n\nSee [Semantic Events](/integrations/data-in/semantic-events/cio-journeys/) to see Customer.io-specific events.\n\nWe also support semantic events for other kinds of destinations. See [Semantic Events for other destinations](#semantic-events-for-other-destinations) below for more information.\n\n| Event Name | Description |\n|------|--------|\n| `Device Created or Updated` | Adds or updates a mobile device (by token), and associates it with a person |\n| `Device Deleted` | Deletes a device |\n| `User Deleted` | Removes a person from your workspace |\n| `User Suppressed` | Removes a person from your workspace and suppresses their identifiers so you can't add them back to Customer.io. |\n| `User Unsuppressed` | Unsuppresses an identifier so you can add someone back to Customer.io and message them again. |\n| `Relationship Deleted` | Remove a relationship between a person and an object|\n| `Object Deleted` | Remove an object (like an account or company) from your Customer.io workspace|\n| `Report Delivery Event` | Report delivery events for messages|\n\n## Semantic events for other destinations\n\nIn addition to events that have special meanings [in Customer.io](#customerio-semantic-events), we have a number of other events that we support across different kinds of destinations. These uniform events ensure that we'll map event data to destinations consistently—so you can move from one provider to another without having to change your event names or payload structures.\n\nFor example, our ecommerce events work across any ecommerce platform we integrate with—even if those ecommerce platforms have different APIs or payload structures.\n\nSee [Semantic Events](/integrations/data-in/semantic-events/getting-started/) to learn more.\n\n* [A/B Test](/integrations/api/cdp/ab-test/)\n* [Ecommerce](/integrations/api/cdp/ecommerce/)\n* [Email](/integrations/api/cdp/email/)\n* [Live Chat](/integrations/api/cdp/live-chat/)\n* [Mobile App](/integrations/api/cdp/mobile-app/)\n* [Video](/integrations/api/cdp/video/)\n\n## Backfilling data\n\nBy default, Customer.io records a `timestamp` when we receive requests. If you're sending data to Customer.io in real time, you don't need to worry about the timestamp.\n\nIf you want to backfill requests, you can send a `timestamp`—an ISO 8601 date-time string—telling us when the request occurred. This provides a way to log `track` and `page` calls when the activities _actually_ took place.\n"
  },
  "servers": [
    {
      "url": "https://cdp.customer.io/v1",
      "description": "The base URL for all Data Pipelines calls in our United States (US) region."
    },
    {
      "url": "https://cdp-eu.customer.io/v1",
      "description": "The base URL for all Data Pipelines calls in our European Union (EU) region."
    }
  ],
  "paths": {
    "/identify": {
      "post": {
        "operationId": "identify",
        "summary": "Add and Update People",
        "description": "Identifies a person and assigns `traits` to them.\n\nIn most cases, you'll identify people with a `userId` or an `anonymousId`. But when you use Customer.io as a destination, you can pass an empty `userId` or `anonymousId`, and identify people by their `email` trait.\n\n**When you use our libraries, you'll typically only provide an ID and `traits`. The libraries fill in the rest of the payload automatically.**\n",
        "servers": [
          {
            "url": "https://cdp.customer.io/v1",
            "description": "This is a Data Pipeline API."
          }
        ],
        "security": [
          {
            "Basic-Auth": []
          }
        ],
        "parameters": [
          {
            "name": "X-Strict-Mode",
            "in": "header",
            "description": "When set to `1`, enables strict validation that returns proper HTTP error codes (400/401) for validation failures. When not set or set to any other value, the API operates in permissive mode, logging errors but returning HTTP 200. [Learn more](/integrations/api/track-vs-cdp-api#pipelines-strict-mode)\n",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "1"
              ]
            },
            "example": "1"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/identify"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "json",
            "label": "JSON",
            "source": "{\n  \"type\": \"identify\",\n  \"traits\": {\n    \"name\": \"Cool Person\",\n    \"email\": \"cool.person@example.com\",\n    \"likes_baseball\": true,\n    \"games_attended\": 5\n  },\n  \"userId\": \"97980cfea0067\"\n}"
          },
          {
            "label": "Curl",
            "lang": "shell",
            "source": "curl --request POST \\\n  --url https://cdp.customer.io/v1/identify \\\n  -u api_key: \\\n  -H 'content-type: application/json' \\\n  --data-raw '\n  {\n      \"userId\": \"97980cfea0067\",\n      \"traits\": {\n          \"name\": \"Cool Person\",\n          \"email\": \"cool.person@example.com\",\n          \"likes_baseball\": true,\n          \"games_attended\": 5\n      }\n  }'\n"
          },
          {
            "label": "JavaScript (SDK)",
            "lang": "javascript",
            "source": "analytics.identify(\"97980cfea0067\", {\n  name: \"Cool Person\",\n  email: \"cool.person@example.com\",\n  likes_baseball: true,\n  games_attended: 5\n});\n"
          },
          {
            "label": "Node.js (SDK)",
            "lang": "javascript",
            "source": "analytics.identify({\n  userId: '019mr8mf4r',\n  traits: {\n    name: 'Cool Person',\n    email: 'cool.person@example.com',\n    plan: 'Enterprise',\n    friends: 42\n  }\n});\n"
          },
          {
            "label": "Python (SDK)",
            "lang": "python",
            "source": "analytics.identify('f4ca124298', {\n  email: 'cool.person@example.com'\n  first_name: 'cool',\n  last_name: 'person'\n})\n"
          },
          {
            "label": "Go (SDK)",
            "lang": "go",
            "source": "client.Enqueue(analytics.Identify{\n  UserId: \"019mr8mf4r\",\n  Traits: analytics.NewTraits().\n    SetName(\"Cool Person\").\n    SetEmail(\"cool.person@example.com\").\n    Set(\"plan\", \"Enterprise\").\n    Set(\"fav_number\", 42),\n})\n"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/200"
          }
        }
      }
    },
    "/track": {
      "post": {
        "operationId": "track",
        "summary": "Track events",
        "description": "Send an event associated with a person. The `track` call is how you record the things that people do on your website or in your app.\n\nWhile this endpoint takes any `event` name you want to send, Customer.io also supports \"semantic events.\" These are specific `event` names (like `User Deleted` or `Device Created or Updated`) that perform special operations in Customer.io like deleting people, adding mobile devices to profiles, and so on. See the [Customer.io Semantic Events documentation](/integrations/api/cdp/customerio/) for complete schemas and examples.\n\n**When you use our libraries, you'll typically only provide an `event`, an ID for the person, and `properties`. The libraries fill in the rest of the payload automatically.**\n",
        "servers": [
          {
            "url": "https://cdp.customer.io/v1",
            "description": "This is a Data Pipeline API."
          }
        ],
        "security": [
          {
            "Basic-Auth": []
          }
        ],
        "parameters": [
          {
            "name": "X-Strict-Mode",
            "in": "header",
            "description": "When set to `1`, enables strict validation that returns proper HTTP error codes (400/401) for validation failures. When not set or set to any other value, the API operates in permissive mode, logging errors but returning HTTP 200. [Learn more](/integrations/api/track-vs-cdp-api#pipelines-strict-mode)\n",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "1"
              ]
            },
            "example": "1"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/track"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "json",
            "label": "JSON",
            "source": "{\n  \"anonymousId\": \"23adfd82-aa0f-45a7-a756-24f2a7a4c895\",\n  \"context\": {\n    \"library\": {\n      \"name\": \"analytics.js\",\n      \"version\": \"2.11.1\"\n    },\n    \"page\": {\n      \"path\": \"/\",\n      \"referrer\": \"https://www.google.com/\",\n      \"search\": \"?q=analytics\",\n      \"title\": \"Customer.io Docs\",\n      \"url\": \"https://docs.customer.io\"\n    },\n    \"userAgent\": \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_0) AppleWebKit/537.36 (KHTML like Gecko) Chrome/46.0.2490.86 Safari/537.36\",\n    \"ip\": \"108.0.78.21\"\n  },\n  \"event\": \"Course Started\",\n  \"integrations\": null,\n  \"messageId\": \"ajs-f8ca1e4de5024d9430b3928bd8ac6b96\",\n  \"properties\": {\n    \"title\": \"Intro to Customer.io\"\n  },\n  \"receivedAt\": \"2015-12-12T19:11:01.266Z\",\n  \"sentAt\": \"2015-12-12T19:11:01.169Z\",\n  \"timestamp\": \"2015-12-12T19:11:01.249Z\",\n  \"type\": \"track\",\n  \"userId\": \"AiUGstSDIg\",\n  \"originalTimestamp\": \"2015-12-12T19:11:01.152Z\"\n}"
          },
          {
            "label": "Curl",
            "lang": "shell",
            "source": "curl --request POST \\\n  --url https://cdp.customer.io/v1/track \\\n  -u api_key: \\\n  -H 'content-type: application/json' \\\n  --data-raw '\n  {\n      \"userId\": \"97980cfea0067\",\n      \"event\": \"Course Started\",\n      \"properties\": {\n          \"title\": \"Intro to Customer.io\"\n      }\n  }'\n"
          },
          {
            "label": "JavaScript (SDK)",
            "lang": "javascript",
            "source": "analytics.track(\"video_watched\", {\n  video_name: \"Cool New Video\"\n  length: 1.56\n  speed: 1.25\n  finished: false\n});\n"
          },
          {
            "label": "Node.js (SDK)",
            "lang": "javascript",
            "source": "analytics.track({\n  userId: '019mr8mf4r',\n  event: 'added_to_cart',\n  properties: {\n    product: \"shoes\",\n    revenue: 39.95,\n    qty: 1,\n    size: 9\n  }\n});\n"
          },
          {
            "label": "Python (SDK)",
            "lang": "python",
            "source": "analytics.track('f4ca124298', 'class_started', {\n  title: 'How to use Customer.io',\n  progress: '2%',\n  category: 'getting started'\n})\n"
          },
          {
            "label": "Go (SDK)",
            "lang": "go",
            "source": "client.Enqueue(analytics.Track{\n  UserId: \"f4ca124298\",\n  Event:  \"added_to_cart\",\n  Properties: analytics.NewProperties().\n    Set(\"product\", \"shoes\"),\n    Set(\"price\", 39.95),\n})\n"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/200"
          }
        }
      }
    },
    "/page": {
      "post": {
        "operationId": "page",
        "summary": "Track pageviews",
        "description": "Sends a page view event. If you use our JavaScript source, it automatically records `page` events whenever it loads (every page). If you use a single-page app, you'll need to call the `page` method people change routes.\n\nThe request consists of the page `name` and additional properties about the page.\n\nIf you use our JavaScript library, the page name and URL are automatically gathered and passed as event properties.\n\n**When you use our libraries, you'll typically only provide a user ID/anonymous ID and the `name` of the page. The libraries fill in the rest of the payload automatically.**\n",
        "servers": [
          {
            "url": "https://cdp.customer.io/v1",
            "description": "This is a Data Pipeline API."
          }
        ],
        "security": [
          {
            "Basic-Auth": []
          }
        ],
        "parameters": [
          {
            "name": "X-Strict-Mode",
            "in": "header",
            "description": "When set to `1`, enables strict validation that returns proper HTTP error codes (400/401) for validation failures. When not set or set to any other value, the API operates in permissive mode, logging errors but returning HTTP 200. [Learn more](/integrations/api/track-vs-cdp-api#pipelines-strict-mode)\n",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "1"
              ]
            },
            "example": "1"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/page"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "json",
            "label": "JSON",
            "source": "{\n  \"anonymousId\": \"507f191e810c19729de860ea\",\n  \"channel\": \"browser\",\n  \"context\": {\n    \"ip\": \"8.8.8.8\",\n    \"userAgent\": \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML like Gecko) Chrome/40.0.2214.115 Safari/537.36\"\n  },\n  \"integrations\": {\n    \"All\": true,\n    \"Mixpanel\": false,\n    \"Salesforce\": false\n  },\n  \"messageId\": \"022bb90c-bbac-11e4-8dfc-aa07a5b093db\",\n  \"name\": \"Home\",\n  \"properties\": {\n    \"title\": \"Welcome | ACME, Inc.\",\n    \"url\": \"https://www.example.com\"\n  },\n  \"receivedAt\": \"2015-02-23T22:28:55.387Z\",\n  \"sentAt\": \"2015-02-23T22:28:55.111Z\",\n  \"timestamp\": \"2015-02-23T22:28:55.111Z\",\n  \"type\": \"page\",\n  \"userId\": \"97980cfea0067\",\n  \"version\": 1.1\n}"
          },
          {
            "label": "Curl",
            "lang": "shell",
            "source": "curl --request POST \\\n  --url https://cdp.customer.io/v1/page \\\n  -u api_key: \\\n  -H 'content-type: application/json' \\\n  --data-raw '\n  {\n      \"userId\": \"f4ca124298\",\n      \"name\": \"Home\",\n      \"properties\": {\n          \"title\": \"Welcome | ACME, Inc.\",\n          \"url\": \"https://www.example.com\"\n      }\n  }'\n"
          },
          {
            "label": "JavaScript (SDK)",
            "lang": "javascript",
            "source": "analytics.page(\"Retail Page\",\"shoes\", {\n  affiliate: \"Pro annual\",\n  accountType: \"Facebook\"\n});\n"
          },
          {
            "label": "Node.js (SDK)",
            "lang": "javascript",
            "source": "analytics.page({\n  userId: '019mr8mf4r',\n  category: 'Docs',\n  name: 'Customer.io Data Pipelines',\n  properties: {\n    url: 'https://customer.io/cdp/',\n    path: '/cdp/',\n    title: 'Customer.io Data Pipelines',\n    referrer: 'https://customer.io'\n  }\n});\n"
          },
          {
            "label": "Python (SDK)",
            "lang": "python",
            "source": "analytics.page('<user_id>', 'Retail Page', 'shoes', {\n    'url': 'https://example.com/products/showes'\n})\n"
          },
          {
            "label": "Go (SDK)",
            "lang": "go",
            "source": "client.Enqueue(analytics.Page{\n  UserId: \"f4ca124298\",\n  Name:   \"Customer.io Data Pipelines\",\n  Category: \"Docs\",\n  Properties: analytics.NewProperties().\n    SetURL(\"https://customer.io/cdp/\"),\n})\n"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/200"
          }
        }
      }
    },
    "/screen": {
      "post": {
        "operationId": "screen",
        "summary": "Track mobile screenviews",
        "description": "Sends a screen view event for mobile devices. Screen events help you understand the screens that people use in your app. You should send a screen call whenever a user requests a page of your app.\n",
        "servers": [
          {
            "url": "https://cdp.customer.io/v1",
            "description": "This is a Data Pipeline API."
          }
        ],
        "security": [
          {
            "Basic-Auth": []
          }
        ],
        "parameters": [
          {
            "name": "X-Strict-Mode",
            "in": "header",
            "description": "When set to `1`, enables strict validation that returns proper HTTP error codes (400/401) for validation failures. When not set or set to any other value, the API operates in permissive mode, logging errors but returning HTTP 200. [Learn more](/integrations/api/track-vs-cdp-api#pipelines-strict-mode)\n",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "1"
              ]
            },
            "example": "1"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/screen"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "json",
            "label": "JSON",
            "source": "{\n  \"anonymousId\": \"507f191e810c19729de860ea\",\n  \"context\": {\n    \"ip\": \"8.8.8.8\"\n  },\n  \"integrations\": {\n    \"All\": true,\n    \"Salesforce\": false\n  },\n  \"messageId\": \"022bb90c-bbac-11e4-8dfc-aa07a5b093db\",\n  \"name\": \"feed\",\n  \"properties\": {\n    \"subscriptions\": [\n      \"baseball\",\n      \"basketball\"\n    ]\n  },\n  \"receivedAt\": \"2015-02-23T22:28:55.387Z\",\n  \"sentAt\": \"2015-02-23T22:28:55.111Z\",\n  \"timestamp\": \"2015-02-23T22:28:55.111Z\",\n  \"type\": \"screen\",\n  \"userId\": \"97980cfea0067\",\n  \"version\": 1.1\n}"
          },
          {
            "label": "Curl",
            "lang": "shell",
            "source": "curl --request POST \\\n  --url https://cdp.customer.io/v1/screen \\\n  -u api_key: \\\n  -H 'content-type: application/json' \\\n  --data-raw '\n  {\n      \"userId\": \"f4ca124298\",\n      \"name\": \"feed\",\n      \"properties\": {\n          \"subscriptions\": [\n              \"baseball\",\n              \"basketball\"\n          ]\n      }\n  }'\n"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/200"
          }
        }
      }
    },
    "/group": {
      "post": {
        "operationId": "group",
        "summary": "Create objects and relationships",
        "description": "Group calls add people to a group. Groups could be a companies, accounts, online classes, and so on. How groups are represented in your destination depends on the destination. Some destinations have concepts of \"groups\"; Customer.io's destination calls groups \"objects.\"\n\n**When you use our libraries, you'll typically only provide an ID for the user, the `groupId`, and `traits`. The libraries fill in the rest of the payload automatically.**\n",
        "servers": [
          {
            "url": "https://cdp.customer.io/v1",
            "description": "This is a Data Pipeline API."
          }
        ],
        "security": [
          {
            "Basic-Auth": []
          }
        ],
        "parameters": [
          {
            "name": "X-Strict-Mode",
            "in": "header",
            "description": "When set to `1`, enables strict validation that returns proper HTTP error codes (400/401) for validation failures. When not set or set to any other value, the API operates in permissive mode, logging errors but returning HTTP 200. [Learn more](/integrations/api/track-vs-cdp-api#pipelines-strict-mode)\n",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "1"
              ]
            },
            "example": "1"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/group"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "json",
            "label": "JSON",
            "source": "{\n  \"anonymousId\": \"507f191e810c19729de860ea,\",\n  \"channel\": \"browser,\",\n  \"context\": {\n    \"ip\": \"8.8.8.8\",\n    \"userAgent\": \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.115 Safari/537.36\"\n  },\n  \"integrations\": {\n    \"All\": true,\n    \"Mixpanel\": false,\n    \"Salesforce\": false\n  },\n  \"messageId\": \"022bb90c-bbac-11e4-8dfc-aa07a5b093db,\",\n  \"receivedAt\": \"2015-02-23T22:28:55.387Z,\",\n  \"sentAt\": \"2015-02-23T22:28:55.111Z,\",\n  \"timestamp\": \"2015-02-23T22:28:55.111Z,\",\n  \"traits\": {\n    \"name\": \"ACME, Inc.\",\n    \"industry\": \"Technology\",\n    \"employees\": 329,\n    \"plan\": \"enterprise\",\n    \"total billed\": 830\n  },\n  \"type\": \"group\",\n  \"userId\": \"97980cfea0067\",\n  \"groupId\": \"0e8c78ea9d97a7b8185e8632,\",\n  \"version\": 1.1\n}"
          },
          {
            "label": "Curl",
            "lang": "shell",
            "source": "curl --request POST \\\n  --url https://cdp.customer.io/v1/group \\\n  -u api_key: \\\n  -H 'content-type: application/json' \\\n  --data-raw '\n  {\n      \"userId\": \"97980cfea0067\",\n      \"groupId\": \"0e8c78ea9d97a7b8185e8632\",\n      \"traits\": {\n          \"objectTypeId\": 2,\n          \"name\": \"ACME, Inc.\",\n          \"industry\": \"Technology\",\n          \"employees\": 329,\n          \"plan\": \"enterprise\",\n          \"total billed\": 830\n      }\n  }'\n"
          },
          {
            "label": "JavaScript (SDK)",
            "lang": "javascript",
            "source": "analytics.group(\"0e8c78ea9d97a7b8185e8632\", {\n  objectTypeId: 2,\n  name: \"Acme\",\n  industry: \"Technology\",\n  road_runner_accidents: 329,\n  plan: \"enterprise\",\n  \"total billed\": 830\n});\n"
          },
          {
            "label": "Node.js (SDK)",
            "lang": "javascript",
            "source": "analytics.group({\n  userId: '019mr8mf4r',\n  groupId: '56',\n  traits: {\n    objectTypeId: 2,\n    name: 'ACME, Inc.',\n    description: 'Giant anvils'\n  }\n});\n"
          },
          {
            "label": "Python (SDK)",
            "lang": "python",
            "source": "analytics.group('user_id', 'group_id', {\n  'objectTypeId': 2,\n  'name': 'ACME, Inc.',\n  'domain': 'Giant anvils'\n})\n"
          },
          {
            "label": "Go (SDK)",
            "lang": "go",
            "source": "client.Enqueue(analytics.Group{\n  UserId:  \"019mr8mf4r\",\n  GroupId: \"56\",\n  Traits: map[string]interface{}{\n    \"objectTypeId\": 2,\n    \"name\":        \"ACME, Inc.\",\n    \"description\": \"Giant anvils\",\n  },\n})\n"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/200"
          }
        }
      }
    },
    "/alias": {
      "post": {
        "operationId": "alias",
        "summary": "Merge profiles",
        "description": "*You **only** need to use this method to support a few select destinations like Mixpanel.*\n\nThe `alias` method reconciles identifiers in systems that don't automatically handle identity changes—like when a person graduates from an anonymous user to an identified user.\n\nFor example, a person typically has an `anonymousId` until you identify them by `userId`. Most destinations will automatically associate data from the anonymous ID with the new user ID when you send an `identify` call. But a select few destinations, like [Mixpanel](/integrations/data-out/connections/mixpanel/), won't! The `alias` call tells Mixpanel to represent the `anonymousId` with the new `userId`.\n\nIf you need to use the `alias` call, you'll want to send it before you identify someone with a `userId`.\n\nIf you use our web or server-side libraries, and you've already identified someone, we assume that this is the `userId` that you want to keep. Otherwise, you need to pass both the `previousId` and the `userId`.\n\n**When you use our libraries, you'll typically only provide the `previousId` and `userId`. The libraries fill in the rest of the payload automatically.**\n",
        "servers": [
          {
            "url": "https://cdp.customer.io/v1",
            "description": "This is a Data Pipeline API."
          }
        ],
        "security": [
          {
            "Basic-Auth": []
          }
        ],
        "parameters": [
          {
            "name": "X-Strict-Mode",
            "in": "header",
            "description": "When set to `1`, enables strict validation that returns proper HTTP error codes (400/401) for validation failures. When not set or set to any other value, the API operates in permissive mode, logging errors but returning HTTP 200. [Learn more](/integrations/api/track-vs-cdp-api#pipelines-strict-mode)\n",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "1"
              ]
            },
            "example": "1"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/alias"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "json",
            "label": "JSON",
            "source": "{\n  \"previousId\": \"string\",\n  \"userId\": \"string\"\n}"
          },
          {
            "label": "Curl",
            "lang": "shell",
            "source": "curl --request POST \\\n  --url https://cdp.customer.io/v1/alias \\\n  -u api_key: \\\n  -H 'content-type: application/json' \\\n  -d '{\"previousId\":\"23adfd82-aa0f-45a7-a756-24f2a7a4c895\",\"userId\":\"97980cfea0067\"}'\n"
          },
          {
            "label": "JavaScript (SDK)",
            "lang": "javascript",
            "source": "analytics.alias(\"old-id\",\"new-id\");\n"
          },
          {
            "label": "Node.js (SDK)",
            "lang": "javascript",
            "source": "analytics.alias({ previousId: 'anonymous_user', userId: 'identified@example.com' })\n"
          },
          {
            "label": "Python (SDK)",
            "lang": "python",
            "source": "analytics.alias(previous_id, user_id)\n"
          },
          {
            "label": "Go (SDK)",
            "lang": "go",
            "source": "client.Enqueue(analytics.Alias{\n  PreviousId: anonymousUser,\n  UserId:     \"019mr8mf4r\",\n})\n"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/200"
          }
        }
      }
    },
    "/batch": {
      "post": {
        "operationId": "batch",
        "summary": "Bat

# --- truncated at 32 KB (159 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/customer-io/refs/heads/main/openapi/_original/customer-io-pipelines-api-openapi.json