ClinikoGoHighLevel

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

01

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.

02

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.

architecture-diagram.svg
Hub & Spoke
CLINIKOMIDDLEWAREGOHIGHLEVELGET /patientsEnqueue jobDequeueTransformPOST /contactsCliniko REST APISource of TruthPolling ModuleEvery 5 minJob QueueRabbitMQ / SQSData Sync ServiceOrchestratorData MapperTransformGHL REST APICRM Target

Core Components

ComponentDescription
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.
03

Patient Journey Logic

NEW

The 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

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.

04

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.

1
2
3
4
5
05

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.

DirectIdentifierTransformCustom FieldGenerated

Cliniko Patient → GHL Contact

Cliniko FieldGHL FieldType
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.

06

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)

Required

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

Required

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

Required

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

Required

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

Required

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

Best Practice

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

07

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.

08

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.

09

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

10

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

P1
P2
P3
P4
Wk 1–2
Wk 3–4
Wk 5–6
Wk 7–8
11

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 Constraint

The 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 Constraint

This 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 Enhancement

If 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 Enhancement

A 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.

12

GHL Workflow Builder

NEW

Each 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.

TRIGGERACTIONWAITCONDITIONTAG
🔧

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.

13

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.

Architecture Spec v1.1 · Cliniko REST API v1 · GHL API v2
14

Configuration Reference

NEW

All 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_KEY
CLINIKO_SHARD
GHL_API_KEY
GHL_LOCATION_ID
GHL_PIPELINE_ID
CLINIC_TIMEZONE
INITIAL_CONSULT_TYPES
🔑

Authentication credentials for both platforms. Store in environment variables — never in source code.

ParameterTypeReq.
CLINIKO_API_KEY

e.g. MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI6

Cliniko API key. Found in Cliniko → Settings → Integrations → API Keys. Shard-specific (au1, au2, etc.).

envyes
CLINIKO_SHARD

e.g. au1

Your Cliniko API shard region. Determines the base URL: api.{shard}.cliniko.com/v1

envyes
GHL_API_KEY

e.g. eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

GoHighLevel API key (v2). Found in GHL → Settings → Integrations → API Keys.

envyes
GHL_LOCATION_ID

e.g. ve9EPM428h8vShlRW1KT

Your GHL sub-account (location) ID. Required for all contact and opportunity API calls.

envyes
GHL_PIPELINE_ID

e.g. pipelineId_abc123

The ID of the 'Patient Journey' pipeline in GHL. Used when creating new opportunities.

envyes
15

Building the GHL Workflows

NEW

Each 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. 1.Go to Automation → Workflows in your GHL sub-account
  2. 2.Click + New Workflow → Start from Scratch
  3. 3.Name the workflow (use the exact names below for clarity)
  4. 4.Set the Trigger to 'Contact Enrolled in Workflow' — the middleware handles enrolment
  5. 5.Build the steps as documented below
  6. 6.Publish the workflow (toggle to Active)
  7. 7.Copy the Workflow ID from ⚙️ Settings and paste it into your middleware config
TRIGGER
ACTION
IF/ELSE
WAIT
END
— click any step to expand details
16

Testing the Integration

NEW

Before 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

Reset any test threshold overrides (e.g. DROP_OFF_THRESHOLD_DAYS) to production values
Delete or archive test contacts in GHL
Delete or deactivate test patients in Cliniko
Confirm all 7 GHL workflow IDs are set in the middleware config
Confirm CLINIC_TIMEZONE is set correctly (Australia/Melbourne)
Confirm POLL_INTERVAL_MINUTES is set to production value (5)
Enable dead-letter queue alerts (DEAD_LETTER_ALERT_EMAIL)
Run the middleware in production mode and monitor logs for the first 24 hours
17

Setup Checklist

NEW

Work 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.

0%

Setup Progress

0 of 48 steps completed across 7 groups

18

Message Templates

NEW

Ready-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.

19

Middleware Health Dashboard

NEW

Connect 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

Not Connected

Service Checks

Cliniko API

Connection to Cliniko REST API (au1 shard)

Unknown
GoHighLevel API

Connection to GHL v2 API

Unknown
Job Queue

Appointment sync and trigger processing queue

Unknown
Scheduler

Polling cron job and daily health-check job

Unknown
Database

Middleware state persistence store

Unknown

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
    }
  }
}
20

Appointment Type Validator

NEW

Paste 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

Facebook Initial Appointment
Initial Appointment
NC Family Initial Appointment
Decompression New Patient
Workcover Initial+workcover
TAC Initial+tac
21

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.

ADDEDUPDATEDREMOVEDFIXEDNOTE— change type indicators
ADDED

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)

ADDED

WF9 Maintenance Patient Reminder: 2 templates — proactive reminder SMS and gentle follow-up email

UPDATED

Section 18 Message Templates now covers all 9 workflows (30 total templates)

22

Quick Reference

NEW

A 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.

T1 — Initial Consult Appointment Types (exact match)
Facebook Initial Appointment
Initial Appointment
NC Family Initial Appointment
Decompression New Patient
Workcover Initial
TAC Initial

Workcover Initial and TAC Initial also apply funding_source tags.

9 Triggers → GHL Workflow Mapping
IDTrigger ConditionWF
T1New Initial Consult BookedWF1
T2First Appointment AttendedWF2
T3No-ShowWF3
T4Appointment CancelledWF4
T5Drop-Off Risk (schedule-aware)WF5
T6Lapsed (45 days inactive)WF6
T7Lapsed Patient Re-booksWF7
T8First-Appt No-Show (10 days)WF8
T9Maintenance Reminder (80% interval)WF9
Schedule-Aware Drop-Off Thresholds
ScheduleAvg IntervalT5 Fires AtT6 Lapsed At
Weekly≤ 10 days14 days45 days
Fortnightly≤ 17 days21 days45 days
Other / Long> 17 days30–45 days45 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.

GHL Workflow IDs — ENV Keys
WF1New Patient Booked
WF_NEW_PATIENT_BOOKED
WF2Welcome to Care
WF_WELCOME_TO_CARE
WF3No-Show Re-engagement
WF_NO_SHOW
WF4Appointment Cancelled
WF_CANCELLED
WF5Re-engagement (Drop-Off)
WF_DROP_OFF_RISK
WF6Reactivation Funnel
WF_REACTIVATION
WF7Reactivation Booked
WF_REACTIVATION_BOOKED
WF8Long-Term Lead Nurture
WF_LEAD_NURTURE
WF9Maintenance Reminder
WF_MAINTENANCE_REMINDER

Find Workflow IDs in GHL → Automation → Workflows → [workflow] → Settings → Workflow ID.

Cliniko → GHL Field Mapping
Cliniko FieldGHL 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)
GHL Custom Fields to Create
Field KeyType
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.