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.022 / 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}
}
}'
$call = @{
Method = "Post"
Uri = "https://api.axforge.ai/v1/systemone"
Headers = @{ Authorization = "Bearer $env:AXFORGE_API_KEY" }
ContentType = "application/json"
Body = '{
"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}
}
}'
}
(Invoke-RestMethod @call).answers.department.choice # billing
curl.exe 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}}}"
{
"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 to 1 | Optional. Below it the answer carries "decided": false. |
| min_confidence | number 0 to 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.
From your code
# pip install requests · the key is read from AXFORGE_API_KEY
import os
import requests
goal = "Download invoice 2041 for the customer"
tool_output = "HTTP 500 from the invoices API"
r = requests.post(
"https://api.axforge.ai/v1/systemone",
headers={"Authorization": "Bearer " + os.environ["AXFORGE_API_KEY"]},
json={
"model": "xev-latest",
"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"
print(step)
// Node 18+ (fetch is built in) · the key is read from AXFORGE_API_KEY
const goal = "Download invoice 2041 for the customer";
const toolOutput = "HTTP 500 from the invoices API";
const r = await fetch("https://api.axforge.ai/v1/systemone", {
method: "POST",
headers: { "Authorization": "Bearer " + process.env.AXFORGE_API_KEY, "Content-Type": "application/json" },
body: JSON.stringify({
model: "xev-latest",
state: { last_tool_result: toolOutput, 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 },
},
}),
});
const a = (await r.json()).answers.next;
const step = a.decided ? a.choice : "ask_user";
console.log(step);
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 to 32 |
|---|---|
| Options per choice | 2 to 26 |
| Levels per score | 2 to 10 |
| State | up to 200,000 characters |
| Input | €0.022 / 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.