Dashboard|

Judgment API

Structured decisions from decision models (TypeSafe Jev) — yes/no, choice, and score answers with probabilities over any state.

Get calibrated decisions instead of generated text. Send a state plus typed questions and get back one answer per question with probabilities your code can branch on — routing tickets, gating automation on confidence, scoring content against a rubric. Any judgment-type catalog model works through this same endpoint (TypeSafe's Jev today).

This is a proxy over TypeSafe's System One API (POST /v1/systemone): Cencori adds its own auth, per-project keys (BYOK), input-token billing, logging, and usage metering.

Endpoints

PathPurpose
POST /v1/judgmentsJudge a state against typed questions
GET /v1/judgmentsJudgment models + pricing + limits (no key required)

Authenticate with your Cencori key (CENCORI_API_KEY: csk_... header or Authorization: Bearer). A TypeSafe key is resolved per project — your own typesafe provider key first, the managed key as fallback. BYOK calls are not charged; managed calls bill input tokens at $0.042/MTok (output tokens are unbilled).

Quick start

curl https://api.cencori.com/v1/judgments \
  -H "CENCORI_API_KEY: csk_..." \
  -H "Content-Type: application/json" \
  -d '{
    "model": "jev-latest",
    "state": "I was charged twice. Please refund the duplicate.",
    "questions": {
      "department": {
        "type": "choice",
        "instructions": "Which team should handle this?",
        "criteria": {
          "billing": "Payments, invoicing, refunds",
          "technical": "Bugs, outages, integrations"
        }
      },
      "requests_refund": {
        "type": "noul",
        "instructions": "Does the customer request a refund?"
      }
    }
  }'
import { Cencori } from 'cencori';
 
const cencori = new Cencori({ apiKey: 'csk_...' });
const result = await cencori.judgment.judge({
  state: 'I was charged twice. Please refund the duplicate.',
  questions: {
    department: {
      type: 'choice',
      instructions: 'Which team should handle this?',
      criteria: { billing: 'Payments, invoicing, refunds', technical: 'Bugs, outages' },
    },
    requests_refund: { type: 'noul', instructions: 'Does the customer request a refund?' },
  },
});
 
if (result.answers.department.type === 'choice' && result.answers.department.confidence > 0.8) {
  routeTicket(result.answers.department.choice);
}

Omit model to use the default (jev-latest). Aliases resolve upstream — the response names the version that actually judged (e.g. jev-1.13.0).

Question types

TypeAsksReturns
noulA yes/no questionnoul: probability the answer is yes (0–1)
choicePick one of 1–255 options you definechoice, confidence (0–1), full probabilities per option
scoreRate against 2–10 ordered levels, lowest firstscore, confidence, legend, full probabilities per level

Every question needs instructions. choice needs criteria as an option → rubric map (use null where an option needs no detail); score needs criteria as the ordered level array. noul accepts optional true/false criteria describing each side. Answers come back under the same ids you sent.

state is what the questions are about: a string, a JSON object, or an array of text. The 64k-token per-request budget covers the state plus all questions combined (state plus the single longest question must fit 32k) — over-budget requests are rejected before billing.

Models

ModelMeaning
jev-latestLatest stable Jev release (default)
jev-previewPreview build, ahead of latest when one exists
jev-1.13.0Pinned release

GET /v1/judgments is the authoritative list with live pricing and availability.

Response

{
  "object": "judgment",
  "model": "jev-1.13.0",
  "answers": {
    "department": {
      "type": "choice",
      "choice": "billing",
      "confidence": 0.91,
      "probabilities": { "billing": 0.93, "technical": 0.07 }
    },
    "requests_refund": { "type": "noul", "noul": 0.97 }
  },
  "usage": { "input_tokens": 214, "output_tokens": 18 }
}

confidence (choice/score) says how peaked the distribution is — use it as a second axis: act above your threshold, escalate to a person or a reasoning model below it. (noul carries no separate confidence; max(noul, 1 - noul) is the equivalent.)

Errors

CodeStatusMeaning
invalid_questions / invalid_state / context_exceeded400Fix the request (limits above); nothing was billed
unknown_model404Not a judgment model id — see GET /v1/judgments
model_not_allowed403The calling key is not granted this model
provider_connection_required402No TypeSafe key configured — add a typesafe provider key
rate_limited429Upstream rate limit; honor retry-after and retry with backoff
provider_auth / provider_validation / upstream_error502Upstream rejected the key or the call

When not to use it

Judgment classifies and rates content you already have — it never writes replies, summaries, or code, and it answers one flat batch of independent questions per call (no agent loop, no tool use). For generation or multi-step reasoning, use Chat or Responses and let a judgment call gate or route the result.