Customer.io Batch API

Send multiple API calls in a single request for improved performance.

Operations 1

POST /batch Batch requests #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • 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.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/customer-io-batch-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no email required.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

customer-io-batch-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  version: 1.0.0
  title: Pipelines Batch API
  description: '# Overview

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


    # Server addresses: US and EU

    Customer.io hosts services in the United States (US) and European Union. Select the appropriate server address for your region.


    | Region | Server Address |

    | :-- | :-- |

    | US | https://cdp.customer.io |

    | EU | https://cdp-eu.customer.io |


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


    # Get an API key


    1. Go to the <svg class="icon"><use href="#connection" /></svg> tab and click **Sources**.

    1. Click **Add Source**, pick **HTTP**, and click **Next**.

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

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

    1. Click **Submit**.


    Now you can use the key as a username with a blank password to authenticate and send requests to our API.


    # Authentication & rate limits


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


    Our sources are all authenticated using a **API Key** that we generate when you create a source.



    ## Rate and payload limits


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


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


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


    <div class="fly-panel fly-light regionUS">

    <div class="fly-panel-body us-server">

    <p class="text--bold">Warning</p>

    <p>Rate limits are subject to change. We may adjust these thresholds to ensure stable performance for all customers.</p>

    </div></div>


    # Try out our postman collection


    We''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**.


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


    If you fork this collection, you might want to disable the *Watch original collection* option. We automatically update our Postman collection whenever we release changes to our documentation, even if we don''t change our APIs—which happens daily! Rather than being flooded with Postman notifications, you can check out our [Release Notes](/release-notes/) for updates to our APIs.


    [<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=)


    # Deletions, suppressions, and other semantic events


    You''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*.


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


    For example, you can send a `track` event with the name `Delete Person` to remove a person from your workspace.


    See [Semantic Events](/integrations/data-in/semantic-events/cio-journeys/) to see Customer.io-specific events.


    We also support semantic events for other kinds of destinations. See [Semantic Events for other destinations](#semantic-events-for-other-destinations) below for more information.


    | Event Name | Description |

    |------|--------|

    | `Device Created or Updated` | Adds or updates a mobile device (by token), and associates it with a person |

    | `Device Deleted` | Deletes a device |

    | `User Deleted` | Removes a person from your workspace |

    | `User Suppressed` | Removes a person from your workspace and suppresses their identifiers so you can''t add them back to Customer.io. |

    | `User Unsuppressed` | Unsuppresses an identifier so you can add someone back to Customer.io and message them again. |

    | `Relationship Deleted` | Remove a relationship between a person and an object|

    | `Object Deleted` | Remove an object (like an account or company) from your Customer.io workspace|

    | `Report Delivery Event` | Report delivery events for messages|


    ## Semantic events for other destinations


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


    For example, our ecommerce events work across any ecommerce platform we integrate with—even if those ecommerce platforms have different APIs or payload structures.


    See [Semantic Events](/integrations/data-in/semantic-events/getting-started/) to learn more.


    * [A/B Test](/integrations/api/cdp/ab-test/)

    * [Ecommerce](/integrations/api/cdp/ecommerce/)

    * [Email](/integrations/api/cdp/email/)

    * [Live Chat](/integrations/api/cdp/live-chat/)

    * [Mobile App](/integrations/api/cdp/mobile-app/)

    * [Video](/integrations/api/cdp/video/)


    ## Backfilling data


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


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

    '
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.
tags:
- name: Batch
paths:
  /batch:
    post:
      operationId: batch
      summary: Batch requests
      description: 'The batch method helps you send an array of `identify`, `group`, `track`, `page` and/or `screen` requests in a single call, so you don''t have to send multiple requests. Our server-side sources use this method automatically to increase performance.


        Requests are limited to 500KB total per request and 32KB per call in the request. In a batch request, the `context` and `integrations` objects apply to _all calls in the request_. You can''t set different context or integrations values for different calls in the same request.

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

          '
        required: false
        schema:
          type: string
          enum:
          - '1'
        example: '1'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/batch'
      x-codeSamples:
      - lang: json
        label: JSON
        source: '{}'
      - lang: shell
        label: Curl
        source: "curl --request POST \\\n  --url https://cdp.customer.io/v1/batch \\\n  -u api_key: \\\n  -H 'content-type: application/json' \\\n  --data-raw '\n  {\n      \"batch\": [\n          {\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          },\n          {\n              \"type\": \"track\",\n              \"userId\": \"97980cfea0067\",\n              \"event\": \"Course Started\",\n              \"properties\": {\n                  \"title\": \"Intro to Customer.io\"\n              }\n          }\n      ]\n  }'\n"
      responses:
        '200':
          $ref: '#/components/responses/200'
      tags:
      - Batch
components:
  schemas:
    userId:
      x-scalar-ignore: true
      type: string
      description: The unique identifier for a person. This value should be unique across systems, so you recognize the same person in your sources _and_ destinations.
      example: 241ma8mf4a
    context_mobile:
      x-scalar-ignore: true
      description: A dictionary of context about a source call/event, like the user’s IP address or locale. Context is automatically collected by our source libraries.
      title: Mobile
      allOf:
      - $ref: '#/components/schemas/context_common'
      - type: object
        description: Fields included in events from mobile libraries.
        properties:
          app:
            type: object
            description: 'Contains information about the mobile app the event originated from, automatically collected by our mobile libraries when possible.

              '
            properties:
              name:
                type: string
                description: The name of the app.
              version:
                type: string
                description: The version of the app the call originated from.
              build:
                type: string
                description: The specific build number in the app.
              namespace:
                type: string
                description: The app's namespace.
          device:
            type: object
            description: 'Contains information about the device the event originated from.

              '
            properties:
              id:
                type: string
                description: The device ID.
              advertisingId:
                type: string
                description: The advertising ID is a unique, anonymous ID for advertising.
              manufacturer:
                type: string
                description: The device manufacturer.
              model:
                type: string
                description: The device model.
              name:
                type: string
                description: The device name.
              type:
                type: string
                description: The device type—android, iOS, etc.
                enum:
                - android
                - ios
              version:
                type: string
                description: The firmware version for the device.
          network:
            type: object
            description: Information about the current network connection, containing `bluetooth`, `carrier`, `cellular`, and `wifi`. If the `context.network.cellular` and `context.network.wifi` fields are empty, then the user is offline.
            properties:
              bluetooth:
                type: boolean
                description: Lets you know if bluetooth is enabled on a device.
              carrier:
                type: string
                description: The cellular carrier the phone uses.
              cellular:
                type: boolean
                description: Indicates whether the device's cellular connection is enabled or not.
              wifi:
                type: boolean
                description: Indicates whether a device's wifi connection is enabled or not.
          os:
            type: object
            description: 'Dictionary of information about the operating system, containing `name` and `version`.

              '
            properties:
              name:
                type: string
                description: The operating system running on the device.
              version:
                type: string
                description: The version of the OS running on the device.
    all_common_fields:
      x-scalar-ignore: true
      allOf:
      - $ref: '#/components/schemas/common_fields'
      - type: object
        properties:
          context:
            description: A dictionary of context about a source call/event, like the user’s IP address or locale. Context is automatically collected by our source libraries.
            oneOf:
            - $ref: '#/components/schemas/context_non_mobile'
            - $ref: '#/components/schemas/context_mobile'
    batch:
      x-scalar-ignore: true
      type: object
      properties:
        batch:
          type: array
          description: A group of requests you want to send to Data Pipelines in the call.
          items:
            anyOf:
            - title: Identify
              $ref: '#/components/schemas/identify'
            - title: Track
              oneOf:
              - title: Known User
                allOf:
                - type: object
                  required:
                  - userId
                  - event
                  - type
                  properties:
                    userId:
                      $ref: '#/components/schemas/userId'
                    type:
                      type: string
                      enum:
                      - track
                      description: The event type. This is set automatically by the request method/endpoint.
                    event:
                      type: string
                      description: The name of the event
                      example: new_account
                    properties:
                      type: object
                      description: Additional properties for your event.
                      additionalProperties:
                        x-additionalPropertiesName: Event Properties
                        description: Additional properties that you want to capture in the event. These can take any JSON shape.
              - title: Anonymous User
                allOf:
                - type: object
                  required:
                  - event
                  - type
                  properties:
                    anonymousId:
                      $ref: '#/components/schemas/anonymousId'
                    type:
                      type: string
                      enum:
                      - track
                      description: The event type. This is set automatically by the request method/endpoint.
                    event:
                      type: string
                      description: The name of the event
                      example: new_account
                    properties:
                      type: object
                      description: Additional properties for your event.
                      additionalProperties:
                        x-additionalPropertiesName: Event Properties
                        description: Additional properties that you want to capture in the event. These can take any JSON shape.
            - title: Page
              oneOf:
              - title: Known User
                allOf:
                - type: object
                  required:
                  - userId
                  - type
                  properties:
                    userId:
                      $ref: '#/components/schemas/userId'
                    type:
                      type: string
                      enum:
                      - page
                      description: The event type. This is set automatically by the request method/endpoint.
                    name:
                      type: string
                      description: The name of the page.
                      example: home
                    properties:
                      type: object
                      description: Additional properties for your event.
                      properties:
                        category:
                          type: string
                          description: The category of the page. This might be useful if you have a single page routes or have a flattened URL structure.
                      additionalProperties:
                        x-additionalPropertiesName: Page Properties
                        description: A dictionary of properties about the page.
              - title: Anonymous User
                allOf:
                - type: object
                  required:
                  - anonymousId
                  - type
                  properties:
                    anonymousId:
                      $ref: '#/components/schemas/anonymousId'
                    type:
                      type: string
                      enum:
                      - page
                      description: The event type. This is set automatically by the request method/endpoint.
                    name:
                      type: string
                      description: The name of the page.
                      example: home
                    properties:
                      type: object
                      description: Additional properties for your event.
                      properties:
                        category:
                          type: string
                          description: The category of the page. This might be useful if you have a single page routes or have a flattened URL structure.
                      additionalProperties:
                        x-additionalPropertiesName: Page Properties
                        description: A dictionary of properties about the page.
            - title: Screen
              oneOf:
              - title: Known User
                allOf:
                - type: object
                  required:
                  - userId
                  - type
                  properties:
                    userId:
                      $ref: '#/components/schemas/userId'
                    type:
                      type: string
                      enum:
                      - screen
                      description: The event type. This is set automatically by the request method/endpoint.
                    name:
                      type: string
                      description: The name of the screen the person visited.
                      example: home
                    properties:
                      type: object
                      description: Additional properties for your screen.
                      additionalProperties:
                        x-additionalPropertiesName: Screen Properties
                        description: A dictionary of properties about the screen.
              - title: Anonymous User
                allOf:
                - type: object
                  required:
                  - anonymousId
                  - type
                  properties:
                    anonymousId:
                      $ref: '#/components/schemas/anonymousId'
                    type:
                      type: string
                      enum:
                      - screen
                      description: The event type. This is set automatically by the request method/endpoint.
                    name:
                      type: string
                      description: The name of the screen the person visited.
                      example: home
                    properties:
                      type: object
                      description: Additional properties for your screen.
                      additionalProperties:
                        x-additionalPropertiesName: Screen Properties
                        description: A dictionary of properties about the screen.
            - title: Group
              oneOf:
              - title: Known User
                allOf:
                - type: object
                  required:
                  - userId
                  - groupId
                  - type
                  properties:
                    userId:
                      $ref: '#/components/schemas/userId'
                    type:
                      type: string
                      enum:
                      - group
                      description: The event type. This is set automatically by the request method/endpoint.
                      example: group
                    groupId:
                      type: string
                      description: ID of the group
                      example: 0e8c78ea9d97a7b8185e8632
                    traits:
                      type: object
                      description: Additional information about the group.
                      additionalProperties:
                        x-additionalPropertiesName: Group Traits
                        description: A dictionary of traits for the group.
                        example:
                          name: Acme
                          industry: Technology
                          road_runner_accidents: 329,
                          plan: enterprise,
                          total_billed: 830
              - title: Anonymous User
                allOf:
                - type: object
                  required:
                  - anonymousId
                  - groupId
                  - type
                  properties:
                    anonymousId:
                      $ref: '#/components/schemas/anonymousId'
                    type:
                      type: string
                      enum:
                      - group
                      description: The event type. This is set automatically by the request method/endpoint.
                      example: group
                    groupId:
                      type: string
                      description: ID of the group
                      example: 0e8c78ea9d97a7b8185e8632
                    traits:
                      type: object
                      description: Additional information about the group.
                      additionalProperties:
                        x-additionalPropertiesName: Group Traits
                        description: A dictionary of traits for the group.
                        example:
                          name: Acme
                          industry: Technology
                          road_runner_accidents: 329,
                          plan: enterprise,
                          total_billed: 830
        context:
          description: A dictionary of context about a source call/event, like the user’s IP address or locale. Context is automatically collected by our source libraries.
          oneOf:
          - $ref: '#/components/schemas/context_non_mobile'
          - $ref: '#/components/schemas/context_mobile'
        integrations:
          $ref: '#/components/schemas/integrations'
    identify:
      x-scalar-ignore: true
      oneOf:
      - title: Known User
        allOf:
        - type: object
          required:
          - userId
          properties:
            userId:
              $ref: '#/components/schemas/userId'
            anonymousId:
              $ref: '#/components/schemas/anonymousId'
            type:
              type: string
              enum:
              - identify
              description: The event type. This is set automatically by the request method/endpoint.
            traits:
              type: object
              description: Additional properties that you know about a person. We've listed some common/reserved traits below, but you can add any traits that you might use in another system.
              properties:
                email:
                  type: string
                  description: A person's email address. In some cases, you can pass an empty `userId` and we'll use this value to identify a person.
                createdAt:
                  type: string
                  format: date-time
                  description: We recommend that you pass date-time values as ISO 8601 date-time strings. We convert this value to fit destinations where appropriate.
                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>`. To update channel preferences, use `"cio_subscription_preferences.channels.<channel>":<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:
                        topic_1: true
                        topic_2: false
                    channels:
                      type: object
                      description: Contains channel subscription preferences. Keys are channel type names.
                      additionalProperties:
                        x-additionalPropertiesName: channel_type
                        description: 'Each property is a boolean keyed by the channel type name: `email`, `sms`, `push`, `in_app`, `whatsapp`, `slack`, `line`, or `inbox`. `true` means a person is subscribed to the channel; `false` means they are unsubscribed. Both the topic and channel must be subscribed for a message to send.'
                        type: boolean
                      example:
                        email: true
                        push: false
                unsubscribed:
                  description: If `true`, a person is unsubscribed from emails, SMS, WhatsApp, and push notifications (not in-app messages). Any casing of "true" (i.e. TRUE, true, tRUe, etc.), 1, or "1" means the person is unsubscribed. If `false`, absent, or any value not considered "true", a person is globally subscribed, or if you enabled a subscription center, a person will receive messages based on their `cio_subscription_preferences`.
                  type: boolean
              additionalProperties:
                x-additionalPropertiesName: Additional Traits
                description: Traits that you want to set on a person. These can take any JSON shape.
        - $ref: '#/components/schemas/all_common_fields'
      - title: Anonymous User
        allOf:
        - type: object
          required:
          - anonymousId
          properties:
            anonymousId:
              $ref: '#/components/schemas/anonymousId'
            type:
              type: string
              enum:
              - identify
              description: The event type. This is set automatically by the request method/endpoint.
            traits:
              type: object
              description: Additional properties that you know about a person. We've listed some common/reserved traits below, but you can add any traits that you might use in another system.
              properties:
                email:
                  type: string
                  description: A person's email address. In some cases, you can pass an empty `userId` and we'll use this value to identify a person.
                createdAt:
                  type: string
                  format: date-time
                  description: We recommend that you pass date-time values as ISO 8601 date-time strings. We convert this value to fit destinations where appropriate.
              additionalProperties:
                x-additionalPropertiesName: Additional Traits
                description: Traits that you want to set on a person. These can take any JSON shape.
        - $ref: '#/components/schemas/all_common_fields'
      example:
        type: identify
        traits:
          name: Cool Person
          email: cool.person@example.com
          likes_baseball: true
          games_attended: 5
        userId: 97980cfea0067
    integrations:
      x-scalar-ignore: true
      type: object
      description: 'Contains a list of booleans indicating the integrations that are enabled (true) or disabled (false). By default, all integrations are enabled (returning an empty object). Set `"All": false` to reverse this behavior.

        '
      additionalProperties:
        type: boolean
        x-additionalPropertiesName: Enabled/Disabled integrations
      example:
        All: true
        Salesforce: false
    anonymousId:
      x-scalar-ignore: true
      type: string
      description: A unique substitute for a User ID in cases when you don’t have an absolutely unique identifier. Our libraries generate this value automatically to help you track people before they sign up, log in, provide their email, etc.
      example: c0e5cae6-6f04-46e4-97a8-25076e8bdc0b
    context_common:
      x-scalar-ignore: true
      type: object
      description: Contains contextual information about the event.
      properties:
        active:
          type: boolean
          description: 'Whether a user is active.


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

            '
        ip:
          type: string
       

# --- truncated at 32 KB (37 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/customer-io/refs/heads/main/openapi/customer-io-batch-api-openapi.yml