Behavioral messaging platform
Customer.io logo

Customer.io API + MCP (2026): three APIs, one official MCP server

Customer.io has no SMTP relay and no single API key — it exposes three separate REST APIs on three hosts with three credential types, and transactional email leaves through the App API at POST /v1/send/email rather than any mail server. That split is the biggest source of integration bugs here. It is also why MCP matters more on this platform than most: Customer.io ships a first-party remote MCP server with OAuth, separate read and write scopes, and 7 tools covering the whole App API rather than a curated handful of actions.

At a glance

3
public REST APIs
Track, App and Pipelines — three hosts, three auth schemes, each with an EU twin

12
official SDKs
4 server-side, 3 Data Pipelines clients, 5 mobile and cross-platform

Official
MCP server, remote
OAuth, 7 tools, read scope by default, US and EU endpoints

MCP integration in 2026

Model Context Protocol is how an assistant such as Claude, ChatGPT or Cursor gets authenticated, structured access to a vendor API instead of guessing at endpoints. Customer.io shipped a first-party server early, and its design — generic API-shaped tools rather than a fixed catalogue of feature verbs — is what gives it full coverage.

Official remote MCP server, whole-API coverage

The first-party remote server lives at https://mcp.customer.io/mcp (EU: https://mcp-eu.customer.io/mcp), authenticated by OAuth against your normal login. Transport type is httpsse is explicitly unsupported. A connection defaults to the read scope and never exceeds the permissions of the user who authorised it.

Available MCP servers

Two endpoints are worth wiring up, for different risk profiles: the official server for analysis and workspace management, the Zapier endpoint as a narrow write-only ingestion path.

Why buyers should care

Most ESPs in 2026 have no MCP server, or expose a thin curated action set that breaks the moment you need something outside it. The cio_prime plus cio_schema pattern means the agent learns the API surface then calls it, so coverage tracks the App API as endpoints ship. Check the scope model in procurement: reads, writes and deletes are separate tools, connections default to read-only, and May 26, 2026 added toggles for live-data editing and sensitive-attribute access. Setup guides exist for Claude, ChatGPT and Cursor. Comparing shortlists? See the same section on Klaviyo, ActiveCampaign and Brevo.

Customer.io API essentials

There is no such thing as “the Customer.io API”. There are three, they do different jobs, and confusing their hosts or credentials is the most common failure mode here. Track ingests people, events and devices. The App API sends transactional messages, triggers broadcasts and manages campaigns, segments and templates. Pipelines (CDP) is a Segment-spec ingestion endpoint. Region is fixed at account creation for every workspace in the account; the dashboard is fly.customer.io in both regions and the EU data centre is in Belgium.

Track API base URLhttps://track.customer.io · EU https://track-eu.customer.io
App API base URLhttps://api.customer.io · EU https://api-eu.customer.io
Pipelines (CDP) base URLhttps://cdp.customer.io · EU https://cdp-eu.customer.io
MCP endpointhttps://mcp.customer.io/mcp · EU https://mcp-eu.customer.io/mcp
VersionsTrack v1 and v2, App v1, Pipelines unversioned (Segment spec). No dated version header
Response formatJSON on every surface
Recipients per transactional request15 total across To, CC and BCC
Region redirectsOnly track and transactional calls are redirected between regions — App management and Pipelines calls are not


Track v1 is what every official library and third-party CDP connector calls; Customer.io states v2 is not used in any of its own libraries, so /api/v2/entity and /api/v2/batch are a hand-rolled path you opt into for batching. The July 15, 2026 UI rename left endpoint names alone, so /v1/campaigns and /v1/newsletters still work.

Authentication methods

Four distinct credential types are in play. There is no unified key, and a key from one surface returns a bare 401 on another.

Track API — HTTP Basic with Site ID

Username is the Site ID, password the Track API key, both workspace-scoped. It writes people, events, devices and objects and can delete profiles — treat it as a write credential.

App API — Bearer token with scopes

Created in Account Settings under API Credentials, sent as Authorization: Bearer <App API key>. This key sends transactional email, triggers broadcasts, and reads or writes campaigns, segments, collections, exports, snippets and deliveries. Keys are scoped — mint one per integration.

Pipelines (CDP) API — HTTP Basic with a blank password

Username is the source write key, password blank. HTTP clients that drop an empty password field break here. On an unexplained 401, check the raw Authorization header: it must be base64 of writekey: including the trailing colon.

MCP server — OAuth against your login

No API key. OAuth against your Customer.io login, inheriting your role permissions, which is why read, write and delete are separate tools. Connections start read-only; live-data editing and sensitive-attribute reads are explicit toggles added May 26, 2026.

