
Claude Triage API
A reference customer-support triage service on the Claude API — four routes, six labs, and a fake outdoor retailer where you can file a ticket and watch it get classified live.
By Michael Lynn • 8/19/2026
Claude Triage API
Most Claude API tutorials show you one thing at a time. Structured outputs in one repo. Tool use in another. Streaming in a third. Fine for a hello world. Not fine for production, where the same request might need a validated schema, a policy lookup, a streamed reply, and a cost estimate before anyone hits send.
I built the version I wanted when I was learning this early on.
Three things, one scenario
Everything hangs off of a fictional company called Northwind Outfitters. Imagine that they sell outdoor gear on a lifetime workmanship guarantee, which sounds nice until you hear they take 4,100 support tickets a week. And once they left a child's injury report sitting unrouted for three days because it opened with "probably nothing."
This closely mirrors a company, and a use case I encountered when I was executing Developer Days interviews back at MongoDB.
That incident in question was not fiction... but it shaped the way I looked at implementing support case triage and helped me crystalize how I wanted to create a learning lab. It is precisely why the triage schema was created with a calibrated confidence score. It is also why
/v1/resolve returns the full tool trace. And it is why the eval set includes a deliberately ambiguous case that is allowed to fail.| What | Where |
|---|---|
| The service | src/ — runs locally, not deployed |
| The course | claude-triage-labs.vercel.app — six labs, solutions, instructor guide, interactive playgrounds |
| The scenario, made real | northwind-outfitters.vercel.app — browse the catalog, file a ticket, watch your words get classified live |
The storefront calls Claude for real. Rate-limited and spend-capped through MongoDB Atlas. Five requests per IP per ten minutes, a global daily ceiling, and it fails closed rather than running uncapped.
Four routes
Each route builds on the one before it.
| Route | Capability | What it teaches |
|---|---|---|
POST /v1/triage | Structured outputs | The model's output contract is your type system |
POST /v1/resolve | Tool use | Claude queries your systems and shows its work |
POST /v1/draft | Streaming | Token-by-token delivery over SSE, with real cost accounting |
POST /v1/estimate | Token counting | Know the bill before you pay it |
Prompt caching on a ~1,400-word policy handbook runs through all of it. So does usage and cost accounting on every response, typed error handling, and an eval harness with both deterministic scoring and an LLM judge.
The structured output route is the one I keep coming back to. One Zod schema in
src/schemas.ts is the model's output constraint, the runtime validator, and the TypeScript type your consumers get. No JSON.parse in a try/catch. No "respond only with JSON" in the prompt. No repair loop.The course
Roughly four hours end to end, with solutions included.
- Your first call, and reading usage (20 min)
- Structured outputs and schema design (35 min)
- Tool use and the agentic loop (45 min)
- Streaming and SSE (30 min)
- Prompt caching and cost (35 min)
- Evals and LLM-as-judge (45 min)
The Docusaurus site at claude-triage-labs.vercel.app has inline knowledge checks, four interactive playgrounds (cost explorer, trace stepper, cache inspector, queue demo), and an auto-scored assessment. The markdown source lives in
curriculum/ in the repo and syncs into the site. Edit the markdown on GitHub, not the generated docs.Start with the scenario page before Lab 1. Most of the questions the labs ask only make sense once you know why a refund cap exists or why the trace has to come back with the decision.
Quickstart
If you want to run the service locally:
bash code-highlightgit clone https://github.com/mrlynn/claude-triage-api.git
cd claude-triage-api
npm install
cp .env.example .env
# add your key from console.anthropic.com
npm run smoke
npm run smoke exercises all four routes in-process and prints the prompt-cache hit on the second call. It costs about $0.10. Full setup and troubleshooting are in the repo's curriculum/setup.md.What I was trying to get right
A few details mattered more than the feature list.
Two identical-prefix calls to
/v1/triage came back 81% cheaper on the warm call. But the cold call cost more than no caching at all, because of the write premium. Caching a one-shot prefix loses money. That is Lab 5, not a footnote.Usage on
/v1/resolve is summed across every turn. Report only the final message's usage and you under-report a five-turn loop by roughly 5×. The tool trace comes back with the decision because in support tooling, "show your work" is an audit requirement. Not a nice-to-have.Three eval runs scored the tone judge at 3/4, 1/4, and 2/4 on the same four-case sample. Same route, same rubric, same model. CI gates on the deterministic half of the eval, not the judge. Lab 6 explains why.
The only case that flips between runs is the one labelled deliberately ambiguous. It scores 0.45–0.50 confidence both times, against ~0.84 on the cases that pass. A confidence field that behaves like that supports threshold routing. One that reports 0.9 on everything does not.
If you're looking for enablement content for your product, I hope you'll find this refreshing and perhaps a source of inspiration. Feel free to reach out to discuss your specific enablement requirements and how we might work together.
Links
| Course & labs | claude-triage-labs.vercel.app |
| Northwind storefront | northwind-outfitters.vercel.app |
| GitHub | github.com/mrlynn/claude-triage-api |