Skip to main content

Decisions

celeris-1-decision answers questions about a piece of data with probabilities instead of text. You send a state (the data) and named questions, and each answer comes back as a number you can threshold, rank, or route on.

The endpoint is POST /v1/systemone. It implements TypeSafe's System One API, so code written for Jev with the Jev SDK runs against it once you change the base URL, key, and model name. Each response is one JSON body. There is no streaming.

A yes/no question​

curl https://inference.celeris.ai/celeris-1-decision/v1/systemone \
-H "Authorization: Bearer $CELERIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "celeris-1-decision",
"state": "I was charged twice this month. Please refund one of the payments.",
"questions": {
"refund": {"type": "noul", "instructions": "The customer is asking for a refund."}
}
}'
{
"model": "celeris-1-decision",
"answers": {
"refund": {"type": "noul", "noul": 0.91}
},
"usage": {"input_tokens": 351, "output_tokens": 21}
}

noul is the probability that the answer is yes.

To switch existing code without editing it, set the SDK's environment variables:

export TYPESAFE_BASE_URL=https://inference.celeris.ai/celeris-1-decision
export TYPESAFE_API_KEY=$CELERIS_API_KEY
export TYPESAFE_DEFAULT_MODEL=celeris-1-decision

Question types​

Each question needs a type and usually carries instructions. One request can hold several questions of any mix of types, and state can be a string or any other JSON value.

typecriteriaAnswer
noulOptional. {"true": ..., "false": ...} describes each outcome.noul: the probability of yes.
choiceRequired. An object of at least two options. Each key is an option name and each value describes it, or is null.choice: the most likely option. probabilities: one per option.
scoreRequired. An array of at least two levels, lowest first. Levels are numbered from 0.score: the average level, weighted by probability. probabilities: one per level. legend: each level's description.

choice and score answers also carry confidence, the top probability rescaled so that 0 is an even split across the options and 1 is certainty. Probabilities are rounded to two decimal places and sum to 1.

curl https://inference.celeris.ai/celeris-1-decision/v1/systemone \
-H "Authorization: Bearer $CELERIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "celeris-1-decision",
"state": {
"subject": "Charged twice",
"body": "I was charged twice this month and nobody has answered my emails for a week. Please refund one of the payments."
},
"questions": {
"refund": {"type": "noul", "instructions": "The customer is asking for a refund."},
"team": {
"type": "choice",
"instructions": "Which team should handle this ticket?",
"criteria": {
"billing": "Payments, invoices and refunds.",
"technical": "Bugs and outages.",
"sales": "Upgrades and quotes."
}
},
"frustration": {
"type": "score",
"instructions": "How frustrated is the customer?",
"criteria": ["Calm.", "Annoyed.", "Angry."]
}
}
}'
{
"model": "celeris-1-decision",
"answers": {
"refund": {"type": "noul", "noul": 0.91},
"team": {
"type": "choice",
"choice": "billing",
"probabilities": {"billing": 0.88, "technical": 0.07, "sales": 0.05},
"confidence": 0.82
},
"frustration": {
"type": "score",
"score": 1.41,
"probabilities": {"0": 0.18, "1": 0.23, "2": 0.59},
"confidence": 0.38,
"legend": {"0": "Calm.", "1": "Annoyed.", "2": "Angry."}
}
},
"usage": {"input_tokens": 673, "output_tokens": 102}
}

Celeris extensions​

Celeris adds options that System One does not have. They go in one optional top-level object, x_celeris. The Jev SDK sends it through extra_body.

Explanations​

Set explain to true to get one sentence per question on why the model picked its answer. The sentences come back in x_celeris.explanations, keyed by question name. Explanations make the request slower.

curl https://inference.celeris.ai/celeris-1-decision/v1/systemone \
-H "Authorization: Bearer $CELERIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "celeris-1-decision",
"state": "I was charged twice this month and nobody has answered my emails for a week.",
"questions": {
"team": {
"type": "choice",
"instructions": "Which team should handle this ticket?",
"criteria": {
"billing": "Payments, invoices and refunds.",
"technical": "Bugs and outages.",
"sales": "Upgrades and quotes."
}
}
},
"x_celeris": {"explain": true}
}'
{
"model": "celeris-1-decision",
"answers": {
"team": {
"type": "choice",
"choice": "billing",
"probabilities": {"billing": 0.88, "technical": 0.07, "sales": 0.05},
"confidence": 0.82
}
},
"usage": {"input_tokens": 431, "output_tokens": 64},
"x_celeris": {
"explanations": {
"team": "The user is reporting a double charge, which falls directly under payments and invoices."
}
}
}

Images​

Attach images in images, an object that maps a name to a base64 data URL. Images are part of the state, and your state and questions can refer to one by its name.

max_soft_tokens sets the resolution the model reads every image in the request at. It takes the values listed there.

IMAGE_B64=$(base64 < receipt.png | tr -d '\n')

curl https://inference.celeris.ai/celeris-1-decision/v1/systemone \
-H "Authorization: Bearer $CELERIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "celeris-1-decision",
"state": {"claim": {"amount": 13.50, "category": "meals"}},
"questions": {
"matches": {"type": "noul", "instructions": "The receipt total matches the claimed amount."}
},
"x_celeris": {
"images": {"receipt": "data:image/png;base64,'"$IMAGE_B64"'"},
"max_soft_tokens": 560
}
}'

Usage and cost​

The usage block reports input_tokens and output_tokens. Input tokens are billed at the celeris-1-decision rate, and output tokens are free. Images count as input tokens.

input_tokens covers everything the model reads for the request, which is more than your state and questions alone. Read it from the response instead of estimating it from your payload. The yes/no request above reported 351 input tokens, about $0.000014.

Errors​

An invalid request returns a 422. A 422 whose msg says the answers do not fit in one response comes back after the model has run, so its input tokens are charged.

Statuses such as 401, 402, and 429 behave as described in Errors, and rate limits apply as for any other model.