openapi: 3.2.0 info: version: 1.0.0 title: Customer.io Track Track Customers API description: "# Overview\n\nOur Track API provides ways to send real-time customer data to your Customer.io workspace including customer identification and event tracking.\n\n# Use our Postman collection\n\nWe've generated a Postman collection to help you get started with our APIs.\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**NOTE**: Postman endpoints default to our US APIs. If you're in our European (EU) region, you'll need to add `-eu` to the server variables (`track_api_url` and `app_api_url`).\n\n[\"Run](https://god.gw.postman.com/run-collection/23697545-0f7ae1e8-8177-46fc-808a-2fd363dd52b9?action=collection%2Ffork&source=rip_markdown&collection-url=entityId%3D23697545-0f7ae1e8-8177-46fc-808a-2fd363dd52b9%26entityType%3Dcollection%26workspaceId%3Db886877f-fc09-475f-84fe-6221a98f4d18#?env%5BCustomer.io%20API%20Environment%5D=W3sia2V5IjoidHJhY2tfYXBpX3VybCIsInR5cGUiOiJkZWZhdWx0IiwidmFsdWUiOiJ0cmFjay5jdXN0b21lci5pbyIsImVuYWJsZWQiOnRydWV9LHsia2V5IjoiYXBwX2FwaV91cmwiLCJ0eXBlIjoiZGVmYXVsdCIsInZhbHVlIjoiYXBpLmN1c3RvbWVyLmlvIiwiZW5hYmxlZCI6dHJ1ZX0seyJrZXkiOiJzaXRlX2lkIiwidHlwZSI6ImRlZmF1bHQiLCJ2YWx1ZSI6IiIsImVuYWJsZWQiOnRydWV9LHsia2V5IjoiYXBpX2tleSIsInR5cGUiOiJzZWNyZXQiLCJ2YWx1ZSI6IiIsImVuYWJsZWQiOnRydWV9LHsia2V5IjoiYmVhcmVyIiwidHlwZSI6ImRlZmF1bHQiLCJ2YWx1ZSI6IiIsImVuYWJsZWQiOnRydWV9LHsia2V5IjoiYnJvYWRjYXN0X2lkIiwidHlwZSI6ImRlZmF1bHQiLCJ2YWx1ZSI6IiIsImVuYWJsZWQiOnRydWV9LHsia2V5IjoiaW1wb3J0X2lkIiwidHlwZSI6ImRlZmF1bHQiLCJ2YWx1ZSI6IiIsImVuYWJsZWQiOnRydWV9LHsia2V5IjoiZW1haWxfYWRkcmVzcyIsInR5cGUiOiJkZWZhdWx0IiwidmFsdWUiOiIiLCJlbmFibGVkIjp0cnVlfSx7ImtleSI6InN1cHByZXNzaW9uX3R5cGUiLCJ0eXBlIjoiZGVmYXVsdCIsInZhbHVlIjoiIiwiZW5hYmxlZCI6dHJ1ZX0seyJrZXkiOiJjb2xsZWN0aW9uX2lkIiwidHlwZSI6ImRlZmF1bHQiLCJ2YWx1ZSI6IiIsImVuYWJsZWQiOnRydWV9LHsia2V5Ijoic25pcHBldF9uYW1lIiwidHlwZSI6ImRlZmF1bHQiLCJ2YWx1ZSI6IiIsImVuYWJsZWQiOnRydWV9LHsia2V5Ijoid2ViaG9va19pZCIsInR5cGUiOiJkZWZhdWx0IiwidmFsdWUiOiIiLCJlbmFibGVkIjp0cnVlfSx7ImtleSI6InNlbmRlcl9pZCIsInR5cGUiOiJkZWZhdWx0IiwidmFsdWUiOiIiLCJlbmFibGVkIjp0cnVlfSx7ImtleSI6ImV4cG9ydF9pZCIsInR5cGUiOiJkZWZhdWx0IiwidmFsdWUiOiIiLCJlbmFibGVkIjp0cnVlfSx7ImtleSI6Im1lc3NhZ2VfaWQiLCJ0eXBlIjoiZGVmYXVsdCIsInZhbHVlIjoiIiwiZW5hYmxlZCI6dHJ1ZX0seyJrZXkiOiJzZWdtZW50X2lkIiwidHlwZSI6ImRlZmF1bHQiLCJ2YWx1ZSI6IiIsImVuYWJsZWQiOnRydWV9LHsia2V5IjoibmV3c2xldHRlcl9pZCIsInR5cGUiOiJkZWZhdWx0IiwidmFsdWUiOiIiLCJlbmFibGVkIjp0cnVlfSx7ImtleSI6ImNvbnRlbnRfaWQiLCJ0eXBlIjoiZGVmYXVsdCIsInZhbHVlIjoiIiwiZW5hYmxlZCI6dHJ1ZX0seyJrZXkiOiJjYW1wYWlnbl9pZCIsInR5cGUiOiJkZWZhdWx0IiwidmFsdWUiOiIiLCJlbmFibGVkIjp0cnVlfSx7ImtleSI6ImFjdGlvbl9pZCIsInR5cGUiOiJkZWZhdWx0IiwidmFsdWUiOiIiLCJlbmFibGVkIjp0cnVlfSx7ImtleSI6ImN1c3RvbWVyX2lkIiwidHlwZSI6ImRlZmF1bHQiLCJ2YWx1ZSI6IiIsImVuYWJsZWQiOnRydWV9LHsia2V5IjoidHJhbnNhY3Rpb25hbF9pZCIsInR5cGUiOiJkZWZhdWx0IiwidmFsdWUiOiIiLCJlbmFibGVkIjp0cnVlfSx7ImtleSI6InRyaWdnZXJfaWQiLCJ0eXBlIjoiZGVmYXVsdCIsInZhbHVlIjoiIiwiZW5hYmxlZCI6dHJ1ZX0seyJrZXkiOiJmb3JtX2lkIiwidHlwZSI6ImRlZmF1bHQiLCJ2YWx1ZSI6IiIsImVuYWJsZWQiOnRydWV9LHsia2V5IjoiaWRlbnRpZmllciIsInR5cGUiOiJkZWZhdWx0IiwidmFsdWUiOiIiLCJlbmFibGVkIjp0cnVlfSx7ImtleSI6ImRldmljZV9pZCIsInR5cGUiOiJkZWZhdWx0IiwidmFsdWUiOiIiLCJlbmFibGVkIjp0cnVlfSx7ImtleSI6ImRlbGl2ZXJ5X2lkIiwidHlwZSI6ImRlZmF1bHQiLCJ2YWx1ZSI6IiIsImVuYWJsZWQiOnRydWV9XQ==)\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://track.customer.io |\n| EU | https://track-eu.customer.io |\n\nNote 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.\n\n# Authentication \n\nYou can find all of your API authentication information in your [Account Settings](https://fly.customer.io/settings/api_credentials). 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.\n\n# v1 vs v2 APIs\n\nMost of the time, when we talk about *The Track API*, we're talking about the v1 API because the v2 API isn't used in any of our libraries and rarely used in libraries built by third parties; it's much more common that you'd encounter the v1 API.\n\nIf you're integrating with Customer.io using one of our libraries, or a third party customer data platform (CDP) like Segment or Rudderstack, you'll be using the v1 API.\n\nThe v2 API is newer and supports two important features that the v1 API doesn't natively support: objects and batching. But, if you're integrating directly with our API, we suggest you use the [Pipelines API](/integrations/api/cdp/). The Pipelines API supports both objects, batching, *and* all of our newest integrations and libraries are based on it.\n\n# Rate Limits\n\nThe Track API has a rate limit of 1000 requests per second 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**Rate limits are subject to change. We may adjust these thresholds to ensure stable performance for all customers.**\n\nBelow 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. \n\n## Customer limits\n\nThese limits apply to people and their attributes, often referred to as \"customers\" in our APIs.\n\n| Data Type | Limit | Description |\n| -- | -- | -- |\n| ID | 150 bytes | Max length of a person's ID value |\n| Attribute Name | 150 bytes | Max length of each attribute name |\n| Attribute Value | 1000 bytes | Max length of attribute values |\n| Unique attributes | 300 | Max number of attributes allowed per person or Identify call |\n\n## Object and relationship limits\n\nObjects (groups) and relationships between people and objects can have their own attributes. Their limits are similar to people (customers).\n\n| Data Type | Limit | Description |\n| -- | -- | -- |\n| Object ID | 150 bytes | Max length of a object's ID |\n| Attribute Names | 150 bytes | Max length of each attribute name |\n| Attribute Values | 1000 bytes | Max length of attribute values |\n| Unique attributes | 300 | Max number of attributes allowed per object or relationship |\n| Total attribute size | 100 Kilobytes | Max size of all attributes associated with an object or relationship |\n\n## Track API Event limits\n\nThese limits apply to events that you'll send with the `/v1/track` call.\n\n| Data Type | Limit | Description |\n| -- | -- | -- |\n| Event Name | 100 bytes | Max length of each event name |\n| Event Data | 100000 bytes | Max length of each event data |\n\n\n## v2 API Limits\n\nThe v2 API has two endpoints, both of which have limits on the total size of requests. \n* `/entity` is limited to requests 32kb or smaller.\n* `/batch` is limited to requests 500kb or smaller.\n \n Each of the requests within a batch must also be 32kb or smaller.\n" servers: - url: https://track.customer.io description: The base URL for the Track API. Track endpoints use basic authentication with your Site ID as the user name and your secret key as the password. - url: https://track-eu.customer.io description: The base URL for the Track API (EU region). Track endpoints use basic authentication with your Site ID as the user name and your secret key as the password. tags: - name: Track Customers x-displayName: Customers description: Add, modify, suppress, or unsuppress people (referred to as "customers" in our APIs). You can also use these endpoints to set attributes on people. paths: /api/v1/customers/{identifier}: put: operationId: identify tags: - Track Customers summary: Add or update a customer parameters: - $ref: '#/components/parameters/track_customer_id' description: '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_`—unless when updating an `email` with the [Allow updates to email using ID](/accounts/workspaces#update-email-with-id) setting enabled. You can get the `cio_id` value from the [App API](/api/#tag/Customers). 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. **Tip**: If your workspace identifies people by both `email` and `id`, and you send an identify call with a new `id` but an `email` that already belongs to someone, we update the existing person rather than creating a new one. The existing person gets the new `id`. This is a common source of confusion during testing—if you''re generating new IDs but reusing the same email address, you''re updating one person repeatedly, not creating multiple people. ' servers: - url: https://track.customer.io description: This endpoint is a part of the Track API. Track endpoints use basic authentication with your Site ID as the user name and your secret key as the password. security: - Tracking-API-Key: [] requestBody: content: application/json: schema: type: object description: 'The body of the request contains key-value pairs representing attributes that you want to assign to, or update for, a person. If your request body contains "identifiers" (like `id` or `email`), your request attempts to update that person. If the identifier in the path and identifiers in the request body belong to different people, your request will produce an *Attribute Update Failure*. ' additionalProperties: x-additionalPropertiesName: Attributes description: Set attributes on customers. Attributes can have string, integer, or boolean values. oneOf: - type: string - type: integer - type: boolean properties: id: type: string description: 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: type: string format: email description: The email address of the customer. anonymous_id: $ref: '#/components/schemas/anonymous_id' created_at: type: integer description: The Unix timestamp when the user was created. _timestamp: type: integer description: The Unix timestamp for when the attribute update occurred. This can be used to control the order of attribute updates when multiple requests are sent in rapid succession. _update: type: boolean description: '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. ' cio_relationships: $ref: '#/components/schemas/v1_cio_relationships' unsubscribed: type: boolean description: 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. We support any case of true (i.e. TRUE, true, tRUe, etc.), 1, or "1" to represent unsubscribed. Any other value is considered “false”, or subscribed. cio_subscription_preferences: description: Stores your audience's subscription preferences if you enable our [subscription center](/journeys/channels/subscriptions/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_":`. type: object properties: topics: type: object description: Contains active topics in your workspace, named `topic_`. additionalProperties: x-additionalPropertiesName: topic_ description: Each property is a boolean named `topic_`. Topic `id` values begin at `1` and increment for each new topic. You can find your topic ids in [Workspace Settings](https://fly.customer.io/workspaces/last/settings/subscription_center/topics) or by querying our [App API](https://customer.io/api/app/#operation/getTopics). For each boolean, `true` means that a person is subscribed to the topic; false means they are unsubscribed. An empty or missing value reverts to the default preference for the topic (opt-in or opt-out). type: boolean example: email: customer@example.com created_at: 1361205308 first_name: Bob plan: basic cio_relationships: action: add_relationships relationships: - identifiers: object_type_id: '1' object_id: 01H5Q5SZVQDJ71SBME2SMDXS88 relationship_attributes: role: admin - identifiers: object_type_id: '2' object_id: 1171SBME relationship_attributes: role: viewer cio_subscription_preferences: topics: topic_1: true topic_2: true topic_3: false responses: '200': $ref: '#/components/responses/200' '401': $ref: '#/components/responses/401' x-codeSamples: - lang: json label: JSON source: "{\n \"email\": \"customer@example.com\",\n \"created_at\": 1361205308,\n \"first_name\": \"Bob\",\n \"plan\": \"basic\",\n \"cio_relationships\": {\n \"action\": \"add_relationships\",\n \"relationships\": [\n {\n \"identifiers\": {\n \"object_type_id\": \"1\",\n \"object_id\": \"01H5Q5SZVQDJ71SBME2SMDXS88\"\n },\n \"relationship_attributes\": {\n \"role\": \"admin\"\n }\n },\n {\n \"identifiers\": {\n \"object_type_id\": \"2\",\n \"object_id\": \"1171SBME\"\n },\n \"relationship_attributes\": {\n \"role\": \"viewer\"\n }\n }\n ]\n },\n \"cio_subscription_preferences\": {\n \"topics\": {\n \"topic_1\": true,\n \"topic_2\": true,\n \"topic_3\": false\n }\n }\n}" - label: Node.js (SDK) lang: javascript + Node.js source: "const { TrackClient, RegionUS } = require('customerio-node');\nlet cio = new TrackClient(siteId, apiKey, { region: RegionUS });\n\ncio.identify(5, {\n email: 'customer@example.com',\n created_at: 1361205308,\n first_name: 'Bob',\n plan: 'basic'\n});\n" - label: Ruby (SDK) lang: ruby source: "$customerio = Customerio::Client.new(\"YOUR SITE ID\", \"YOUR API SECRET KEY\", region: Customerio::Regions::US)\n\n$customerio.identify(\n :id => 5,\n :email => \"bob@example.com\",\n :created_at => customer.created_at.to_i,\n :first_name => \"Bob\",\n :plan => \"basic\"\n)\n" - label: Python (SDK) lang: python source: 'from customerio import CustomerIO, Regions cio = CustomerIO(site_id, api_key, region=Regions.US) cio.identify(id="5", email=''customer@example.com'', name=''Bob'', plan=''premium'') ' - label: Go (SDK) lang: go source: "track := customerio.NewTrackClient(\"YOUR SITE ID\", \"YOUR API SECRET KEY\", customerio.WithRegion(customerio.RegionUS))\n\nif err := track.Identify(\"5\", map[string]interface{}{\n \"email\": \"bob@example.com\",\n \"created_at\": time.Now().Unix(),\n \"first_name\": \"Bob\",\n \"plan\": \"basic\",\n}); err != nil {\n // do something with error\n}\n" delete: parameters: - $ref: '#/components/parameters/track_customer_id' summary: Delete a customer operationId: delete description: '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. ' tags: - Track Customers servers: - url: https://track.customer.io description: This endpoint is a part of the Track API. Track endpoints use basic authentication with your Site ID as the user name and your secret key as the password. security: - Tracking-API-Key: [] responses: '200': $ref: '#/components/responses/200' '401': $ref: '#/components/responses/401' x-codeSamples: - label: Node.js (SDK) lang: javascript + Node.js source: '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); ' - label: Ruby (SDK) lang: ruby source: '$customerio = Customerio::Client.new("YOUR SITE ID", "YOUR API SECRET KEY", region: Customerio::Regions::US) // Depending on your workspace settings, the id (5) may be an email address. $customerio.delete(5) ' - label: Python (SDK) lang: python source: 'from customerio import CustomerIO, Regions cio = CustomerIO(site_id, api_key, region=Regions.US) // Depending on your workspace settings, the customer_id may be an email address. cio.delete(customer_id="5") ' - label: Go (SDK) lang: go source: "track := customerio.NewTrackClient(\"YOUR SITE ID\", \"YOUR API SECRET KEY\", customerio.WithRegion(customerio.RegionUS))\n\n// Depending on your workspace settings, the id (5) may be an email address.\nif err := track.Delete(\"5\"); err != nil {\n // do something with error\n}\n" /api/v1/customers/{identifier}/devices: parameters: - $ref: '#/components/parameters/track_customer_id' put: operationId: add_device summary: Add or update a customer device description: Customers can have more than one device. Use this method to add iOS and Android devices to, or update devices for, a customer profile. tags: - Track Customers servers: - url: https://track.customer.io description: This endpoint is a part of the Track API. Track endpoints use basic authentication with your Site ID as the user name and your secret key as the password. security: - Tracking-API-Key: [] requestBody: content: application/json: schema: type: object required: - device description: Define the device you want to add to the customer profile. properties: device: $ref: '#/components/schemas/device_object' responses: '200': $ref: '#/components/responses/200' '400': $ref: '#/components/responses/400' '401': $ref: '#/components/responses/401' x-codeSamples: - lang: json label: JSON source: "{\n \"device\": {\n \"id\": \"string\",\n \"platform\": \"ios\"\n }\n}" - label: Node.js (SDK) lang: javascript source: '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.addDevice(5, "device_id", "ios", { primary: true }); ' - lang: Ruby source: '$customerio = Customerio::Client.new("YOUR SITE ID", "YOUR API SECRET KEY", region: Customerio::Regions::US) // Depending on your workspace settings, the id (5) may be an email address. $customerio.add_device(5, "my_ios_device_id", "ios") $customerio.add_device(5, "my_android_device_id", "android") ' - lang: Python (3) source: 'from customerio import CustomerIO, Regions cio = CustomerIO(site_id, api_key, region=Regions.US) // Depending on your workspace settings, the customer_id may be an email address. cio.add_device(customer_id="1", device_id=''device_hash'', platform=''ios'', last_used=1514764800}) ' - lang: Go source: "track := customerio.NewTrackClient(\"YOUR SITE ID\", \"YOUR API SECRET KEY\", customerio.WithRegion(customerio.RegionUS))\n\n// Depending on your workspace settings, the id (5) may be an email address.\nif err := track.AddDevice(\"5\", \"messaging token\", \"android\", map[string]interface{}{\n \"last_used\": time.Now().Unix(),\n}) err != nil {\n // do something with error\n}\n" /api/v1/customers/{identifier}/devices/{device_id}: parameters: - $ref: '#/components/parameters/track_customer_id' - $ref: '#/components/parameters/device_id' delete: operationId: delete_device summary: Delete a customer device description: 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. tags: - Track Customers servers: - url: https://track.customer.io description: This endpoint is a part of the Track API. Track endpoints use basic authentication with your Site ID as the user name and your secret key as the password. security: - Tracking-API-Key: [] responses: '200': $ref: '#/components/responses/200' '400': description: Invalid or malformed request. content: application/json: schema: type: object properties: meta: type: object properties: errors: type: array description: An array of errors. items: type: string description: Error descriptions. '401': $ref: '#/components/responses/401' x-codeSamples: - label: Node.js (SDK) lang: javascript source: '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.deleteDevice(5, "device_token") ' - lang: Ruby source: '$customerio = Customerio::Client.new("YOUR SITE ID", "YOUR API SECRET KEY", region: Customerio::Regions::US) // Depending on your workspace settings, the id (5) may be an email address. $customerio.delete_device(5, "my_device_token") ' - lang: Python (3) source: 'from customerio import CustomerIO, Regions cio = CustomerIO(site_id, api_key, region=Regions.US) // Depending on your workspace settings, the customer_id may be an email address. cio.delete_device(customer_id="5", device_id=''device_hash'') ' - lang: Go source: "track := customerio.NewTrackClient(\"YOUR SITE ID\", \"YOUR API SECRET KEY\", customerio.WithRegion(customerio.RegionUS))\n\n// Depending on your workspace settings, the id (5) may be an email address.\nif err := track.DeleteDevice(\"5\", \"messaging-token\"); err != nil {\n // do something with error\n}\n" /api/v1/customers/{identifier}/suppress: parameters: - $ref: '#/components/parameters/track_customer_id' post: operationId: suppress summary: Suppress a customer profile description: '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 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.

