---
title: "Customer.io Connector"
description: "Complete Customer.io integration guide for syncing people, events, campaigns, and workflow data with Brevo via Tajo."
url: https://tajo.io/docs/connectors/marketing/customerio/
markdown: https://tajo.io/docs/connectors/marketing/customerio.md
lang: en-US
robots: noindex
---

# Customer.io Connector

Connector status: Planned Not built yet. Tajo does not run this connector today.

| Source field | Destination field | Sample value |
| --- | --- | --- |
| `record.id` | `source_id` | `record_1042` |
| `record.updated_at` | `updated_at` | `2026-10-18T08:00:00Z` |
| `record.value` | `value` | `sample_value` |

Connect your Customer.io messaging platform to Brevo for unified customer data, cross-platform campaign coordination, and consolidated engagement analytics.

## Overview

| Property | Value |
| --- | --- |
| **Platform** | Customer.io |
| **Category** | Marketing |
| **Setup Complexity** | Moderate |
| **Official Integration** | No |
| **Data Synced** | People, Events, Campaigns, Segments |
| **APIs Used** | Track API, App API, Pipelines API |
| **Authentication** | Site ID + API Key / App API Key |
| **Base URLs** | `track.customer.io`, `api.customer.io` |

## Features

- **People sync** - Bidirectional customer profile synchronization with Brevo contacts
- **Event forwarding** - Track behavioral events and forward to Brevo for automation triggers
- **Campaign analytics** - Sync campaign performance metrics for unified reporting
- **Workflow data** - Mirror Customer.io workflow states in Brevo contact attributes
- **Segment replication** - Replicate Customer.io segments as Brevo lists
- **Object data sync** - Sync non-people objects and relationship data

## Prerequisites

Before you begin, ensure you have:

1. A Customer.io account with API access
2. Your Site ID and Track API Key (found in Settings > API Credentials)
3. An App API key for reading campaign and segment data
4. A Brevo account with API access
5. A Tajo account with an active subscription

## Authentication

Customer.io uses two separate APIs with different authentication methods:

### Track API (Behavioral Data)

Used for sending people, events, and device data. Authenticates with Site ID and API Key via Basic Auth.

```bash
# Basic Auth: Site ID as username, API Key as password
curl -X POST https://track.customer.io/api/v1/customers/user123 \
  -u "$SITE_ID:$API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"email": "user@example.com"}'
```

### App API (Read Data)

Used for retrieving campaigns, segments, and customer data. Authenticates with a Bearer token.

```bash
curl -X GET https://api.customer.io/v1/campaigns \
  -H "Authorization: Bearer $APP_API_KEY"
```

API Key Separation

The Track API key and App API key are different credentials. The Track API key is used for writing data, while the App API key is for reading data. Both are required for full Tajo integration.

### Connecting to Tajo

```bash
tajo connectors install customerio \
  --site-id $CIO_SITE_ID \
  --track-api-key $CIO_TRACK_API_KEY \
  --app-api-key $CIO_APP_API_KEY
```

## Configuration

### Basic Setup

```yaml
connectors:
  customerio:
    enabled: true
    region: "us"  # or "eu" for EU data center

    sync:
      people: true
      events: true
      campaigns: true
      segments: true
      objects: false

    lists:
      all_contacts: 12
      active_subscribers: 13
      churned: 14
```

### Field Mapping

Map Customer.io person attributes to Brevo contact attributes:

```yaml
field_mapping:
  # Standard fields
  id: CIO_ID
  email: email
  first_name: FIRSTNAME
  last_name: LASTNAME
  phone: SMS

  # Engagement metrics
  created_at: SIGNUP_DATE
  last_activity: LAST_ACTIVE
  plan: PLAN_NAME

  # Custom attributes
  company: COMPANY
  role: JOB_TITLE
  mrr: MONTHLY_REVENUE
  lifecycle_stage: LIFECYCLE_STAGE
```

### Event Mapping

```yaml
event_mapping:
  # Customer.io event -> Brevo event
  purchase_completed: ORDER_PLACED
  subscription_started: SUBSCRIPTION_START
  feature_activated: FEATURE_USED
  support_ticket_opened: SUPPORT_REQUEST
```

## API Endpoints

Tajo integrates with the following Customer.io API endpoints:

| Endpoint | Method | API | Purpose |
| --- | --- | --- | --- |
| `/api/v1/customers/{id}` | PUT | Track | Create or update a person |
| `/api/v1/customers/{id}/events` | POST | Track | Track a person event |
| `/api/v1/events` | POST | Track | Track anonymous events |
| `/api/v2/entity` | POST | Track | Create or update people/objects (Pipelines) |
| `/v1/campaigns` | GET | App | List campaigns |
| `/v1/campaigns/{id}/metrics` | GET | App | Campaign performance metrics |
| `/v1/segments` | GET | App | List segments |
| `/v1/segments/{id}/membership` | GET | App | Get segment members |
| `/v1/customers/{id}/attributes` | GET | App | Get customer attributes |
| `/v1/customers/{id}/activities` | GET | App | Get customer activity log |

## Code Examples

### Initialize Connector

