Decisions

Decision models answer typed questions about a piece of content instead of generating text. You send the content to judge and a set of 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, checking a photo, or deciding whether an agent should take an action.

Decision models are not chat models. They are served on two endpoints that share the same models, the same billing and the same answers, in two wire shapes:

EndpointShapeUse it with
POST https://backend.sovereigneg.com/v1/decisionsOpenAI Decisions APIThe OpenAI SDKs' client.decisions.create, SovereignEG's seg-sdk, or any OpenAI-style HTTP client
POST https://backend.sovereigneg.com/v1/systemoneTypeSafe System OneThe TypeSafe SDK, or clients already written against System One

Pick the one that matches the client you already have. Both authenticate with your SovereignEG API key: Authorization: Bearer sk-....

Question types

Every question has instructions (what to judge). The three types, and what they are called on each endpoint:

Asks/v1/decisions type/v1/systemone typeAnswer
A yes/no questionpredicatenoulProbability the answer is yes, from 0 to 1
Pick one optionchoicechoiceThe most likely option, plus every option's probability and a confidence
Rate on an ordered rubricscorescoreA probability-weighted level, plus every level's probability and a confidence

A choice question takes 2 to 255 options. A score question takes 2 to 10 levels, lowest first.

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.

Images

Decision models whose catalog entry lists image under input_modalities also judge pictures. Images are sent inline as base64 data URLs; hosted image URLs are not fetched. A model whose input_modalities lists only text refuses a request that carries images with 400 unsupported_input before the request reaches the provider. Check input_modalities on the model's entry in GET https://backend.sovereigneg.com/v1/models.

How to attach an image on each endpoint is shown below.

/v1/decisions

POST https://backend.sovereigneg.com/v1/decisions

Request

ParameterTypeRequiredDescription
modelstringYesDecision model ID (see Available models)
inputstring / arrayYesThe content to evaluate: plain text, or a list of user messages whose content is text or a list of input_text and input_image parts
questionsarrayYesOrdered questions. Each has type, instructions and an optional name that is echoed back; choice questions carry choices (value, optional description), score questions carry levels (label, optional description)
safety_identifierstringNoA stable identifier for your end user, for abuse tracking

Example

from openai import OpenAI
 
client = OpenAI(api_key="sk-...", base_url="https://backend.sovereigneg.com/v1")
 
decision = client.decisions.create(
    model="jev-1.13",
    input="I paid for my order twice and it still has not arrived after a week.",
    questions=[
        {"type": "predicate", "name": "refund",
         "instructions": "Is the customer asking for money back?"},
        {"type": "choice", "name": "team",
         "instructions": "Which team should handle this?",
         "choices": [
             {"value": "billing", "description": "Charges, refunds, invoices"},
             {"value": "shipping", "description": "Delivery and tracking"},
             {"value": "technical", "description": "Bugs and outages"},
         ]},
        {"type": "score", "name": "urgency",
         "instructions": "How urgent is this?",
         "levels": [{"label": "Can wait"}, {"label": "Handle today"}, {"label": "Handle now"}]},
    ],
)
 
refund, team, urgency = decision.answers
if refund.probability > 0.8:
    route_to(team.choice)

SovereignEG's own Python SDK makes the same call with from seg import SEG and no base URL to set: seg-sdk on PyPI.

import OpenAI from 'openai'
 
const client = new OpenAI({ apiKey: process.env.SOVEREIGNEG_API_KEY, baseURL: 'https://backend.sovereigneg.com/v1' })
 
const decision = await client.decisions.create({
  model: 'jev-1.13',
  input: 'I paid for my order twice and it still has not arrived after a week.',
  questions: [
    { type: 'predicate', name: 'refund', instructions: 'Is the customer asking for money back?' },
    {
      type: 'choice',
      name: 'team',
      instructions: 'Which team should handle this?',
      choices: [
        { value: 'billing', description: 'Charges, refunds, invoices' },
        { value: 'shipping', description: 'Delivery and tracking' },
        { value: 'technical', description: 'Bugs and outages' },
      ],
    },
  ],
})
 
const [refund, team] = decision.answers
if (refund.type === 'predicate' && refund.probability > 0.8) routeTo(team.choice)
curl https://backend.sovereigneg.com/v1/decisions \
  -H "Authorization: Bearer $SOVEREIGNEG_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "jev-1.13",
    "input": "I paid for my order twice and it still has not arrived after a week.",
    "questions": [
      { "type": "predicate", "name": "refund", "instructions": "Is the customer asking for money back?" },
      { "type": "choice", "name": "team", "instructions": "Which team should handle this?",
        "choices": [
          { "value": "billing", "description": "Charges, refunds, invoices" },
          { "value": "shipping", "description": "Delivery and tracking" },
          { "value": "technical", "description": "Bugs and outages" }
        ] },
      { "type": "score", "name": "urgency", "instructions": "How urgent is this?",
        "levels": [ { "label": "Can wait" }, { "label": "Handle today" }, { "label": "Handle now" } ] }
    ]
  }'

