Skip to content
SupportCHOICENOUL

Support ticket routing Jev pattern

Send a ticket to the right department and flag whether it should jump the queue.

A handwritten ticket sliding into a tray labeled Technical
Closed department options. Not a drafted reply.

Most routing prompts ask an LLM to “classify this ticket.” You then parse a string and hope the department name matches an enum. This pattern makes the department a Choice and urgency a Noul, evaluated against the same state in one call. Keep the threshold in your router, not in the model.

This support ticket routing schema is a paste-ready TypeSafe Jev request for jev-latest. Copy the JSON, keep thresholds in your code, and calibrate on your labels. Jev Patterns is independent and not affiliated with TypeSafe AI.

Use support ticket routing when

  • You have a closed set of queues or teams.
  • The ticket text plus a little metadata is enough to route.
  • You want urgency as a separate gate, not mixed into the department label.

Do not use support ticket routing when

  • The next step is writing a reply — use an LLM for that.
  • You need the customer’s entire account history summarized first.
  • Departments overlap so much that a human taxonomy does not exist yet.

Confidence thresholds for support ticket routing

Keep these in your code. They are not part of the model call.

WhenAction
department.confidence >= 0.75Auto-assign to department.choice
is_urgent.noul >= 0.80Jump the queue, regardless of department
department.confidence < 0.75Leave unassigned and show the distribution to a human

Pass examples

Reset email never arrives

Clear account ownership. Urgency is real but not an outage — gate it separately.

{
  "ticket": {
    "subject": "Can't log in",
    "body": "I cannot log in. The password reset email never arrives."
  }
}

Double charge

Billing, not account. The charge is annoying, not an outage.

{
  "ticket": {
    "subject": "Charged twice",
    "body": "You billed me twice for March. Invoice INV-10419."
  }
}

API 500s

Technical + urgent. Route to the on-call queue.

{
  "ticket": {
    "subject": "webhooks returning 500",
    "body": "All webhook deliveries have failed since 14:00 UTC. Customers are not getting events."
  }
}

Ambiguous examples

Login plus invoice

Account and billing both fire. Confidence should fall; a human picks the owner.

{
  "ticket": {
    "body": "I can't log in to download last month's invoice. Also the total looks wrong."
  }
}

Polite feature ask

Could be technical or other. Do not invent a product-feedback department.

{
  "ticket": {
    "body": "Would be nice if the export included tags. No rush."
  }
}

Forwarded thread

State is empty of a request. Other + low urgency is the honest answer.

{
  "ticket": {
    "body": "FYI — see below. Not sure who this is for."
  }
}

The problem support ticket routing is for

Most production support ticket routing still looks like this: send the subject and body to a chat model, ask for JSON, parse department and urgency, retry when the enum is wrong. Anthropic’s ticket-routing guide, n8n write-ups, and Zendesk automations all teach that shape. It works until the model returns finance instead of billing, or a confidence field that is just a word.

Support ticket routing is two jobs, not one. Which queue owns the ticket is a closed set. Whether it should jump that queue is a separate yes/no. Bundling them into a single label — billing-urgent — hides the distribution and makes SLA code parse strings. The Jev pattern for support ticket routing keeps department as a Choice and is_urgent as a Noul, evaluated in parallel against the same state.

Search results for support ticket routing are full of prompt templates. Almost none of them give you a probability over your actual queues, or a number you can threshold without hoping the model invented a honest score. That is the gap this support ticket routing schema is for.

Why this support ticket routing schema uses Jev

A Choice over account | billing | technical | sales | other cannot emit a department that is not on the list. The criteria object is the enum. Support ticket routing then returns a full probability vector plus a confidence derived from how peaked that vector is. Your router branches on those numbers, not on a parsed string.

Urgency does not belong inside the department name. A login outage and a polite password question are both account. Only one should jump the queue. The Noul is_urgent asks a boolean with true/false criteria. A value of 0.5 means the model is unsure — not medium priority. Keep that distinction or your SLA buckets will lie.

