Decision models (System One)
Decision models answer typed questions about a piece of content instead of generating text. You send a state (the content to judge) and a set of named questions; the model returns one typed answer per question, with real probabilities, in a single fast call.
Use them wherever your code has to make a decision: routing a support ticket, flagging a message, grading an answer, or deciding whether an agent should take an action.
Decision models are not chat models: they are served on /v1/systemone, not /v1/chat/completions, and the OpenAI SDK has no method for them. The endpoint implements TypeSafe's System One contract, so any TypeSafe client works unchanged.
Endpoint
POST https://backend.sovereigneg.com/v1/systemone
Authenticate with your SovereignEG API key: Authorization: Bearer sk-....
Request
| Parameter | Type | Required | Description |
|---|---|---|---|
model | string | Yes | Decision model ID, e.g. jev-1.13 (see Available models) |
state | string / object / array | Yes | The content to evaluate: plain text, or structured data such as a chat log or a record |
questions | object | Yes | Named questions. You choose each key; the answer comes back under the same key |
Every question has a type and instructions, plus type-specific criteria:
type | Asks | criteria |
|---|---|---|
noul | A yes/no question | Optional {"true": "...", "false": "..."} describing what yes and no mean |
choice | Pick one option | Required: a map of option → description (or null), up to 255 options |
score | Rate on an ordered rubric | Required: a list of 2–10 level descriptions, lowest first |
instructions and every criteria description can be a string, an object, or an array. Put the question in one field and data it refers to in others, and point at them by name in backticks:
"instructions": {
"potential_duplicate": { "name": "John Smith", "location": "Oakland, California" },
"question": "Is the resume for the same person as `potential_duplicate`?"
}Example
curl https://backend.sovereigneg.com/v1/systemone \
-H "Authorization: Bearer $SOVEREIGNEG_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "jev-1.13",
"state": "I paid for my order twice and it still has not arrived after a week.",
"questions": {
"refund": {
"type": "noul",
"instructions": "Is the customer asking for money back?"
},
"team": {
"type": "choice",
"instructions": "Which team should handle this?",
"criteria": {
"billing": "Charges, refunds, invoices",
"shipping": "Delivery and tracking",
"technical": "Bugs and outages"
}
},
"urgency": {
"type": "score",
"instructions": "How urgent is this?",
"criteria": ["Can wait", "Handle today", "Handle now"]
}
}
}'import httpx
response = httpx.post(
"https://backend.sovereigneg.com/v1/systemone",
headers={"Authorization": "Bearer sk-..."},
json={
"model": "jev-1.13",
"state": "I paid for my order twice and it still has not arrived after a week.",
"questions": {
"refund": {"type": "noul", "instructions": "Is the customer asking for money back?"},
"team": {
"type": "choice",
"instructions": "Which team should handle this?",
"criteria": {
"billing": "Charges, refunds, invoices",
"shipping": "Delivery and tracking",
"technical": "Bugs and outages",
},
},
},
},
timeout=30,
)
answers = response.json()["answers"]
if answers["refund"]["noul"] > 0.8:
route_to(answers["team"]["choice"])Response
One answer per question, under the keys you chose:
{
"model": "jev-1.13",
"answers": {
"refund": { "type": "noul", "noul": 0.96 },
"team": {
"type": "choice",
"choice": "billing",
"probabilities": { "billing": 0.84, "shipping": 0.14, "technical": 0.02 },
"confidence": 0.75
},
"urgency": {
"type": "score",
"score": 1.62,
"legend": { "0": "Can wait", "1": "Handle today", "2": "Handle now" },
"probabilities": { "0": 0.02, "1": 0.34, "2": 0.64 },
"confidence": 0.71
}
},
"usage": { "input_tokens": 312, "output_tokens": 30 }
}| Answer | Fields |
|---|---|
noul | noul: probability the answer is yes, from 0 to 1 |
choice | choice: the most likely option · probabilities: every option's probability (sums to 1) · confidence |
score | score: probability-weighted level (can land between levels) · legend: level number → your description · probabilities · confidence |
Because the answers are probabilities, you pick the threshold: act automatically above 0.9, send to a human between 0.5 and 0.9, and so on.
Using the TypeSafe SDK
Point the official TypeSafe SDK at SovereignEG by changing its base URL and API key. The SDK adds /v1/systemone itself, so the base URL is the API origin without /v1:
from typesafe_sdk import TypeSafeClient
client = TypeSafeClient(
api_key="sk-...", # your SovereignEG API key
base_url="https://backend.sovereigneg.com",
)
result = client.system_one(
model="jev-1.13",
state="I paid for my order twice and it still has not arrived after a week.",
questions={
"refund": {"type": "noul", "instructions": "Is the customer asking for money back?"},
},
)
print(result.answers["refund"])import { TypeSafeClient } from '@typesafe-ai/sdk'
const client = new TypeSafeClient({
apiKey: process.env.SOVEREIGNEG_API_KEY,
baseURL: 'https://backend.sovereigneg.com',
})
const result = await client.systemOne({
model: 'jev-1.13',
state: 'I paid for my order twice and it still has not arrived after a week.',
questions: {
refund: { type: 'noul', instructions: 'Is the customer asking for money back?' },
},
})
console.log(result.answers.refund)Only systemOne / system_one is supported. The SDK's model listing calls GET /v1/models, which returns the SovereignEG catalog shape rather than TypeSafe's — browse the catalog instead.
Available models
Decision models are listed in the model catalog under Modality: Decision, or with GET https://backend.sovereigneg.com/v1/models where modality is "decision". The model page of each one shows ready-to-run code for that model.
Pricing
Decision models are billed per million input tokens — the state plus your questions — in Egyptian pounds. The short typed answers carry no output charge on any decision model today. usage on every response reports the tokens billed.
Errors
| Status | Code | Meaning |
|---|---|---|
| 400 | model_not_supported_on_endpoint | The model is not a decision model (or a decision model was sent to /v1/chat/completions). The message names the right endpoint |
| 400 | model_not_found | Unknown model ID |
| 400 | empty_input | state is empty |
| 401 | missing_auth_header | No or invalid API key |
| 402 | insufficient_balance | Top up your balance |
| 422 | invalid_request_body | Malformed request: a missing field, an unknown question type, or criteria outside the limits above. param names the field |
| 429 | rate_limit_exceeded | Too many requests for your plan — back off and retry |
| 503 | provider_backings_unavailable | The model is temporarily unavailable — retry shortly |
System One responses are never streamed: each request returns one JSON body.