Customer.io: Telltide Seed Address Guide
Place Telltide seeds in Customer.io segments and campaigns.
Customer.io uses two separate identifiers for each person: an id (your system's identifier) and an email. The platform exposes three API surfaces relevant to seed management: the Track API for identifying people and firing events, the Pipelines (CDP) API for newer integrations using an Identify/Track spec, and the App API for managing campaigns, segments, and triggering API broadcasts. For seed management, the Track API or Pipelines API creates and updates people; the App API triggers API broadcasts.
Quick reference
| Send type | Where to add seeds | Complexity |
|---|---|---|
| Newsletter (one-off broadcast) | Create seed person with email; target by manual segment, data-centric segment, or recipient filter | Low |
| Campaign (triggered workflow) | Create seed person; fire the campaign trigger event, satisfy the segment, or set the qualifying attribute | Medium |
| API-Triggered Broadcast | Create seed person; include the seed's segment in the recipients payload of the trigger call | Medium |
1. Scheduled / one-off sends (Newsletters)
Customer.io Newsletters are one-time broadcast emails sent to a defined audience. The audience can be everyone in the workspace, a manual segment, a data-centric segment, an uploaded CSV, or a recipient filter built from attribute and segment conditions.
Where to add seed addresses
Create a seed person profile in Customer.io, then target them by including the seed's manual segment in the Newsletter recipients, or by adding a recipient filter that the seed satisfies.
Non-technical path
For CRM managers working entirely in the Customer.io UI, no code required.
Add a single seed via the People UI:
- Navigate to People.
- Click Add People.
- Scroll to the bottom of the modal and click Add a single person.
- Set the ID (your unique identifier for this seed, for example
seed-monitor-001) and the email address (the seed inbox). - Optionally set an attribute like
internal_test_user = trueso seeds are easy to filter. - Click Save.
Bulk add seeds via CSV import:
- Navigate to People, click Add People, then Import CSV.
- Upload a CSV containing at minimum an
idcolumn and anemailcolumn. Add aninternal_test_usercolumn set totrueto tag seeds. - Map columns to person attributes during the import wizard.
- Confirm the import. Customer.io creates or updates each person by
id.
Add seeds to a manual segment via the UI:
- In Segments, create a manual segment named, for example, "Telltide seeds".
- Find the seed person in People (search by email or ID).
- Open their profile and click the Segments tab.
- Click the Doesn't Belong To sub-tab.
- Click Add to segment next to "Telltide seeds".
Include the seed segment in a Newsletter:
- Navigate to Broadcasts, click Create Broadcast, then Newsletter.
- In the Recipients step, choose Send to people matching conditions and add a condition such as
member of segment "Telltide seeds", or pick the segment directly. - Complete content and schedule or send.
Technical path
For programmatic seed management.
Create or update a seed person via Track API:
PUT https://track.customer.io/api/v1/customers/seed-monitor-001
Authorization: Basic {{base64(site_id:api_key)}}
Content-Type: application/json
{
"email": "seed@example.com",
"first_name": "Seed",
"last_name": "Monitor",
"internal_test_user": true,
"created_at": 1744732800
}
The path segment after /customers/ is the person's id. If the ID does not exist, Customer.io creates a new person; if it does, the profile is updated. Single Track requests must be smaller than 32 KB.
Create or update a seed person via Pipelines (CDP) API:
POST https://cdp.customer.io/v1/identify
Authorization: Basic {{base64(pipelines_api_key:)}}
Content-Type: application/json
{
"userId": "seed-monitor-001",
"traits": {
"email": "seed@example.com",
"firstName": "Seed",
"lastName": "Monitor",
"internalTestUser": true,
"createdAt": "2026-04-15T00:00:00Z"
}
}
The Pipelines API is the recommended surface for new integrations.
Add the seed to a manual segment via Track API:
POST https://track.customer.io/api/v1/segments/{segment_id}/add_customers
Authorization: Basic {{base64(site_id:api_key)}}
Content-Type: application/json
{
"ids": ["seed-monitor-001"]
}
You can pass an id_type query parameter set to id, email, or cio_id to choose how the IDs in the body are resolved. The default is id. Up to 1000 IDs per request.
Trigger an API-Triggered Broadcast scoped to the seed segment via App API:
POST https://api.customer.io/v1/campaigns/{broadcast_id}/triggers
Authorization: Bearer {{app_api_key}}
Content-Type: application/json
{
"recipients": {
"segment": { "id": 123 }
},
"data": {
"subject_override": "Telltide monitor"
}
}
When recipients is supplied in the API call, it overrides any UI-defined recipients on the broadcast.
Always-on flow coverage
Newsletters are one-shot, but a seed must still satisfy the configured recipient definition for that send.
- If the Newsletter targets a data-centric segment (for example,
subscribed_to_marketing is true AND country is US), set those exact attributes on the seed person so they are inside the segment when the Newsletter is sent. - If the Newsletter targets a manual segment, ensure the seed has been added to that manual segment via the UI, CSV upload, or
add_customerscall. - If the Newsletter is sent to everyone or to a broad recipient filter, no extra step is needed beyond creating the seed person with a valid email.
- If your team uses a separate "production audience only" segment as the Newsletter target, mirror that segment's conditions on the seed (for example, set
subscribed_to_marketing = true) or add the seed to that segment manually. - The subscription status on the seed must include the channel and topic the Newsletter is sending on. A seed that is unsubscribed at the channel level, or not opted in to the topic the Newsletter targets, is skipped.
Profile attributes required
Seeds need:
id(your unique identifier).email(the seed inbox address).- Any person attributes referenced in the email template via Liquid (for example
{{ customer.first_name }}). - Any attributes referenced by the recipient filter (for example
country,subscribed_to_marketing).
Ensuring seeds receive the same version as real recipients
Customer.io Newsletters do not have built-in A/B variant testing at the Newsletter level in the same way Campaigns do. The seed receives the same content as all other recipients selected by the Newsletter's audience.
Gotchas
Unsubscribed people: If the seed person is marked as unsubscribed (channel-level opt-out) or has not opted in to the relevant subscription topic, they will not receive the Newsletter. Avoid testing unsubscribe flows with seed addresses. Check the person's subscription status in their profile.
Message limits: If your workspace has a message limit configured (Settings > Workspace Settings > Message limit) and the Newsletter has "Count toward message limit" enabled, the seed may be blocked after hitting the cap. Either exempt the monitoring Newsletter from the limit or raise the cap for seed IDs.
2. Ongoing / automated journeys (Campaigns)
Customer.io Campaigns are triggered automation workflows. The trigger determines when a person enters the campaign and begins traversing the journey. Once inside, the person can be filtered out, branched, or held by Wait Until / Time Window steps.
Campaign trigger types
| Trigger type | Description | Seed approach |
|---|---|---|
| Event-triggered | Person enters when a named event fires for them | Fire the event via Track API for the seed |
| Segment-triggered | Person enters when they join a segment | Add the seed to the trigger segment, or set attributes that put the seed into a data-centric segment |
| Attribute changed | Person enters when a specific attribute changes to a qualifying value | Update the attribute on the seed via Track or Pipelines API |
| Important date | Person enters on or around a date attribute (annually, monthly, or once) | Set the date attribute on the seed person |
Frequency settings
Customer.io exposes campaign frequency on the trigger configuration. Available options:
- One time (default): the person can enter only once.
- On every event (event-triggered campaigns only): the person re-enters every time the event fires.
- Once within a time period: the person can re-enter, but only after the specified window has passed.
For seed monitoring you almost always want On every event (event triggers) or Once within a time period with a window shorter than your monitoring cadence (segment, attribute, or date triggers), so the seed can re-enter on each cycle without manual reset.
Creating seed profiles per journey type
Welcome / onboarding
- Trigger: event-triggered on a
signed_uporaccount_createdevent, or segment-triggered on "recently created people". - Seed requirements:
id,email, person profile existing in Customer.io.
Non-technical path
- Create the seed in People with the same shape your real signups have (set the same attributes your welcome filter checks, for example
subscribed_to_marketing = true). - If the campaign is segment-triggered on a manual segment, add the seed to that segment from their profile.
- Use the campaign's Send test event dialog (event triggers) to fire the trigger with the seed selected as the test person.
Technical path
POST https://track.customer.io/api/v1/customers/seed-monitor-001/events
Authorization: Basic {{base64(site_id:api_key)}}
Content-Type: application/json
{
"name": "signed_up",
"data": {
"signup_source": "web",
"plan": "pro"
}
}
For attribute-based or date-based triggers, set the qualifying attribute (for example a recent created_at) when you identify the seed.
Always-on flow coverage
- Confirm the campaign Filter (separate from the trigger) does not exclude seeds. Filters such as
email is not contains @example.comwill silently drop seeds. - Set the campaign Frequency to On every event or Once within a time period matching your monitoring cadence. The default One time value will block re-entry after the first cycle.
- If the campaign is segment-triggered, the seed only enters on transition into the segment. Removing and re-adding the seed to the segment is the way to re-trigger.
Abandoned cart
- Trigger: event-triggered on a
cart_updatedor custom cart abandonment event. - Seed requirements:
id,email, event fired with cart data properties referenced by the email template.
Technical path
POST https://track.customer.io/api/v1/customers/seed-monitor-001/events
{
"name": "cart_updated",
"data": {
"cart_id": "CART-TEST-001",
"cart_total": 215.00,
"currency": "USD",
"items": [
{
"product_id": "SKU-123",
"name": "Widget Pro",
"price": 99.00,
"quantity": 2,
"image_url": "https://example.com/img/widget.jpg",
"product_url": "https://example.com/products/widget"
}
],
"cart_url": "https://yourstore.com/cart"
}
}
Always-on flow coverage
- The campaign typically has a Wait Until or delay step, then a goal check (for example
purchase_completedcancels the journey). To make the seed receive the email, do not fire the goal event for the seed during the wait window. - Set Frequency to On every event so the seed retriggers on each monitoring cycle.
- Cart event data is exposed to Liquid in the email (for example
{{ event.data.cart_total }}). Make sure your seed event payload includes every field the template references, otherwise Liquid renders empty strings and the message can look broken.
Browse abandonment
- Trigger: event-triggered on a page view or product view event.
- Seed requirements:
id,email.
Technical path
POST https://track.customer.io/api/v1/customers/seed-monitor-001/events
{
"name": "page_viewed",
"data": {
"product_id": "SKU-123",
"product_name": "Widget Pro",
"category": "Electronics",
"url": "https://yourstore.com/products/widget",
"price": 49.99
}
}
If your stack uses Customer.io's in-app JavaScript tracker, cio.page() fires the equivalent event from the browser.
Always-on flow coverage
- The campaign normally waits, then exits if a purchase or cart event occurs. Fire only the trigger event for the seed; do not fire goal events during the wait.
- Set Frequency to On every event.
Winback / re-engagement
- Trigger: segment-triggered on a "lapsed" data-centric segment (for example
last_purchase_date is before 90 days ago), or Important date trigger relative tolast_purchase_date. - Seed requirements:
id,email,last_purchase_date(orlast_seen) attribute set so the seed satisfies the segment or date condition.
Technical path
PUT https://track.customer.io/api/v1/customers/seed-monitor-001
{
"last_purchase_date": 1735689600
}
Unix timestamp format (seconds since epoch). 1735689600 is approximately January 1, 2025.
Always-on flow coverage
- Segment-triggered campaigns enter the seed only at the moment they join the segment. To re-trigger, set the seed's
last_purchase_dateto a value that pulls them out of the segment, then back to a lapsed value to re-enter. - For an Important date trigger configured as "30 days after
last_purchase_date", setlast_purchase_dateto exactly 30 days ago for each monitoring cycle. - Set Frequency to Once within a time period with a window shorter than your monitoring cadence.
Post-purchase
- Trigger: event-triggered on
purchase_completedor equivalent order event. - Seed requirements:
id,email.
Technical path
POST https://track.customer.io/api/v1/customers/seed-monitor-001/events
{
"name": "purchase_completed",
"data": {
"order_id": "TEST-ORD-001",
"total": 149.99,
"currency": "USD",
"items": [
{
"product_id": "SKU-123",
"name": "Widget Pro",
"quantity": 1,
"price": 149.99
}
],
"customer_name": "Seed Monitor"
}
}
Always-on flow coverage
- Set Frequency to On every event.
- If the post-purchase campaign has a filter such as
total > 0, ensure the seed event satisfies it.
Birthday / anniversary
- Trigger: Important date trigger set to "Every year" on the
birthdayperson attribute. - Seed requirements:
id,email,birthdayperson attribute in ISO 8601 or Unix timestamp format.
Technical path
PUT https://track.customer.io/api/v1/customers/seed-monitor-001
{
"birthday": "1990-04-15T00:00:00Z"
}
Always-on flow coverage
- Important date triggers fire on the month and day stored (year ignored for "Every year" frequency). To force a fire today, set the seed's
birthdayto today's month and day in any past year. - If the
birthdayattribute is not set or is not a valid date, the seed is silently skipped.
Triggering test events via the Customer.io UI
Customer.io provides a UI mechanism to fire events for testing.
- Open the campaign and navigate to its Trigger configuration.
- Click Send test event (event-triggered campaigns).
- Search for the seed person.
- Enter the event name (must match the campaign trigger event exactly) and any data fields referenced by the journey or template.
- Click Send event.
This fires the event for the selected seed and immediately evaluates whether they qualify to enter the campaign.
How to add a seed to a manual segment
Manual segments give you direct control over membership.
Non-technical path
- Find the seed person in People (search by email or ID).
- Open their profile and click the Segments tab.
- Click the Doesn't Belong To sub-tab.
- Click Add to segment next to the target manual segment.
CSV upload is also supported on the manual segment's Members view.
Technical path
Manual segment membership is managed through the Track API, not the App API.
POST https://track.customer.io/api/v1/segments/{segment_id}/add_customers
Authorization: Basic {{base64(site_id:api_key)}}
Content-Type: application/json
{
"ids": ["seed-monitor-001"]
}
To remove:
POST https://track.customer.io/api/v1/segments/{segment_id}/remove_customers
{
"ids": ["seed-monitor-001"]
}
Up to 1000 IDs per request. Pass ?id_type=email or ?id_type=cio_id to resolve by email or cio_id instead of id.
How to change campaign re-eligibility settings
Frequency lives on the campaign's trigger configuration.
- Open the Campaign in Customer.io.
- Navigate to the Trigger settings.
- Locate the Frequency setting.
- Choose One time, On every event (event triggers), or Once within a time period.
- Save.
For event-triggered campaigns used as monitoring targets, set On every event so the seed re-enters on each cycle by firing the trigger event again.
How to reset seeds for repeated testing
Event-triggered campaigns set to On every event: fire the event again. No reset needed.
Event-triggered campaigns set to One time: to re-trigger, either:
- Change frequency to On every event or Once within a time period.
- Delete and recreate the seed person with a new
id.
Segment-triggered campaigns: remove the seed from the trigger segment (or change attributes so they leave a data-centric segment), wait for Customer.io to register the exit, then re-add.
Attribute-changed triggers: set the qualifying attribute back to a non-qualifying value, then back to the qualifying value to fire the change again.
Delete and recreate approach:
DELETE https://track.customer.io/api/v1/customers/seed-monitor-001
Then recreate with the same or new id. The old profile and all its event history are permanently deleted.
3. Platform-specific considerations
API options
Track API: create or update person
PUT https://track.customer.io/api/v1/customers/{id}
Authorization: Basic {{base64(site_id:api_key)}}
Track API: fire event for person
POST https://track.customer.io/api/v1/customers/{id}/events
Track API: delete person
DELETE https://track.customer.io/api/v1/customers/{id}
Track API: add to manual segment
POST https://track.customer.io/api/v1/segments/{segment_id}/add_customers
Track API: remove from manual segment
POST https://track.customer.io/api/v1/segments/{segment_id}/remove_customers
Pipelines API: identify (recommended for new integrations)
POST https://cdp.customer.io/v1/identify
Authorization: Basic {{base64(pipelines_api_key:)}}
Pipelines API: track event
POST https://cdp.customer.io/v1/track
App API: trigger an API-Triggered Broadcast
POST https://api.customer.io/v1/campaigns/{broadcast_id}/triggers
Authorization: Bearer {{app_api_key}}
API credentials location: Settings > API Credentials. Three separate credential types: Track API (Site ID + API key, basic auth), Pipelines API key (basic auth, password empty), App API key (bearer auth).
EU region API bases:
- Track:
https://track-eu.customer.io/api/v1/ - Pipelines:
https://cdp-eu.customer.io/v1/ - App:
https://api-eu.customer.io/v1/
If your account is in the EU region, always call the -eu hosts. Calls to the US hosts may be redirected but data passes through US infrastructure on the way.
Rate limits
| API | Limit |
|---|---|
| Track API | Fair-use 100 requests per second per workspace; not a hard cutoff |
| Single Track request | 32 KB max payload size |
| Track Batch endpoint | 500 KB max payload size |
| Manual segment add or remove | 1000 IDs per request |
| Pipelines API | Similar fair-use model to Track |
| App API | Approximately 10 requests per second on most endpoints |
Implement retry with exponential backoff. Treat 5xx and connection errors on Track and Pipelines as rate pressure even when no 429 is returned. App API does return 429 when its tighter limit is exceeded.
Duplicate contact handling
Customer.io identifies people by up to three fields: id, email, and cio_id (assigned by Customer.io). When PUT /customers/{id} is called with an existing id, the profile is updated, not duplicated.
If your workspace is configured to identify people by email, Customer.io will merge profiles with the same email address.
Multi-identifier merge: enable in Settings > Workspace Settings > Merge Settings to automatically reconcile duplicates.
Manual merge: from a person's profile, use the Merge option. Irreversible once started.
For seeds: use a stable id value (for example seed-monitor-001) per seed inbox. Calling PUT /customers/seed-monitor-001 always updates the same profile.
Platform-specific terminology
| Customer.io term | What it means |
|---|---|
| Person | A contact or profile in Customer.io. |
| Workspace | An isolated environment for people, campaigns, and segments. Production and staging are typically separate workspaces. |
| Campaign | An automated triggered workflow (analogous to a Flow, Journey, or Automation in other platforms). |
| Newsletter | A one-time broadcast email send. |
| API-Triggered Broadcast | A broadcast started by an App API call, with recipients defined in the call. |
| Broadcast | The parent category covering Newsletters and API-Triggered Broadcasts. |
| Workflow | The visual sequence of steps inside a campaign (emails, waits, branches, goals). |
| Data-centric segment | A dynamic segment whose membership is computed from attribute and event conditions. |
| Manual segment | A segment with explicit membership; people are added or removed by API, CSV, or UI. |
| Track API | Streaming API for identifying people and tracking events; also handles manual segment membership. |
| Pipelines API | CDP-style API for identify and track; recommended for new integrations. |
| App API | Management API for campaigns, broadcasts, segments, and triggering broadcasts. |
cio_id | Customer.io's internally assigned unique identifier for a person. Immutable. |
| Important date trigger | Campaign trigger that fires based on a date attribute (once, annually, or monthly). |
| Frequency | Per-campaign re-eligibility setting: One time, On every event, or Once within a time period. |
| Filter | A separate gate inside the campaign (post-trigger) that drops people who do not match. |
| Message limit | Workspace-level cap on messages per person per time window. Optional; must be enabled per campaign. |
Known limitations and workarounds
Three API surfaces for full automation. Track for people and events, Pipelines as the modern alternative, App for campaigns and broadcast triggers. Manual segment add or remove lives on the Track API. Plan credentials accordingly.
Default Frequency is One time. Event-triggered campaigns at default Frequency cannot be re-triggered without profile deletion or ID change. Switch to On every event or Once within a time period for any campaign you need to monitor continuously.
Date attributes must be ISO 8601 or Unix timestamps. Strings such as "April 15, 1990" are not parsed. Use "1990-04-15T00:00:00Z" or 1234567890.
Manual segment addition requires the person to exist first. Always call identify before add_customers.
Filters are evaluated separately from triggers. A seed can satisfy the trigger but be silently dropped by a campaign Filter (for example a domain exclusion). Audit filters when seeds enter but never receive messages.
Message limits are not applied by default. The workspace message limit exists but individual campaigns must opt in to "Count toward message limit". If seeds stop receiving mid-journey, check whether limits are configured and applying.
Subscription topics gate sends. A seed must be subscribed to the topic (and channel) used by the campaign or Newsletter, or the message is suppressed at delivery time.
Start monitoring your Customer.io sends
Place a Telltide seed in your Customer.io audience, and we will tell you when an expected email did not land.
Start free