Decisions API
POST /v1/decisions sends the decision model a piece of context (state) and one or more typed questions, and returns the model's answers. It is built for classification and routing: triage a support message, pick a category, score a probability — decisions rather than prose.
This is a separate surface from chat: the decision model is not a chat model, it is deliberately not listed in GET /v1/models, and /v1/decisions is the only way to reach it.
#Quickstart
curl https://api.radienthq.com/v1/decisions \
-H "Authorization: Bearer $RADIENT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"state": "Customer writes: I was charged twice for my invoice this month and want a refund.",
"questions": {
"topic": {
"type": "choice",
"instructions": "Which department should handle this message?",
"criteria": {
"billing": "Payments, invoices, refunds",
"technical": "Bugs and outages",
"other": "Anything else"
}
}
}
}'
{
"answers": {
"topic": {
"type": "choice",
"choice": "billing",
"probabilities": { "billing": 1, "technical": 0, "other": 0 },
"confidence": 1
}
},
"id": "gen-dec-…",
"model": "…",
"provider": "…",
"usage": { "input_tokens": 345, "output_tokens": 38, "cost": 0.00001449 }
}
The model and provider values above are trimmed: they identify the model and the serving endpoint. The numbers are as returned.
#Request
| Field | Type | Required | Notes |
|---|---|---|---|
state | string | yes | The context the questions are asked about. Put the full material here; there is no separate prompt field. |
questions | object | yes | One entry per question, keyed by the id you want back in answers. |
model | string | no | Defaults to jev-1.13. Other configured spellings are mapped to the model the deployment serves. |
Each question object:
| Field | Type | Required | Notes |
|---|---|---|---|
type | string | yes | choice for a selection from a fixed set; noul for a probability between 0 and 1. |
instructions | string | yes | What the model should decide. |
criteria | object | for choice | {label: description} — the allowed answers. Answers come back as one of the labels (a string). |
The request body is capped at 1 MiB; a larger body is refused with 413 {"error":"The decision request body is too large"}.
#Response
answers— keyed by your question ids. Achoiceanswer carrieschoice(one of your labels),probabilities(one per label) andconfidence; anoulanswer carriesnoul, a probability between 0 and 1:
"is_urgent": { "type": "noul", "noul": 0.99 }
id,model,provider— the request id, the model that answered, and the serving endpoint.usage—input_tokens,output_tokens, andcostin USD.
The answer body comes from the decision model, so additional fields may appear as it evolves. Treat unknown fields as informational.
#Errors
| Status | Body | Cause |
|---|---|---|
400 | {"error":"Could not read the request body"} | The request body could not be read (from the controller; not reproducible with a stock client) |
401 | auth bodies | No or invalid credential (Authentication) |
402 | {"error":"insufficient credits"} | The credit gate refused the call |
405 | {"error":"Method Not Allowed"} | GET /v1/decisions — the route is POST-only |
413 | {"error":"The decision request body is too large"} | Body over 1 MiB |
422 | the model's own body, naming the offending field | The model itself rejected the request; its body is passed through as returned (from the controller's passthrough set; not reproducible with a stock model) |
429 | the model's own body | Rate limited by the model; Retry-After is passed through when present |
502 | {"error":"The decision model upstream failed with status N"} | Any upstream status other than 2xx, 422, 429 or 529, with that status in the message |
502 | {"error":"The decision model upstream could not be reached"} | The model service could not be reached at all |
503 | a Decisions are unavailable… body | This deployment has no decision model configured. Nothing was metered or billed. |
Only the model's own 2xx, 422, 429 and its overloaded 529 are passed through with the model's body. Every other status — including the model's own 400-class rejections — becomes 502 {"error":"The decision model upstream failed with status N"}; a non-JSON body, an empty body and an unusable question shape were each executed and measured this way.
#Cost and limits
- Priced per input token: $0.042 per million tokens ($0.000000042 per token). Output tokens appear in
usagebut are not charged. Example: a 345-input-token call costs $0.00001449. - The credit gate reserves up to $0.30 per call before admitting it (see the credit gate).
- An upstream "overloaded" status (529) is passed through with the model's body.
- The model call has a 30-second server-side timeout; there are no server-side retries or failover.
- There is no request-rate limit on this route beyond the credit gate and the model's own
429s.
See also: Usage and credits API · API Reference.