Classification
POST /v1/evaluate answers typed questions about one piece of state: pick an
option, place it on a scale, or give the probability of a yes. It runs on Jev,
TypeSafe's classifier model. The request and response follow the AI Gateway
/v1/evaluate wire, whose fields are the AI SDK's evaluation-model fields.
The call runs on your project's TypeSafe key and is metered like any model op. A smith's own TypeSafe key is not used. Nothing is stored: the state, the questions, and the answers are not persisted.
Classify text
# Authorization: tenant-admin token (server-side only)
curl https://api.cloud.ingram.tech/v1/evaluate \
-H "Authorization: Bearer $IC_TOKEN" \
-H "IC-Api-Version: 2026-05-01" \
-H "Content-Type: application/json" \
-d '{
"state": "My card was charged twice.",
"questions": {
"route": {
"type": "choice",
"instructions": "Route this ticket.",
"criteria": { "billing": "payment problems", "shipping": "delivery problems" }
},
"urgency": {
"type": "score",
"instructions": "How urgent is this ticket?",
"criteria": ["can wait", "today", "now"]
},
"refund": { "type": "boolean", "instructions": "Does the customer ask for a refund?" }
}
}'
state is a string, a JSON object, or a JSON array. Each key of questions is
an id you choose; its answer comes back under the same id.
type | criteria | Answer |
|---|---|---|
choice | option name → description (null for none); at least one option | choice, the most probable option, and probabilities over every option |
score | ordered levels, lowest first; at least two | score, a fractional level counted from 0, and probabilities keyed by level index |
boolean | optional { "true": …, "false": … } descriptions | probability, the model's P(true) |
instructions and each description take a string, a JSON object, or a JSON
array.
model is optional and defaults to typesafe-ai.jev-latest. jev-latest
moves when TypeSafe ships a new version; pin typesafe-ai.jev-1.13.0 for output
that stays stable.
Response
{
"model": "typesafe-ai.jev-latest",
"answers": {
"route": { "type": "choice", "choice": "billing", "probabilities": { "billing": 0.99, "shipping": 0.01 } },
"urgency": { "type": "score", "score": 1.2, "probabilities": { "0": 0.1, "1": 0.6, "2": 0.3 } },
"refund": { "type": "boolean", "probability": 0.8 }
},
"usage": { "inputTokens": 58, "outputTokens": 0 },
"rounding": { "probabilityDecimals": 2, "scoreDecimals": 2 },
"providerMetadata": { "typesafe": { "confidence": { "route": 0.97, "urgency": 0.9 } } }
}
Probabilities and scores are rounded to the places in rounding.
providerMetadata.typesafe.confidence is TypeSafe's confidence in each choice
and score answer. It is not a probability, and boolean answers carry none.
warnings appears when the provider reports one.
Limits & errors
TypeSafe accepts at most 255 options on a choice question, 10 levels on a score question, 64k tokens per request, and 32k tokens for the state plus the longest question.
| Status | Code | When |
|---|---|---|
422 | invalid_request | The body breaks the shape above. |
422 | model_kind_mismatch | model is not a classifier model. |
422 | model_key_missing | Your project has no TypeSafe key. |
400 | model_request_failed | TypeSafe refused the request: a bad key, or a limit above. The message carries TypeSafe's reason. |
402 | budget_exceeded, card_required, insufficient_credits | As for runs; only a project-wide budget applies. See Usage and Billing. |
429 | rate_limit_exceeded | TypeSafe is rate-limiting your key. Retry after the Retry-After seconds. |
500 | evaluation_failed | Any other failure. |
Keys
Add your TypeSafe key in Settings → Models, or over the API:
# Authorization: tenant-admin token (server-side only)
curl -X PUT https://api.cloud.ingram.tech/v1/tenant/model_keys/typesafe-ai \
-H "Authorization: Bearer $IC_ADMIN_TOKEN" \
-H "IC-Api-Version: 2026-05-01" \
-H "Content-Type: application/json" \
-d '{ "api_key": "…" }'
TypeSafe bills your account for the tokens; your wallet is charged the platform fee alone. See Your own keys.
The call needs a tenant token with the runs:write scope. A smith token is
refused with 403 tenant_token_required. See Auth & tokens.