Documentation
Official client libraries for integrating with the Cari platform.
Typed client for all Cari API endpoints with built-in auth and error handling.
The official Cari SDK for TypeScript and JavaScript applications. It provides a typed client for all Cari API endpoints with built-in authentication, error handling, and response envelope unwrapping.
# npm npm install @cari/sdk # yarn yarn add @cari/sdk # pnpm pnpm add @cari/sdk
import { CariClient } from "@cari/sdk";
const cari = new CariClient({
baseUrl: "https://api.cari.care",
// Option 1: API key (from Developer API Keys)
apiKey: "your-api-key",
// Option 2: PASETO token
token: "v4.public.eyJ...",
});API keys, PASETO tokens, and username/password login.
The SDK supports three authentication methods: API keys (recommended for server-to-server), PASETO tokens, and username/password login.
import { CariClient } from "@cari/sdk";
// API keys are created at /api/developer/keys
const cari = new CariClient({
baseUrl: "https://api.cari.care",
apiKey: process.env.CARI_API_KEY,
});import { CariClient } from "@cari/sdk";
const cari = new CariClient({
baseUrl: "https://api.cari.care",
});
// Login and store the token
const { user, token } = await cari.auth.login({
email: "developer@example.com",
password: "SecureP@ss123",
});
// The token is automatically used for subsequent requests
console.log("Logged in as:", user.email);// The SDK handles token refresh automatically when configured
const cari = new CariClient({
baseUrl: "https://api.cari.care",
token: "v4.public.eyJ...",
refreshToken: "v4.public.refresh...",
onTokenRefresh: (newToken) => {
// Store the new token (e.g., in a database or env)
console.log("Token refreshed");
},
});Use API key authentication for server-to-server integrations. It eliminates the need for token refresh and simplifies your integration.
Patients, appointments, clinical records, prescriptions, lab results, and more.
// List patients in an organization
const patients = await cari.patients.list(orgId, {
page: 1,
limit: 20,
});
console.log(`Found ${patients.meta.total} patients`);
// Get a specific patient
const patient = await cari.patients.get(patientId);
console.log(patient.first_name, patient.last_name);
// Create a patient
const newPatient = await cari.patients.create({
first_name: "Amara",
last_name: "Okafor",
date_of_birth: "1990-03-15",
gender: "female",
phone: "+234801234567",
});
// Search patients by MRN
const results = await cari.patients.search(orgId, {
mrn: "MRN-001",
});// Check availability
const slots = await cari.appointments.availability({
resource_id: doctorResourceId,
date: "2026-04-25",
});
// Book an appointment
const appointment = await cari.appointments.book({
resource_id: doctorResourceId,
patient_name: "Amara Okafor",
patient_email: "amara@example.com",
patient_phone: "+234801234567",
start_time: "2026-04-25T09:00:00Z",
end_time: "2026-04-25T09:30:00Z",
reason: "Annual checkup",
});
// Cancel an appointment
await cari.appointments.cancel(appointmentId);
// Get kanban board view
const kanban = await cari.appointments.kanban({
date: "2026-04-25",
});// List clinical records for a patient
const records = await cari.clinical.records.list(patientId);
// Create a clinical record
const record = await cari.clinical.records.create({
patient_id: patientId,
encounter_type: "consultation",
chief_complaint: "Persistent headache",
notes: "Patient reports headache for 3 days...",
});
// Record vitals
const vitals = await cari.vitals.create({
patient_id: patientId,
heart_rate: 72,
blood_pressure_systolic: 120,
blood_pressure_diastolic: 80,
temperature: 36.6,
respiratory_rate: 16,
oxygen_saturation: 98,
});// Create a prescription
const prescription = await cari.prescriptions.create({
patient_id: patientId,
medication: "Amoxicillin",
dosage: "500mg",
frequency: "3 times daily",
duration: "7 days",
instructions: "Take with food",
});
// Sign the prescription
await cari.prescriptions.sign(prescription.id);
// Send to pharmacy via e-prescribing
await cari.eprescriptions.create({
prescription_id: prescription.id,
pharmacy_id: pharmacyId,
});// List lab results for a patient
const labResults = await cari.labs.listResults(patientId);
// Create a lab order
const labOrder = await cari.labs.createOrder({
patient_id: patientId,
test_type: "CBC",
priority: "routine",
notes: "Annual screening",
});
// AI lab interpretation
const interpretation = await cari.ai.interpretLab({
patient_id: patientId,
lab_result_id: labResultId,
});// Check for drug-drug interactions
const interactions = await cari.cds.checkDrugInteractions({
medications: [
{ name: "Warfarin", rxcui: "11289" },
{ name: "Aspirin", rxcui: "1191" },
{ name: "Ibuprofen", rxcui: "5640" },
],
});
if (interactions.length > 0) {
for (const interaction of interactions) {
console.warn(
`[${interaction.severity}] ${interaction.description}`
);
}
}// List my organizations
const myOrgs = await cari.organizations.me();
// Get organization details
const org = await cari.organizations.get(orgId);
// Invite a member
await cari.organizations.invite(orgId, {
email: "newdoctor@hospital.org",
role: "ORG:DOCTOR",
});
// List members
const members = await cari.organizations.members(orgId);// Initiate a mobile money payment
const payment = await cari.payments.initiateMobileMoney({
provider: "mpesa",
phone: "+254712345678",
amount: 1500.00,
currency: "KES",
order_id: orderId,
description: "Consultation payment",
});
// Check payment status
const status = await cari.payments.getStatus(orderId);
console.log("Payment status:", status.state);Typed error classes with HTTP status codes and error codes.
import { CariClient, CariApiError } from "@cari/sdk";
const cari = new CariClient({ baseUrl: "https://api.cari.care" });
try {
const patient = await cari.patients.get("nonexistent-id");
} catch (error) {
if (error instanceof CariApiError) {
console.error(`API Error [${error.status}]: ${error.code}`);
console.error(error.message);
switch (error.status) {
case 401:
// Token expired — refresh or re-login
break;
case 403:
// Insufficient permissions
break;
case 404:
// Resource not found
break;
case 429:
// Rate limited — back off and retry
break;
}
}
}The SDK throws CariApiError for all non-2xx responses. Always wrap API calls in try/catch blocks for production applications.
Automatic envelope unwrapping with TypeScript types for all resources.
The SDK automatically unwraps the standard API response envelope. List endpoints return data with pagination metadata:
// Single resource — returns the data directly
const patient = await cari.patients.get(id);
// patient = { id, first_name, last_name, ... }
// List endpoint — returns data + meta
const result = await cari.patients.list(orgId, { page: 1, limit: 20 });
// result.data = [{ id, first_name, ... }, ...]
// result.meta = { page: 1, limit: 20, total: 42 }
// TypeScript types are provided for all resources
import type {
Patient,
Appointment,
ClinicalRecord,
Prescription,
Organization,
LabResult,
Vital,
} from "@cari/sdk";Full list of CariClient constructor options.
const cari = new CariClient({
// Required
baseUrl: "https://api.cari.care",
// Authentication (one of these)
apiKey: "your-api-key", // Recommended for server-to-server
token: "v4.public.eyJ...", // PASETO token
refreshToken: "v4.public...", // For automatic token refresh
// Optional
timeout: 30000, // Request timeout in ms (default: 30s)
retries: 3, // Number of retries on 5xx errors
onTokenRefresh: (token) => {}, // Callback when token is refreshed
userAgent: "my-app/1.0", // Custom User-Agent header
});Call the API directly from any HTTP client without the SDK.
If you prefer not to use the SDK, you can call the REST API directly from any HTTP client. All endpoints accept and return JSON:
// Using fetch (JavaScript)
const response = await fetch("https://api.cari.care/api/patients/" + patientId, {
headers: {
"Authorization": "Bearer v4.public.eyJ...",
"Content-Type": "application/json",
},
});
const { success, data } = await response.json();
if (success) {
console.log("Patient:", data.first_name, data.last_name);
}
// Using curl
curl -X GET https://api.cari.care/api/patients/{id} \
-H "Authorization: Bearer v4.public.eyJ..." \
-H "Content-Type: application/json"
// Using Python requests
import requests
response = requests.get(
f"https://api.cari.care/api/patients/{patient_id}",
headers={"Authorization": f"Bearer {token}"},
)
patient = response.json()["data"]Create, rotate, and revoke API keys for server-to-server integrations.
For server-to-server integrations, create API keys through the Organization service. API keys can be rotated and revoked without affecting user accounts.
// Create an API key
POST /api/developer/keys
Authorization: Bearer v4.public.eyJ...
Content-Type: application/json
{
"name": "Production Integration",
"scopes": ["patients:read", "appointments:write"]
}
// List API keys
GET /api/developer/keys
// Rotate a key (generates a new secret, old key remains valid for 24h)
POST /api/developer/keys/:id/rotate
// Revoke a key (immediate)
DELETE /api/developer/keys/:idRotate API keys regularly and use scoped keys with minimal permissions. The 24-hour grace period during rotation ensures zero-downtime key rotation.