Decisions
Answer typed questions about an input with any model of a project, through an endpoint compatible with OpenAI's Decisions API.
POST /v1/decisions answers typed questions about an input, with probabilities. It is compatible with OpenAI's Decisions API.
Any model in the Spicepod of the project can answer:
| Model | Example from | Probabilities |
|---|---|---|
| TypeSafe decision model | typesafe:jev | Calibrated by the model. |
| OpenAI decision model | openai:gpt-6-luna | The model's estimates. |
| Chat model | openai:gpt-4o-mini, anthropic:claude-haiku-4-5 | The model's own estimates, which are not calibrated. |
Create a decision
POST https://data.spiceai.io/v1/decisions
Headers
| Header | Type | Description |
|---|---|---|
X-API-Key | string | Your project API key |
Content-Type | string | application/json |
Body
| Field | Type | Description |
|---|---|---|
model | string | The name of a model under models in the Spicepod. Required. |
input | string or array | The text that every question is about, or user messages with text parts. Image parts return 400. Required. |
questions | array | 1 to 200 questions, answered in order. Required. |
reasoning_effort | string | none, minimal, low, medium, high, or xhigh. Spice passes it to a chat model. A decision model returns 400 for it. A Spice extension. |
safety_identifier | string | An opaque ID for the end user, at most 128 characters. Spice forwards it to OpenAI decision models. |
A field that this table does not list returns 400.
input can also be a list of user messages. Each message has the user role, and its content is a string or a list of input_text parts. An input_image part returns 400.
"input": [
{"role": "user", "content": [{"type": "input_text", "text": "Help! My payouts have been failing for 3 days."}]}
]Each question has a type, its instructions, and an optional name that its answer repeats:
type | Asks | Adds |
|---|---|---|
predicate | How likely a statement about the input is true. | Nothing. |
choice | Which option fits the input. | choices: 2 to 255 distinct options, each a value with an optional description. |
score | Where the input sits on ordered levels. | levels: 2 to 10 levels, lowest first, each a label with an optional description. |
curl -X POST "https://data.spiceai.io/v1/decisions" \
-H "X-API-Key: <project-api-key>" \
-H "Content-Type: application/json" \
-d '{
"model": "jev",
"input": "Help! My payouts have been failing for 3 days.",
"questions": [
{"type": "predicate", "name": "urgent", "instructions": "Does this convey urgency?"},
{"type": "choice", "name": "team", "instructions": "Which team should handle this?",
"choices": [{"value": "billing", "description": "Payments and payouts"}, {"value": "technical", "description": "Bugs and outages"}]},
{"type": "score", "name": "tone", "instructions": "How upset is the customer?",
"levels": [{"label": "calm"}, {"label": "annoyed"}, {"label": "furious"}]}
]
}'Response
answers holds one answer per question, in question order. Each answer has the question's type and name, or null when the question has no name.
type | Fields |
|---|---|
predicate | probability: the probability that the statement is true. |
choice | choice: the most probable option. probabilities: each option's probability. confidence: 0 for a uniform distribution, 1 for a certain one. |
score | score: the probability-weighted, 0-based index of the levels. probabilities and confidence, as for choice. |
refusal | None. The model declined this question, and the other answers stand. |
{
"model": "jev",
"answers": [
{"type": "predicate", "name": "urgent", "probability": 0.9},
{"type": "choice", "name": "team", "choice": "billing",
"probabilities": [{"value": "billing", "probability": 0.8}, {"value": "technical", "probability": 0.2}], "confidence": 0.6},
{"type": "score", "name": "tone", "score": 1.3,
"probabilities": [{"value": 0, "label": "calm", "probability": 0.1}, {"value": 1, "label": "annoyed", "probability": 0.5}, {"value": 2, "label": "furious", "probability": 0.4}], "confidence": 0.3}
],
"usage": {"input_tokens": 612, "input_tokens_details": {"cached_tokens": 0, "cache_write_tokens": 0},
"output_tokens": 0, "output_tokens_details": {"reasoning_tokens": 0}, "total_tokens": 612}
}model is the name that the request used. usage is absent when the model reports no token counts.
Errors
Errors use OpenAI's envelope: {"error": {"message", "type", "param", "code"}}.
| Status | Cause |
|---|---|
400 | The request is not valid. Unknown fields, image inputs, and reasoning_effort for a decision model return it. |
401 | The model provider rejected the credentials. |
403 | The model provider denied access. |
404 | No model has this name. |
429 | The request was rate limited. |
500 | The model could not answer. |
503 | The model provider is unavailable. |
In the Portal
The Playground has a Decisions page that sends these requests to the project. See Playground.