Skip to navigation

Decisions API

View as Markdown

The Decisions API answers typed questions about an input. You send a state (the input to decide on) and a map of questions, and every answer comes back as a typed value with a probability for every option. Nothing is generated, so there is no text to parse and no output format to enforce.

Use it wherever you would otherwise prompt a chat model to “answer yes or no” or “reply with one of these labels”: routing, triage, moderation, judging agent runs, and scoring.

The Decisions API serves Sarvam Prism (sarvam-prism). The SDK examples need sarvamai 0.1.43 or later for Python (pip install -U "sarvamai>=0.1.43") and sarvamai 1.1.15 or later for JavaScript (npm install sarvamai@latest).

Make a decision

Use POST /v2/systemone. One request answers every question in questions, and each answer comes back under the same ID.

from sarvamai import SarvamAI
client = SarvamAI(api_subscription_key="YOUR_SARVAM_API_KEY")
response = client.decisions.create(
model="sarvam-prism",
state="The customer asked for a refund within the 30-day window.",
questions={
"refund": {
"type": "noul",
"instructions": "Should we approve the refund?",
},
},
)
print(response.answers["refund"].noul)

Response:

{
"model": "sarvam-prism",
"answers": {
"refund": { "type": "noul", "noul": 0.8646 }
},
"usage": { "input_tokens": 45, "output_tokens": 0 }
}

noul is the probability that the answer is yes. output_tokens is always 0.

Question types

Every question has a type. Its criteria define the options, and its answer has a matching shape.

typeAskscriteriaAnswer fields
noulYes or noOptional. {"true": "…", "false": "…"}noul
choicePick one optionRequired. Object of option ID → description, 2 to 255 optionschoice, confidence, probabilities
scoreRate on an ordered scaleRequired. List of levels, lowest first, 2 to 10 levelsscore, confidence, legend, probabilities

instructions is the question to ask about the state: a string, or an object or array rendered as JSON. A noul needs instructions, criteria, or both. For choice and score, instructions is optional but usually makes the question clearer.

Yes/no with criteria

Describe when each answer applies in criteria:

{
"type": "noul",
"instructions": "Should we approve the refund?",
"criteria": {
"true": "The request meets the refund policy",
"false": "The request breaks the refund policy"
}
}

Choice

Write each option’s description as the condition under which it applies. Option IDs come back verbatim as the keys of probabilities, and the order you list them in does not affect the answer.

{
"type": "choice",
"instructions": "Which team should handle this?",
"criteria": {
"billing": "Payments or invoices",
"technical": "Bugs or outages",
"sales": "New business enquiries"
}
}

Score

List the levels from lowest to highest. The answer keys them "0", "1", … in your order, and legend maps each key back to your text.

{
"type": "score",
"instructions": "Rate the severity.",
"criteria": ["trivial", "minor", "moderate", "major", "critical"]
}

Ask several questions at once

Put every question about the same state in one request. The state is counted once per request, so extra questions add only their own tokens.

from sarvamai import SarvamAI
client = SarvamAI(api_subscription_key="YOUR_SARVAM_API_KEY")
response = client.decisions.create(
model="sarvam-prism",
state="My Stripe integration stopped working and all checkout payments are failing.",
questions={
"urgent": {
"type": "noul",
"instructions": "Is this urgent and revenue-impacting?",
},
"department": {
"type": "choice",
"instructions": "Which team should handle this?",
"criteria": {
"billing": "Payments or invoices",
"technical": "Bugs or outages",
"sales": "New business enquiries",
},
},
"severity": {
"type": "score",
"instructions": "Rate the severity.",
"criteria": ["trivial", "minor", "moderate", "major", "critical"],
},
},
)
for question_id, answer in response.answers.items():
if answer.type == "noul":
print(question_id, "yes" if answer.noul > 0.5 else "no", answer.noul)
elif answer.type == "choice":
print(question_id, answer.choice, answer.probabilities[answer.choice])
elif answer.type == "score":
print(question_id, answer.score, answer.legend[str(round(answer.score))])

Response:

