System One API Reference
The System One API exposes the native TYPESAFE AI schema through AvalAI. Give Jev the evidence to evaluate in state, define focused judgments in questions, and read typed results from answers. Your application owns validation, permissions, and the action taken after a judgment.
Use https://api.avalai.ir/v1/systemone with your AvalAI key. This is different from the Decisions API: native System One uses a question-ID object and state, whereas the Decisions surface uses its own request and response schema.
Endpoint and Authentication
POST https://api.avalai.ir/v1/systemone
Authorization: Bearer $AVALAI_API_KEY
Content-Type: application/jsonKeep AVALAI_API_KEY on the server. A TYPESAFE AI key is not needed when making these requests through AvalAI. Send UTF-8 JSON and inspect both the HTTP status and response body.
Models and Pricing
The following AvalAI mappings were announced on October 23, 2026:
Request model | Underlying Jev version | Input / 1M tokens | Cached input / 1M tokens | Output / 1M tokens |
|---|---|---|---|---|
jev-preview | jev-1.13.0 | $0.042 | $0.00 | $0.00 |
jev-latest | jev-1.14.0 | $0.042 | $0.00 | $0.00 |
These are AvalAI alias mappings; upstream aliases may point to different versions. Use the documented aliases rather than assuming the underlying version strings are direct AvalAI request IDs. Aliases can change; record the alias and the evaluation date when comparing behavior.
Zero output pricing does not mean zero input cost or zero output tokens. A cached-input price does not guarantee a cache hit or support for a cache-control parameter. See the TYPESAFE AI provider page for pricing interpretation and version notes.
Request Body
| Field | Type | Required | Meaning |
|---|---|---|---|
model | string | Yes | An enabled AvalAI alias, currently jev-latest or jev-preview. |
state | string, object, or array | Yes | The evidence every question evaluates. A top-level number or boolean is not a documented state shape. |
questions | object | Yes | A nonempty map from caller-chosen question IDs to question objects. |
Every question in a request sees the same state and is evaluated independently. A question does not receive another question's answer as hidden context. If an answer determines newly fetched evidence or the next question's options, make a subsequent request explicitly.
Question IDs such as route identify answers for your code. Upstream documents that the IDs themselves are not sent to the model, so a descriptive ID does not replace instructions.
State
Use a string for one message. Use an object or array when field boundaries or record IDs clarify the evidence:
{
"ticket": {
"id": "ticket-1042",
"message": "I was charged twice. Please help."
}
}For structured state, name the relevant path in the instructions, for example, Which team should handle `ticket.message`?. Preserve exact identifiers as strings when arithmetic is not needed. Prefer a short relevant record to a large unrelated history.
The shape above follows the native upstream contract. The live checks later on this page exercised strings and JSON objects; several cookbook cases successfully used object state. The particular ticket object above is illustrative, and array state was not included in that check matrix.
Question Objects
| Field | Type | Meaning |
|---|---|---|
type | string | choice, score, or noul for the text primitives described here. |
instructions | string, object, array, or null | Defines the judgment and the evidence to inspect. Publish clear instructions even where upstream permits omission or null. |
criteria | Depends on type | An option map for Choice, an ordered array for Score, or optional true / false descriptions for Noul. |
Use ordinary strings for simple instructions and descriptions. Structured objects can separate a rubric, examples, or evidence boundaries; any nested keys you choose are your content, not additional special API fields.
Do not add Chat Completions or Responses fields such as messages, temperature, max_tokens, stream, or tools to this native request. The documented text request does not establish support for those controls.
Choice: Select One Unordered Option
Choice asks which option best matches the state. criteria is an object mapping each allowed value to its description:
{
"type": "choice",
"instructions": "Which team should handle this message?",
"criteria": {
"billing": "Payments or invoices",
"technical": "Software or API problems",
"other": "Anything else"
}
}The native schema permits 1–255 options; use at least two when a meaningful choice is needed. Option names and descriptions are visible to the model. A null description asks it to interpret the option name alone. Prefer explicit descriptions, especially for labels such as internal queue IDs.
Choice labels have no inherent order. Distinguish overlapping categories with concrete boundaries. A closed set always has a best option even when none is a good match; evaluate a suitable other option or a separate applicability Noul for your task.
Choice Answer
| Field | Type | Interpretation |
|---|---|---|
type | string | "choice". |
choice | string | The selected criterion key. Validate it against the options you sent. |
confidence | number | A 0-to-1 signal calculated upstream from the distribution, not a measured probability that the decision is correct. |
probabilities | object | Criterion keys and numeric probabilities. See the captured AvalAI response before requiring a complete map. |
Upstream describes a probability for every option. The captured AvalAI response below omits the selected option from this map. Keep the map as received. Do not fill an absent entry with zero, require the available values to sum to one, or recompute confidence from an incomplete map.
Score: Evaluate an Ordered Rubric
Score represents an ordered spectrum. Supply an array of descriptions, from the lowest level to the highest:
{
"type": "score",
"instructions": "How severe is the reported issue?",
"criteria": [
"Cosmetic issue; functionality works",
"Feature is degraded, but a workaround exists",
"Blocking failure with no workaround"
]
}The native schema accepts 1–10 levels. Use 2–10 for a useful scale. Array positions assign the level numbers 0 through n - 1; they are not arbitrary numeric labels. Each description should stand on its own: the model does not see that level's numeric position or neighboring descriptions. Avoid wording such as “more severe than the previous level.”
Score Answer
| Field | Type | Interpretation |
|---|---|---|
type | string | "score". |
score | number | The probability-weighted mean of level positions; it can be fractional and lies between 0 and n - 1. |
legend | object | Maps level positions to their descriptions. JSON keys are strings such as "0", "1", and "2". |
probabilities | object | Probabilities keyed by the same string level positions. |
confidence | number | A 0-to-1 distribution signal that accounts for distances between ordered levels. |
For example, a three-level distribution of (0, 0.57, 0.43) has score 1.43. This is an explanation of the upstream computation, not a captured AvalAI Score response. The score is not a percentage, an exact extracted quantity, or the probability that a result is correct.
A middle score can mean a clear middle-level judgment or disagreement between opposite ends. Inspect the distribution and confidence when they are available and complete. If combining different rubric lengths in application code, normalize with score / (n - 1) only when n > 1, and tune the weights on labeled examples.
The native primitive check used the exact Score question above and the state Checkout is blocked and there is no workaround. Please refund the duplicate charge. It returned this answers.severity object for both AvalAI aliases:
{
"type": "score",
"score": 2.0,
"confidence": 1.0,
"legend": {
"0": "Cosmetic issue; functionality works",
"1": "Feature is degraded, but a workaround exists",
"2": "Blocking failure with no workaround"
},
"probabilities": {
"0": 0.0,
"1": 0.0,
"2": 1.0
}
}This is a captured answer within a larger response. The same request included the Noul question below; both question answers passed typed validation in the live check. Scores and probabilities can be rounded separately in responses, so do not require exact arithmetic equality between a reported score and a value recomputed from the displayed probability entries.
Noul: Estimate a Yes/No Probability
Noul evaluates one concrete proposition and returns the probability of yes/true:
{
"type": "noul",
"instructions": "Does this message explicitly request a refund?",
"criteria": {
"true": "Explicitly asks for money to be refunded",
"false": "Does not explicitly ask for a refund"
}
}criteria is optional. When provided, use true and false keys with descriptions consistent with the instructions. Split compound conditions into independent questions and combine their answers in code.
Noul Answer
The same primitive check returned this captured answers.refund_intent object for both aliases:
{
"type": "noul",
"noul": 0.99
}The live check sent the explicit true / false criteria shown above. A separate cookbook check also succeeded with Noul instructions and no criteria. noul is a finite number from 0 to 1. There is no separate confidence field. A value near 0.5 means uncertainty between yes and no; it does not mean a medium amount of a property such as urgency. Use Score for a spectrum.
Select task-specific yes, no, and review ranges using labeled data. A high Noul value does not authorize a payment, grant a permission, or establish that a claim is true. Validate the relevant facts and policy in application code.
First Request: Captured AvalAI Choice Check
The user ran this exact request payload with their own AvalAI key against both aliases on October 23, 2026. Both returned HTTP 200. The shell wrapper below adds bounded retries without changing the payload.
Run the request on a machine where AVALAI_API_KEY is already set. The example prints the status, request ID, and complete response; it does not print the key. It uses at most three attempts and a 60-second overall budget. A retry can create another billable inference request. The curl wrapper also requires Python 3 to inspect error JSON safely.
curl
# Run with Bash and an existing AVALAI_API_KEY.
: "${AVALAI_API_KEY:?Set AVALAI_API_KEY in your environment}"
request_dir=$(mktemp -d) || exit 1
trap 'rm -rf "$request_dir"' EXIT
cat >"$request_dir/request.json" <<'JSON'
{
"model": "jev-latest",
"state": "I was charged twice. Please help.",
"questions": {
"route": {
"type": "choice",
"instructions": "Which team should handle this message?",
"criteria": {
"billing": "Payments or invoices",
"technical": "Software or API problems",
"other": "Anything else"
}
}
}
}
JSON
deadline=$((SECONDS + 60))
for attempt in 1 2 3; do
remaining=$((deadline - SECONDS))
((remaining > 0)) || break
timeout=$((remaining < 20 ? remaining : 20))
: >"$request_dir/headers"
: >"$request_dir/response.json"
status=$(curl --silent --show-error \
--connect-timeout 10 --max-time "$timeout" \
--dump-header "$request_dir/headers" \
--output "$request_dir/response.json" \
--write-out '%{http_code}' \
https://api.avalai.ir/v1/systemone \
-H "Authorization: Bearer $AVALAI_API_KEY" \
-H 'Content-Type: application/json' \
--data-binary "@$request_dir/request.json")
curl_status=$?
printf 'HTTP status: %s\n' "$status"
awk 'tolower($1) == "avalai-request-id:" {print}' "$request_dir/headers"
cat "$request_dir/response.json"
printf '\n'
if ((curl_status == 0)) && [[ $status == 2?? ]]; then
exit 0
fi
retryable=false
if ((curl_status == 0)); then
quota_error=$(
python3 - "$request_dir/response.json" <<'PY'
import json
import sys
try:
with open(sys.argv[1], encoding="utf-8") as response:
body = json.load(response)
except (OSError, ValueError):
sys.exit(0)
if isinstance(body, dict):
containers = [body, body.get("error")]
terminal = ("quota_exceeded", "insufficient_quota")
if any(
isinstance(item, dict) and any(item.get(key) in terminal for key in ("code", "type", "error_type"))
for item in containers
):
print("yes")
PY
) || exit 1
[[ $quota_error != yes ]] || exit 1
case "$status" in 408 | 429 | 5??) retryable=true ;; esac
else
case "$curl_status" in 6 | 7 | 28 | 52 | 55 | 56) retryable=true ;; esac
fi
[[ $retryable == true && $attempt -lt 3 ]] || exit 1
delay=$((1 << (attempt - 1)))
retry_after=$(awk 'tolower($1) == "retry-after:" {
$1=""; sub(/^[ \t]+/, ""); sub(/\r$/, ""); value=$0
} END {print value}' "$request_dir/headers")
if [[ $retry_after =~ ^[0-9]+$ ]]; then
delay=$((10#$retry_after))
elif [[ -n $retry_after ]]; then
retry_at=$(LC_ALL=C date -u -d "$retry_after" +%s 2>/dev/null \
|| LC_ALL=C date -ju -f '%a, %d %b %Y %H:%M:%S GMT' "$retry_after" +%s 2>/dev/null)
if [[ $retry_at =~ ^[0-9]+$ ]]; then
delay=$((retry_at - $(date +%s)))
((delay >= 0)) || delay=0
fi
fi
((SECONDS + delay + 1 < deadline)) || break
sleep "$delay.$((RANDOM % 1000))"
done
exit 1This shell example accepts a numeric Retry-After or an HTTP date using GNU date or macOS/BSD date. It does not retry request-validation failures. Replace only the model value with jev-preview to repeat the same check for that alias.
Python: Standard Library HTTP
This example uses direct HTTP rather than assuming the OpenAI SDK has a native System One method. It sends the same JSON payload as curl.
import json
import os
import random
import time
import urllib.error
import urllib.request
from datetime import datetime, timezone
from email.utils import parsedate_to_datetime
payload = {
"model": "jev-latest",
"state": "I was charged twice. Please help.",
"questions": {
"route": {
"type": "choice",
"instructions": "Which team should handle this message?",
"criteria": {
"billing": "Payments or invoices",
"technical": "Software or API problems",
"other": "Anything else",
},
},
},
}
def quota_failure(text):
try:
body = json.loads(text)
except ValueError:
return False
if not isinstance(body, dict):
return False
terminal = ("quota_exceeded", "insufficient_quota")
return any(
isinstance(item, dict)
and any(item.get(key) in terminal for key in ("code", "type", "error_type"))
for item in (body, body.get("error"))
)
def retry_delay(headers, attempt):
value = headers.get("Retry-After", "").strip()
if value.isdigit():
return int(value) + random.uniform(0, 0.25)
if value:
try:
when = parsedate_to_datetime(value)
if when.tzinfo is None:
when = when.replace(tzinfo=timezone.utc)
return max(
0, (when - datetime.now(timezone.utc)).total_seconds()
) + random.uniform(0, 0.25)
except (TypeError, ValueError, OverflowError):
pass
return min(2 ** (attempt - 1), 5) + random.uniform(0, 0.25)
def systemone(body):
deadline = time.monotonic() + 60
encoded = json.dumps(body).encode("utf-8")
for attempt in range(1, 4):
remaining = deadline - time.monotonic()
if remaining <= 0:
raise TimeoutError("System One retry budget exhausted")
request = urllib.request.Request(
"https://api.avalai.ir/v1/systemone",
data=encoded,
headers={
"Authorization": f"Bearer {os.environ['AVALAI_API_KEY']}",
"Content-Type": "application/json",
},
method="POST",
)
try:
with urllib.request.urlopen(
request, timeout=min(20, remaining)
) as response:
result = json.loads(response.read().decode("utf-8"))
return result, response.headers.get("avalai-request-id")
except urllib.error.HTTPError as error:
error_body = error.read().decode("utf-8", errors="replace")
request_id = error.headers.get("avalai-request-id")
retryable = not quota_failure(error_body) and (
error.code in (408, 429) or 500 <= error.code < 600
)
if not retryable or attempt == 3:
raise RuntimeError(
f"HTTP {error.code}; request_id={request_id}; {error_body}"
) from error
headers = error.headers
except (urllib.error.URLError, TimeoutError) as error:
if attempt == 3:
raise RuntimeError(
"System One transport failure after three attempts"
) from error
headers = {}
delay = retry_delay(headers, attempt)
if delay >= deadline - time.monotonic():
raise TimeoutError("Retry-After exceeds the remaining retry budget")
time.sleep(delay)
raise RuntimeError("System One request did not complete")
result, request_id = systemone(payload)
print("avalai-request-id:", request_id)
print(json.dumps(result, indent=2, ensure_ascii=False))The timeout passed to urlopen applies to blocking socket operations, rather than imposing a strict wall-clock deadline on every response read. The overall retry budget limits attempts and waits; use an HTTP client with a total timeout if your service needs a strict whole-operation deadline. Sanitize error bodies before putting them in production logs.
JavaScript: Node.js Fetch
Use Node.js 20 or newer. Keep the key in the server environment and run this as an ES module; do not copy it into browser code.
const apiKey = process.env.AVALAI_API_KEY;
if (!apiKey) throw new Error("Set AVALAI_API_KEY in your environment");
const payload = {
model: "jev-latest",
state: "I was charged twice. Please help.",
questions: {
route: {
type: "choice",
instructions: "Which team should handle this message?",
criteria: {
billing: "Payments or invoices",
technical: "Software or API problems",
other: "Anything else",
},
},
},
};
function quotaFailure(text) {
let body;
try {
body = JSON.parse(text);
} catch {
return false;
}
if (!body || typeof body !== "object" || Array.isArray(body)) return false;
const terminal = new Set(["quota_exceeded", "insufficient_quota"]);
return [body, body.error].some((item) =>
item && typeof item === "object" && !Array.isArray(item) &&
["code", "type", "error_type"].some((key) => terminal.has(item[key]))
);
}
function retryDelay(headers, attempt) {
const value = headers?.get("retry-after")?.trim();
let delay = Math.min(1000 * 2 ** (attempt - 1), 5000);
if (value && /^\d+$/.test(value)) {
delay = Number(value) * 1000;
} else if (value) {
const when = Date.parse(value);
if (Number.isFinite(when)) delay = Math.max(0, when - Date.now());
}
return delay + Math.random() * 250;
}
async function systemone(body) {
const deadline = performance.now() + 60_000;
for (let attempt = 1; attempt <= 3; attempt += 1) {
const remaining = deadline - performance.now();
if (remaining <= 0) throw new Error("System One retry budget exhausted");
let response;
let text;
try {
response = await fetch("https://api.avalai.ir/v1/systemone", {
method: "POST",
headers: {
Authorization: `Bearer ${apiKey}`,
"Content-Type": "application/json",
},
body: JSON.stringify(body),
signal: AbortSignal.timeout(Math.ceil(Math.min(20_000, remaining))),
});
text = await response.text();
} catch (error) {
if (attempt === 3) throw error;
}
if (response && text !== undefined) {
const requestId = response.headers.get("avalai-request-id");
if (response.ok) return { result: JSON.parse(text), requestId };
const retryable = !quotaFailure(text) && (
[408, 429].includes(response.status) ||
(response.status >= 500 && response.status < 600)
);
if (!retryable || attempt === 3) {
throw new Error(`HTTP ${response.status}; request_id=${requestId}; ${text}`);
}
}
const delay = retryDelay(response?.headers, attempt);
if (delay >= deadline - performance.now()) {
throw new Error("Retry-After exceeds the remaining retry budget");
}
await new Promise((resolve) => setTimeout(resolve, delay));
}
throw new Error("System One request did not complete");
}
const { result, requestId } = await systemone(payload);
console.log("avalai-request-id:", requestId);
console.log(JSON.stringify(result, null, 2));The examples retry temporary HTTP 408, 429, and 5xx responses, including upstream overload status 529, and selected transport failures. They inspect the error body's code, type, and error_type, including an error object, and stop immediately for quota_exceeded or insufficient_quota: waiting does not replenish credit. They preserve the original error body for diagnosis; remove sensitive information before sharing or logging it.
The clients stop after three attempts or their remaining budget; invalid request bodies and invalid successful-response JSON are not retried. A timeout can occur after the server has processed a request, so retries may increase usage. Apply downstream actions only once, after a validated result and your own authorization checks.
Captured Complete Response
For jev-latest, the support Choice check returned this complete JSON body on October 23, 2026 at 16:11:37 UTC:
{
"model": "jev-latest",
"answers": {
"route": {
"type": "choice",
"choice": "billing",
"confidence": 1.0,
"probabilities": {
"technical": 0.0,
"other": 0.0
}
}
},
"usage": {
"input_tokens": 333,
"output_tokens": 38
},
"estimated_cost": {
"unit": "0.0000139860",
"irt": 3.78,
"exchange_rate": 270000
}
}The corresponding avalai-request-id header was 01a16988-3487-7b81-b0e8-122228180f1c. The jev-preview check also returned HTTP 200, echoed "model": "jev-preview", and returned the same answer, usage counts, and cost values in that sample; its request ID was 01a16988-5bd1-7931-a0ff-cc06d6cc9bde.
The gateway echoed the requested aliases here. It did not return a resolved version or a top-level id, and its probabilities map did not contain billing. Do not add those fields to a purported captured response.
The displayed body is one captured request. It is not an accuracy, latency, token-count, or price-conversion guarantee. The exchange rate and local-currency estimate can change.
Live Verification Scope
On October 23, 2026, the user ran six native cases for each alias against api.avalai.ir: all 12 System One requests returned HTTP 200 and passed typed-answer validation. Four additional Decisions requests also passed, making 16 successful checks across the two endpoints.
| Native case | Verified request shape | Aliases checked |
|---|---|---|
| Support routing | One Choice over string state; the complete capture above. | jev-latest, jev-preview |
| Primitive reference | Score and Noul together over string state; ordered Score criteria and explicit Noul true / false criteria. | jev-latest, jev-preview |
| Retrieval and citation | Two Scores and one Choice over a JSON object. | jev-latest, jev-preview |
| Guardrail signal | One Noul over a JSON object, with instructions and no criteria. | jev-latest, jev-preview |
| Weighted rubric | Two independent Scores over a JSON object. | jev-latest, jev-preview |
| Proposed function routing | One Choice over a JSON object; application code still owns execution and authorization. | jev-latest, jev-preview |
These synthetic requests establish compatibility for the tested payloads. They do not validate every input, array state, every SDK, automatic retry behavior on the live service, production task accuracy, rate-limit capacity, or optional native extensions. See the Jev cookbook for the corresponding workflows.
Response Fields
| Field | Meaning |
|---|---|
model | Response model metadata. In the captured checks this was the requested alias; do not rely on it to disclose the resolved version. |
answers | Map of question IDs to their typed answers. Check that each required ID exists. |
usage.input_tokens | Input token usage reported for the request. This includes billable request material, not just visible message characters. |
usage.output_tokens | Reported output tokens; free output pricing does not remove this count. |
estimated_cost.unit | AvalAI estimated dollar cost, returned as a decimal string in the captured response. |
estimated_cost.irt | Estimated cost in Iranian toman at the reported exchange rate. |
estimated_cost.exchange_rate | Exchange rate used for the local-currency estimate. |
Keep decimal monetary values as decimals or strings when accounting precision matters. Reconcile billing through AvalAI's User API rather than treating a sample cost as a fixed cost per request. Record the avalai-request-id response header for support; intermediary X-Request-ID values can differ. See Response Headers.
Validate Before Using an Answer
Check the response independently of its HTTP success:
- Require a JSON object, an
answersobject, and every question ID your code depends on. - Match the returned
typeto the requested primitive. - For Choice, require an allowed
choice. If confidence is used, require a finite number in 0–1. Validate probability entries that are present, while preserving an incomplete map as incomplete. - For Score, require a finite
scorein0throughn - 1; check the expected legend and probability key shapes before interpreting them. Do not replace missing numeric values with zero. - For Noul, require a finite
noulin 0–1. Do not look for a separate confidence field. - Route absent answers, unexpected types, unknown labels, malformed values, and evidence gaps to an explicit error or review path.
Confidence describes the model's distribution; it is not a substitute for measured task accuracy. Tune thresholds on representative English and Persian examples, include ambiguous and out-of-scope cases, and keep consequential actions behind application policy. The decision-model guide explains evaluation and review paths.
Limits and Optional Native Features
Upstream documents default context limits of 64k tokens per request (state plus all questions) and 32k tokens per question (state plus that question). These are separate constraints, not capacities to add together. There is no separate upstream question-count limit; request size and context still constrain a batch.
The official native request rules also specify a 32 MiB body limit, finite JSON numbers, UTF-8 without a byte-order mark, and at most 64 nested object/array levels in state, instructions, and criteria. Treat these as upstream rules; AvalAI and intermediary limits can be lower. Start with small uncompressed text JSON and reduce unnecessary evidence when a request is rejected.
Upstream publishes opt-in long-context and experimental image/Box features. Their header forwarding, asset handling, billing, and response behavior through AvalAI have not been verified by the text checks here. This reference's runnable requests do not establish those features. Check compatibility separately before depending on them; see the provider notes.
Errors and Debugging
An AvalAI error body can use an error object with message, type, param, code, and request_id; upstream TYPESAFE AI may instead return validation details. A documented upstream HTTP 422 is not a promise that AvalAI exposes the same status or body. Capture the actual status and sanitized JSON before classifying a failure.
| Symptom or status | First check | Retry unchanged? |
|---|---|---|
400 or 422, invalid request | Correct endpoint, model alias, state shape, nonempty question map, type, instructions, and type-specific criteria. | No |
Context or payload rejection, including 413 | Reduce state, question material, or body size; split only where the judgment still has enough evidence. | No |
401 | Bearer header and the AvalAI key loaded by the application. | No |
403 | Account permission and model access. | No |
415 | Send uncompressed JSON with Content-Type: application/json. | No |
429 with quota_exceeded or insufficient_quota | Credit balance, account quota, and billing details. | No; resolve the account condition |
Temporary 408, 429, or 5xx | Request ID, server delay, rate limits, and transient service status. | With bounded backoff and jitter |
| Connection failure or timeout | Network path and timeout budget; the server may already have processed the request. | With a bounded policy |
| HTTP 200 but missing or invalid answers | Validate the complete body and preserve a sanitized diagnostic sample. | Do not silently accept or retry a schema mismatch |
A frequent schema mistake is sending Choice criteria as an array. Omitting instructions because the question ID looks descriptive can also leave the intended judgment unclear, even though the upstream schema permits omission or null. For Score, descriptions belong in an ordered array; for Noul, optional criteria use true and false.
Log the endpoint, selected alias, status, latency, retry count, and avalai-request-id when supplied. Keep credentials and unnecessary raw state out of logs. Do not make unrelated live requests simply to diagnose a validation failure. See Error Handling for the wider AvalAI policy.
Related Guides and Official Sources
- Decision-model guide: design, evaluation, and debugging
- Decision workflows with Jev cookbook
- TYPESAFE AI provider and pricing
- Decisions API reference
- Official native System One API
- Official Choice, Score, and Noul primitives
- Official probability and confidence explanation
- Official model context limits
- Official request rules and errors
The official sources describe upstream behavior. AvalAI mappings and pricing come from the release announcement; the captured response identifies exactly which native behavior was observed through AvalAI.