Decision Models API: Typed Answers With Probabilities
POST /v1/decide takes state plus typed boolean, choice, and score questions and returns verified answers with probabilities. Use trev-1.0, Jev, or any chat model through the attested TrustedRouter gateway.
Ask your software a question. Get a typed answer with a probability.
Most calls to a language model inside an application are not conversations. They are decisions: is this a refund request, which queue does it go to, how urgent is it, did the agent finish, should it retry. Asking a chat model for prose and then parsing it is slow, expensive, and fragile.
POST /v1/decide takes a piece of state and a set of typed questions, and returns one typed answer per question, each with probabilities you can threshold on. All questions are answered in a single call.
Every answer is verified against your request before it is returned. You never receive an option you did not declare, a probability outside 0 to 1, or a distribution that does not add up.
curl https://api.trustedrouter.com/v1/decide \
-H "Authorization: Bearer $TRUSTEDROUTER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "trustedrouter/trev-1.0",
"state": "I was charged twice for order A-1 and need this fixed today.",
"questions": {
"refund": {
"type": "boolean",
"instructions": "Is the customer asking for money back?"
},
"route": {
"type": "choice",
"instructions": "Route this support ticket.",
"criteria": {
"billing": "payment or charge problems",
"shipping": "delivery problems",
"technical": "application bugs"
}
},
"urgency": {
"type": "score",
"instructions": "How urgent is this ticket?",
"criteria": ["low", "medium", "high"]
}
}
}'
One answer per question, keyed by the names you chose.
A boolean returns the probability that the answer is yes. A choice returns the selected option and a probability for every option you declared. A score returns a probability for each level and the expected level as a single number, so 1.8 on a three-level scale sits between medium and high.
Automate the confident cases and send the uncertain ones to a person: if answers.refund.probability > 0.9.
{
"model": "trustedrouter/trev-1.0",
"answers": {
"refund": { "type": "boolean", "probability": 0.97 },
"route": { "type": "choice", "choice": "billing",
"probabilities": { "billing": 0.96,
"shipping": 0.02,
"technical": 0.02 } },
"urgency": { "type": "score", "score": 1.8,
"probabilities": { "0": 0.0, "1": 0.2, "2": 0.8 } }
},
"usage": { "inputTokens": 519, "outputTokens": 229 }
}
Question types
Yes or no, with a probability.
instructions is required. criteria is optional: an object with "true" and/or "false" describing what each side means.
Returns probability, the chance the answer is yes.
Pick one of your options.
criteria is required: an object mapping each option name to a description. Between 2 and 255 options.
Returns choice and probabilities for every option. The choice is always the most probable option.
Rate along an ordered scale.
criteria is required: an array of 2 to 10 level labels, lowest first.
Returns probabilities keyed "0" to "n-1", and score, their expected value. The gateway computes it from the probabilities it returns, so the two always agree.
Models
Six names, one APIEvery model below takes the same request and returns the same response, so switching is changing one string. Start with trustedrouter/trev-1.0: it is the fastest, and it reasons briefly before it answers.
| Model | Pick it for | Median model latency | Eval accuracy | About one decision costs |
|---|---|---|---|---|
| trustedrouter/trev-1.0 | Speed. An open-weight 120B reasoning model on the fastest hardware we could measure, with automatic failover across four hosts. | about 330 ms | 29 / 29 | $0.00034 |
| typesafe-ai/jev | A purpose-built decision model from TypeSafe AI, called at TypeSafe's own API with automatic failover to Vercel AI Gateway. | about 250 ms | 29 / 29 | $0.00002 |
| trustedrouter/gev-1.0 | A Google model. Small, from the Gemini family, with the format enforced by the host. | about 0.8 s | 29 / 29 | $0.00023 |
| trustedrouter/dev-1.0 | Harder judgments on a budget. A DeepSeek flash model: strong judgment, cheap input. | about 1 s (0.7 to 2.4 s) | 29 / 29 | $0.00013 |
| trustedrouter/oev-1.0 | A cheap all-rounder. An open-weight 20B model that reasons briefly. | about 1.6 s | 29 / 29 | $0.00004 |
| trustedrouter/mev-1.0 | The lowest price. A small open Gemma model. | about 2 s | 29 / 29 | $0.00002 |
What a name is. A trustedrouter/ name is one tuned configuration: a model, the host it was measured on, its reasoning setting and its output format. It runs only on its own hosts, so the speed and price above are what you get, and it answers POST /v1/decide only. Improvements ship as a new version (trev-1.1) rather than by changing a name you have pinned.
Prefer a plain model id? The same tuning applies when you name one of these chat models directly, and any other chat model in the catalog, such as anthropic/claude-opus-5, works too, untuned. Larger models do better on harder judgments.
| Tuned chat model | Runs on |
|---|---|
| google/gemini-3.1-flash-lite | Google AI Studio |
| deepseek/deepseek-v4.1-flash | DeepInfra |
| openai/gpt-oss-20b | DeepInfra |
| google/gemma-4-e4b-it | DeepInfra |
How to read this. The eval is small and deliberately easy: eight labeled support tickets, four questions each, 29 checks, run in September 2026. It shows that every model here answers clear cases correctly in the right form; it does not rank them on hard ones, and across repeated runs one borderline ticket occasionally costs a model a single check. Latency is the typical median time for the model host to answer, measured from one client over repeated runs; hosts vary from run to run, and your request also pays for authorization and settlement through the gateway. Cost is for that four-question request, about 410 to 480 input tokens, at list price. Live per-token prices are always in GET /v1/models.
Turn reasoning on. The output does not change.
By default a decision model answers without deliberating, which is what makes it fast. For a judgment that needs thought, pass reasoning (true, or {"effort": "low" | "medium" | "high"}) or reasoning_effort, and the model thinks first. You still get exactly the same typed answers, verified the same way.
provider accepts the same routing preferences as chat, so you can move a tuned model to a cheaper or regional host. max_tokens raises the budget if a long deliberation is being cut short.
These three options apply to chat-model-backed decisions. typesafe-ai/jev has no reasoning to turn on and rejects them with a clear 400 rather than ignoring them. A trustedrouter/ name always runs on its own hosts.
{
"model": "deepseek/deepseek-v4.1-flash",
"reasoning": { "effort": "high" },
"provider": { "only": ["deepinfra"] },
"state": { "diff": "...", "tests": "12 passed, 1 failed" },
"questions": {
"safe_to_merge": {
"type": "boolean",
"instructions": "Is this change safe to merge as is?",
"criteria": {
"true": "no failing tests, no behavior change outside the diff's stated purpose",
"false": "any failing test or unexplained behavior change"
}
}
}
}
What "verified" means
No special model support needed.
The gateway shows the model the exact JSON shape to fill in, and adds a strict JSON schema where the model's host can enforce one. That is why models with no structured-output support, such as Gemma 4 E4B, still work.
Never the answer.
Code fences, surrounding prose, percentages, and an option written by name are normalized. A missing question, a word where a number belongs, an option you did not declare, probabilities far from summing to one, or two answers in one reply are not repaired: the gateway never chooses for the model.
The same check for every model.
Exactly one answer per question, of the right type. Every probability between 0 and 1. Every declared option present, none invented, mass summing to one. The choice is the most probable option; the score is the distribution's mean. Hosted models are checked exactly as chat models are.
If a chat model's answer fails the second pass, the gateway asks once more. If that also fails you receive a 502, never a guess. Both attempts consumed tokens at the model host and both are billed.
Same request and response as Vercel AI Gateway's evaluate endpoint.
POST /v1/evaluate is an alias for POST /v1/decide. The model, state, and questions fields, the three question types, and the answers and usage response fields are the same, so an HTTP client written for that endpoint needs only its base URL and key changed.
state may be a string, an object, or an array, so you can pass a record or a message history without serializing it yourself.
import httpx, os
r = httpx.post(
"https://api.trustedrouter.com/v1/decide",
headers={"Authorization": f"Bearer {os.environ['TRUSTEDROUTER_API_KEY']}"},
json={
"model": "trustedrouter/trev-1.0",
"state": ticket_text,
"questions": {
"route": {
"type": "choice",
"instructions": "Route this support ticket.",
"criteria": {
"billing": "payment or charge problems",
"shipping": "delivery problems",
"technical": "application bugs",
},
},
},
},
timeout=30,
)
route = r.json()["answers"]["route"]
if route["probabilities"][route["choice"]] > 0.9:
assign(route["choice"])
else:
send_to_human()
Billing, privacy, limits
Tokens, like everything else.
typesafe-ai/jev bills input tokens only; its output is free. Chat-model-backed decisions bill the input and output tokens of the underlying call at the rate of the host that served it. A trustedrouter/ name lists the rate of its most expensive host; a request served by a cheaper fallback host costs less.
Your state never reaches our control plane.
As with chat, state and questions terminate inside the attested gateway and go only to the model host. Authorization and billing see token counts, not content. typesafe-ai/jev is called at TypeSafe's own API. Only if TypeSafe is down or rate limiting does the request fail over to Vercel AI Gateway, and only then does it cross two third parties.
Sized for real applications.
Up to 64 questions per request, 255 options per choice and 10 levels per score: the same limits on every model, so a request written for one runs on any other. Question and option names up to 128 characters, with no control characters. No streaming: a decision is one small JSON object. typesafe-ai/jev accepts about 32,000 tokens of state.
Errors
| Status | Meaning |
|---|---|
| 400 | The request is malformed. error.param names the field, for example questions.route.criteria. Also returned when a decision model is named on a chat endpoint, or when the hosted model itself rejects the request, for example as too long. |
| 401 / 402 | Invalid API key, or not enough credit. |
| 502 | The model host failed, or the model's answer failed verification twice. No unverified answer is ever returned. When a model had already run, the response carries x-should-retry: false: retrying would pay for it again. |
| 503 | Every host in a model's chain is unavailable. Retry shortly. |