Decisions
POST /v1/decisions serves the OpenAI Decisions API. It evaluates shared input
against up to 400 typed questions and returns an answer per question: the
probability that a statement is true, one option from a fixed set, or a score on
a rubric. It does not generate text, which makes it a fast, cheap fit for
classification, routing and prioritization.
Requests and responses use OpenAI's wire format, so the OpenAI SDKs work by
pointing base_url at LLM API. The model ID is gpt-6-luna-decisions: the
decisions surface of GPT-6 Luna, listed separately from the gpt-6-luna chat
model.
Quick start
curl -X POST "https://api.llmapi.ai/v1/decisions" \
-H "Authorization: Bearer $LLM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-6-luna-decisions",
"input": "I was charged twice for my order. Please return the extra charge.",
"questions": [
{
"type": "predicate",
"name": "refund_requested",
"instructions": "Does the customer ask for a refund?"
}
]
}'
{
"model": "gpt-6-luna",
"answers": [{ "type": "predicate", "name": "refund_requested", "probability": 0.95 }],
"usage": {
"input_tokens": 162,
"input_tokens_details": { "cached_tokens": 0, "cache_write_tokens": 0 },
"output_tokens": 0,
"output_tokens_details": { "reasoning_tokens": 0 },
"total_tokens": 162
}
}
With the OpenAI Python SDK:
from openai import OpenAI
client = OpenAI(base_url="https://api.llmapi.ai/v1", api_key=LLM_API_KEY)
decision = client.decisions.create(
model="gpt-6-luna-decisions",
input="Export fails in Safari but works in Chrome.",
questions=[{
"type": "score",
"name": "severity",
"instructions": "How severe is this issue?",
"levels": [
{"label": "Cosmetic"},
{"label": "Workaround available"},
{"label": "Fully blocked"},
],
}],
)
Answers come back in question order and carry the question's name.
Question types
| Type |
Asks |
Answer fields |
predicate |
How likely is this statement true? |
probability (0–1) |
choice |
Which of 2–255 choices applies? |
choice, probabilities, confidence |
score |
Where does the input sit on 2–10 ordered levels? |
score, probabilities, confidence |
Any question can come back as {"type": "refusal", "name": ...} while the
others are still answered, so check each answer's type before reading it.
Input
input is either a string or an array of messages. User messages accept
input_text, input_image (a public HTTPS URL or a base64 data URL) and
input_json parts; developer and system messages are text only. Files, audio
and file IDs are not supported.
"input": [{
"role": "user",
"content": [
{ "type": "input_text", "text": "Inspect the product in this photo." },
{ "type": "input_image", "image_url": "https://example.com/product.png" }
]
}]
Pricing and caching
Decisions are billed on input tokens only; output tokens are free. Repeated
input of 1,024 tokens or more is cached automatically: cache reads are billed
at the discounted cached-input rate and cache writes at the cache-write rate.
prompt_cache_key and prompt_cache_options are forwarded to the provider
unchanged. The request log shows the input, cached and cache-write tokens of
every request; current rates are in the model catalog.
Providers
The request is served by OpenAI or Azure OpenAI; the response's model field
names the model or Azure deployment that answered. When the first provider is
rate limited or unavailable, the next one is tried. Pin a provider with a
prefix, for example azure/gpt-6-luna-decisions; a pinned request is never
moved to another provider. A provider that does not offer the Decisions API,
such as AWS Bedrock, answers 400.
Notes
- Ask several questions in one request: they share the same input, so one call is cheaper and faster than one per question.
- Responses arrive in one piece. There is no streaming.
- The gateway checks that
model, input and 1–400 questions are present; everything else is validated by the provider, whose 400 message names the offending field.
/v1/systemone serves TypeSafe's System One models, which use a different request format.
API operation: POST /v1/decisions