Migrating from Iterable
Iterable is a serious enterprise lifecycle platform. The reasons teams move are usually:
- Cost. Iterable starts at ~$2,000/mo and scales steeply with MAU. Apex's per-MAU pricing is roughly 50-70% lower at the same volume tiers.
- Control of delivery. Apex uses the sender domain and push credentials you connect, so those identities remain yours.
- Unified experiments. Website experiments, email experiments, and Journey Experiment steps use the same readiness rules and reporting.
- Tighter calibrated-impact integration. Iterable's Send-Time Optimization and Predictive Goals are advanced; the explicit holdout-vs-exposed lift dashboard is uniquely Apex's.
If you're using Iterable for the Workflows product, this is the migration path. If you're using Iterable Push or Iterable Embedded — same path; channels are first-class in Apex.
Concept mapping
| Iterable | Apex | Notes |
|---|---|---|
| Workspace | Workspace (workspaceKey) | Same shape. Apex workspaces nest under an Org for cross-workspace cohorts. |
| User Profile | End-User (endUserId) | Apex unifies on a stable per-user identity rather than Iterable's email-as-primary-key model. |
| Lists (Static) | Segment (org scope) | Org-scope Segments referenced from a journey. |
| Segments (Dynamic) | Segment | Predicates over events + attributes + other Segments. |
| Workflow | Adaptive Journey | Same shape. The migration tool maps the workflow tree directly. |
| Workflow Trigger: Event | Trigger step (event mode) | Direct mapping. |
| Workflow Trigger: API | Trigger step + transactional API call | The journey trigger remains; just call /api/events from your backend instead of Iterable's API. |
| Workflow Trigger: List | Segment-entry trigger | Pick Segment entry, then choose the Segment. |
| Workflow Step: Wait | Wait step (duration mode) | Direct mapping. |
| Workflow Step: Wait Until Event | Wait step (until_event mode) | Step Functions task tokens; survives across deploys. |
| Workflow Step: Yes/No Split | Branch step (conditional, single condition) | Direct mapping. |
| Workflow Step: Multivariate Split | Branch step (conditional, multiple conditions) | Direct mapping. |
| Workflow Step: Experiment | Experiment step | Compare letters against one conversion. After Apex names the winner, you decide whether to apply it. |
| Workflow Step: Send | Send step | Reuses your existing comm template via the comm picker. |
| Workflow Step: Push / SMS / Embedded | Send step (channel = mobile_push / webhook / in_app) | Apex SMS via the Webhook step + Twilio; everything else is native. |
| Workflow Step: Webhook | Webhook step | HMAC + DNS-rebinding-safe URL validation included. |
| Workflow Step: Update User | Webhook → /api/events | Or direct via the SDK — Apex's user updates are events, not workflow steps. |
| Predictive Goals | Journey conversion event (goalEventName) | Set per-journey (toolbar still says Set goal). Calibrated impact reads from this. |
| Holdout Group (per-workflow) | Global Holdout | Iterable's per-workflow holdouts compose poorly when workflows overlap. Apex's global holdout gives every journey the same control group — a cleaner statistical contract. |
| Send-Time Optimization | Wait + Branch (On engagement) | STO maps to a Wait, then a Branch on who engaged. Manual but explicit. |
What you can leave as-is
- SES / IP pool: Apex sends through the SES account you connect. If you already use SES under Iterable's hood, this transfers cleanly.
- APNS / FCM credentials — same; mobile push doesn't proxy through Apex.
- Templates — Iterable's Handlebars + custom templates port to Apex's LiquidJS with mostly-mechanical conversion.
- Event tracking — your event payloads to Iterable's
/api/events/trackmove to Apex's/api/events. Same shape.
Migration steps
1. Inventory
Pull from Iterable's API:
- All Workflows (the JSON tree representation)
- All Segments + Lists
- User catalog with attributes
- (Optional) recent event history
2. Provision Apex
Sign up, create the workspace, install the snippet. Verify the SES domain is set up in the account you plan to connect.
3. Translate
The migration tool emits:
- Apex Segments from Iterable dynamic segments
- Org-scope Segments from static lists
- Adaptive Journey drafts from Iterable workflows
- Communications from email/push templates (Handlebars → Liquid where mechanical; flags non-portable helpers)
4. Review + publish
Walk every translated journey. Pay particular attention to:
- Workflow Experiments → Experiment step: compare letters with an Experiment step. On a rule is for routing, not for testing two letters.
- Per-workflow holdouts: the migration tool flags these and recommends deleting them in favor of the global holdout. Don't migrate per-workflow holdouts; they bias your lift estimates when workflows overlap.
- Send-Time Optimization: surfaces as a Wait → On engagement Branch. Review the conversion event for each.
5. Cut over
- Pause the Iterable workflow (stops new entrants)
- Publish the Apex journey
- Wait 1-2 weeks for in-flight Iterable workflows to drain
- Sunset the Iterable workspace
On per-workflow vs global holdouts
This is the biggest conceptual difference and worth pausing on.
Iterable lets you set a holdout per workflow — say 10% of workflow A's Segment receives nothing. The trouble: workflow A's holdout people are still exposed to workflows B, C, and D. They're not really a control. The holdout people have unique exposure profiles you can't easily compare to non-holdout people.
Apex's global holdout is once per workspace, forever, deterministic. Every journey's lift number uses the same control group. The math is simpler, the statistical contract is cleaner, and you can compare lift across journeys directly.
The migration tool will offer to translate Iterable per-workflow holdouts into Apex's global holdout setting. Most teams that move to this model end up preferring it; if you have a specific reason to want per-workflow control, you can fall back to a custom Segment predicate that excludes the bucket.
What's NOT in the migration
- Iterable's reporting suite. Apex's calibrated-impact + branch-performance dashboards answer different questions. Most operators find Apex's leaner.
- Iterable's email template editor history. Templates port; revision history doesn't.
- Iterable's predictive goals model. The training data lives in Iterable. Each Apex Experiment starts with fresh evidence from that Journey run.
FAQ
Does Apex have feature parity with Iterable's Embedded messages? Apex sends in-app today. Confirm the in-app SDK is on the page before you publish.
Can I run Apex alongside Iterable? Sure. Iterable for marketing campaigns, Apex for adaptive journeys. The two systems share the same SES domain reputation.
How long does a typical migration take? Workspaces with 5-10 workflows: a couple of days. Larger setups (50+ workflows): 1-2 weeks because the review step is human-in-the-loop. Pricing parity from day one.
Get migration help
migration@apex.inc — share your Iterable workspace ID + API key and we'll send back a translated Apex workspace + a workflow-by-workflow upgrade memo.