Integrations

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 typeWhere to add seedsComplexity
Newsletter (one-off broadcast)Create seed person with email; target by manual segment, data-centric segment, or recipient filterLow
Campaign (triggered workflow)Create seed person; fire the campaign trigger event, satisfy the segment, or set the qualifying attributeMedium
API-Triggered BroadcastCreate seed person; include the seed's segment in the recipients payload of the trigger callMedium

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:

  1. Navigate to People.
  2. Click Add People.
  3. Scroll to the bottom of the modal and click Add a single person.
  4. Set the ID (your unique identifier for this seed, for example seed-monitor-001) and the email address (the seed inbox).
  5. Optionally set an attribute like internal_test_user = true so seeds are easy to filter.
  6. Click Save.

Bulk add seeds via CSV import:

  1. Navigate to People, click Add People, then Import CSV.
  2. Upload a CSV containing at minimum an id column and an email column. Add an internal_test_user column set to true to tag seeds.
  3. Map columns to person attributes during the import wizard.
  4. Confirm the import. Customer.io creates or updates each person by id.

Add seeds to a manual segment via the UI:

  1. In Segments, create a manual segment named, for example, "Telltide seeds".
  2. Find the seed person in People (search by email or ID).
  3. Open their profile and click the Segments tab.
  4. Click the Doesn't Belong To sub-tab.
  5. Click Add to segment next to "Telltide seeds".

Include the seed segment in a Newsletter:

  1. Navigate to Broadcasts, click Create Broadcast, then Newsletter.
  2. 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.
  3. 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_customers call.
  • 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 typeDescriptionSeed approach
Event-triggeredPerson enters when a named event fires for themFire the event via Track API for the seed
Segment-triggeredPerson enters when they join a segmentAdd the seed to the trigger segment, or set attributes that put the seed into a data-centric segment
Attribute changedPerson enters when a specific attribute changes to a qualifying valueUpdate the attribute on the seed via Track or Pipelines API
Important datePerson 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_up or account_created event, or segment-triggered on "recently created people".
  • Seed requirements: id, email, person profile existing in Customer.io.

Non-technical path

  1. 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).
  2. If the campaign is segment-triggered on a manual segment, add the seed to that segment from their profile.
  3. 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.com will 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_updated or 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_completed cancels 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 to last_purchase_date.
  • Seed requirements: id, email, last_purchase_date (or last_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_date to 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", set last_purchase_date to 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_completed or 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 birthday person attribute.
  • Seed requirements: id, email, birthday person 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 birthday to today's month and day in any past year.
  • If the birthday attribute 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.

  1. Open the campaign and navigate to its Trigger configuration.
  2. Click Send test event (event-triggered campaigns).
  3. Search for the seed person.
  4. Enter the event name (must match the campaign trigger event exactly) and any data fields referenced by the journey or template.
  5. 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

  1. Find the seed person in People (search by email or ID).
  2. Open their profile and click the Segments tab.
  3. Click the Doesn't Belong To sub-tab.
  4. 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.

  1. Open the Campaign in Customer.io.
  2. Navigate to the Trigger settings.
  3. Locate the Frequency setting.
  4. Choose One time, On every event (event triggers), or Once within a time period.
  5. 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:

  1. Change frequency to On every event or Once within a time period.
  2. 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

APILimit
Track APIFair-use 100 requests per second per workspace; not a hard cutoff
Single Track request32 KB max payload size
Track Batch endpoint500 KB max payload size
Manual segment add or remove1000 IDs per request
Pipelines APISimilar fair-use model to Track
App APIApproximately 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 termWhat it means
PersonA contact or profile in Customer.io.
WorkspaceAn isolated environment for people, campaigns, and segments. Production and staging are typically separate workspaces.
CampaignAn automated triggered workflow (analogous to a Flow, Journey, or Automation in other platforms).
NewsletterA one-time broadcast email send.
API-Triggered BroadcastA broadcast started by an App API call, with recipients defined in the call.
BroadcastThe parent category covering Newsletters and API-Triggered Broadcasts.
WorkflowThe visual sequence of steps inside a campaign (emails, waits, branches, goals).
Data-centric segmentA dynamic segment whose membership is computed from attribute and event conditions.
Manual segmentA segment with explicit membership; people are added or removed by API, CSV, or UI.
Track APIStreaming API for identifying people and tracking events; also handles manual segment membership.
Pipelines APICDP-style API for identify and track; recommended for new integrations.
App APIManagement API for campaigns, broadcasts, segments, and triggering broadcasts.
cio_idCustomer.io's internally assigned unique identifier for a person. Immutable.
Important date triggerCampaign trigger that fires based on a date attribute (once, annually, or monthly).
FrequencyPer-campaign re-eligibility setting: One time, On every event, or Once within a time period.
FilterA separate gate inside the campaign (post-trigger) that drops people who do not match.
Message limitWorkspace-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