Decision Models
A decision model reads some state and answers your typed questions with calibrated probabilities. Use it for routing, classification and yes/no gates inside an app, where a fast, structured answer matters more than prose.
Two decision models are served through the gateway, both on the /v1/systemone endpoint in the SystemOne format:
| Model | Maker | Context | Input | Output |
|---|---|---|---|---|
sage-2 | Levanto Labs | 32K | $0.07 / 1M | $2.00 / 1M |
jev-1.13 | TypeSafe | 32K | $0.042 / 1M | free |
They don't serve /v1/chat/completions or /v1/messages: sending one there returns a 400 that points to /v1/systemone. For the same reason, /v1/models/health shows them as unknown when they've had no calls in the last 15 minutes: idle models are checked with a chat probe, which a decision model can't answer, so that status doesn't mean an outage.
Asking a question
POST /v1/systemone
Authentication is the same as every other gateway endpoint: a Bankr API key (bk_...) via X-API-Key or Authorization: Bearer.
curl -X POST https://llm.bankr.bot/v1/systemone \
-H "Content-Type: application/json" \
-H "X-API-Key: bk_YOUR_API_KEY" \
-d '{
"model": "sage-2",
"state": "User: please swap 1 ETH to USDC on Base",
"questions": {
"is_trade": {
"type": "noul",
"instructions": "Is the user asking to make a trade?"
},
"chain": {
"type": "choice",
"instructions": "Which chain does the user want to trade on?",
"criteria": { "base": "Base", "ethereum": "Ethereum mainnet", "solana": "Solana" }
}
}
}'
Request
| Field | Description |
|---|---|
model | Required. sage-2 or jev-1.13. |
state | Required. What the questions are about: a string, or a JSON object. |
questions | Required. An object of at least one question, keyed by an ID you choose. |
Apart from the privacy fields and "stream": false, any other field is rejected with 400 unsupported_parameter. Streaming is not supported.
Every question has a type and instructions. The three types:
| Type | Asks | criteria |
|---|---|---|
noul | A yes/no question | None |
choice | Pick one option | Required. An object of option ID to description |
score | Where it sits on a scale | Required. A list of scale labels, from the lowest to the highest |
Response
{
"id": "dec-k5lcsV1k57JzQ2qjXrDUL",
"model": "sage-2",
"answers": {
"is_trade": { "type": "noul", "noul": 0.991 },
"chain": {
"type": "choice",
"choice": "base",
"confidence": 0.9997,
"probabilities": { "base": 0.9997, "ethereum": 0.0002, "solana": 0.00005 }
}
},
"usage": { "input_tokens": 127, "output_tokens": 0 }
}
Each answer carries its question's type:
noul:noulis the probability that the answer is yes.choice:choiceis the most likely option, with itsconfidenceand theprobabilitiesof every option.score:scoreruns from 0 (the first label) to 1 (the last), withprobabilitiesper label (by position) and alegendmapping each position to its label.
Privacy
Decision models are served without TEE attestation, so a private request ("privacy": "private", "private": true, sage-2:private or the /private path) returns 422 confidential_unavailable.
Zero data retention depends on the model:
jev-1.13takes a ZDR request ("privacy": "zdr","zdr": true,jev-1.13:zdror the/zdrpath), which only reaches a provider that retains nothing. Accounts with zero data retention turned on can call it too.sage-2has no zero-retention route, so a ZDR request returns422 zdr_unavailable, and so does every Sage call from an account with zero data retention turned on.
See Privacy Tiers for how the tiers work on chat models.
Error responses
| Status | Code | Meaning |
|---|---|---|
400 | missing_required_fields | model or state is missing. |
400 | invalid_value | questions is missing, empty or not an object. |
400 | unsupported_parameter | The body has a field other than the ones above. |
400 | stream_not_supported | stream was set to anything but false. |
400 | unsupported_model | The model is unknown or not a decision model. |
400 | invalid_privacy | A privacy field has a value it doesn't take. |
400 | privacy_conflict | The request asks for a tier the path doesn't. |
422 | confidential_unavailable / zdr_unavailable | Private tier, or ZDR with no zero-retention hosts. |
A malformed question (for example a choice with no criteria) is rejected by the model's host with a 4xx, whose message usually names the field.
Pricing
Each call bills its input_tokens and output_tokens at the model's rates from your LLM credit balance, and shows on your usage dashboard. A short request costs a fraction of a cent: the 127-token call above costs about $0.00001 on Sage. See credit management to top up.
Next steps
- API Reference: endpoint summary
- Supported Models: the chat model catalog
- Overview: routing, payments and credit management