With an image, send input as messages:

"input": [
  {
    "role": "user",
    "content": [
      { "type": "input_text", "text": "Photo the courier sent on delivery." },
      { "type": "input_image", "image_url": "data:image/jpeg;base64,..." }
    ]
  }
]

Response

One answer per question, in the order you asked, with your name echoed back:

{
  "object": "decision",
  "model": "jev-1.13",
  "answers": [
    { "type": "predicate", "name": "refund", "probability": 0.96 },
    {
      "type": "choice",
      "name": "team",
      "choice": "billing",
      "confidence": 0.75,
      "probabilities": [
        { "value": "billing", "probability": 0.84 },
        { "value": "shipping", "probability": 0.14 },
        { "value": "technical", "probability": 0.02 }
      ]
    },
    {
      "type": "score",
      "name": "urgency",
      "score": 1.62,
      "confidence": 0.71,
      "probabilities": [
        { "label": "Can wait", "value": 0, "probability": 0.02 },
        { "label": "Handle today", "value": 1, "probability": 0.34 },
        { "label": "Handle now", "value": 2, "probability": 0.64 }
      ]
    }
  ],
  "usage": {
    "input_tokens": 312,
    "input_tokens_details": { "cached_tokens": 0, "cache_write_tokens": 0 },
    "output_tokens": 30,
    "output_tokens_details": { "reasoning_tokens": 0 },
    "total_tokens": 342
  }
}
AnswerFields
predicateprobability: probability the answer is yes, from 0 to 1
choicechoice: the most likely option, with the same type you sent (string or boolean) · confidence · probabilities: every option's probability
scorescore: probability-weighted level (can land between levels) · confidence · probabilities: every level's probability with its label and value
refusalThe model returned no usable answer for that question. Other questions still answer

confidence and probabilities are the model's own numbers. When a model does not report them, they are null; they are never estimated for you.

/v1/systemone

POST https://backend.sovereigneg.com/v1/systemone

This endpoint implements TypeSafe's System One contract, so a TypeSafe client's System One calls work once you point it at SovereignEG's base URL and API key. See Using the TypeSafe SDK.

Request

ParameterTypeRequiredDescription
modelstringYesDecision model ID (see Available models)
statestring / object / arrayYesThe content to evaluate: plain text, structured data such as a chat log or a record, or an array mixing text with inline images
questionsobjectYesNamed questions. You choose each key; the answer comes back under the same key

Every question has a type and instructions, plus type-specific criteria:

typecriteria
noulOptional {"true": "...", "false": "..."} describing what yes and no mean
choiceRequired: a map of option → description (or null)
scoreRequired: a list of 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`?"
}

With an image, send state as an array: text items as plain strings, and each image as an object holding a base64 data URL:

"state": [
  "Photo the courier sent on delivery.",
  { "type": "image_url", "image_url": { "url": "data:image/jpeg;base64,..." } }
]

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 }
}
AnswerFields
noulnoul: probability the answer is yes, from 0 to 1
choicechoice: the most likely option · probabilities: every option's probability · confidence
scorescore: probability-weighted level (can land between levels) · legend: level number → your description · probabilities · confidence

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, and input_modalities tells you whether it takes images.

Pricing

Decision models are billed per million input tokens — the content plus your questions — in Egyptian pounds, the same on both endpoints. The short typed answers carry no output charge on any decision model today. usage on every response reports the tokens billed.

Errors

StatusCodeMeaning
400model_not_supported_on_endpointThe model is not a decision model (or a decision model was sent to /v1/chat/completions). The message names the right endpoint
400model_not_foundUnknown model ID
400empty_inputinput / state is empty
400unsupported_inputThe request carries images but the model's input_modalities lists only text. Pick a model that lists image
400remote_media_not_supported / invalid_image_urlAn image is a hosted URL, or its data URL is not a supported image type or is over the size limit. Inline it as a base64 data URL
400too_many_image_partsMore than 20 images in one request
400duplicate_choiceTwo choices on one /v1/decisions question have the same value
401missing_auth_header / invalid_api_key / key_revoked / key_expired / invalid_tokenNo Authorization: Bearer header; the sk- key is unknown, revoked or expired; or the token isn't an sk- key (invalid_token)
402quota_exceededNo spendable credit left. Top up in Dashboard → Billing
402insufficient_balanceYour remaining credit can't cover this request. Top up, or send shorter content or fewer questions
402spending_cap_reached / project_spend_cap_exceededThe key's or the project's monthly spend cap is reached. Use a key with a higher cap (a key's cap can't be changed after creation), or raise the project cap under Dashboard → Projects → Limits
422invalid_request_bodyMalformed request: a missing field, an unknown question type, or choices / levels / criteria outside the limits above. param names the field
429rate_limit_exceededToo many requests for your plan — back off and retry
503provider_backings_unavailableThe model is temporarily unavailable — retry shortly

Decision responses are never streamed: each request returns one JSON body.

Decisions | SovereignEG Docs