```javascript
import { TajoClient } from '@tajo/sdk';

const tajo = new TajoClient({
  apiKey: process.env.TAJO_API_KEY,
  brevoApiKey: process.env.BREVO_API_KEY
});

await tajo.connectors.connect('customerio', {
  siteId: process.env.CIO_SITE_ID,
  trackApiKey: process.env.CIO_TRACK_API_KEY,
  appApiKey: process.env.CIO_APP_API_KEY,
  region: 'us'
});
```

### Sync People to Brevo

```javascript
// Incremental sync of Customer.io people
await tajo.connectors.sync('customerio', {
  type: 'incremental',
  resources: ['people'],
  since: '2024-01-01',
  batchSize: 100
});

const status = await tajo.connectors.status('customerio');
console.log(status);
// {
//   connected: true,
//   lastSync: '2024-03-15T14:20:00Z',
//   peopleCount: 32500,
//   campaignsTracked: 18,
//   eventsProcessed: 87000
// }
```

### Forward Events

```javascript
// Forward Customer.io reporting webhook events to Brevo
app.post('/webhooks/customerio', async (req, res) => {
  const events = req.body;

  for (const event of events) {
    await tajo.connectors.handleEvent('customerio', {
      type: event.metric,
      payload: {
        customerId: event.data.customer_id,
        campaignId: event.data.campaign_id,
        timestamp: event.timestamp
      }
    });
  }

  res.status(200).send('OK');
});
```

### Export Segment

```javascript
const result = await tajo.connectors.exportSegment('customerio', {
  segmentId: 42,
  targetList: 13,
  includeAttributes: ['email', 'first_name', 'last_name', 'plan']
});

console.log(`Exported ${result.count} people to Brevo list 13`);
```

## Rate Limits

Customer.io enforces different rate limits per API:

| API | Rate Limit | Notes |
| --- | --- | --- |
| **Track API** | ~100 requests/second | Per workspace |
| **App API** | 10 requests/second | Per API key |
| **Pipelines API** | 100 requests/second | Recommended for bulk data |
| **Batch endpoint** | 1,000 people per request | Max payload 500KB |

Use Batch Endpoints

For large syncs, Tajo uses the Customer.io batch endpoint to send up to 1,000 people per request, significantly reducing API call volume.

## Troubleshooting

### Common Issues

| Issue | Cause | Solution |
| --- | --- | --- |
| 401 Unauthorized | Invalid Site ID or API key | Verify credentials in Customer.io Settings > API |
| People not syncing | Missing identifier | Ensure each person has an `id` or `email` |
| Events not tracked | Wrong API key type | Use Track API key for events, not App API key |
| EU data not accessible | Wrong region configured | Set region to `eu` for EU workspaces |
| Rate limit errors | Too many App API calls | Reduce polling frequency for campaign data |

### Debug Mode

```yaml
connectors:
  customerio:
    debug: true
    log_level: verbose
    log_api_calls: true
```

### Test Connection

```bash
tajo connectors test customerio
# ✓ Track API connection successful
# ✓ App API connection successful
# ✓ People accessible
# ✓ Campaigns readable
# ✓ Segments listable
```

## Best Practices

1. **Use the Pipelines API for bulk data** - The newer Pipelines API is optimized for high-volume ingestion
2. **Set up reporting webhooks** - Forward Customer.io email events to Tajo in real time
3. **Map lifecycle stages** - Sync Customer.io segment membership to Brevo attributes
4. **Use consistent identifiers** - Match `id` fields across Customer.io and Brevo
5. **Sync incrementally** - Avoid full exports; leverage `last_activity` timestamps
6. **Monitor webhook delivery** - Set up alerts for failed webhook deliveries

## Security

- **Basic Auth** - Track API authenticates with Site ID and API Key
- **Bearer Token** - App API uses OAuth-style bearer tokens
- **HTTPS Only** - All API communication encrypted via TLS 1.2+
- **Regional Data Centers** - EU data center option for GDPR compliance
- **Encrypted Storage** - All credentials encrypted at rest in Tajo
- **Webhook Signatures** - Verify webhook payloads with HMAC signatures

## Related Resources

- [Braze Connector](https://tajo.io/docs/connectors/marketing/braze)
- [Iterable Connector](https://tajo.io/docs/connectors/marketing/iterable)
- [Customer Sync Skill](https://tajo.io/docs/skills/data-sync/customer-sync)
- [Brevo Contacts API](https://tajo.io/docs/contact-management)

## Open-Source Implementation Map

No official open-source repository was found in the current Tajo connector catalog for Customer.io. Keep this page focused on the verified public API contract and vendor documentation until an official schema, SDK, MCP server, or public integration repository is available.

### Tajo Revamp Checklist

- Verify authentication and scope requirements against the vendor documentation before each connector release.
- Document primary sync objects, external IDs, pagination strategy, and rate limits explicitly.
- Add smoke tests from public API examples rather than undocumented behavior.
- Capture webhook signature verification and replay protection when the vendor supports webhooks.
- Record gaps where no official public repository or schema exists so future maintainers know what still needs source-backed validation.
