Clinical resources
The diet office over the API. All clinical endpoints require the clinical feature (Pro and Enterprise plans); reads need membership, writes generally need staff rank or above, and diet-order verification honors the rd credential model described in Authentication.
Residents (census)
GET /orgs/{orgId}/residents?siteId&status&unit
POST /orgs/{orgId}/residents
GET /orgs/{orgId}/residents/{id} — chart: orders, intake, weights
PATCH /orgs/{orgId}/residents/{id}
POST /orgs/{orgId}/import/residents — CSV roster import
Residents are unique per organization by MRN; site + MRN is the match key used by the HL7 ADT feed.
Diet orders
POST /orgs/{orgId}/diet-orders/parse — AI: free text → structured order (503 when AI is off)
POST /orgs/{orgId}/residents/{id}/diet-orders — write a new order (supersedes the active one)
POST /orgs/{orgId}/diet-orders/{id}/verify — dietitian verification
POST /orgs/{orgId}/diet-orders/{id}/discontinue
Orders are kardex-style: one active order per resident; writing a new one supersedes the previous and keeps the history. There is deliberately no "edit" — correct an order by writing its replacement.
Tray line
POST /orgs/{orgId}/trays/generate — {siteId, date, dayPart}
GET /orgs/{orgId}/trays?siteId&date&dayPart
PATCH /orgs/{orgId}/trays/{id} — assembling → checked → delivered
POST /orgs/{orgId}/trays/late — ad-hoc late tray
Generation builds one ticket per active resident from the effective menu × their active diet order. Conflicts (allergen, diet, texture, NPO) are computed with deterministic shared rules; where a menu alternate satisfies the order, the substitution is applied automatically and recorded on the ticket's conflicts. Tray delivery fires the tray.delivered webhook.
Intake, weights, risk
GET /orgs/{orgId}/intake?siteId&date&dayPart
POST /orgs/{orgId}/intake — % eaten, fluids, refusals per meal
POST /orgs/{orgId}/weights
GET /orgs/{orgId}/intake/risk — the nutrition-risk dashboard feed
GET /orgs/{orgId}/clinical/summary — diet-office landing KPIs
GET /orgs/{orgId}/clinical/summary?siteId=… returns the landing KPIs:
{
"census": 8,
"withOrders": 8,
"withoutOrders": 0,
"unverifiedTherapeutic": 1,
"dietCounts": { "cardiac": 1, "low_sodium": 1, "renal": 1, "vegetarian": 1 },
"textureCounts": { "regular": 6, "iddsi_6": 1, "iddsi_4": 1 },
"units": ["East Wing", "West Wing"]
}
Intake writes are idempotent per resident × meal — resubmitting merges rather than duplicates (they're also what the offline staff app syncs).
Population nutrition
GET/POST /orgs/{orgId}/population-targets (+ PUT /{id})
POST /orgs/{orgId}/menu-analysis — menu vs targets, diet coverage
GET /orgs/{orgId}/resident-cost?siteId&from&to — per-resident food cost (RFCPRD)
GET /orgs/{orgId}/resident-cost/{residentId}?from&to — per-meal breakdown
Resident cost mirrors tray-selection logic without persisting anything: it sums published recipe cost per portion for what would be served, flags uncosted items, and returns days, by-resident, and by-unit breakdowns plus the RFCPRD figure.