CRM migration
Field-level mapping, validation, and rollback between Customer.io and Twenty CRM. We move data and schema; workflows are rebuilt natively in Twenty CRM.
Customer.io
Source
Twenty CRM
Destination
Compatibility
9 of 12
objects map 1:1 between Customer.io and Twenty CRM.
Complexity
BStandard
Timeline
3-5 weeks
Overview
Customer.io and Twenty CRM serve fundamentally different roles, which makes this migration a category shift as much as a platform switch. Customer.io is a behavioral messaging platform where People records are enriched by event streams and trait updates. Twenty CRM is a relationship management platform built around Contacts, Organizations, Opportunities, and Activities with a structured data model. The migration challenge is translating Customer.io's identity-and-event profile into Twenty's contact-object schema, mapping Custom Object namespaces to Twenty's custom object types, and carrying event history into Activity records that remain readable but are not live-segmentable. We do not migrate Campaigns, Journeys, Broadcasts, or transactional message templates as automations; we document their structure so your admin rebuilds them in Twenty's workflow engine. Push notification setup is out of scope because it depends on app SDK changes that happen independently of data migration.
Every standard and custom field arrives verified.
AI proposes the map; you confirm before any record moves.
Parent–child, lookups, and ownership stay linked.
Calls, emails, meetings — with original timestamps.
Documents, uploads, and inline notes move with the record.
Why teams make this switch
Leaving
What's pushing teams away
Choosing
What's pulling them in
Object mapping
Each row shows how a Customer.io object lands in Twenty CRM, including any object-level transformations, lookup resolution, or schema-design dependencies.
Typical mapping — final map is confirmed during the sample migration step.
Customer.io
Person (Profile)
Twenty CRM
Person
1:1Customer.io People records map to Twenty CRM Person objects. The email address serves as the dedupe key during import. Standard CRM fields (name, email, phone, job title, address components) are extracted from traits where present. The Customer.io userId is stored in a custom field for audit traceability. Any trait that does not map to a native Twenty field is created as a custom field during schema setup. Anonymous profiles with no email are flagged in the reconciliation report and held for admin decision before import. Event history is not embedded in the Person record but migrated as separate Activity records.
Customer.io
Custom Object: Company
Twenty CRM
Company
1:1Customer.io Custom Objects with object_type_id indicating a company map to Twenty CRM Company records. The company name is the primary field; domain and website are extracted from traits and mapped to the corresponding Company fields. Relationships to People are preserved as a Company-Person association in Twenty. Custom fields on the Customer.io company object migrate to Twenty Company custom fields.
Customer.io
Segment
Twenty CRM
Tag
lossyCustomer.io segment membership is exported as a list of segment names per Person. In Twenty, each segment name becomes a Tag applied to the Person record. Because segments in Customer.io are dynamic (membership changes with trait updates), we capture membership as a snapshot at migration time. The written handoff document includes the full segment criteria for the customer to rebuild equivalent dynamic segments as Twenty Views and saved filters.
Customer.io
Custom Object (general)
Twenty CRM
Custom Object
1:1Customer.io Custom Object namespaces beyond Companies (for example Products, Partners, or custom relationship objects) map to Twenty CRM custom objects. We pre-create the destination schema in Twenty before import, including all custom fields matching the source object_type_id field definitions. Lookup relationships between custom objects and People are resolved at migration time using the object_id and the corresponding Person record.
Customer.io
Custom Event
Twenty CRM
Activity
1:1Customer.io custom events (created via track()) migrate to Twenty CRM Activity records. Each Activity record stores the event name, properties as a JSON field, and the original timestamp. The Activity is linked to the corresponding Person record via a Person lookup. Event properties are not flattened into individual fields to preserve schema flexibility. Activity records are readable in the Twenty timeline but do not drive segmentation in the same way Customer.io event triggers do.
Customer.io
Engagement: Email (sent through Customer.io)
Twenty CRM
Activity
1:1Email send events recorded in Customer.io migrate as Activity records in Twenty. The activity title captures the email campaign or broadcast name, and the properties field stores subject line, send timestamp, and delivery status (sent, delivered, bounced, undeliverable). The Activity is linked to the Person record. Note that Customer.io broadcast API has a rate limit of 1 request per 10 seconds; large email send histories are chunked during export to avoid rate-throttle gaps.
Customer.io
Engagement: Call
Twenty CRM
Activity
1:1Call engagements recorded in Customer.io migrate as Activity records in Twenty with call disposition and duration stored in the Activity properties. Each Activity is linked to the Person record via lookup. Call recording URLs stored in Customer.io are not importable and are flagged in the written handoff for manual re-linking post-migration.
Customer.io
Engagement: Meeting
Twenty CRM
Activity
1:1Meeting engagements migrate as Activity records in Twenty with start and end timestamps, location, and attendee list preserved in the properties field. Each Activity links to the Person record. Meeting recording links stored in Customer.io are flagged for manual re-association.
Customer.io
Engagement: Note
Twenty CRM
Comment
1:1Customer.io note engagements map to Comment records in Twenty CRM linked to the Person timeline. The note body migrates as plain text. Attachments on notes cannot be imported via CSV and are flagged in the written handoff for manual re-upload. Note author is stored in the Comment author field.
Customer.io
Engagement: Task
Twenty CRM
Activity
1:1Task engagements in Customer.io migrate as Activity records in Twenty. Task status (completed, open) maps to Activity completion. Assigned owner resolves by email match to the corresponding Person record if the assignee is a Customer.io user who also exists as a Person in Twenty.
Customer.io
Broadcast
Twenty CRM
Workflow (configuration export)
lossyCustomer.io Broadcasts are one-time sends to a segment or full audience. They do not migrate as live automations because Twenty's workflow engine has a different trigger and action model. We export broadcast configuration including name, target segment, content, and send timestamp as a structured JSON document delivered in the written handoff. The customer's admin rebuilds equivalent one-time outreach sequences in Twenty Workflows using the exported criteria.
Customer.io
Campaign / Journey
Twenty CRM
Workflow (configuration export)
lossyCustomer.io Campaigns and Journeys are automated workflows with entry triggers, branching conditions, and multi-channel message actions. These do not migrate as automation code because Twenty's workflow engine uses a different trigger-action model and does not support the same multi-channel campaign step types. We export the full campaign and journey structure including trigger conditions, wait steps, branching logic, and channel assignments as a structured document. The customer's admin rebuilds equivalent sequences in Twenty Workflows using the exported criteria.
| Customer.io | Twenty CRM | Compatibility | |
|---|---|---|---|
| Person (Profile) | Person1:1 | Fully supported | |
| Custom Object: Company | Company1:1 | Fully supported | |
| Segment | Taglossy | Fully supported | |
| Custom Object (general) | Custom Object1:1 | Fully supported | |
| Custom Event | Activity1:1 | Fully supported | |
| Engagement: Email (sent through Customer.io) | Activity1:1 | Fully supported | |
| Engagement: Call | Activity1:1 | Fully supported | |
| Engagement: Meeting | Activity1:1 | Fully supported | |
| Engagement: Note | Comment1:1 | Fully supported | |
| Engagement: Task | Activity1:1 | Fully supported | |
| Broadcast | Workflow (configuration export)lossy | Fully supported | |
| Campaign / Journey | Workflow (configuration export)lossy | Fully supported |
Gotchas + challenges
Platform-specific issues from each side, plus the pair-specific challenges that don't show up on either platform's page on its own.
Customer.io gotchas
Deleted profiles still count toward billing for the remainder of the cycle
Push migration requires a new app version with the Customer.io SDK
Broadcast API rate limit constrains high-volume re-imports
Inactive user profiles inflate monthly billing with no campaign benefit
Transactional message content may be redacted in stored logs
Twenty CRM gotchas
Import order is enforced and critical
Export limited to 20,000 records and visible columns only
Soft-deleted records count toward uniqueness and trigger restores
API rate limits cap at 200 req/min on Organization tier
No native email sequences — follow-up cadences require external tools
Pair-specific challenges
Migration approach
Discovery and scoping
We audit the Customer.io workspace across profile count, trait schemas, Custom Object types and volumes, segment definitions, event names and property schemas, engagement history volume, and active broadcast and campaign configurations. We pair this with a Twenty CRM environment review to confirm the target schema, custom object availability, and any self-hosted versus cloud configuration differences that affect the import path. The discovery output is a written migration scope document covering record counts per object type, field mapping specifications, and a list of all objects requiring custom field creation in Twenty.
Schema design and field mapping
We design the destination schema in Twenty CRM before any data moves. This includes creating custom fields on Person to host Customer.io traits that do not map to native Twenty fields, pre-creating Custom Object types to match Customer.io object_type_id namespaces, and defining the tag set that will represent segment membership. We also document every Customer.io segment and campaign structure as a structured rule set for the written handoff. The schema is validated in Twenty before production migration begins.
Sandbox migration and reconciliation
We run a migration using a subset of production-like data into Twenty CRM to validate the field mapping, custom object schema, and deduplication logic. The customer reviews the reconciled output, spot-checks Person records against the Customer.io source, and confirms that Custom Object relationships are preserved. Mapping corrections are made at this stage. We do not proceed to production migration until the customer signs off on the sandbox output.
Deleted profile audit and integration freeze
We extract all profiles deleted within the current billing cycle and cross-reference them against active Customer.io integrations that could re-import them mid-migration. We present this report to the customer before cutover. The customer pauses or redirects integrations that could re-import deleted profiles. This step ensures that the final migrated record count matches the intended scope and that the Customer.io billing cycle closes on the correct profile total.
Production migration in dependency order
We run production migration in record-dependency order: Person records first (with email as dedupe key, trait fields mapped, and userId preserved), Company records next (with Person lookup resolved), Custom Objects next (with object_type_id preserved and Person and Company lookups resolved), then Activity history (events, emails, calls, meetings, notes, tasks as Activity or Comment records with Person lookup). Attachments are migrated via API after the main record import or flagged for manual re-upload. Each phase emits a row-count reconciliation report before the next phase begins.
Cutover, validation, and workflow rebuild handoff
We freeze writes to Customer.io during cutover, run a final delta migration of any records modified during the migration window, then enable Twenty CRM as the system of record. We deliver the written handoff document containing all segment criteria, broadcast configurations, and campaign journey structures for the customer to rebuild in Twenty Workflows. We do not rebuild Customer.io automations as Twenty Workflows inside the migration scope; that is a separate engagement. We support a one-week hypercare window for reconciliation issues raised during the first week of live use.
Platform deep dives
Customer.io
Source
Strengths
Weaknesses
Twenty CRM
Destination
Strengths
Weaknesses
Complexity grading
Standard CRM migration. 1 of 8 objects need a mapping; the rest are 1:1.
Overall complexity
Standard migration
Derived from compatibility, mapping clarity, API constraints, and data volume across Customer.io and Twenty CRM.
Object compatibility
1 of 8 objects need a mapping; the rest are 1:1.
Field mapping clarity
Field mapping is derived from defaults — final spec confirmed during the sample migration.
Timeline complexity
8-object category — typical timelines run 2–7 days end-to-end.
API constraints
Customer.io: Not publicly documented for general API; transactional broadcast endpoint capped at 1 request per 10 seconds.
Data volume sensitivity
Customer.io exposes a bulk API — large-volume migrations stream efficiently.
Estimator
Rule-based pricing — no per-record fees, no manual quotes. Migrations over 2M records are scoped individually.
Step 1
Pick a category, then your source and destination platforms.
Category
FAQ
Answers to the questions buyers ask most during Customer.io to Twenty CRM migration scoping. Not seeing yours? Book a call.
Walk through your Customer.io to Twenty CRM migration with a real engineer — 30 minutes, free, written quote within 24 hours.
Book a free 30 minute consultationAdjacent paths
Other ways to leave Customer.io
Other ways to arrive at Twenty CRM
Ready when you are
Tell us record counts and timeline. We'll come back with a written quote inside 1 business day — no commitment, no sales pitch.