Skip to main content

API Routing Architecture

The Zynomi platform uses same-origin split routing so that all browser API calls stay on a single domain — eliminating CORS complexity and simplifying authentication.


Overview

Every request hits a single origin (e.g., https://ctms.example.com). The reverse proxy (Caddy) inspects the path and routes it to the correct backend:

PathRouted ToHandles
/api/v1/*KrakenD API GatewayREST API (patients, studies, auth, appointments, etc.)
/* (everything else)Next.js ApplicationPages, SSR, static assets, /api/health
                          ┌──────────────────────────┐
│ Browser / Client │
│ https://ctms.example.com │
└────────────┬─────────────┘


┌──────────────────────────┐
│ Caddy (Reverse Proxy) │
│ Automatic HTTPS (443) │
└────────┬───────┬─────────┘
│ │
/api/v1/* │ │ /* (all else)
▼ ▼
┌─────────────────┐ ┌──────────────────┐
│ KrakenD Gateway │ │ Next.js (Zynexa) │
│ (Port 8080) │ │ (Port 3000) │
└────────┬────────┘ └──────────────────┘

┌───────────┼───────────┐
▼ ▼ ▼
┌────────┐ ┌──────────┐ ┌──────────┐
│ Frappe │ │ Supabase │ │ Other │
│ Health │ │ (Auth) │ │ Services │
└────────┘ └──────────┘ └──────────┘

Why Same-Origin?

BenefitDescription
No CORSBrowser API calls are same-origin — no preflight OPTIONS requests or Access-Control-* headers needed
Shared cookiesAuthentication cookies are shared automatically between pages and API calls
Simpler DNSOne domain per environment instead of separate api.* and app.* subdomains
Better securityTighter same-origin policy by default

API Endpoints

The KrakenD API Gateway provides a unified REST API over multiple backends (Frappe Health, Supabase, external services):

Core Endpoints

EndpointMethodsDescription
/api/v1/signinPOSTUser authentication (Supabase)
/api/v1/signupPOSTUser registration (Supabase)
/api/v1/signoutPOSTSign out
/api/v1/patient/{email}GETPatient details by email
/api/v1/patientsGETList patients
/api/v1/doctype/{entity}GET, POSTGeneric entity CRUD
/api/v1/doctype/{entity}/{id}GET, PUT, DELETESpecific entity operations
/api/v1/{entity}/countGETEntity record count

Clinical Endpoints

EndpointMethodsDescription
/api/v1/appointmentsGETList appointments
/api/v1/appointment/{id}GET, DELETEAppointment details
/api/v1/appointment/bookingPOSTBook new appointment
/api/v1/practitioner/{id}GETPractitioner details
/api/v1/practitioner/appointment/availabilityGETAvailable slots
EndpointMethodsDescription
/api/v1/devicesGET, POST, DELETEDevice management
/api/v1/medication_consumption_logsGET, POSTMedication tracking
/api/v1/notification/logsGET, POST, PATCHPush notifications
/api/v1/remindersGETMedication reminders

Server-Side vs Client-Side

The platform separates API URLs for Docker deployments where internal and external addresses differ:

ContextURLTransport
Browser (client-side)https://ctms.example.com/api/v1→ Caddy → KrakenD
Server (SSR / API routes)http://api-gateway:8080/api/v1→ Docker network (direct)
  • Client-side calls go through Caddy (HTTPS, same-origin)
  • Server-side calls skip Caddy and go directly to the API Gateway over the Docker network — faster and no TLS overhead

This is configured via environment variables:

VariablePurpose
RUNTIME_API_BASE_URLServer-side URL (Docker-internal, used by Next.js SSR)
RUNTIME_API_CLIENT_URLClient-side URL (browser-accessible, same-origin)

Adding New API Routes

When adding new endpoints, choose the correct location:

If the route needs...Add it to...Path prefix
Frappe/Supabase proxy, aggregation, cachingKrakenD gateway config/api/v1/
Next.js-specific logic (SSR data, auth callbacks)Next.js API routes/api/ (no /v1/)
Important

All requests to /api/v1/* are routed to the KrakenD API Gateway. New Next.js API routes should not use the /api/v1/ prefix — use /api/ instead.


Local Development

For local Docker development, the platform uses *.localhost domains:

# /etc/hosts (add these entries)
127.0.0.1 zynexa.localhost api.localhost sublink.localhost
127.0.0.1 cube.localhost mcp.localhost odm.localhost observe.localhost
URLService
https://zynexa.localhostCTMS Web App + API (same-origin)
https://api.localhostAPI Gateway (standalone, for direct testing)
https://sublink.localhostSublink Mobile App
https://cube.localhostCube.dev Analytics Playground
https://observe.localhostOpenObserve (Logs & Metrics)

Caddy generates self-signed certificates automatically (local_certs). Accept the browser warning on first visit.