{
"model": "sarvam-prism",
"answers": {
"urgent": { "type": "noul", "noul": 0.9782 },
"department": {
"type": "choice",
"choice": "billing",
"confidence": 0.7065,
"probabilities": { "billing": 0.8044, "technical": 0.1869, "sales": 0.0087 }
},
"severity": {
"type": "score",
"score": 3.832,
"confidence": 0.916,
"legend": { "0": "trivial", "1": "minor", "2": "moderate", "3": "major", "4": "critical" },
"probabilities": { "0": 0.0026, "1": 0.0034, "2": 0.0115, "3": 0.1245, "4": 0.8581 }
}
},
"usage": { "input_tokens": 153, "output_tokens": 0 }
}

Every answer carries its type, so switching on it narrows the answer to the right shape in the typed SDKs.

Read the answers

FieldTypeDescription
noulnumberProbability from 0 to 1 that the answer is yes.
choicestringThe option ID with the highest probability.
scorenumberExpected level, Σ index × probability with levels indexed from 0. A float such as 3.83: round it if you need a level.
probabilitiesobjectProbability for every option or level, keyed by option ID (choice) or "0", "1", … (score). Sums to 1.
confidencenumberHow decisive the answer is, from 0 to 1. For choice, the top probability rescaled so that an even split is 0 and certainty is 1: (p_top − 1/n) / (1 − 1/n) for n options. For score, 0 when probability is spread across the scale and 1 when it all sits on one level.
legendobjectscore only. Your level text, keyed the same way as probabilities.

Probabilities can vary slightly between identical requests; the top answer is stable.

Act on confidence

Sarvam Prism’s probabilities are calibrated: an answer given with 90% probability is wrong about 10% of the time or less. Act on confident answers automatically and send the rest to a person.

from sarvamai import SarvamAI
client = SarvamAI(api_subscription_key="YOUR_SARVAM_API_KEY")
THRESHOLD = 0.9
response = client.decisions.create(
model="sarvam-prism",
state="I was charged twice for my last order.",
questions={
"department": {
"type": "choice",
"instructions": "Which team should handle this?",
"criteria": {
"billing": "Payments or invoices",
"technical": "Bugs or outages",
"sales": "New business enquiries",
},
},
},
)
answer = response.answers["department"]
if answer.probabilities[answer.choice] >= THRESHOLD:
print("Route to", answer.choice)
else:
print("Send to a person")

Set the threshold on the top probability (noul, or probabilities[choice]), not on confidence: the calibration figures on the Sarvam Prism page refer to the probability.

Send structured state

state can be a string, an object, or an array. Objects and arrays are rendered as compact JSON, so you can pass a record as it is.

from sarvamai import SarvamAI
client = SarvamAI(api_subscription_key="YOUR_SARVAM_API_KEY")
response = client.decisions.create(
model="sarvam-prism",
state={"invoice": {"vendor": "Acme", "total": 1250, "status": "overdue"}},
questions={
"follow_up": {
"type": "choice",
"instructions": "When should we follow up?",
"criteria": {
"later": "Can wait",
"this_week": "This week",
"today": "Today",
},
},
},
)
print(response.answers["follow_up"].choice)

Parameters

ParameterRequiredDescription
modelYessarvam-prism. A request without model returns 400; an unknown ID returns 404.
stateYesA string, object, or array. An empty string is allowed; a missing or null state returns 422. Never truncated.
questionsYesMap of your question ID to a question, at least one. There is no cap on the number of questions.

Each question accepts only these keys:

KeyRequiredDescription
typeYesnoul, choice, or score (lowercase).
instructionsnoul: if no criteriaThe question to ask about the state. A string, or an object or array rendered as JSON.
criteriachoice, scoreThe options, see Question types.

Refused or unsupported on this route

The Decisions API returns probabilities only, so generation settings don’t apply:

  • temperature, max_tokens, stream, and other generation fields return 422.
  • Images are not supported. An image URL in images returns 400; an inline image returns 422.
  • Any key in a question other than type, instructions, and criteria returns 422, including misspellings such as instruction.
  • A choice outside 2–255 options or a score outside 2–10 levels returns 422.

Limits and billing

  • 32,768 tokens per question (state + that question’s instructions and options). If any one question is over, the whole request fails with 422 and names the question.
  • 60 seconds per request. A longer request fails with 503 model_overloaded; split very large batches of questions across several requests.
  • Pricing: ₹4 per 1M input tokens and ₹0 per 1M output tokens, on every plan. Check usage.input_tokens for the exact count.

Errors return message, code and request_id; validation errors also return param, the path to the field at fault, such as questions.urgent.noul.instruction. See the Sarvam Prism page for the error table and the Decisions API Reference for the complete request and response schemas.