Cliniko API and Python: How We Built a Custom AI Solution for Clinics

Introduction

In today’s fast-paced medical environment, healthcare professionals juggle patient care with administrative tasks that often slow them down. While tools like Cliniko have streamlined practice management—handling scheduling, patient records, and billing—there’s still room to make workflows even more efficient with custom AI-powered solutions.

At FutureSmart AI, we specialize in building AI-driven automation, NLP-based assistants, and workflow optimization solutions that integrate seamlessly with existing platforms. In this blog, we not only explore how to leverage Cliniko APIs with Python but also showcase how we helped a client build a custom AI solution on top of Cliniko, automating key processes for clinics and improving efficiency.

1. Understanding Cliniko APIs

What is Cliniko?

Cliniko is a cloud-based software designed for comprehensive medical practice management. It combines flexibility and ease of use to streamline daily operations. The platform excels in the following areas:

  • Appointment scheduling via a customizable calendar.

  • Patient management, including medical histories and communication records.

  • Billing and invoicing with integrated payment tracking.

  • Multi-location support for organizations operating across various sites.

API Overview

The Cliniko API enables developers to programmatically access and manipulate data. Here are some key capabilities:

  • Retrieve, create, or update appointment records.

  • Access detailed patient data.

  • Manage practitioner and business information.

The API’s flexibility allows for custom integrations that cater to unique business workflows, making it a powerful tool for healthcare organizations.


2. Setting Up Access

1. Generate API Key

To generate a Cliniko API key follow below steps :

  • Log into your Cliniko account.

  • Navigate to My Info and then go to the Manage API Keys section.

  • Click Add an API key to create a new one, which will allow you to interact with Cliniko's API.

2. Manage Permissions

After generating your API key, assign appropriate scopes based on the specific data you need access to. Each scope allows access to different parts of Cliniko’s system (appointments, patients, etc.). Be mindful to select only the required permissions for your needs.

3. Understand Shards

  • Shards represent geographically isolated instances of Cliniko’s system. When you create a new account, you’ll select a region for hosting your data.

  • Each shard is identified by a short code at the end of the API key (e.g., au1). This shard ID is crucial when constructing API URLs as it ensures proper routing of your requests to the correct server.

    Example API key :

MS0xLWl4SzYYYYdtR3V2HNOT..............-au1

In the above example, the shard is au1.

4. Identifying Your Application

To identify your application, you need to send the User-Agent header. In case of an issue, this will allow Cliniko to track down your requests and contact you. The format for this header should be:

APP_VENDOR_NAME (APP_VENDOR_EMAIL)

Where:

  • APP_VENDOR_NAME is the name of your application.

  • APP_VENDOR_EMAIL is the contact email for you or your company.

Example of a valid User-Agent header :

Really helpful app (contact@futuresmart.ai)

5. Consult Documentation

Cliniko’s https://docs.api.cliniko.com/ provides detailed information on available endpoints, parameters, and request examples. Reviewing this documentation will ensure you understand how to interact with Cliniko’s data programmatically.


3. Getting Started with Python

Setting Up the Environment

Start by preparing a Python environment. Here’s what you’ll need:

  • Python 3.x

  • IDE: PyCharm, VSCode, or Jupyter Notebook.

  • Libraries: Install the necessary packages using pip:

      pip install requests
    

Authentication with Cliniko API

Cliniko uses API Key authentication for secure access. Below is a simple way to set it up:

import requests

key = "your_api_key_here"
shard = API_KEY[-3:]
headers={"Accept":"application/json","User-Agent":""} # Use your User-Agent
username = API_KEY  # Use API key as the username
password = ""

url = f"<https://api>.{shard}.cliniko.com/v1/bookings/"

response = requests.get(url, headers=headers, auth=(username,password))

if response.status_code == 200:
    bookings = response.json()
    print("Bookings fetched successfully:", bookings)
else:
    print(f"Failed to fetch bookings. Status code: {response.status_code}, Response: {response.text}")

4. Making Basic API Requests

Fetching Appointment Data :

url = f"<https://api>.{shard}.cliniko.com/v1/bookings"
response = requests.get(url, headers=headers, auth=(username,password))
if response.status_code == 200:
    appointments = response.json()
    print("Appointments fetched successfully:", appointments)
else:
    print("Failed to fetch appointments. Status code:", response.status_code)

Fetching Individual Appointment Data :

id = 
url = f"<https://api>.{shard}.cliniko.com/v1/bookings/{id}"
response = requests.get(url, headers=headers, auth=(username,password))
if response.status_code == 200:
    appointments = response.json()
    print("Appointments fetched successfully:", appointments)
