Integration Architecture
A technical reference guide for building a middleware-based, HIPAA-compliant bridge between Cliniko and GoHighLevel — enabling automated patient data sync and CRM journey automation.
Jump to
Executive Summary
The proposed solution is a middleware-based integration that provides a robust, scalable, and HIPAA-compliant bridge between Cliniko and GoHighLevel (GHL). This architecture enables the automated transfer of patient and appointment data from Cliniko to GHL, facilitating the use of GHL's powerful CRM and marketing automation features to manage the patient journey end-to-end.
Automated Sync
Patient records and appointment events flow from Cliniko to GHL without manual intervention.
HIPAA-Compliant
All PHI is encrypted in transit and at rest. BAA agreements cover all third-party services.
5-Min Latency
Polling every 5 minutes ensures near-real-time data freshness for CRM workflows.
Architecture Overview
A hub-and-spoke architecture is recommended, with a central middleware service acting as the hub. This approach decouples the two systems, making the integration more resilient, scalable, and easier to maintain. The middleware can be a custom-built application or a self-hosted, HIPAA-compliant iPaaS like .
While Cliniko does not officially support webhooks, a polling mechanism is a reliable alternative. A 5-minute polling interval is acceptable for most CRM and marketing automation use cases.
Core Components
| Component | Description |
|---|---|
| The central application that orchestrates the entire integration workflow. | |
| Periodically queries the Cliniko API for new and updated patient and appointment data. | |
| Interacts with the GHL API to create/update contacts and trigger workflows. | |
| Transforms data from the Cliniko API format to the GHL API format. | |
| A message queue (e.g., RabbitMQ, AWS SQS) to manage and buffer API requests, ensuring reliability and handling rate limits. | |
| A system for logging all integration activities and monitoring the health of the service. | |
| Securely stores all credentials, API keys, and other configuration parameters. |
Patient Journey Logic
NEWThe patient journey architecture maps every meaningful clinical event in Cliniko to a corresponding state transition in GHL. The middleware maintains a state machine for each patient — from their first booking as a lead through active care, drop-off risk, lapsing, and reactivation — and fires the appropriate GHL workflow at each transition.
GHL Patient Journey Pipeline
Lead
New Patient Booked
Started Care
In Care
Drop-Off Risk
Lapsed
Long-Term Lead Nurture
Reactivated
Lead
Existing GHL contact. Has not yet booked a Cliniko appointment.
New Patient Booked
First appointment created in Cliniko. Middleware detects first-ever appointment for this patient.
Started Care
First appointment attended (patient_arrived = true). Patient has begun their care journey.
In Care
Actively attending appointments. Future bookings exist. No significant gap detected.
Drop-Off Risk
Schedule-aware gap detected with no future booking. Enters reactivation funnel. Sequence stops immediately if patient re-books.
Lapsed
45 days since last appointment with no future booking. Enters reactivation funnel. Sequence stops immediately if patient re-books.
Long-Term Lead Nurture
First-appointment no-show who hasn't re-booked in 10 days. Phase 1: direct re-booking push (2–3 touchpoints). Phase 2: slow educational drip until they book.
Reactivated
Lapsed, drop-off, or lead-nurture patient books a new appointment. Removed from funnel immediately.
Appointment Types Are Fetched Dynamically — Your 6 Active Initial Consult Types Are Pre-configured
The Cliniko API exposes a GET /appointment_types endpoint returning every type in your account with its name, category, and id. The middleware builds a lookup map on startup. Your 6 active initial consult types are matched by exact name (not pattern): Facebook Initial Appointment, Initial Appointment, NC Family Initial Appointment, Decompression New Patient, Workcover Initial, TAC Initial. Paediatric New Patient is excluded from the current integration scope. Workcover and TAC appointments also receive their own tags for downstream workflow routing. When you add new appointment types in Cliniko, simply update the config list — no code changes required.
Data Flow & Workflows
Two primary workflows drive the integration. The Patient Sync workflow keeps GHL contacts up to date with Cliniko patient records. The Appointment Trigger workflow fires GHL automations in response to appointment lifecycle events.
Data Mapping
The Data Mapper translates Cliniko's patient object schema into GHL's contact schema. Standard fields map directly; others require transformation or the creation of custom fields in the GHL sub-account. Click any field name to copy it to your clipboard.
Cliniko Patient → GHL Contact
| Cliniko Field | GHL Field | Type |
|---|---|---|
| Direct | ||
| Direct | ||
| Identifier | ||
| Transform | ||
| Transform | ||
| Direct | ||
| Custom Field | ||
| Custom Field | ||
| Identifier | ||
| Generated |
GHL Sub-Account Pre-Configuration Required
Before the integration can run, the following custom fields must be created in the GHL sub-account: , , and . The field is critical — it is used as the deduplication key for all upsert operations.
HIPAA Compliance
Because this integration handles Protected Health Information (PHI), all components — including the middleware, infrastructure, and third-party services — must comply with HIPAA's Technical, Physical, and Administrative Safeguards.
Australian Context: Privacy Act 1988 & APP
For Australian healthcare practices, compliance is governed by the Privacy Act 1988 and the Australian Privacy Principles (APPs) rather than HIPAA. The controls listed below satisfy both frameworks. Ensure all data residency requirements are met — patient data should remain within Australian data centres where possible.
Business Associate Agreement (BAA)
If using a third-party iPaaS (e.g., n8n Cloud, Zapier), the vendor must sign a BAA before any PHI flows through their platform. Self-hosted deployments require a BAA with the cloud infrastructure provider (AWS, GCP, Azure).
HIPAA-Compliant Infrastructure
Self-hosted middleware must run on infrastructure configured for HIPAA compliance. This includes enabling AWS HIPAA-eligible services, configuring VPC isolation, and enabling CloudTrail audit logging.
Data Encryption
All data must be encrypted in transit using TLS 1.2 or higher. Data at rest (job queue payloads, logs, configuration store) must be encrypted using AES-256. Key management must use a dedicated KMS.
Access Control
Strict role-based access controls (RBAC) must govern who can access the middleware, its logs, and its configuration. Multi-factor authentication (MFA) is mandatory for all administrative access.
Audit Logging
Detailed audit logs of all data access and modifications must be maintained, including timestamps, actor identifiers, and payload hashes. HIPAA requires a minimum 6-year retention period for audit logs.
Data Minimisation
Only the minimum necessary PHI fields required for CRM functionality should be synced to GHL. Clinical notes, treatment records, and diagnosis codes should not be transferred unless explicitly required.
Recommended Services for Compliance
Error Handling & Reliability
The integration must be designed to be resilient to transient failures in either the Cliniko or GHL APIs. A layered retry strategy combined with a dead-letter queue ensures no data is silently lost.
Retries with Exponential Backoff
If an API call fails, the middleware retries with an exponential backoff strategy (e.g., 1s → 2s → 4s → 8s) to handle transient errors without overwhelming the upstream service.
Dead-Letter Queue
After a configurable number of retries (recommended: 5), a failed job is moved to a dead-letter queue for manual inspection and reprocessing. Alerts are sent to the operations team.
Idempotency
All API operations are idempotent to prevent duplicate data. The upsert pattern for contacts and unique Cliniko IDs as GHL custom fields ensure safe retries.
Scalability
The architecture is designed to scale horizontally as the volume of patients and appointments grows. The job queue acts as the primary scaling lever — additional worker instances can be added without any changes to the core logic.
Horizontal Scaling
The Data Sync Service can be scaled by adding more worker instances to process jobs from the queue in parallel.
Load Balancing
A load balancer distributes polling requests and API calls across multiple middleware instances for even throughput.
Security
Security is a critical aspect of this integration given the handling of Protected Health Information (PHI). The following controls must be in place before any production deployment.
- Credential Management: All API keys and secrets must be stored in a dedicated secrets management service such as AWS Secrets Manager or HashiCorp Vault. Never hardcode credentials in source code.
- Input Validation: All incoming data from Cliniko must be validated and sanitised before being processed and forwarded to GHL to prevent injection attacks.
- Principle of Least Privilege: The API keys used for both Cliniko and GHL must have the minimum required permissions — read-only on Cliniko for patient/appointment data, write-only on GHL for contacts and workflow enrollment.
- TLS 1.2+ Everywhere: All API calls must be made over HTTPS with TLS 1.2 or higher. Certificate pinning is recommended for production deployments.
- Audit Logging: Every data access and modification event must be logged with a timestamp, actor, and payload hash. Logs must be retained for a minimum of 6 years per HIPAA requirements.
Key Security Tools
Implementation Strategy
The implementation is structured across four sequential phases over an estimated 8-week timeline. Each phase has clear deliverables and acceptance criteria before proceeding to the next.
- Provision a HIPAA-compliant hosting environment (e.g., AWS with HIPAA-eligible services enabled).
- Install and configure the chosen middleware — either self-hosted n8n on a dedicated EC2 instance, or a custom Node.js service.
- Configure AWS Secrets Manager (or equivalent) and store Cliniko API key and GHL API key securely.
- Set up VPC, security groups, and IAM roles with least-privilege policies.
- Enable CloudTrail and configure log retention for HIPAA compliance.
- Sign BAA with all relevant third-party vendors.
8-Week Timeline Overview
Limitations & Future Roadmap
The current architecture reflects practical constraints of the Cliniko API. The following limitations are acknowledged and the roadmap items represent planned enhancements.
Polling Delay
Current ConstraintThe absence of native Cliniko webhooks means real-time synchronisation is not achievable. The current 5-minute polling interval introduces an acceptable delay for most CRM use cases, but is not suitable for time-critical workflows.
One-Way Sync
Current ConstraintThis architecture focuses on a unidirectional flow from Cliniko to GHL. Updates made in GHL (e.g., contact information changes) are not reflected back in Cliniko.
Webhook Support
Future EnhancementIf Cliniko introduces webhook support in a future API version, the polling module can be replaced with an event-driven listener, reducing latency to near-zero.
Bidirectional Sync
Future EnhancementA future phase could implement a bidirectional sync, allowing GHL contact updates (e.g., opt-out preferences, communication notes) to flow back into Cliniko patient records.
GHL Workflow Builder
NEWEach of the four GHL workflows below maps directly to an appointment lifecycle event in Cliniko. Expand a workflow to see the recommended step sequence, personalisation tokens, and suggested tooling. Click any token to copy it to your clipboard.
GHL Setup Prerequisites
Before activating these workflows, ensure the following are configured in your GHL sub-account: (1) Custom values for clinic_name, clinic_address, clinic_phone, and booking_url. (2) Custom contact fields for appointment_date, appointment_time, appointment_datetime, and appointment_status. (3) Twilio and SendGrid integrations connected in GHL Settings → Integrations.
Conclusion
The proposed integration architecture provides a solid foundation for a reliable, scalable, and HIPAA-compliant solution to connect Cliniko and GoHighLevel. By leveraging a middleware-based hub-and-spoke approach, the integration is decoupled from both platforms — making it resilient to API changes and straightforward to extend.
Healthcare practices adopting this architecture can unlock the full potential of their patient data for CRM automation, enabling personalised patient journeys, reduced no-shows through automated reminders, and improved retention through targeted re-engagement workflows — all while maintaining the data governance standards required in a clinical environment.
Configuration Reference
NEWAll middleware behaviour is controlled through environment variables and a configuration file. The table below documents every parameter, its type, default value, and purpose. Parameters marked required must be set before the middleware will start. All others have sensible defaults that can be tuned as the integration matures.
Minimum Config to Go Live
To run the integration for the first time, you only need to set the 5 required API credentials, your CLINIC_TIMEZONE, the INITIAL_CONSULT_TYPES list, and the 7 GHL workflow IDs. Everything else defaults to the recommended values documented below.
CLINIKO_API_KEYCLINIKO_SHARDGHL_API_KEYGHL_LOCATION_IDGHL_PIPELINE_IDCLINIC_TIMEZONEINITIAL_CONSULT_TYPESAuthentication credentials for both platforms. Store in environment variables — never in source code.
| Parameter | Type | Req. |
|---|---|---|
CLINIKO_API_KEYe.g. MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI6 Cliniko API key. Found in Cliniko → Settings → Integrations → API Keys. Shard-specific (au1, au2, etc.). | env | yes |
CLINIKO_SHARDe.g. au1 Your Cliniko API shard region. Determines the base URL: api.{shard}.cliniko.com/v1 | env | yes |
GHL_API_KEYe.g. eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... GoHighLevel API key (v2). Found in GHL → Settings → Integrations → API Keys. | env | yes |
GHL_LOCATION_IDe.g. ve9EPM428h8vShlRW1KT Your GHL sub-account (location) ID. Required for all contact and opportunity API calls. | env | yes |
GHL_PIPELINE_IDe.g. pipelineId_abc123 The ID of the 'Patient Journey' pipeline in GHL. Used when creating new opportunities. | env | yes |
Building the GHL Workflows
NEWEach of the 7 GHL workflows below needs to be built manually inside your GHL sub-account. The middleware does not create workflows — it only enrols contacts into existing workflows via the GHL API. Build each workflow first, then paste its Workflow ID into the corresponding environment variable in your middleware config.
How to Create a Workflow in GHL
- 1.Go to Automation → Workflows in your GHL sub-account
- 2.Click + New Workflow → Start from Scratch
- 3.Name the workflow (use the exact names below for clarity)
- 4.Set the Trigger to 'Contact Enrolled in Workflow' — the middleware handles enrolment
- 5.Build the steps as documented below
- 6.Publish the workflow (toggle to Active)
- 7.Copy the Workflow ID from ⚙️ Settings and paste it into your middleware config
Testing the Integration
NEWBefore going live, run through each test scenario below in a staging environment — ideally using a dedicated test Cliniko account or a test patient profile that won't affect real patient records. Each scenario maps to a specific middleware trigger and verifies the expected GHL outcome. Use the Pass/Fail toggles to track your progress.
Use a Staging Environment
Never run integration tests against your live Cliniko account with real patients. Create a dedicated test patient (e.g., "Test Patient Integration") with a test email address. In GHL, use a test contact with the same email. This ensures no real patients receive test messages and no production data is corrupted.
6
Total Scenarios
T1–T5
Triggers Covered
~2 hours
Estimated Time
Post-Testing Go-Live Checklist
Setup Checklist
NEWWork through the 7 groups below in order. Your progress is saved automatically in your browser — you can close and reopen this guide at any time and your completed steps will be preserved.
Setup Progress
0 of 48 steps completed across 7 groups
Message Templates
NEWReady-to-use message templates for all 7 GHL workflows. Click Copy on any template to paste it directly into GHL. Replace all [bracketed placeholders] with your clinic's details. GHL merge tokens ({{contact.first_name}} etc.) are inserted automatically by GHL at send time — click any token chip to copy it.
32
Total Templates
20
SMS Templates
12
Email Templates
Before Using These Templates
Replace all [bracketed placeholders] with your clinic's actual details: clinic name, phone number, online booking link, address, parking info, and practitioner names. GHL merge tokens like {{contact.first_name}} are filled automatically — do not replace these. Review the tone of each template to ensure it matches your clinic's voice before publishing.
Middleware Health Dashboard
NEWConnect this dashboard to your middleware's /health endpoint to get a live view of all service connections. Your middleware should expose a JSON health endpoint — see the expected response format below.
Middleware Health Endpoint
Not yet connected
Service Checks
Connection to Cliniko REST API (au1 shard)
Connection to GHL v2 API
Appointment sync and trigger processing queue
Polling cron job and daily health-check job
Middleware state persistence store
Expected /health Response Format
JSON{
"status": "healthy", // "healthy" | "degraded" | "down"
"version": "1.0.0",
"uptime": 86400, // seconds since middleware started
"services": {
"cliniko": {
"status": "ok", // "ok" | "degraded" | "error"
"latency": 142 // ms
},
"ghl": {
"status": "ok",
"latency": 89
},
"jobQueue": {
"status": "ok",
"pending": 0,
"failed": 0
},
"scheduler": {
"status": "ok",
"nextRun": "2026-03-06T08:05:00Z"
},
"database": {
"status": "ok",
"latency": 4
}
}
}Appointment Type Validator
NEWPaste any appointment type name from Cliniko to see which middleware trigger it maps to, which GHL workflow it fires, and whether any additional tags are applied. Useful when adding new appointment types in Cliniko or debugging unexpected behaviour.
Appointment Type Name
Quick fill — your configured types:
All Configured T1 Types
Changelog
A running record of every change made to this integration guide. Use this log to understand what rules have been added or modified, and to communicate changes to your developer or clinic team. Add new entries at the top whenever the integration logic, thresholds, or workflows are updated.
WF8 Long-Term Lead Nurture: 6 templates — Phase 1 re-booking push (SMS ×2 + objection-handling email) and Phase 2 slow drip (monthly health tip email, check-in SMS, long-term nurture email)
WF9 Maintenance Patient Reminder: 2 templates — proactive reminder SMS and gentle follow-up email
Section 18 Message Templates now covers all 9 workflows (30 total templates)
Quick Reference
NEWA condensed single-page reference for developers building the middleware. All values are copyable. For full context and explanations, refer to the relevant numbered sections in the guide.
Facebook Initial AppointmentInitial AppointmentNC Family Initial AppointmentDecompression New PatientWorkcover InitialTAC InitialWorkcover Initial and TAC Initial also apply funding_source tags.
| ID | Trigger Condition | WF |
|---|---|---|
| T1 | New Initial Consult Booked | WF1 |
| T2 | First Appointment Attended | WF2 |
| T3 | No-Show | WF3 |
| T4 | Appointment Cancelled | WF4 |
| T5 | Drop-Off Risk (schedule-aware) | WF5 |
| T6 | Lapsed (45 days inactive) | WF6 |
| T7 | Lapsed Patient Re-books | WF7 |
| T8 | First-Appt No-Show (10 days) | WF8 |
| T9 | Maintenance Reminder (80% interval) | WF9 |
| Schedule | Avg Interval | T5 Fires At | T6 Lapsed At |
|---|---|---|---|
| Weekly | ≤ 10 days | 14 days | 45 days |
| Fortnightly | ≤ 17 days | 21 days | 45 days |
| Other / Long | > 17 days | 30–45 days | 45 days |
T8 fires 10 days after a first-appointment no-show with no re-booking. T9 fires at 80% of avg interval with no future booking.
WF_NEW_PATIENT_BOOKEDWF_WELCOME_TO_CAREWF_NO_SHOWWF_CANCELLEDWF_DROP_OFF_RISKWF_REACTIVATIONWF_REACTIVATION_BOOKEDWF_LEAD_NURTUREWF_MAINTENANCE_REMINDERFind Workflow IDs in GHL → Automation → Workflows → [workflow] → Settings → Workflow ID.
| Cliniko Field | GHL Field |
|---|---|
first_name | firstName |
last_name | lastName |
email | email |
phone_mobile | phone |
phone_home | phone (fallback) |
date_of_birth | customField.date_of_birth |
gender | customField.gender |
address_1 | address1 |
city | city |
state | state |
post_code | postalCode |
medicare_number | customField.medicare_number |
referral_source | source |
notes (excluded) | — |
| Field Key | Type |
|---|---|
cliniko_patient_id | Text |
cliniko_last_synced | Date |
appointment_count | Number |
last_appointment_date | Date |
next_appointment_date | Date |
avg_appointment_interval | Number |
patient_status | Text |
appointment_type_last | Text |
funding_source | Text |
date_of_birth | Date |
gender | Text |
medicare_number | Text |
lead_nurture_enrolled_at | Date |
maintenance_interval_days | Number |
Create these in GHL → Settings → Custom Fields → Contacts before configuring workflows.