A wrong key returns a bare 401 that names nothing

Every mismatch — App API key on a Track call, Track key on a send, write key with a non-blank password — returns 401 with no indication of which credential or which host was expected. Log the target host alongside the credential name on every outbound call, and audit each host string for its -eu twin before you start swapping keys.

Rate limits

Limits are per API surface, not per account. Customer.io calls them soft — not strictly enforced, but consistently exceeding them may cause throttling or dropped data — and subject to change.

SurfaceLimitNotes
App API — standard endpoints10 requests/secondCampaigns, segments, exports, collections, deliveries
App API — transactional send3000 requests / 3 secondsSoft limit, shared with the rest of the ingress
App API — triggered broadcasts1 request / 10 secondsTightest limit on the platform — batch recipients into one trigger
Track API1000 requests/secondLive integrations and historical backfill alike
Pipelines (CDP) API3000 requests / 3 secondsPOST-only Segment-spec surface
Payload caps32 KB per entity, 500 KB per batchTrack v2 and Pipelines batch; 32 KB per contained item

There is no published per-hour email throttle: Customer.io meters monthly email allotment per plan instead, with Essentials including 1 million emails and 5k profiles. The fix for the two limits that actually bite is architectural. For API-triggered broadcasts at 1 per 10 seconds, stop calling per recipient — one trigger carries the whole audience, and per-person timing belongs in an event-triggered automation. For bulk ingestion, move off per-person Track calls onto /api/v2/batch or the Pipelines batch endpoint sized just under 500 KB. Track payload caps are enforced separately, and the 300 unique attributes per person ceiling is the one that surprises B2B teams.

Official SDKs

Customer.io maintains 12 first-party clients in three families. The four server-side clients (Python, Node, Go, Ruby) wrap both the Track API and the App API, transactional send included. The Data Pipelines clients are forks of the Segment libraries and speak only to cdp.customer.io. The five mobile SDKs cover identify and track plus push and in-app.

LanguagePackageInstallRepo
Pythoncustomeriopip install customeriocustomerio-python
Node.js / TypeScriptcustomerio-nodenpm i --save customerio-nodecustomerio-node
Gogo-customeriogo get github.com/customerio/go-customerio/v3go-customerio
Rubycustomeriogem install customeriocustomerio-ruby
JS, Python, Go (Data Pipelines)cdp-analytics-*npm i @customerio/cdp-analytics-node, pip install customerio-cdp-analytics, go get github.com/customerio/cdp-analytics-gocdp-analytics-js
Swift / iOScustomerio-iosSwift Package Manager, or CocoaPods pod 'CustomerIO'customerio-ios
Kotlin / Androidio.customer.androidGradle, coordinate and version from the READMEcustomerio-android
React Native, Flutter, Expocustomerio-reactnative, customer_io, customerio-expo-pluginnpm i customerio-reactnative, flutter pub add customer_io, npx expo install customerio-expo-plugincustomerio org

Maintenance is healthy, but pin the coordinate from the README

Staleness is not the issue: the mobile repos were pushed on August 19, 2026, the server-side clients between July 24 and July 29, 2026. Coordinates are. The Go module major version, the Android Gradle coordinate and the registry names for the Flutter and Data Pipelines packages are version-dependent — copy them from each repo README. Every server-side client takes a region argument and defaults to US.

Notable community SDKs

Community coverage is thin by design. Track and Pipelines are simple enough (Basic auth, JSON POST) that most teams call them with the HTTP client they already have, and because Pipelines follows the Segment spec, any Segment-compatible library works after a host and write-key swap — that is the de facto community SDK layer. For PHP, Java, .NET and Elixir, check last commit date and EU-host support first.

Endpoints reference

The working set. Paths are relative to their own host. Full reference and OpenAPI spec: Customer.io API documentation.

