TypeSafe-compatible API

Send TypeSafe’s systemone request shape to decision-machine-1 and get typed answers with the model’s own probabilities.

decision-machine-1 serves POST https://api.milliseconds.ai/v1/systemone. The request and response follow the wire format of TypeSafe’s /v1/systemone. Keep your request builder. Change the base URL, the key and the model name.

Set the base URL to https://api.milliseconds.ai, model to decision-machine-1, and the bearer token to your test or production key. See Authentication.

This route is a compatibility layer over three native capabilities. noul runs yes-no, choice runs classify and score runs rate. Every question runs on the same state, in parallel.

milliseconds.ai is not affiliated with TypeSafe AI. The route implements a public wire format.

The first call

One state, three named questions, one call.

curl https://api.milliseconds.ai/v1/systemone \
-H "content-type: application/json" \
-H "authorization: Bearer test_sk-..." \
-d '{
"state": "Shoes arrived two weeks late and in the wrong size. Also I see two charges on my card. What are you going to do about this?",
"model": "decision-machine-1",
"questions": {
"department": {
"type": "choice",
"instructions": "Which team should handle this?",
"criteria": {
"returns": "Exchanges, refunds, wrong or damaged items",
"shipping": "Delivery status, delays, lost packages",
"billing": "Charges, invoices, payment problems"
}
},
"double_charge": {
"type": "noul",
"instructions": "Does the customer report a duplicate charge?",
"criteria": {
"true": "The customer says they were charged more than once",
"false": "No duplicate charge is mentioned"
}
},
"urgency": {
"type": "score",
"instructions": "How urgent is this ticket?",
"criteria": ["can wait", "this week", "today"]
}
}
}'

The response carries one answer per question, keyed by your question names. This is a real capture.

{
"model": "decision-machine-1",
"answers": {
"department": {
"type": "choice",
"choice": "billing",
"probabilities": {"returns": 0.242, "shipping": 0.133, "billing": 0.625},
"confidence": 0.438
},
"double_charge": {"type": "noul", "noul": 0.592},
"urgency": {
"type": "score",
"score": 0.684,
"legend": {"0": "can wait", "1": "this week", "2": "today"},
"probabilities": {"0": 0.602, "1": 0.112, "2": 0.286},
"confidence": 0.658
}
},
"usage": {"input_tokens": 394, "output_tokens": 0}
}

The request

FieldTypeMeaning
statestring, object or arrayThe content to evaluate. The API renders an object or array to text: keys become labels, array items become lines. At most 20,000 characters once rendered.
modelstring, optionaldecision-machine-1. Omit it for the same result. Any other value returns 404 model_not_found.
questionsmap of name to question1 to 32 named questions. Every question runs on the same state.

Every question carries type and instructions. instructions accepts a string, object or array and renders the same way as state.

typecriteriaRuns asAnswer fields
noulOptional { "true": ..., "false": ... } descriptionsyes-no with when_true and when_falsenoul, the probability of yes
choiceMap of 2 to 64 option names to descriptions, null for noneclassifychoice, probabilities per option, confidence
scoreOrdered array of 2 to 10 level descriptions, low to highratescore, legend, probabilities per level index, confidence

The answers

  • noul is the model’s probability that the statement holds. It is the probability field of yes-no.
  • choice names the option with the highest probability. probabilities is the full distribution over your option names. It sums to 1.
  • score is the probability-weighted level, from 0 to the number of levels minus one. legend maps each level index to the criterion you sent. probabilities is keyed by level index as a string.
  • confidence describes the shape of the distribution, not the probability. For choice it is how far the winner sits above a flat distribution: (K × max − 1) / (K − 1) for K options. For score it is one minus the mean distance from the most likely level, scaled to 0 to 1. noul answers carry no confidence.

usage.input_tokens is the input billed for the call. usage.output_tokens is always 0. The model generates nothing.

Differences from TypeSafe

  • model must be decision-machine-1 or absent. The response echoes that name.
  • Validation errors return 400 with the { "error": { "code", "message" } } envelope, not 422. See Errors.
  • choice accepts 2 to 64 options. score accepts 2 to 10 levels. One call carries at most 32 questions.
  • This route takes no image. Use the native capabilities for images.
  • The response carries the x-input-chars, x-input-tokens and x-inference-ms headers, like every capability. See Limits and rate limits.

Billing and rate limits

The call bills its input tokens once, at the standard price. Each question counts as one inference request unit against the requests-per-minute limit, like each statement on yes-no. Three questions spend three units. See Pricing and Limits and rate limits.

Benchmarks

The route serves the request shape that the open JevBench harness sends through its typesafe adapter. Point the adapter at https://api.milliseconds.ai with --model decision-machine-1 and your key. It needs no changes.

Next