Migrating from Customer.io
If you're hitting Customer.io's pricing wall (Premium starts at $1,000/mo, the per-MAU billing scales unfavorably past 100k subscribers), tired of running workflow experiments by hand, or want one sampler across web + email + push, Apex is built for the move. This guide maps the concepts and walks the migration.
Why teams move
- A decision, not just a split. Customer.io ships split paths in workflows; you set the weights and read the result. Apex's Experiment step compares letters against the conversion you chose and waits for enough evidence to name a winner.
- Real lift number. Customer.io has no first-class global holdout; lift estimates are DIY through your own reporting. Apex ships a global holdout and a calibrated-impact dashboard per journey.
- Unified experiment engine. Website experiments, email experiments, and Journey Experiment steps share the same readiness rules and reporting. One mental model, one dashboard.
- Keep the delivery accounts you control. Email uses the sender setup you connect. Push uses your APNS/FCM credentials. Apex adds orchestration without replacing those identities.
Concept mapping
| Customer.io | Apex | Notes |
|---|---|---|
| Workspace | Workspace (workspaceKey) | Same shape. Apex workspaces nest under an Org for cross-workspace cohorts. |
| Person | End-User (endUserId) | Apex unifies on a stable per-user identity rather than per-channel destinations. |
| Segment | Segment | Segments are saved predicates over events and attributes. The migration tool emits Apex segment predicates. |
| Manual Segment | Segment (org scope) | Larger lists land as org-scope Segments referenced from a journey. |
| Campaign (manual) | Communication + one-shot Send | Most one-shot Customer.io campaigns map cleanly to a journey with a single Send step. |
| Event-Triggered Campaign | Adaptive Journey | Same shape: trigger on event, run a workflow, exit. The migration tool maps the workflow tree directly. |
| Workflow Step: Email | Send step (channel = email) | Reuses your existing comm template via the comm picker. |
| Workflow Step: Push | Send step (channel = mobile_push) | Same. |
| Workflow Step: SMS | Webhook step → Twilio destination | Apex doesn't ship SMS native; the Webhook step + your Twilio account is the BYO path. |
| Workflow Step: Wait | Wait step (duration mode) | Direct mapping. |
| Workflow Step: Wait Until Event | Wait step (until_event mode) | Wait-for-event uses Step Functions task tokens; survives across deploys. |
| Workflow Step: Branch | Branch step (On a rule) | Direct mapping. |
| Workflow Step: A/B Test | Experiment step | Compare two letters. The old Adaptive Branch authoring mode is retired. |
| Webhook Action | Webhook step | Same shape; Apex adds HMAC signing + DNS-rebinding-safe URL validation. |
| Liquid templating | LiquidJS templating | Identical syntax. Most templates port verbatim. |
| Goal Events | Journey conversion event (goalEventName) | Set on the journey rather than per-campaign. The calibrated-impact dashboard reads from this. The toolbar still says Set goal. |
What you can leave as-is
- SES: Keep your existing domain identity, IPs, and configuration sets. Apex sends through the SES account you connect.
- APNS / FCM credentials — same. Mobile push doesn't proxy through Apex's account.
- Event tracking — if you're already firing events into Customer.io via their
trackAPI, the migration is a URL swap to/api/events. Same JSON payload shape. - Liquid templates — copy-paste into Apex's comm editor. The few syntax differences (e.g. some Customer.io-specific filters) are flagged at preview time.
Migration steps
1. Export from Customer.io
Pull your workspace data via Customer.io's Track API export endpoint. The migration tool consumes:
- A JSON dump of segments + manual segments
- A JSON dump of campaigns + workflows
- A CSV of person attributes + identifiers
- (Optional) a CSV of recent event history for backfill
2. Provision the Apex workspace
Sign up at apex.inc, create your workspace, install the snippet. The snippet is the same backbone as your tracking layer — you don't need to dual-write events.
3. Translate segments
Open /dashboard/customers/segments and review the segments the migration tool translated. Each Customer.io segment becomes an Apex segment predicate. Static / manual segments become static segments.
The tool flags any segment behaviors Apex doesn't fully support yet (these are rare — Apex's predicate language is roughly a superset).
4. Translate campaigns + workflows
Each Customer.io workflow becomes an Adaptive Journey draft in Apex. Walk through each one in /dashboard/communications/journeys/[id]:
- Verify the trigger contract is wired correctly
- Walk the canvas to check step routing
- For split-tested workflow branches, add an Experiment step to compare letters. Do not look for an Adaptive Branch toggle.
- For workflows with a success event, set the conversion event in the toolbar (Set goal)
- Dry-run with a test subject to verify
5. Cut over
Recommend dual-running for 1-2 weeks:
- In Customer.io: pause the source workflow (stops new entrants but lets in-flight finish)
- In Apex: publish the equivalent journey
- Wait 1-2 weeks for Customer.io in-flight workflows to drain
- Archive the Customer.io workspace
How to translate a split test
When the migration tool encounters a Customer.io split, choose the Apex step by what the split is doing:
| Use On a rule when... | Use an Experiment step when... |
|---|---|
| Different people should follow different paths because of a known rule | You are comparing variants of the same Communication |
| Each path continues through different Journey steps | Every variant should return to the same next step |
| There is no winner to promote | A conversion event can decide which letter wins |
An Experiment starts with an even split by default. After Apex names the winner, you decide whether to apply it to the communication.
What's NOT in the migration
- Customer.io email reputation. It does not transfer. You are sending through your own SES account with your own DNS records. This is a feature: your reputation, your control.
- In-Customer.io event history. Apex starts collecting events when the snippet installs; historical events stay in your warehouse if you want them.
- Customer.io's reporting dashboards. Apex's calibrated-impact dashboard answers a different (better) question. If you need historical Customer.io metrics, export them before sunsetting the workspace.
FAQ
Does Apex support the same trigger conditions Customer.io does? All event-name + filter conditions: yes. Schedule + time-based triggers: the runtime accepts them but the UI is event-only in Phase 1; cron-style triggers land in Phase 2.
What about Customer.io's Visual Workflow Editor? Apex's canvas editor is the equivalent. Read-only canvas for published versions; drag-drop with per-step config drawer for drafts.
Can I keep Customer.io for SMS? Yes. Use Apex for email/push/in-app journeys; route SMS sends out of journeys via the Webhook step to a Twilio-or-similar destination.
How long does a typical migration take? Workspaces with 5-15 active workflows: half a day to a day. Workspaces with 50+ workflows: a couple of days because the review step is human-in-the-loop.
Get migration help
Drop us a line at migration@apex.inc with your Customer.io workspace export — we'll walk through the translated graphs and answer the cutover questions before you publish.