' tags: - Track Customers servers: - url: https://track.customer.io description: This endpoint is a part of the Track API. Track endpoints use basic authentication with your Site ID as the user name and your secret key as the password. security: - Tracking-API-Key: [] responses: '200': $ref: '#/components/responses/200' '401': $ref: '#/components/responses/401' x-codeSamples: - label: Node.js (SDK) lang: javascript source: '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.suppress(5) ' - lang: Ruby source: '$customerio = Customerio::Client.new("YOUR SITE ID", "YOUR API SECRET KEY", region: Customerio::Regions::US) // Depending on your workspace settings, the id (5) may be an email address. $customerio.suppress(5) ' - lang: Python (3) source: 'from customerio import CustomerIO, Regions cio = CustomerIO(site_id, api_key, region=Regions.US) // Depending on your workspace settings, customer_id may be an email address. cio.suppress(customer_id="5") ' /api/v1/customers/{identifier}/unsuppress: parameters: - $ref: '#/components/parameters/track_customer_id' post: operationId: unsuppress summary: Unsuppress a customer profile description: 'Unsuppressing a profile allows you to add the customer back to Customer.io. If you unsuppress a person in a workspace 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. ' tags: - Track Customers servers: - url: https://track.customer.io description: This endpoint is a part of the Track API. Track endpoints use basic authentication with your Site ID as the user name and your secret key as the password. security: - Tracking-API-Key: [] responses: '200': $ref: '#/components/responses/200' '401': $ref: '#/components/responses/401' x-codeSamples: - lang: Ruby source: '$customerio = Customerio::Client.new("YOUR SITE ID", "YOUR API SECRET KEY", region: Customerio::Regions::US) // Depending on your workspace settings, the id (5) may be an email address. $customerio.unsuppress(5) ' - lang: Python (3) source: 'from customerio import CustomerIO, Regions cio = CustomerIO(site_id, api_key, region=Regions.US) // Depending on your workspace settings, customer_id may be an email address. cio.unsuppress(customer_id="5") ' /unsubscribe/{delivery_id}: parameters: - $ref: '#/components/parameters/delivery_id' post: operationId: unsubscribe summary: Custom unsubscribe handling description: 'This endpoint lets you set a global unsubscribed status outside of the subscription pathways native to Customer.io. If you use [custom unsubscribe links](/journeys/people/multiple-subscription-types), 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](#operation/identify) to update a person''s custom subscription attributes. ' tags: - Track Customers security: [] servers: - url: https://track.customer.io description: This endpoint is a part of the Track API. This endpoint does not require authorization. requestBody: content: application/json: schema: type: object properties: unsubscribe: type: boolean description: If true, a person's `unsubscribed` attribute is set to true and the unsubscription is attributed to the delivery. example: true responses: '200': $ref: '#/components/responses/200' '400': description: The `delivery_id` format is incorrect or the request is malformed. x-codeSamples: - lang: json label: JSON source: '{}' /api/v1/merge_customers: post: operationId: merge tags: - Track Customers summary: Merge duplicate people description: "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. \n\nThe primary profile must already exist in Customer.io for the merge operation to work. If the primary profile doesn't exist, your request won't do anything. \n\nIf you perform requests concurrently or in rapid succession, you could create a race condition where the primary profile doesn't exist yet. For example, if you identify a person and send a request to this endpoint immediately, the primary profile might not exist when we process your merge request.\n\nThe following information is merged into the primary profile from the secondary profile:\n* Attributes that are not set, or are empty, on the primary.\n* The most recent 30-days of event history. Events merged from the secondary person cannot trigger campaigns.\n* Manual segments that the primary person did not already belong to.\n* Message delivery history. \n* 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.\n" servers: - url: https://track.customer.io description: This endpoint is a part of the Track API. Track endpoints use basic authentication with your Site ID as the user name and your secret key as the password. security: - Tracking-API-Key: [] requestBody: content: application/json: schema: type: object description: Provide identifiers for the `primary` and `secondary` people you want to merge together. required: - primary - secondary properties: primary: description: "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. \n\nIf email is disabled as an identifier in your [workspace settings](https://fly.customer.io/workspaces/last/settings/edit), 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. \n" oneOf: - title: ID type: object maxProperties: 1 properties: id: $ref: '#/components/schemas/not_nullable_customer_id' - title: email type: object maxProperties: 1 properties: email: $ref: '#/components/schemas/not_nullable_email_address' - title: cio_id type: object maxProperties: 1 properties: cio_id: $ref: '#/components/schemas/cio_id' secondary: description: '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](https://fly.customer.io/workspaces/last/settings/edit), 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. ' oneOf: - title: ID type: object maxProperties: 1 properties: id: $ref: '#/components/schemas/not_nullable_customer_id' - title: email type: object maxProperties: 1 properties: email: $ref: '#/components/schemas/not_nullable_email_address' - title: cio_id type: object maxProperties: 1 properties: cio_id: $ref: '#/components/schemas/cio_id' example: primary: email: cool.person@company.com secondary: email: cperson@gmail.com responses: '200': $ref: '#/components/responses/200' '400': description: The request was malformed. You cannot have multiple identifiers (id, email, etc) in the `primary` or `secondary` objects. content: application/json: schema: type: object properties: meta: type: object description: Contains errors. properties: error: type: string description: Describes the error that caused your request to fail. '401': $ref: '#/components/responses/401' x-codeSamples: - lang: json label: JSON source: "{\n \"primary\": {\n \"email\": \"cool.person@company.com\"\n },\n \"secondary\": {\n \"email\": \"cperson@gmail.com\"\n }\n}" components: schemas: object_relationships: x-scalar-ignore: true type: array description: Each object in the array represents a relationship you want to add to, or remove from, a person. items: allOf: - $ref: '#/components/schemas/object_identifiers' - type: object properties: relationship_attributes: $ref: '#/components/schemas/relationship_attributes' not_nullable_customer_id: x-scalar-ignore: true type: string description: The ID of a customer profile, analogous to a "person" in the UI. example: '42' device_object: x-scalar-ignore: true description: Device properties collected by [Customer.io SDKs](/integrations/sdk/) unless `autoTrackDeviceAttributes` is disabled. You can use these properties in segments and Liquid. allOf: - type: object required: - id properties: id: description: The device token. type: string - $ref: '#/components/schemas/device_object_common' cio_id: x-scalar-ignore: true type: string description: A unique identifier set by Customer.io, used to reference a person if you want to update their identifiers. example: a3000001 v1_cio_relationships: x-scalar-ignore: true type: object description: Describes relationships to an entity—a non-person object in Customer.io, like a company, educational course, job board, etc. properties: action: type: string description: This determines whether the `relationships` array adds relationships to a person or removes them from a person. enum: - add_relationships - delete_relationships relationships: $ref: '#/components/schemas/object_relationships' object_identifiers: x-scalar-ignore: true type: object properties: identifiers: description: The identifiers for a particular object. You can use either the `object_type_id` and `object_id` (where `object_type_id` represents the type of object and the `object_id` is the individual identifier for the object) or the `cio_object_id`. oneOf: - title: Object ID type: object required: - object_type_id - object_id properties: object_type_id: $ref: '#/components/schemas/object_type_id' object_id: type: string description: The unique identifier for an object. If you use an `object_id` that already exists, we'll update the object accordingly. example: acme - title: CIO Object ID type: object required: - cio_object_id properties: cio_object_id: type: string description: A unique value that Customer.io sets for an object when you create it. This ID is immutable. example: obb7fd050101 relationship_attributes: x-scalar-ignore: true type: object description: 'The attributes associated with a relationship. Passing null or an empty string removes the attribute from the relationship. ' additionalProperties: x-additionalPropertiesName: Relationship Attributes example: role: admin device_object_common: x-scalar-ignore: true type: object description: Device information common to the v1 and v2 APIs. required: - platform properties: last_used: type: integer format: unix timestamp description: The `timestamp` when you last identified this device. If you don't pass a timestamp when you add or update a device, we use the time of the request itself. Our SDKs identify a device when a person launches their app. platform: type: string enum: - ios - android description: The device/messaging platform. attributes: type: object description: Attributes that you can reference to segment your audience—like a person's attributes, but specific to a device. These can be either the attributes defined below or custom key-value attributes. properties: device_os: type: string description: The operating system, including the version, on the device. device_model: type: string description: The model of the device a person uses. app_version: type: string description: The version of your app that a customer uses. You might target app versions to let people know when they need to update, or expose them to new features when they do. cio_sdk_version: type: string description: The version of the Customer.io SDK in the app. _last_status: type: string readOnly: true description: The delivery status of the last message sent to the device—sent, bounced, or suppressed. An empty string indicates that that the device hasn't received a push yet. enum: - '' - bounced - sent - suppressed device_locale: type: string description: The device's [IETF language code](/journeys/channels/localization/getting-started/#supported-languages), such as `en-MX` or `es-ES`. push_enabled: type: string description: If `"true"`, the device is opted-in and can receive push notifications. enum: - 'true' - 'false' additionalProperties: x-additionalPropertiesName: Custom Device Attributes description: Custom properties that you want to associate with the device. type: string object_type_id: x-scalar-ignore: true type: string description: The object type an object belongs to—like "Companies" or "Accounts". Object type IDs are string-formatted integers that begin at `1` and increment for each new type. example: '1' anonymous_id: x-scalar-ignore: true type: string description: 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. not_nullable_email_address: x-scalar-ignore: true type: string description: The email address of the customer. example: test@example.com responses: '200': description: A successful request returns an empty object response. '400': description: Invalid or malformed request. content: application/json: schema: type: object properties: meta: type: object properties: errors: type: array description: An array of errors. items: type: string description: Error descriptions. '401': description: Unauthorized request. Make sure that you provided the right credentials. parameters: device_id: name: device_id in: path required: true description: The ID of the device you want to perform an operation against. schema: type: string delivery_id: name: delivery_id description: The delivery resulting in a request to unsubscribe. in: path required: true schema: type: string track_customer_id: name: identifier required: true in: path description: '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_`. You can''t reference a person by their `phone` number here. We determine the identifier type from the shape of the value, so a phone number in the path is treated as an `id`. To identify people by phone number, use the [Track v2 API](/api/track/#tag/track_v2). ' schema: oneOf: - title: id type: string example: 12345 description: The unique identifier for a person that you want to create or modify. - title: email type: string example: person@example.com description: A person's email address. If adding a new person in an email-based workspace, you must use this value. - title: cio_id type: string format: cio_[a-zA-Z0-9]* description: 'A canonical identifier assigned by Customer.io when you add a person. When referencing a person by this value, you must prefix the value with `cio_`. You can [look up a person using the App API](#tag/Customers) to find their `cio_id`. You must use this value to update a person''s other identifiers—their `id` or `email`, unless you enable your workspace''s [Allow updates to email using ID](/accounts/workspaces#update-email-with-id) setting. ' example: cio_03000001 securitySchemes: Tracking-API-Key: type: http scheme: basic description: '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](https://fly.customer.io/settings/api_credentials). '