else:
    print("Failed to fetch appointments. Status code:", response.status_code)

Retrieving Patient Records :

url = f"<https://api>.{shard}.cliniko.com/v1/patients"
response = requests.get(url, headers=headers, auth=(username,password))
if response.status_code == 200:
    patients = response.json()
    print("Patient records fetched successfully:", patients)
else:
    print("Failed to fetch patient records. Status code:", response.status_code)

5. Advanced API Operations

Filtering and Query Parameters

Cliniko allows the use of powerful query parameters to filter data based on specific conditions. By using the q[] parameter, you can fine-tune your queries for appointments, patients, and other resources. Here are some examples of how to leverage this functionality.

1. Filtering Appointments by Date Range

To fetch appointments within a specific date range, you can apply multiple filters using the q[] parameter for conditions like "greater than" or "less than." For example, retrieving appointments that start after a certain date:

query = {
    "page": "0",
    "per_page": "1",
    "sort": "created_at:desc",
    "q[]": "starts_at:>2014-03-04T20:37:17Z",  # Start date filter
    "order": "asc"
}
url = f"<https://api>.{shard}.cliniko.com/v1/individual_appointments"
response = requests.get(url, params=query, headers=headers, auth=(username,password))

if response.status_code == 200:
    appointments = response.json()
    print("Filtered appointments:", appointments)
else:
    print("Failed to fetch filtered appointments. Status code:", response.status_code)

2. Using Wildcards for Flexible Search

You can perform more complex searches using wildcards by employing the ~~ symbol. For instance, to search for patients whose last names include a variation of "johnson":

query = {
    "page": "0",
    "per_page": "10",
    "q[]": "last_name:~~ja%on%",
    "order": "asc"
}
url = f"<https://api>.{shard}.cliniko.com/v1/patients"
response = requests.get(url, params=query, headers=headers, auth=(username,password))

if response.status_code == 200:
    patients = response.json()
    print("Filtered patients:", patients)
else:
    print("Failed to fetch filtered patients. Status code:", response.status_code)

3. Filtering Archived Records

To fetch archived records, you can filter with archived_at like this:

query = {
    "page": "0",
    "per_page": "10",
    "q[]": "archived_at:*",  # Fetch all records including archived
    "order": "asc"
}
url = f"<https://api>.{shard}.cliniko.com/v1/individual_appointments"
response = requests.get(url, params=query, headers=headers, auth=(username,password))

if response.status_code == 200:
    appointments = response.json()
    print("Archived appointments:", appointments)
else:
    print("Failed to fetch archived appointments. Status code:", response.status_code)

4. Sorting and Ordering Results

By default, results are ordered by the created_at field in ascending order. If you want to sort based on a different field, such as starts_at, and specify the order, you can use the sort and order parameters:

query = {
    "page": "0",
    "per_page": "10",
    "sort": "starts_at,created_at:desc",  # Sort by start time, then creation time
    "q[]": "starts_at:>2014-03-04T20:37:17Z",  # Example filter
    "order": "desc"
}
url = f"<https://api>.{shard}.cliniko.com/v1/individual_appointments"
response = requests.get(url, params=query, headers=headers, auth=(username,password))

if response.status_code == 200:
    appointments = response.json()
    print("Sorted appointments:", appointments)
else:
    print("Failed to fetch sorted appointments. Status code:", response.status_code)

Pagination

Large datasets are paginated. Use the next and prev links to navigate:

url = f"<https://api>.{shard}.cliniko.com/v1/bookings"
while url:
    response = requests.get(url, headers=headers, auth=(username,password))
    if response.status_code == 200:
        data = response.json()
        for record in data['records']:
            print(record)
        url = data.get('next')
    else:
        print("Failed to fetch data. Status code:", response.status_code)
        break

Error Handling in API Requests

To ensure your application handles API errors smoothly, follow this simple structure:

try:
    response = requests.get(url, headers=headers, auth=(username, password))
    response.raise_for_status()  # Checks for any HTTP error
    data = response.json()
except requests.exceptions.HTTPError as err:
    print(f"HTTP error occurred: {err}")
except Exception as e:
    print(f"An error occurred: {e}")

HTTP Response Codes :

  • 2xx: Success – Everything worked as expected.

  • 4xx: Client error – There was an issue with the request (e.g., missing required parameters).

  • 5xx: Server error – Something went wrong on the Cliniko server's side.


