Connect Healthie to AI Agents: Sync Appointments and Lab Orders
Give your AI agent Healthie tools.
A technical guide for engineering teams building AI agents on top of Healthie. Learn how to fetch AI-ready tools, handle GraphQL complexity caps, and build autonomous clinical workflows.
In this guide
- 01Fetch AI-ready Healthie Tools
- 02Bind Tools to the LLM Framework
- 03Implement Rate Limit Handling
- 04Construct the Agent Loop
- 05Deploy and Monitor
The guide
Learn how to connect Healthie to AI agents using Truto's /tools endpoint. Build autonomous workflows for appointments, lab orders, and patient records.
You want to connect Healthie to an AI agent so your platform can independently read charting notes, sync appointments, request lab orders, and trigger automated patient workflows based on historical context. Here is exactly how to do it using Truto's /tools endpoint and SDK, bypassing the need to build a custom integration from scratch.
Giving a Large Language Model (LLM) read and write access to your Healthie instance is an engineering headache. You either spend weeks building, hosting, and maintaining a custom GraphQL connector, or you use a managed infrastructure layer that handles the boilerplate for you. If your team uses ChatGPT, check out our guide on connecting Healthie to ChatGPT, or if you are building on Anthropic's models, read our guide on connecting Healthie to Claude. For developers building custom autonomous workflows, you need a programmatic way to fetch these tools and bind them to your agent framework.
This guide breaks down exactly how to fetch AI-ready tools for Healthie, bind them natively to an LLM using LangChain (or any framework like LangGraph, CrewAI, or Vercel AI SDK), and execute complex clinical operations workflows. For a deeper look at the architecture behind this approach, refer to our research on architecting AI agents and the SaaS integration bottleneck.
Why a Unified Tool Layer Matters for Agent Safety
Before writing a line of integration code, decide what layer your agent talks to. This choice determines how safe your production system will be.
Direct API tools (one tool per raw Healthie endpoint) look convenient, but they push provider quirks directly into the LLM's context window. The model has to remember exactly how Healthie's GraphQL mutations are structured, which query fields are permissible, and how to handle pagination cursors. Every one of those quirks is a hallucination waiting to happen.
By proxying the API through a unified tool layer, your agent sees standard, REST-based operations with flat schemas. It sees list_all_healthie_appointments, create_a_healthie_care_plan, and update_a_healthie_client_by_id. That gives you concrete safety wins:
- Smaller attack surface for hallucination. The LLM only ever chooses from stable function names with strict JSON schemas. It never invents GraphQL fragments.
- Deterministic input validation. Invalid arguments are rejected by the tool layer before they hit Healthie, so a broken tool call fails fast instead of silently corrupting clinical records.
- Optimized Context Window. Standardized tool descriptions reduce token overhead, leaving more context window available for the agent's actual reasoning.
The Engineering Reality of the Healthie API
Giving an LLM access to external data sounds simple in a prototype. You write a Node.js function that makes a fetch request and wrap it in an @tool decorator. In production against complex healthcare platforms like Healthie, this approach collapses.
Healthie's API introduces several specific integration challenges that break standard REST assumptions. If you hardcode these interactions into your agent, you will spend your sprints writing defensive integration code instead of improving your model's reasoning.
The GraphQL Complexity Cap Trap
Healthie's API is built on GraphQL and strictly enforces a complexity cap. Currently, Healthie limits requests to 2000 complexity points. Standard AI agent implementations often attempt to request broad, deep datasets - pulling all appointments, zooming into their nested patient records, attached Zoom meeting recordings, dial-in numbers, and lab results in a single sweep.
If you let an LLM dynamically construct GraphQL queries, it will repeatedly hit the 2000-point complexity limit, resulting in constant request failures. Truto solves this by providing pre-mapped REST-style Proxy APIs on top of the GraphQL layer. To protect the complexity limit, Truto's pre-configured tools explicitly omit heavy, expensive nested objects (like zoom_cloud_recording_files and zoom_dial_in_numbers_json) on broad list queries, ensuring your agent can reliably paginate through records without crashing the connection.
Granular EMR Data Models
Healthie utilizes a highly granular data model tailored for Electronic Medical Records (EMR). You do not simply "create a note." You interact with a FormAnswerGroup that must be carefully linked to a specific Appointment and Client. Creating an episode of care requires mapping specific diagnosis IDs and patient relationships.
LLMs struggle with deeply relational entity mapping. When they try to build these structures dynamically across multiple raw GraphQL mutations, they frequently drop required relationships. By abstracting these resources into dedicated CRUD tools, you enforce strict schema boundaries. The LLM understands that it must pass form_answer_group_id when calling an attachment tool, because the schema explicitly demands it.
Strict Rate Limits and The Retry Responsibility
Like all enterprise platforms, Healthie aggressively rate-limits heavy traffic. Factual note on rate limits: Truto does not retry, throttle, or apply backoff on rate limit errors. When the upstream Healthie API returns an HTTP 429, Truto passes that error directly to the caller.
What Truto does do is normalize the upstream rate limit information into standardized headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset) per the IETF spec.
As the developer, your agent framework is responsible for retry and backoff logic. If you do not explicitly handle 429s in your agent's tool execution loop, a burst of autonomous activity will crash your workflow mid-execution.
Hero Tools for Healthie AI Agents
Truto exposes Healthie's resources as individual, LLM-ready tools. You fetch these dynamically using the /tools endpoint. Here are the core high-leverage operations your agents will use most frequently.
List Appointments
list_all_healthie_appointments
Fetches a paginated collection of appointments. This is the foundation of any scheduling or clinical preparation agent. Truto handles the GraphQL pagination cursors automatically based on the parameters passed.
"Fetch all appointments for today. For each appointment, tell me the patient's name and the reason for the visit so I can prepare the intake notes."
Create an Appointment
create_a_healthie_appointment
Executes the createAppointment mutation for providers. Because booking logic in healthcare is strict, this tool forces the agent to pass exact time, date, and patient parameters, ensuring valid scheduling.
"Book a 30-minute follow-up appointment for patient ID 48291 next Tuesday at 2:00 PM EST. Set the reason as 'Lab Result Review'."
List Lab Orders
list_all_healthie_lab_orders
Fetches the collection of lab orders related to the current user or a specific patient. Essential for agents tasked with pre-visit chart reviews or asynchronous clinical summaries.
"Check the system for any pending lab orders for John Doe (ID 9931) and list the specific tests that were requested last week."
Create a Care Plan
create_a_healthie_care_plan
Creates a new care plan for a patient. This is highly useful for autonomous intake coordinators that need to generate baseline plans when new clients are onboarded.
"Generate a new care plan for patient ID 8821. Include the standard dietary guidelines and set the primary goal to 'Maintain hydration levels'."
Create a Form Answer Group
create_a_healthie_form_answer_group
In Healthie, charting notes and intake forms are handled as form answer groups. This tool allows the agent to construct and save charting data against a specific client.
"Draft a new charting note based on the transcript from our last session. Save it as a new form answer group for patient ID 11223."
Update Client Records
update_a_healthie_client_by_id
Updates demographic or status information for a client. The tool accepts a strict schema, ensuring the LLM cannot overwrite immutable fields or corrupt the patient record.
"Update the contact information for Sarah Connor. Change her primary phone number to 555-0199 and mark her account as active."
For the complete tool inventory and schema details, visit the Healthie integration page.
Workflows in Action
Individual tools are useful, but the real power of AI agents emerges when chaining these operations together to solve complex business logic. Here is what that looks like in practice.
Scenario 1: The Autonomous Intake Coordinator
Clinic administrators spend hours manually checking schedules, verifying care plans, and sending intake forms to new patients. An AI agent can run this workflow autonomously every morning.
"Check my appointments for tomorrow. For any new clients who do not currently have a care plan, create a default care plan and draft their initial intake charting forms."
Agent Execution Steps:
list_all_healthie_appointments: The agent queries Healthie for tomorrow's schedule.list_all_healthie_care_plans: For each patient returned in step 1, the agent queries the system to see if an active care plan exists.create_a_healthie_care_plan: If the array from step 2 is empty, the agent executes this tool to generate a baseline plan.create_a_healthie_form_answer_group: The agent creates the initial intake forms linked to the new patient's profile.
What the user gets: A fully prepared daily schedule where all new patients have been initialized in the EMR without any manual data entry from the front desk.
Scenario 2: The Clinical Lab & Charting Assistant
Providers need to synthesize lab results into charting notes quickly. An agent can monitor incoming labs, summarize the findings, and prepare the chart before the provider even opens the file.
"Pull the latest lab results for patient ID 50921, summarize the key findings, and append them as a new charting note for review."
Agent Execution Steps:
list_all_healthie_lab_orders: The agent retrieves the lab order metadata for the specific patient ID.get_single_healthie_lab_result_by_id: The agent fetches the actual data payload for the most recent completed lab.- LLM Processing: The agent's core model synthesizes the dense lab data into a concise clinical summary.
create_a_healthie_form_answer_group: The agent writes the summary back into Healthie as a new charting note.
What the user gets: A drafted, highly accurate clinical note sitting in the patient's chart, ready for the provider's final signature, saving 10-15 minutes of manual transcription per patient.
Building Multi-Step Workflows
To build these workflows, you need to connect your agent framework to Truto. The following architecture works universally across LangChain, LangGraph, Vercel AI SDK, and custom implementations.
1. Fetching Tools Dynamically
Instead of writing API wrappers, your application fetches the active tools directly from Truto. This ensures your agent always has the most up-to-date descriptions and schemas.
// Fetching Healthie tools from Truto
async function getHealthieTools(integratedAccountId: string) {
const response = await fetch(
`https://api.truto.one/integrated-account/${integratedAccountId}/tools?methods[0]=custom&methods[1]=read&methods[2]=write`,
{
headers: {
Authorization: `Bearer ${process.env.TRUTO_API_KEY}`
}
}
);
if (!response.ok) {
throw new Error(`Failed to fetch tools: ${response.statusText}`);
}
return await response.json();
}2. Binding Tools to the Agent
Once you have the tool definitions, you map them into your framework's expected format. If you are using LangChain, the truto-langchainjs-toolset SDK handles this automatically. If you are building custom, you simply pass the JSON schemas to the model.
import { ChatOpenAI } from "@langchain/openai";
import { TrutoToolManager } from "truto-langchainjs-toolset";
// Initialize the LLM
const llm = new ChatOpenAI({
modelName: "gpt-4o",
temperature: 0,
});
// Initialize Truto tools for the specific Healthie account
const toolManager = new TrutoToolManager({
apiKey: process.env.TRUTO_API_KEY,
integratedAccountId: "healthie-account-id",
});
const tools = await toolManager.getTools();
// Bind the tools to the LLM
const agentWithTools = llm.bindTools(tools);3. The Execution Loop and Rate Limit Handling
The most critical part of an autonomous workflow is the execution loop. Because Truto passes rate limits directly to the caller, your loop must inspect errors and respect the ratelimit-reset header.
sequenceDiagram
participant App as Agent Loop
participant LLM as GPT-4 / Claude
participant Truto as Truto Proxy API
participant Healthie as Healthie GraphQL API
App->>LLM: User prompt + Available Tools
LLM-->>App: tool_calls (e.g., list_all_healthie_appointments)
App->>Truto: Execute Tool (REST)
Truto->>Healthie: Proxy to GraphQL
alt Rate Limit Hit
Healthie-->>Truto: 429 Too Many Requests
Truto-->>App: 429 Error with ratelimit-* headers
App->>App: Sleep until ratelimit-reset
App->>Truto: Retry Tool Execution
Truto->>Healthie: Proxy to GraphQL
end
Healthie-->>Truto: JSON Data
Truto-->>App: Normalized JSON response
App->>LLM: Return Tool Output
LLM-->>App: Final synthesized responseHere is how you implement that robust calling logic in TypeScript:
async function executeToolWithRetry(tool: any, args: any, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
// Execute the tool call
const result = await tool.invoke(args);
return result;
} catch (error: any) {
if (error.status === 429) {
// Truto normalizes these headers from Healthie
const resetTimeStr = error.headers.get('ratelimit-reset');
const resetTime = resetTimeStr ? parseInt(resetTimeStr, 10) : Date.now() + 5000;
const waitTime = Math.max(0, resetTime - Date.now());
console.log(`Rate limit hit. Waiting ${waitTime}ms before retry...`);
await new Promise(resolve => setTimeout(resolve, waitTime));
continue;
}
// If it's not a rate limit, fail fast so the LLM can see the error
throw error;
}
}
throw new Error("Max retries exceeded for tool execution.");
}By feeding the exact error (whether a 400 validation error or a structural issue) back into the LLM context, the model can self-correct. If it hallucinates a parameter, it sees the failure, adjusts its arguments, and tries again.
Moving Fast Without Breaking Healthcare Data
Building AI agents that interact with complex EMR systems like Healthie requires a rigorous approach to system design. You cannot afford to let an LLM invent GraphQL queries on the fly, and you cannot afford to maintain a massive library of custom integration code.
By leveraging Truto's /tools endpoint, you collapse the integration surface area. Your agent gets a clean, standardized set of REST operations, strictly enforced JSON schemas, and deterministic execution paths. You spend your engineering cycles optimizing prompts and agent reasoning, while the infrastructure layer handles the SaaS integration bottleneck.
FAQ
- How does Truto handle Healthie's GraphQL complexity cap?
- Truto proxies Healthie's GraphQL API into standard REST endpoints. However, because Healthie's complexity cap limits the depth of queries, Truto strips excessively complex nested objects (like Zoom meeting metadata) by default to prevent your AI agent from hitting the 2000-point limit on standard list queries.
- Does Truto automatically retry when the agent hits a rate limit?
- No. Truto passes Healthie's HTTP 429 rate limit errors directly to the caller and normalizes the rate limit headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset) per the IETF specification. Your agent framework is responsible for handling retries and exponential backoff.
- Can I use Truto's tools with any LLM framework?
- Yes. Truto's /tools endpoint returns standard JSON schemas describing each API method. You can dynamically bind these to any framework, including LangChain, LangGraph, CrewAI, or the Vercel AI SDK.
- How do I prevent the LLM from hallucinating Healthie IDs?
- By using a unified tool layer. Truto enforces strict JSON schema validation before the payload ever reaches Healthie. If the model hallucinates an invalid argument or malformed ID, the tool rejects the call immediately, returning an error to the LLM so it can correct its mistake without corrupting downstream data.