CRM migration
Field-level mapping, validation, and rollback between Cliniko and Twenty CRM. We move data and schema; workflows are rebuilt natively in Twenty CRM.
Cliniko
Source
Twenty CRM
Destination
Compatibility
12 of 14
objects map 1:1 between Cliniko and Twenty CRM.
Complexity
BStandard
Timeline
5–7 days
Overview
Cliniko organizes healthcare data around patients, practitioners, appointments, and treatment notes. Twenty CRM uses a standard B2B CRM object model: People, Companies, Opportunities, Tasks, and Notes. These models diverge significantly — Cliniko's patient record carries clinical data (DOB, insurance, concession cards) and appointment history, while Twenty's People object is designed for contacts in a sales context. FlitStack AI resolves this by mapping Cliniko patients to Twenty People, appointments to Tasks, treatment notes to Notes, and invoices to a custom Invoice object. We use Cliniko's built-in CSV export (Settings → Data exports) and bulk-import into Twenty via its API and CSV import, respecting Twenty's required import order: Companies first, then People, then Opportunities, then custom objects. Practitioners export from Cliniko and land in Twenty as WorkspaceMembers resolved by email match before appointments can link to them. What does not migrate: appointment reminder automations, SMS credits, Telehealth session logs, and Cliniko's billing model — those require separate decisions post-migration. We deliver a field-level diff on a sample slice before committing the full run.
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 Cliniko 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.
Cliniko
Patient
Twenty CRM
People
1:1Cliniko's patient maps directly to Twenty's People object. We map firstname, lastname, email, phone, date_of_birth, and address fields. Cliniko-created and Cliniko-updated timestamps are preserved as custom datetime fields since Twenty's native timestamps reflect migration time. Cliniko's patient ID is stored as Source_System_ID__c for delta-run de-duplication.
Cliniko
Patient Address
Twenty CRM
People (address fields)
many:1Cliniko stores addresses as a separate object linked to patients with address types (e.g., 'Street', 'Postal'). Twenty People has a single address field. We take the Cliniko address with type 'Street' (or the first address) and populate Twenty's address field as a single formatted string. Additional address types are stored as custom text fields (e.g., Mailing_Address_2__c) for reference.
Cliniko
Appointment
Twenty CRM
Task
1:1Cliniko appointments do not map 1:1 to any Twenty object — Twenty has no appointment entity. We transform appointments to Tasks: the Cliniko appointment date and time become the Task due date and start datetime; the end time becomes the Task end datetime. The Cliniko appointment status ('Awaiting', 'Arrived', 'In Progress', 'Completed', 'No Show') is mapped to a custom Cliniko_Appointment_Status__c field since Twenty Task status has fewer values.
Cliniko
Appointment (appointment_type)
Twenty CRM
AppointmentType (custom object)
1:1Cliniko appointment types (e.g., 'Initial Consultation', 'Follow-up', 'Massage 60min') have no equivalent in Twenty's standard objects. We create a custom object 'AppointmentType' in Twenty with name and duration fields, then link appointments to it via a relation field. If you prefer a flat structure, appointment types can also become a custom pick-list field on the Task.
Cliniko
Practitioner
Twenty CRM
WorkspaceMember
1:1Cliniko practitioners are staff members who create appointments and treatment notes. They map to Twenty WorkspaceMembers resolved by email match. We import practitioners first (before appointments and notes) so their Twenty IDs exist for relation resolution. Practitioners without a matching email in Twenty are flagged before migration and assigned to a fallback WorkspaceMember.
Cliniko
Treatment Note
Twenty CRM
Note
1:1Cliniko treatment notes (customizable SOAP-format templates per clinic) migrate as Twenty Notes. The note body content maps to Note.body; the Cliniko treatment note ID is stored as Source_System_ID__c. Note.body is plain text — rich formatting from Cliniko templates is preserved as plain text, and template field labels are included in the body for context.
Cliniko
Invoice
Twenty CRM
Invoice (custom object)
1:1Cliniko invoices have no equivalent in Twenty's standard object model. We create a custom object 'Invoice' in Twenty with fields for invoice number, total amount, outstanding amount, status, and dates. Invoice status from Cliniko ('Draft', 'Sent', 'Paid', 'Void') maps to a custom pick-list; 'Paid' and 'Void' states are preserved as custom values.
Cliniko
Invoice Line Item
Twenty CRM
Invoice Line Item (custom object) or Invoice custom fields
1:manyCliniko invoice line items link products or services to invoices. For simple cases, we store the product name and quantity as custom fields on the Invoice object. For complex invoices with multiple line items, we create a custom object 'InvoiceLineItem' linked to Invoice with product name, quantity, unit price, and total.
Cliniko
Payment
Twenty CRM
Payment (custom object)
1:1Cliniko payments received against invoices have no native equivalent in Twenty. We create a custom object 'Payment' with fields for payment ID, amount, date, and a relation to the corresponding Cliniko-generated Invoice (stored as Source_System_ID__c). Payment status (fully paid, partially paid, refunded) is preserved as a custom field.
Cliniko
Product / Service
Twenty CRM
Product (custom object)
1:1Cliniko products and services (used in appointments and invoices) do not have a native equivalent in Twenty. We create a custom object 'Product' with name, description, and unit price fields. Products linked to appointments via the appointment type are also stored as a custom field on the AppointmentType object for traceability.
Cliniko
Patient Insurance Profile
Twenty CRM
People (custom fields)
1:1Cliniko stores insurance provider, member ID, policy number, and concession card details on patient records. Twenty has no native insurance fields. We map these as custom text fields on the People record: Insurance_Provider__c, Insurance_Member_ID__c, Policy_Number__c, Concession_Type__c. This data is preserved for reference but requires manual entry for new patients post-migration.
Cliniko
Patient Custom Fields
Twenty CRM
People (custom fields)
1:1Cliniko clinics commonly add custom fields to patient records for clinic-specific data (e.g., 'Preferred Contact Method', 'Emergency Contact', 'Referral Source'). Each Cliniko custom field becomes a Twenty custom field with the same name and field type, created in Settings → Data Model before import. Field values are mapped value-by-value during the migration run.
Cliniko
Appointment Custom Fields
Twenty CRM
Task (custom fields)
1:1Some Cliniko setups add custom fields to appointments (e.g., 'Room Number', 'Equipment Used'). These map to custom fields on the Task object in Twenty, created before import. Note that custom fields on appointments in Cliniko are stored in a separate export and must be joined to the main appointment export by record ID during mapping.
Cliniko
SMS Credit / Telehealth Fee
Twenty CRM
No equivalent
1:1Cliniko bundles SMS credits and Telehealth session fees into its subscription billing. Twenty CRM has no equivalent billing or communications-credit model. These records do not migrate. If SMS appointment reminders are in use, they must be replaced with Twenty workflow-based reminders or a third-party SMS integration post-migration.
| Cliniko | Twenty CRM | Compatibility | |
|---|---|---|---|
| Patient | People1:1 | Fully supported | |
| Patient Address | People (address fields)many:1 | Fully supported | |
| Appointment | Task1:1 | Fully supported | |
| Appointment (appointment_type) | AppointmentType (custom object)1:1 | Fully supported | |
| Practitioner | WorkspaceMember1:1 | Fully supported | |
| Treatment Note | Note1:1 | Fully supported | |
| Invoice | Invoice (custom object)1:1 | Fully supported | |
| Invoice Line Item | Invoice Line Item (custom object) or Invoice custom fields1:many | Fully supported | |
| Payment | Payment (custom object)1:1 | Fully supported | |
| Product / Service | Product (custom object)1:1 | Fully supported | |
| Patient Insurance Profile | People (custom fields)1:1 | Fully supported | |
| Patient Custom Fields | People (custom fields)1:1 | Fully supported | |
| Appointment Custom Fields | Task (custom fields)1:1 | Fully supported | |
| SMS Credit / Telehealth Fee | No equivalent1:1 | 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.
Cliniko gotchas
Background export generation delays for large datasets
Charts export is separate from the main data panel
API key permissions gate record visibility
Form template configurations do not export
The old Appointments export has been deprecated
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
Audit Cliniko data and identify the full export scope
FlitStack AI begins every Cliniko migration by reviewing the full export scope. We pull the patient list, appointment export, treatment notes, invoices, payments, products, and any custom-field exports from Cliniko's Settings → Data exports. We identify custom fields on patient records and appointment types from the export column headers, note address records and insurance profiles, and count record volumes per object. This audit produces the migration scope document: which objects map directly, which require custom objects in Twenty, and which records have no CRM equivalent.
Set up Twenty workspace: data model, custom objects, and user provisioning
Before any data moves, FlitStack AI configures Twenty's data model to receive Cliniko data. We create the custom Invoice and Payment objects with all required fields, add the custom AppointmentType object, and create any custom fields needed on the People and Task objects (insurance fields, appointment status, original timestamps). We also create the custom fields for appointment-type relations and Practitioner Source_System_ID__c on WorkspaceMembers. Your team must invite all practitioners to Twenty and have them accept invitations before we import appointments and notes — their Twenty user IDs are required for relation resolution.
Import in Twenty's required order: Companies, then People, then Tasks, then Notes
Following Twenty's import sequencing rules, FlitStack AI imports Companies first (if any organizational records exist in Cliniko), then People with all custom fields and address merges applied. Next, we import the AppointmentType custom object so Twenty IDs exist for the appointment-type relation. Then we import appointments as Tasks — mapping dates, practitioner links, and the Cliniko appointment status to the custom field. Treatment notes follow as Notes objects linked to the patient People record. Invoice and Payment custom objects are imported last. We validate foreign-key integrity at each stage.
Run a sample migration with field-level diff on a representative slice
A representative slice migrates first: typically 100–500 patient records spanning multiple practitioners, 200–500 appointments across several types and statuses, 50–100 treatment notes, and 20–50 invoices and payments. We generate a field-level diff showing source values and destination values for every mapped field. You can verify that appointment statuses landed in the custom field, practitioner links resolved correctly, insurance fields populated, and invoice amounts match. This step surfaces any field-level mapping errors before the full run commits.
Execute full migration with delta pickup and rollback readiness
The full migration runs against Twenty using Cliniko's complete export. A delta-pickup window (24–48 hours after the initial load) captures any Cliniko records created or modified during the cutover window. Audit logs capture every record operation with before and after snapshots. One-click rollback is available if reconciliation fails. After rollback, any in-flight changes in Cliniko that occurred during the window are re-captured and re-loaded. Your team continues working in Cliniko throughout — FlitStack AI uses export files only, with no disruption to active appointments or patient records.
Deliver migration report, custom object documentation, and rebuild reference
After go-live, FlitStack AI delivers a complete migration report: record counts per object, error log, and a field-mapping reference document showing every Cliniko field and its Twenty destination. For items that require manual action post-migration — SMS reminder automations, Telehealth workflow rebuilds, insurance field validation setup — we provide a rebuild reference guide. The Cliniko workflow definitions are exported as a JSON reference file so your Twenty admin can reconstruct appointment-reminder automations in Twenty Workflows.
Platform deep dives
Cliniko
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 Cliniko 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
Cliniko: Not publicly documented in the OpenAPI schema or public help docs.
Data volume sensitivity
Cliniko doesn't expose a bulk API — REST + parallelization used for high-volume runs.
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 Cliniko to Twenty CRM migration scoping. Not seeing yours? Book a call.
Walk through your Cliniko 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 Cliniko
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.