6. Challenges You Can Face When Using Cliniko APIs in Python

1. Authentication and Authorization Issues

Managing API keys securely is essential to avoid access issues or security vulnerabilities. Each API key is associated with a specific shard—the geographical server where your data is hosted. When making requests, ensure that the API key includes the correct shard information in the request, such as appending the shard ID to the API endpoint to direct the request to the correct server. Expired or invalid keys can lead to authentication failures, so regularly refresh and monitor your API keys.

2. API Deprecation or Changes

Cliniko may update or discontinue API endpoints, introduce new versions, or change response formats, causing compatibility issues. Regularly monitoring the API documentation and release notes helps ensure your integration stays up to date.


7. Custom Solutions for our client Abby

Fine-Tuning Intent Classification Models for Abby

Abby is an AI-powered solution designed to streamline appointment confirmations in healthcare operations through seamless integration with the Cliniko API. The client required us to develop a secure, stand-alone system that does not rely on broad-based language models, ensuring data privacy and adherence to stringent security standards.Available as a Chrome extension for Cliniko users, Abby uses a proprietary AI language model to analyze inbound responses, updating appointment statuses directly within the Cliniko calendar. With over 98% accuracy, it reliably handles most message intents, including emojis, while ongoing refinements address edge cases like conflicting responses.

Key Features:

  • AI-Powered SMS Analysis: Automatically interpret patient responses and instantly update appointment statuses, focusing on what requires action.

  • Enhanced Visuals for Cliniko: Temporary color-coded status markers in your Cliniko calendar make it easy to spot unconfirmed appointments.

  • Integrated Appointment Notes: Abby posts SMS responses directly to appointment notes, keeping all communication in one place.

  • No Learning Curve: A single click provides access to real-time appointment status without disrupting your workflow.

By automating routine tasks, Abby optimizes healthcare operations, improving patient experience while saving valuable administrative time—without compromising on security or patient confidentiality.

Check out Abby here : https://www.abby.clinic/.


8. AI-Powered Innovations for Healthcare

We specialize in developing custom AI solutions that seamlessly integrate with existing platforms like Cliniko, enabling clinics and healthcare businesses to automate processes, enhance patient interactions, and extract actionable insights from data.

Here’s how our AI expertise can benefit your practice:

RAG-Based AI Chatbots for Clinics – AI-powered chatbots capable of retrieving patient information, answering FAQs, and assisting with appointment scheduling based on real-time Cliniko data.

NL2SQL for Healthcare Analytics – Query your Cliniko database using natural language and extract structured insights without writing complex SQL queries.

Document Parsing with Vision LLMs – Process invoices, prescriptions, medical records, and insurance forms using advanced AI models that can accurately extract key details from scanned documents.

Automated Patient Reports & Summaries – Use AI to generate structured patient reports, summarizing appointment details, lab results, and doctor notes, reducing manual effort.

AI Agents for Administrative Tasks – Automate routine clinic operations, such as appointment confirmations, follow-ups, and billing inquiries, reducing workload and improving patient experience.

By combining Generative AI, NLP, and advanced data processing techniques, we create solutions that improve efficiency, reduce administrative burden, and optimize patient management.


9. Why Work With Us?

At FutureSmart AI, we bring a wealth of experience in Cliniko APIs, Python development, and cutting-edge AI solutions tailored for the healthcare industry.

🚀 Cliniko Expertise – Deep understanding of Cliniko APIs, enabling seamless integrations and automation.
🔍 AI-Driven Efficiency – We build secure, privacy-compliant AI solutions that enhance decision-making and reduce operational overhead.
📈 Custom-Tailored Solutions – Whether you need chatbot automation, document parsing, or AI-driven analytics, we create bespoke AI applications to fit your unique needs.
🔒 Security & Compliance – Our solutions adhere to industry best practices, ensuring patient data confidentiality and regulatory compliance.

Want to automate your clinic operations or build a custom AI-powered healthcare solution?
📩 Contact us at contact@futuresmart.ai to discuss how we can help!


10. Conclusion

Cliniko’s API ecosystem, combined with Python and AI, unlocks powerful opportunities for automating clinic workflows, streamlining data processing, and enhancing patient engagement. Whether it's AI-powered chatbots, document automation, or analytics-driven insights, FutureSmart AI can help you build scalable, intelligent solutions tailored to your needs.

Let's transform healthcare operations with AI. 🚀

28
Subscribe to my newsletter

Read articles from Pruthviraj Mahalunge directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Pruthviraj Mahalunge
Pruthviraj Mahalunge