ResourceMethodsDescription
Transactional email
api › /v1/send/email
POSTSend with transactional_message_id (or inline body), to, identifiers and message_data. Returns delivery_id and queued_at.
Transactional push
api › /v1/send/push
POSTPush to a device registered against an identified profile.
Transactional SMS
api › /v1/send/sms
POSTSMS via the configured provider — Twilio, plus Sinch, Infobip and Vonage since July 30, 2026.
Transactional in-app
api › /v1/send/in_app
POSTTrigger a transactional in-app message for a profile.
Transactional inbox
api › /v1/send/inbox_message
POSTDeliver to the app notification inbox channel.
Transactional content
api › /v1/transactional/{id}/content/{content_id}
PUTUpdate the stored body of a transactional template programmatically.
Identify person, v1
track › /api/v1/customers/{identifier}
PUT, DELETECreate or update attributes, or delete the profile.
Event
track › /api/v1/customers/{identifier}/events
POSTBehavioural event on an identified person. Name max 100 bytes, data max 100,000 bytes.
Anonymous event
track › /api/v1/events
POSTEvent for an unidentified visitor, optionally with an anonymous_id for later merge.
Device
track › /api/v1/customers/{identifier}/devices
PUT, DELETERegister or remove a push token for a person.
Entity, v2
track › /api/v2/entity
POSTUnified person, object and event write endpoint. 32 KB max per request.
Batch, v2
track › /api/v2/batch
POSTBatched entity operations. 500 KB total, 32 KB per item.
Pipelines ingestion
cdp › /v1/{identify|track|page|screen|group|alias}
POSTSegment-spec ingestion. Basic auth, write key as username, blank password. POST-only.
Pipelines batch
cdp › /v1/batch
POSTBatched Segment-spec calls. 500 KB total, 32 KB per call.
Workspace management
api › /v1/{broadcasts|campaigns|segments|customers|collections|exports|sender_identities|snippets|activities|messages|newsletters}
GET, POST, PUT, DELETEJourneys management surface: API-triggered broadcasts (1 per 10 seconds), newsletter create and send (April 14, 2026), Design Studio endpoints (March 18, 2026).

Code examples

Send a transactional email with raw REST

The canonical call. The Bearer header carries the App API key, not the Track API key — swapping them returns 401 with no explanation.

curl --request POST https://api.customer.io/v1/send/email
  --header 'Authorization: Bearer YOUR_APP_API_KEY'
  --header 'Content-Type: application/json'
  --data '{
    "transactional_message_id": "3",
    "to": "person@example.com",
    "identifiers": { "email": "person@example.com" },
    "message_data": { "name": "Person", "order_total": "59.99" }
  }'

# 200 -> { "delivery_id": "...", "queued_at": 1755561600 }
# EU: https://api-eu.customer.io/v1/send/email

Python — transactional send plus ingestion

One package, two clients, two credentials: APIClient is the App API, CustomerIO the Track API.

# pip install customerio
from customerio import APIClient, CustomerIO, Regions, SendEmailRequest

client = APIClient("YOUR_APP_API_KEY", region=Regions.US)  # Regions.EU -> api-eu.customer.io

request = SendEmailRequest(
    to="person@example.com",
    transactional_message_id="3",
    identifiers={"email": "person@example.com"},
    message_data={"name": "person", "order_total": "59.99"},
)

with open("receipt.pdf", "rb") as f:
    request.attach("receipt.pdf", f.read())  # attachments under 2 MB combined

print(client.send_email(request))  # -> {'delivery_id': '...', 'queued_at': ...}

# Ingestion: different API, different credentials
cio = CustomerIO("SITE_ID", "TRACK_API_KEY", region=Regions.US)  # track.customer.io
cio.identify(id="user-123", email="person@example.com", plan="pro")

Connect an assistant to the MCP server

Transport must be http; sse is unsupported. Auth is OAuth in the browser on first connect, so no key lands in the config file.

{
  "mcpServers": {
    "customer-io": {
      "type": "http",
      "url": "https://mcp.customer.io/mcp"
    }
  }
}

// EU workspaces MUST use https://mcp-eu.customer.io/mcp
// Call cio_prime, then cio_schema, before any read or write.

Common gotchas

No SMTP relay exists, and the docs page named “Use Your Own SMTP Server” means the opposite

Customer.io exposes no SMTP ingress, so you cannot point WP Mail SMTP, Laravel, Django or an appliance at it. The only SMTP feature is outbound: Customer.io connecting as a client to your server. Port 25 is refused — 465, 587 or 2525 are the alternatives, and they are your provider ports. With custom SMTP on, bounce and delivery data stop reaching Deliveries unless your provider is Mailgun, Mailjet, Mandrill, Postmark, SendGrid or SparkPost with feedback configured, and domain authentication stops being automatic.

Region is permanent, and only two APIs auto-redirect

US or EU is chosen at account creation for every workspace in the account, and Customer.io does not support data centre migrations except in extenuating circumstances. Because only track and transactional calls redirect, a hardcoded US host in an EU integration fails silently on management and Pipelines calls rather than erroring on day one. Geolocation collection also defaults on in the US and off in the EU.

Billing counts profiles, and objects are profiles

