Documentation

Getting Started

Architecture overview, authentication, and your first API call.

Platform Architecture

Independent microservices built in Rust, deployed on Google Cloud Run.

Cari is built as a set of independent microservices, each responsible for a specific domain of healthcare operations. All services are written in Rust using the Axum web framework, backed by CockroachDB for distributed SQL storage, and deployed as containers on Google Cloud Run in the europe-west1 region.

Services

The platform consists of the following backend services:

Gateway:4000

API gateway, PASETO auth, rate limiting, RBAC, FHIR validation

Auth:4001

Registration, login, PASETO tokens, MFA, email verification

Doctors:4002

Doctor profiles, schedules, clinical records, prescriptions

Patients:4003

Patient profiles, vitals, lab results, immunizations, consent

Organization:4005

Org CRUD, members, rooms, admissions, invoices, payments

Scheduling:4006

Resources, schedules, appointments, telemedicine, CHW visits

Session

Recordings, AI transcription, clinical notes, voice dictation

MPI

Master Patient Index — matching, linking, deduplication

CDS

Drug interactions, AI diagnosis, risk scoring, early warnings

RCM

Claims, invoices, eligibility, pre-auth, fraud detection

Marketplace

Supply ordering, inventory, suppliers, purchase orders

Workforce

Staff rostering, shifts, swaps, fairness, training, CME

Treatments

Treatment protocol definitions and patient tracking

Payments

Mobile money — M-Pesa, MTN MoMo, Orange Money

Notifications

WhatsApp messaging, templates, session management

GTM

Leads, contacts, campaigns, email sequences, analytics

Feedback

User feedback collection (authenticated and anonymous)

DHIS2 Export

Bidirectional sync with national health systems

Frontend

The web application is built with Next.js (App Router) using React, TypeScript, Tailwind CSS, and Radix/shadcn UI components. It runs on Vercel or Cloud Run and communicates with the backend through a Next.js API proxy layer that forwards requests to the Rust gateway, handling cookie-based authentication transparently.

Authentication

PASETO v4 public tokens — a modern, secure alternative to JWT.

Cari uses PASETO v4 (public) tokens for authentication. PASETO (Platform-Agnostic Security Tokens) is a modern alternative to JWT that eliminates entire classes of cryptographic vulnerabilities by design.

Token Flow

1

Register or log in

Call /api/auth/register or /api/auth/login to authenticate.

2

Receive tokens

The server returns a PASETO access token and a refresh token, set as httpOnly cookies for web clients.

3

Include in requests

For API access, include the token in the Authorization header as Bearer <paseto_token>.

4

Refresh when expired

When the access token expires, call /api/auth/refresh with the refresh token to obtain a new access token.

Multi-Factor Authentication

Cari supports TOTP-based MFA (compliant with HIPAA 164.312(d) and NIST SP 800-63B AAL2). Use the /api/auth/mfa/enroll, /api/auth/mfa/verify, and /api/auth/mfa/challenge endpoints to manage MFA.

Web vs. API Authentication

Web (browser)

Tokens are stored as httpOnly, secure cookies (paseto_token, refresh_token). The Next.js proxy forwards these automatically.

API (programmatic)

Include the PASETO token in the Authorization: Bearer <token> header with each request.

PASETO eliminates algorithm confusion attacks by design. Unlike JWT, there is no alg header to manipulate — the token version dictates the algorithm.

Making Your First API Call

Register, authenticate, and fetch data in four steps.

1

Register a User

curl -X POST https://api.cari.care/api/auth/register \
  -H "Content-Type: application/json" \
  -d '{
    "email": "developer@example.com",
    "password": "SecureP@ss123",
    "first_name": "Jane",
    "last_name": "Doe",
    "registration_role": "DOCTOR"
  }'
2

Log In

curl -X POST https://api.cari.care/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "developer@example.com",
    "password": "SecureP@ss123"
  }'

# Response:
{
  "success": true,
  "data": {
    "user": { "id": "...", "email": "developer@example.com", ... },
    "token": "v4.public.eyJ..."
  }
}
3

Use the Token

curl https://api.cari.care/api/auth/me \
  -H "Authorization: Bearer v4.public.eyJ..."

# Response:
{
  "success": true,
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "email": "developer@example.com",
    "first_name": "Jane",
    "last_name": "Doe",
    "roles": ["DOCTOR"]
  }
}
4

List Patients (Authenticated)

curl https://api.cari.care/api/organizations/{org_id}/patients \
  -H "Authorization: Bearer v4.public.eyJ..."

# Response:
{
  "success": true,
  "data": [...],
  "meta": { "page": 1, "limit": 20, "total": 42 }
}

Response Format

All API responses follow a consistent envelope format.

Success Response

{
  "success": true,
  "data": { ... },
  "meta": {
    "page": 1,
    "limit": 20,
    "total": 100
  }
}

The meta field is included on paginated list endpoints. Single-resource endpoints return data without meta.

Error Response

{
  "success": false,
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Invalid or expired token"
  }
}
400Bad Request

Validation errors

401Unauthorized

Missing or invalid token

403Forbidden

Insufficient permissions

404Not Found

Resource does not exist

429Rate Limited

Too many requests

500Server Error

Internal server error

Rate Limiting

Per-IP rate limits enforced at the gateway using Redis-backed counters.

Auth endpoints

/api/auth/*

300 req/min

All other endpoints

Every other API path

600 req/min

When rate-limited, the API returns HTTP 429 with a message indicating when the limit resets.