One System One call evaluates both questions in isolation. Adding the Noul barely moves latency. Official TypeSafe figures for jev-latest are about 70–500ms end to end, input around $0.042 per million tokens, output unmetered. Support ticket routing is cheap enough to run on every inbound message, including spam you will later drop.

What to put in state for support ticket routing

Put the ticket subject, body, channel, and plan in state. If you have a recent error code, a billing invoice id, or an open incident flag, put those in too. Support ticket routing cannot read Zendesk custom fields you did not send.

Do not send the entire six-month ticket history. Send the current request plus two or three prior subjects if ownership is disputed. Empty forwards — “FYI see below” with no below — should land on other with low urgency. That is an honest miss, not a model failure.

If departments overlap in your org chart, the taxonomy is the product decision. Jev will not invent a product-feedback queue because a customer said “would be nice.” Add the option to criteria only when a real team exists to receive it.

How to wire support ticket routing in code

Default: if department.confidence is at least 0.75, auto-assign to department.choice. If is_urgent.noul is at least 0.80, jump the queue regardless of department. If confidence is below 0.75, leave the ticket unassigned and show the distribution to a human. Those numbers live in your repo.

Do not auto-reply from this pattern. Support ticket routing decides the owner. The sentence the customer reads is a template, a writer model, or an agent. Mixing those jobs is how chatbots get glued onto System One.

Log the full probability vector. When billing and account split 0.41 / 0.39, the argmax is noise. Your weekly review should look at peakedness, not only hit rate.

Eval plan: label 200 historic tickets with department and a boolean urgent. Run the schema offline. Plot confidence versus accuracy. Move the 0.75 line until auto-apply error is cheaper than the review queue. That is the only honest way to ship support ticket routing.

Failure modes

Login plus invoice in one paragraph

Customers stack requests. Support ticket routing will often flatten confidence instead of picking a winner. That is correct. Split the ticket or let a human pick. Do not add a hyphenated department to paper over the overlap.

Urgency as a department

If you only have a Choice, people start naming options P1-technical. Then you cannot sort an inbox by a Score and you cannot threshold a Noul. Keep the jobs split.

Missing account context

Enterprise seats, open incidents, and contract SLA are not in the email unless you put them in state. Without them, is_urgent reflects the wording, not the blast radius.

Copy, run, calibrate

The JSON in the rail is the support ticket routing request for jev-latest. Copy it into your stack, or open Support ticket routing in Jev Studio and draw the fixture bars. Thresholds stay in your repository. Calibrate on your labels before you auto-apply. Official model docs live at docs.typesafe.ai. Jev Patterns is independent and not affiliated with TypeSafe AI.

Related reading: Choice, Score, Noul, confidence thresholds, when not to use Jev.

Support ticket routing: FAQ

What is the support ticket routing Jev pattern?
Support ticket routing is a paste-ready TypeSafe Jev schema: a Choice over account, billing, technical, sales, and other, plus a Noul named is_urgent. You send ticket state; you get distributions your router can threshold.
How is support ticket routing different from an LLM JSON classifier?
An LLM JSON classifier still samples field values as language. Support ticket routing constrains the department list by construction and returns calibrated probabilities instead of a parsed string you have to validate.
Should urgency be part of support ticket routing?
Yes, but as a separate Noul, not as a department name. Support ticket routing that mixes “billing-urgent” into one label hides the queue owner and the SLA gate.
What confidence should auto-assign in support ticket routing?
Start at department.confidence >= 0.75 and is_urgent.noul >= 0.80. Calibrate on your labels. Low-cost tags can go lower; paging should go higher.
Can support ticket routing draft the customer reply?
No. Jev does not generate text. Support ticket routing decides the queue. Use a template or a writer model for language.
Is this support ticket routing affiliated with TypeSafe AI?
No. Jev Patterns is independent. The official model is TypeSafe Jev. This support ticket routing schema is a starting point you copy into your own stack.

Last reviewed 21 September 2026. Independent of TypeSafe AI.