Essentials starts at $100 per month for 5k profiles — people and objects. Accounts, companies, devices and custom objects consume the same allowance as human contacts, so 5,000 people plus 3,000 accounts is 8,000 profiles. Transactional email is not a separate SKU and eats the same email allowance, with one documented escape hatch: sends through your own custom SMTP server do not count against the plan allotment, at the price of losing delivery reporting.

Transactional hard caps, and the rename that skipped the API

A single transactional request caps at 15 recipients across To, CC and BCC, with all attachments under 2 MB and executable-adjacent extensions (bat, com, exe, msi, vbs, scr and more) blocked. The July 15, 2026 rename left API paths untouched, so a runbook or LLM prompt written in the new vocabulary will not match /v1/campaigns. And “disable message retention” stops Customer.io storing message bodies — right for password-reset tokens, wrong for anything you need to debug.

Deprecations and changelog

  • August 18, 2026 — Customer.io AI in Slack: the agent answers @Customer.io mentions. A distinct surface from the MCP server, not a replacement.
  • August 6, 2026 — Automation rate limiting by channel, plus a step that holds a profile until the message is actually delivered.
  • July 30, 2026 — SMS provider flexibility: Sinch, Infobip and Vonage joined Twilio behind /v1/send/sms.
  • July 15, 2026 — UI terminology change (Campaigns to Automations, People to Profiles, Newsletters to One-time sends) with API endpoint names deliberately unchanged.
  • May 26, 2026 — MCP connection security toggles: control whether a connection may edit live data and whether it may read sensitive profile attributes.
  • March 18, 2026 — Design Studio API endpoints for programmatic creation, update and deletion of emails, components and assets.

No endpoint deprecations landed in this window — the July rename is cosmetic at the API layer. Track the source in the official Customer.io release notes.

Frequently asked questions

What is the Customer.io API base URL, and why are there three of them?

Three products, one brand. track.customer.io ingests people, events and devices. api.customer.io is the App API: transactional sends, broadcast triggers, campaign and segment management. cdp.customer.io is the Data Pipelines endpoint. Each has an EU twin, and only track and transactional calls auto-redirect between regions.

How do I send a transactional email with the Customer.io API?

POST https://api.customer.io/v1/send/email with Authorization: Bearer <App API key> and a body of transactional_message_id, to, identifiers and message_data. A 200 returns delivery_id and queued_at. Caps: 15 recipients across To, CC and BCC, under 2 MB of attachments. There is no SMTP alternative.

Track API key, App API key or Pipelines write key — which do I need?

Depends on the verb. Writing people or events: Track API key, HTTP Basic with your Site ID as username. Sending messages or managing campaigns and segments: App API key, a scoped Bearer token. Feeding Data Pipelines: the source write key as Basic username with a blank password. None is interchangeable, and a wrong key returns a bare 401.

What are the Customer.io API rate limits?

Per surface: App API standard endpoints 10 req/s, transactional sends 3000 per 3 seconds, API-triggered broadcasts 1 per 10 seconds, Track API 1000 req/s, Pipelines 3000 per 3 seconds. Batch payloads cap at 500 KB total, 32 KB per item. Customer.io calls these soft limits but warns that consistently exceeding them may cause throttling or dropped data.

Does Customer.io have an official MCP server, and how do I connect Claude to it?

Yes — a first-party remote server at https://mcp.customer.io/mcp (EU: https://mcp-eu.customer.io/mcp). Add it as an HTTP MCP server; transport must be http, since sse is unsupported. Auth is OAuth against your Customer.io login, so no API key goes in the config and the connection cannot exceed your role permissions. Seven tools, led by cio_prime and cio_schema, with reads, writes and deletes split apart.

Which official SDKs exist and how do I set the EU region in them?

Twelve: Python, Node, Go and Ruby server-side; three Data Pipelines analytics clients (JS, Python, Go); and iOS, Android, React Native, Flutter and Expo on mobile. Region is a constructor argument that defaults to USregion=Regions.EU in Python, { region: RegionEU } in Node. Forgetting it is the most common EU-workspace bug: track and transactional calls still appear to work while management calls fail.

Changelog (recent)

  • 2026-08-18 Customer.io AI in Slack: the agent answers @Customer.io mentions, a surface distinct from the MCP server.
  • 2026-08-06 Automation rate limiting by channel, plus a step that holds a profile until the message is actually delivered.
  • 2026-07-30 SMS provider flexibility: Sinch, Infobip and Vonage joined Twilio behind POST /v1/send/sms.
AAlaa Touil RRabeb How we test →

This review follows our email infrastructure testing methodology. We disclose affiliate relationships in our editorial independence policy.