Customer.io

Sends person events, page views and identify calls to Customer.io’s Track API v2 entity endpoint, keyed by the Signal user_id.

Why route Customer.io through Datafly Signal

  • Profiles are updated from the server, not the browser. Events reach Customer.io even when a tracker blocker or a failed page unload would have dropped a client-side call, so the profile reflects what actually happened.
  • Presets for Retail and B2B / SaaS. The mapping starts from a working configuration for your vertical instead of a blank field map.
  • One consent decision governs every destination. Customer.io is gated by the same consent state as the rest of your stack, so a withdrawal applies everywhere at once.

Prerequisites

Find your Track API credentials

Workspace Settings > API and webhook credentials > Track API keys: copy the Site ID and API key.

Check your region

EU workspaces (fly-eu.customer.io) use track-eu.customer.io.

Configuration

FieldTypeRequiredDescription
site_idstringYesYour Customer.io Site ID (Workspace Settings > API and webhook credentials > Track API keys).
api_keysecretYesThe Track API key paired with the Site ID. Sent with it as HTTP Basic auth.
track_hostselectYesThe Track API host for your account’s region; EU workspaces must use track-eu.customer.io. Options: track.customer.io, track-eu.customer.io.

Signal Setup

  1. Navigate to Integrations in the sidebar and open the Integration Library tab.
  2. Find Customer.io, click Install and fill in the fields above.
  3. Pick the preset for your vertical, then review the mappings in the blueprint editor.
curl -X POST http://localhost:8084/v1/admin/integration-catalog/customer_io/install \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Customer.io",
    "config": {
      "site_id": "abc123def456",
      "api_key": "xxxxxxxxxxxxxxxxxxxx",
      "track_host": "track.customer.io"
    },
    "delivery_mode": "server_side"
  }'

API endpoint

POST https://{track_host}/api/v2/entity
Authorization: Basic base64(site_id:api_key)

Example body:

{"type": "person", "action": "event", "identifiers": {"id": "user-123"}, "name": "purchase",
 "timestamp": 1758500000, "attributes": {"order_id": "T-1001", "value": 439.99, "currency": "GBP"}}

The presets turn on the strict output contract: only the fields the blueprint maps are sent.

Event mapping

Retail preset (ecommerce)

Commerce events: page views, product viewed, product added, checkout started and purchase, with identify keeping the person’s email current. Sent through the Track API v2 entity endpoint, keyed by the Signal user_id as the person id (events without one are not sent). identify writes the person’s email in plain text, because Customer.io sends to it.

Signal eventSent to the vendor as
identifyidentify
pagepage
view_itemproduct_viewed
add_to_cartproduct_added
begin_checkoutcheckout_started
purchasepurchase

B2B / SaaS preset (saas)

Product lifecycle: page views, sign-up, trial start, feature used, subscription created and cancelled, with identify keeping the person’s email current. Sent through the Track API v2 entity endpoint, keyed by the Signal user_id as the person id (events without one are not sent). identify writes the person’s email in plain text, because Customer.io sends to it.

Signal eventSent to the vendor as
identifyidentify
pagepage
sign_upsigned_up
trial_startedtrial_started
feature_usedfeature_used
subscription_startedsubscription_created
subscription_cancelledsubscription_cancelled

Default preset (default)

Identify, page views, sign-up, lead and purchase. Sent through the Track API v2 entity endpoint, keyed by the Signal user_id as the person id (events without one are not sent). identify writes the person’s email in plain text, because Customer.io sends to it.

Signal eventSent to the vendor as
identifyidentify
pagepage
sign_upsigned_up
generate_leadlead_submitted
purchasepurchase

Identity and personal data

The person is identified by identifiers.id, the Signal user_id; events without one are not sent. identify() writes the person’s email (trimmed, lowercased) as an attribute: the email the identify call carries, or, when it carries none, the email Signal has stored for the person (attached as $traits.email). The email is sent in plain text: Customer.io sends to it. Page views send the page URL as the name.

Customer.io events should be sent under the marketing consent category. Customer.io maintains its own opt-in records per channel (email, SMS, push) — Signal forwards CMP consent state on every event so journey logic can suppress messaging where appropriate.

Known limitations

  • The Signal event ID is not sent: Customer.io only accepts a ULID for deduplication.
  • Anonymous (pre-login) activity is not sent; Customer.io’s Pipelines API supports it and would need a separate integration.

Troubleshooting

SymptomCause and fix
401Site ID / API key wrong, or the wrong region.
400Missing identifier, or a page view without a URL.

See also

  • Braze — multi-channel engagement alternative
  • Iterable — cross-channel marketing
  • Klaviyo — email and SMS