Skip to content
Home/Case studies/Patient Message Triage API

Patient Message Triage API

AI that reads patient messages and sends each request to the right team, in under 2 seconds.

Health AICase study6 technologies
Quick summary

An AI routing service: a message with a refill and a new symptom is split and sent to the nurse and clinician queues. It suggests a route, never a diagnosis.

Patient Message Triage API preview

Overview

What this is and why it matters, in plain English.

An AI routing service: a message with a refill and a new symptom is split and sent to the nurse and clinician queues. It suggests a route, never a diagnosis.

AI that reads patient messages and sends each request to the right team, in under 2 seconds.

The situation

What was going on before, and why it needed fixing.

Patient messages often mixed a refill request with a new symptom. One label sent the whole thread to one desk, and urgent symptoms waited behind billing.

One message often held a refill and a new symptom. A single label sent the whole thread to the wrong desk, and urgent swelling waited behind billing.

What it needed to do

The outcomes the project had to deliver.

  • Split mixed messages into separate intents.
  • Route each intent to a queue the clinic actually staffs.
  • Return a route, never a diagnosis or treatment.

What I did

My part of the work and who I worked with.

I built the Node.js service, the prompts for Claude and ChatGPT, the closed label set and RBAC map, and the Redis routing cache.

How it works

The main building blocks, from the screen people use to the data underneath.

A Node service calls Claude or ChatGPT with a fixed label set, stores the route in Redis for the shift, and refuses labels outside the clinic’s RBAC map.

  1. 01

    REST endpoint

    Accepts a patient message and returns one route per intent.

  2. 02

    LLM classification

    Claude or ChatGPT splits intents and labels each from a fixed set.

  3. 03

    RBAC label map

    Filters out any label the clinic has not mapped to a staffed queue.

  4. 04

    Redis

    Stores routes for the shift so queues read quickly.

Key choices and trade-offs

Every build involves trade-offs. These are the important ones and what each one cost.

DecisionTrade-off
Closed enum of labels.New intents need a config change, but the model cannot invent a queue.
Routes, not advice.Less automation, but triage stays a sorting step and clinical judgment stays with people.

Under the hood

Implementation details for technical readers, with a code sample.

  • Routing in under 2 seconds.
  • Closed label set enforced after the model.
  • Automatic first-pass inbox sort.
const labels = ['refill', 'symptom', 'billing', 'scheduling'] as const;

export async function triage(message: string) {
  const raw = await llm.json({
    system: 'Split intents. Use only the allowed labels. No diagnosis.',
    input: message,
    schema: { intents: labels },
  });
  return raw.intents.filter((item) => labels.includes(item.label));
}

Problems solved

What got in the way, and how each problem was fixed.

  1. 01

    Mixed intents had to split instead of picking the first sentence.

    The prompt asks for all intents, and the schema expects a list, so a message with a refill and a symptom produces two routes.

  2. 02

    The model could not invent a queue the clinic did not staff.

    Model output is filtered against the clinic’s RBAC map; unmapped labels are refused.

  3. 03

    A triage suggestion is not a diagnosis, so the API returns a route, not a treatment.

    The API returns a route only and the prompt forbids diagnosis, keeping triage separate from treatment.

Security, speed and growth

How data is protected, and how the system stays fast as usage grows.

Security

RBAC controls which queues exist per clinic, and only routes are stored, not clinical conclusions.

Speed & growth

Each message routes in under 2 seconds, with shift routes cached in Redis.

Quality and releases

How changes were tested and shipped safely.

Message fixtures with mixed intents, out-of-set labels, and requests for advice, each with expected routes.

Tech stack

The tools and technologies used, for recruiters and technical reviewers.

Node.jsClaudeChatGPTRedisRBACREST

Results

Measured outcomes recorded for this project.

MetricResult
Route time<2 sec
Label setclosed enum
Inbox sortauto first pass

Questions

Plain answers first, then the detail a technical reviewer would ask about.

Common questions

Does it give patients medical advice?
No. It only decides which team should see a message. Clinical decisions stay with clinicians.
What does it change for staff?
Messages reach the right queue in under 2 seconds, so nurses and clinicians spend less time sorting the inbox.

For your tech lead

What if a message has two requests?
Each intent becomes its own route to its own queue.
Does it give medical advice?
No. It returns a route only.

Key takeaways

  • •AI that reads patient messages and sends each request to the right team, in under 2 seconds.
  • •Built with Node.js, Claude, ChatGPT, Redis, RBAC, REST.
Send a brief
Engagement

Choose how we work together

01

Join your team

A senior engineer inside your team. I work in your codebase, standups and code reviews, and stay long enough to own a real part of the product. Under the hood: Laravel, Node.js, Python or AWS.

Full-time or long contract
02

Work solely for your company

A dedicated engineer for one company. I take the product from planning to the live version: backend, data, hosting and screens, with your product as my focus.

Dedicated contract
03

One project

A clearly defined build, then a clean handover: an MVP, taking an AI-built prototype (Lovable, Bolt, Cursor) to production, a migration, or an AI feature. Get in touch to discuss scope and pricing.

Fixed-scope project

Prefer to hire through a platform? I'm onUpworkand