Xev decisions
POST /v1/systemone — typed questions about a piece of state, answered with
calibrated probabilities instead of text. Xev speaks the System
One format (Jev-compatible): yes/no, choice and score questions, many per call.
€0.039 / 1M input tokens, output free.
Request & response
$ curl https://api.axforge.ai/v1/systemone \
-H "Authorization: Bearer $AXFORGE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "xev-latest",
"state": "I was charged twice for my subscription.",
"questions": {
"refund": {"type": "noul", "instructions": "Is the customer asking for money back?"},
"department": {"type": "choice", "instructions": "Which team should handle this?",
"criteria": {"billing": "Charges and refunds", "technical": "Bugs and outages"}},
"urgency": {"type": "score", "instructions": "How urgent is this?",
"criteria": ["Can wait a week", "Should be handled today", "Needs an answer within the hour"]},
"angry": {"type": "noul", "instructions": "Is the customer angry?", "min_confidence": 0.9}
}
}'
PS> $body = @{
state = 'I was charged twice for my subscription.'
questions = @{
refund = @{ type = 'noul'; instructions = 'Is the customer asking for money back?' }
department = @{ type = 'choice'; instructions = 'Which team should handle this?'
criteria = @{ billing = 'Charges and refunds'; technical = 'Bugs and outages' } }
}
} | ConvertTo-Json -Depth 5
PS> $r = Invoke-RestMethod https://api.axforge.ai/v1/systemone -Method Post `
-Headers @{ Authorization = "Bearer $env:AXFORGE_API_KEY" } `
-ContentType 'application/json' -Body $body
PS> $r.answers.department.choice # billing
{
"model": "xev-latest",
"answers": {
"refund": {"type": "noul", "noul": 0.8113},
"department": {"type": "choice", "choice": "billing",
"probabilities": {"billing": 0.9464, "technical": 0.0536}, "confidence": 0.8928},
"urgency": {"type": "score", "score": 0.8526,
"legend": {"0": "Can wait a week", "1": "Should be handled today", "2": "Needs an answer within the hour"},
"probabilities": {"0": 0.2884, "1": 0.5706, "2": 0.141}, "confidence": 0.3559},
"angry": {"type": "noul", "noul": 0.4896, "decided": false, "confidence": 0.0208}
},
"usage": {"input_tokens": 224, "output_tokens": 0},
"latency_ms": 1188
}
The request
| Field | Type | Meaning |
|---|---|---|
| state | string · object · array | What the questions are about — a message, a ticket, a record, an agent's transcript. An object or array is read as JSON. Required, up to 200,000 characters. |
| questions | object | Named questions, 1 to 32. The names come back as the keys of answers. |
| questions.*.type | string | noul (yes/no), choice or score. |
| questions.*.instructions | string | The question, in plain words. Required. |
| questions.*.criteria | depends on type | noul: optional {"true": "…", "false": "…"} to say what yes and no mean. choice: {"option": "what it means", …}, 2 to 26 options. score: an ordered array of level descriptions, 2 to 10 levels. |
| questions.*.min_confidence | number 0–1 | Optional. Below it the answer carries "decided": false. |
| min_confidence | number 0–1 | Optional default for every question that sets none. |
| model | string | Optional: xev-latest. Any System One name (such as jev-latest) is accepted. |
The answers
| Type | Fields |
|---|---|
| noul | noul — the probability of yes, 0 to 1. |
| choice | choice — the winning option; probabilities — one per option, adding up to 1; confidence. |
| score | score — the expected level (0 = the first level); legend — your levels by index; probabilities — one per level; confidence. |
confidence is 1 when all the probability sits on one option and 0 when it is
spread evenly. With min_confidence set, every answer also carries
decided: false means "below your line" — the probabilities are
still there, so you can hand the case to a person or a bigger model.
Python
import requests
r = requests.post(
"https://api.axforge.ai/v1/systemone",
headers={"Authorization": "Bearer YOUR_AXFORGE_KEY"},
json={
"state": {"last_tool_result": tool_output, "goal": goal},
"questions": {
"next": {"type": "choice", "instructions": "What should the agent do next?",
"criteria": {"continue": "The result moves the goal forward",
"retry": "The tool failed or returned nothing useful",
"ask_user": "A decision only the user can make",
"stop": "The goal is reached"},
"min_confidence": 0.7},
},
},
timeout=30,
)
a = r.json()["answers"]["next"]
step = a["choice"] if a["decided"] else "ask_user"
Coming from Jev
Xev uses the System One request and answer format. Change the endpoint to
https://api.axforge.ai/v1/systemone and the key to your AxForge key; questions,
criteria and parsing stay the same. min_confidence and decided are
Xev additions — clients that don't know them simply ignore them.
Errors
Errors come back as {"message": "…", "error_type": "…"}.
| Status | error_type | When |
|---|---|---|
| 401 | authentication_error | Missing or unknown API key. |
| 402 | insufficient_quota | The free tokens for this cycle are used and there is no prepaid balance — top up in the console. |
| 422 | invalid_request | The body doesn't fit the format; the message names the field, e.g. questions.q.criteria: at least 2 options. |
| 429 | rate_limit_error | Too many requests for this key, or too many at once — retry with backoff. |
| 529 | overloaded | Busy for a moment — retry with backoff. |
Limits & billing
| Questions per call | 1 – 32 |
|---|---|
| Options per choice | 2 – 26 |
| Levels per score | 2 – 10 |
| State | up to 200,000 characters |
| Input | €0.039 / 1M tokens — the state counted once per call, plus each question's own text |
| Output | Free |
Usage appears in the console like every other model, and counts against the free tokens every account gets first. All input is processed with zero retention, like every endpoint here.