Customer.io Track Customers API
Add, modify, suppress, or unsuppress people (referred to as "customers" in our APIs). You can also use these endpoints to set attributes on people.
Add, modify, suppress, or unsuppress people (referred to as "customers" in our APIs). You can also use these endpoints to set attributes on people.
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/customer-io-track-customers-api"
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
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[<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-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_<cio_id_value>`—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_<topic ID>":<boolean>`.
type: object
properties:
topics:
type: object
description: Contains active topics in your workspace, named `topic_<id>`.
additionalProperties:
x-additionalPropertiesName: topic_<id>
description: Each property is a boolean named `topic_<id>`. 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.
<div class="fly-panel bg-warning">
<div class="fly-panel-body">
<p class="callout-head text--bold text-warning mrg-t-none"><svg class="api-icon"><path fill-rule="evenodd" clip-rule="evenodd" d="M15.4127 13.3333L9.18133 1.43333C8.95116 0.994094 8.49623 0.718884 8.00033 0.718884C7.50444 0.718884 7.04951 0.994094 6.81933 1.43333L0.587332 13.3333C0.370821 13.7467 0.386147 14.2431 0.627743 14.6423C0.869339 15.0415 1.30205 15.2854 1.76867 15.2853H14.2313C14.698 15.2854 15.1307 15.0415 15.3723 14.6423C15.6139 14.2431 15.6292 13.7467 15.4127 13.3333ZM7.33333 5.61533C7.33333 5.24714 7.63181 4.94867 8 4.94867C8.36819 4.94867 8.66667 5.24714 8.66667 5.61533V9.61533C8.66667 9.98352 8.36819 10.282 8 10.282C7.63181 10.282 7.33333 9.98352 7.33333 9.61533V5.61533ZM8.01466 13.2887H8.03333C8.29806 13.2844 8.54988 13.1735 8.73182 12.9812C8.91376 12.7888 9.01044 12.5312 9 12.2667C8.97854 11.7209 8.53019 11.2893 7.984 11.2887H7.96533C7.70125 11.2935 7.4502 11.4043 7.26865 11.5961C7.0871 11.788 6.99029 12.0447 7 12.3087C7.02073 12.8546 7.46838 13.2869 8.01466 13.2887Z" /></svg> This API permanently deletes people</p>
<div class="text-warning"><p>Suppressing a person way deletes their profile <i>and</i> 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. </p>
<p>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.</p></div>
</div>
</div>
'
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
# --- truncated at 32 KB (49 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/customer-io/refs/heads/main/openapi/customer-io-track-customers-api-openapi.yml