curl -X POST https://api.60db.ai/v1/systemone \
-H "Authorization: Bearer your-api-key" \
-H "Content-Type: application/json" \
-d '{
"state": "Agent: I can'"'"'t refund that, it'"'"'s outside the window.",
"questions": {
"tone": {
"type": "choice",
"criteria": {
"professional": "Calm and courteous",
"dismissive": "Brushes the caller off",
"unknown": "Not clear"
}
}
}
}'
const response = await fetch('https://api.60db.ai/v1/systemone', {
method: 'POST',
headers: {
'Authorization': 'Bearer your-api-key',
'Content-Type': 'application/json',
},
body: JSON.stringify({
state: "Agent: I can't refund that, it's outside the window.",
questions: {
tone: {
type: 'choice',
criteria: {
professional: 'Calm and courteous',
dismissive: 'Brushes the caller off',
unknown: 'Not clear',
},
},
},
}),
});
const data = await response.json();
import requests
response = requests.post(
"https://api.60db.ai/v1/systemone",
headers={
"Authorization": "Bearer your-api-key",
"Content-Type": "application/json",
},
json={
"state": "Agent: I can't refund that, it's outside the window.",
"questions": {
"tone": {
"type": "choice",
"criteria": {
"professional": "Calm and courteous",
"dismissive": "Brushes the caller off",
"unknown": "Not clear",
},
},
},
},
)
data = response.json()
{
"model": "60db-decision-model-v1",
"answers": {
"tone": {
"type": "choice",
"choice": "dismissive",
"probabilities": { "dismissive": 0.86, "professional": 0.11, "unknown": 0.03 },
"confidence": 0.79
}
},
"usage": { "input_tokens": 812, "output_tokens": 0 },
"metadata": { "backend": "60db-local", "source_model": "60db-jev-source", "escalated_questions": 0 }
}
Judge
Evaluate
Wire-compatible twin of Evaluate, for callers that already speak the upstream model service’s own contract
POST
/
v1
/
systemone
curl -X POST https://api.60db.ai/v1/systemone \
-H "Authorization: Bearer your-api-key" \
-H "Content-Type: application/json" \
-d '{
"state": "Agent: I can'"'"'t refund that, it'"'"'s outside the window.",
"questions": {
"tone": {
"type": "choice",
"criteria": {
"professional": "Calm and courteous",
"dismissive": "Brushes the caller off",
"unknown": "Not clear"
}
}
}
}'
const response = await fetch('https://api.60db.ai/v1/systemone', {
method: 'POST',
headers: {
'Authorization': 'Bearer your-api-key',
'Content-Type': 'application/json',
},
body: JSON.stringify({
state: "Agent: I can't refund that, it's outside the window.",
questions: {
tone: {
type: 'choice',
criteria: {
professional: 'Calm and courteous',
dismissive: 'Brushes the caller off',
unknown: 'Not clear',
},
},
},
}),
});
const data = await response.json();
import requests
response = requests.post(
"https://api.60db.ai/v1/systemone",
headers={
"Authorization": "Bearer your-api-key",
"Content-Type": "application/json",
},
json={
"state": "Agent: I can't refund that, it's outside the window.",
"questions": {
"tone": {
"type": "choice",
"criteria": {
"professional": "Calm and courteous",
"dismissive": "Brushes the caller off",
"unknown": "Not clear",
},
},
},
},
)
data = response.json()
{
"model": "60db-decision-model-v1",
"answers": {
"tone": {
"type": "choice",
"choice": "dismissive",
"probabilities": { "dismissive": 0.86, "professional": 0.11, "unknown": 0.03 },
"confidence": 0.79
}
},
"usage": { "input_tokens": 812, "output_tokens": 0 },
"metadata": { "backend": "60db-local", "source_model": "60db-jev-source", "escalated_questions": 0 }
}
Byte-for-byte wire-compatible twin of Evaluate — same auth, same billing, same request body — for a caller that already speaks the upstream model service’s own contract directly. This path matches the upstream’s own
Every error above is returned as
POST /v1/systemone exactly, so that caller needs no custom integration to point at api.60db.ai.
Three differences from POST /judge/evaluate:
- The response is the raw upstream answer — no
{success,data}envelope, and noid/saved/credits_chargedfields. - Errors are
{error:{code,message}}, not{success:false,message,code}. - A run through this route is never saved to Judge history — there’s no
save,label, orrubric_idon the wire, and nothing you send changes that.
/judge/evaluate — the same wallet, the same refund-on-failure — it just has nowhere to go in the upstream’s own envelope, so it rides the x-credit-charged / x-credit-balance / x-billing-tx response headers instead of the body.
Billed per input token, same rate as Evaluate. See Judge pricing.
Request
Headers
string
required
Bearer token — your standard 60db API key (
sk_…), or a user JWT. The same credential as every other Judge route.string
required
application/json
Body
Identical to Evaluate, minus the 60db-local fields that don’t exist on the upstream’s own wire format:string | object | array
required
The content every question is asked about. Top-level numbers, booleans and
null are rejected.object
required
Map of answer key → question, 1–32 entries —
choice, score or noul. See Evaluate → Body for the full shape of each type.string
default:"jev-latest"
Model name. Fetch the valid list from List models.
No
rubric_id, save, or label fields — those are 60db-local conveniences with no place in the upstream contract. Use Evaluate if you need a saved rubric or run history.Response
The raw upstream object — no envelope:string
The resolved model id, e.g.
60db-decision-model-v1.object
One answer per question, under the same key you supplied. Same shape as Evaluate’s
data.answers.object
input_tokens and output_tokens (snake_case, as the upstream reports them). output_tokens can be non-zero — billing is input-only regardless.object
Includes
escalated_questions — how many answers the service refined when confidence was low. The same model answers every question; there is no separate second-stage model.Errors
| Status | Meaning |
|---|---|
400 | Invalid rubric — the message names the offending question. Also returned when the request exceeds 512 KiB or the 200,000-token context. |
402 | Insufficient credits. |
403 | Your role cannot run the judge, or an API key lacks the judge scope. |
429 | The judge’s inference queue is full — back off and retry. |
502 / 503 | The judge service is misconfigured or unavailable. |
{"error": {"code": "...", "message": "..."}}, not {success:false,...}.
Example
curl -X POST https://api.60db.ai/v1/systemone \
-H "Authorization: Bearer your-api-key" \
-H "Content-Type: application/json" \
-d '{
"state": "Agent: I can'"'"'t refund that, it'"'"'s outside the window.",
"questions": {
"tone": {
"type": "choice",
"criteria": {
"professional": "Calm and courteous",
"dismissive": "Brushes the caller off",
"unknown": "Not clear"
}
}
}
}'
const response = await fetch('https://api.60db.ai/v1/systemone', {
method: 'POST',
headers: {
'Authorization': 'Bearer your-api-key',
'Content-Type': 'application/json',
},
body: JSON.stringify({
state: "Agent: I can't refund that, it's outside the window.",
questions: {
tone: {
type: 'choice',
criteria: {
professional: 'Calm and courteous',
dismissive: 'Brushes the caller off',
unknown: 'Not clear',
},
},
},
}),
});
const data = await response.json();
import requests
response = requests.post(
"https://api.60db.ai/v1/systemone",
headers={
"Authorization": "Bearer your-api-key",
"Content-Type": "application/json",
},
json={
"state": "Agent: I can't refund that, it's outside the window.",
"questions": {
"tone": {
"type": "choice",
"criteria": {
"professional": "Calm and courteous",
"dismissive": "Brushes the caller off",
"unknown": "Not clear",
},
},
},
},
)
data = response.json()
{
"model": "60db-decision-model-v1",
"answers": {
"tone": {
"type": "choice",
"choice": "dismissive",
"probabilities": { "dismissive": 0.86, "professional": 0.11, "unknown": 0.03 },
"confidence": 0.79
}
},
"usage": { "input_tokens": 812, "output_tokens": 0 },
"metadata": { "backend": "60db-local", "source_model": "60db-jev-source", "escalated_questions": 0 }
}