DocsGet started
Move from System One
Point a System One client you already have at decisio by changing two settings, the base URL and the model name; what changes once it is there.
The route, the request and the answer stay the same, so the rest of your code does not change. With TypeSafe’s SDK, set its environment variables and leave the code as it is:
export TYPESAFE_BASE_URL=http://127.0.0.1:8000export TYPESAFE_API_KEY=unusedexport TYPESAFE_DEFAULT_MODEL=decisio-gemma-4-31b-it-lettersRun against the CPU stand-in at v0.35.0 on 2026-10-26: sets the variables the SDK reads.
Figure · Moving a client
An existing client changes where it sends, and the model name; nothing else.
What changes in the client
- base_url = "https://<the address it sent to before>"+ base_url = "http://127.0.0.1:8000"- model = "<the name it used before>"+ model = "decisio-gemma-4-31b-it-letters"
What stays
- The route, POST /v1/systemone
- The request's fields
- The answer's fields
What to know
- The model field does not choose a model; the server serves one base
- There is no authentication; any key is ignored
- Unknown request fields are ignored, not rejected
The served name is the one GET /v1/models lists for the default base.
Source: docs/migrating.md of the pinned release.
1. Point the client at the server
Section titled “1. Point the client at the server”Give the client the server’s address and any key; the server ignores the key. In code, with TypeSafe’s Python SDK:
from typesafe_sdk import TypeSafeClient
client = TypeSafeClient( base_url="http://127.0.0.1:8000", # the SDK requires one; decisio ignores it api_key="unused", # the name GET /v1/models lists model="decisio-gemma-4-31b-it-letters",)answer = client.system_one( state="Since this morning none of our staff can log in to the dashboard.", questions={"category": {"type": "choice", "instructions": "Which team should handle this ticket?", "criteria": {"billing": None, "access": None, "bug": None}}},)category = answer.choices["category"]# the chosen label and its confidence, for example: access 0.96print(category.choice, category.confidence)Run against the CPU stand-in at v0.35.0 on 2026-10-26: with TypeSafe's Python SDK 0.7.2, the version the page names. It printed: Its comments are shown above their commands.
access 0.3154285637293386
Any other client sends the same JSON to http://127.0.0.1:8000/v1/systemone.
2. Set the model to the served name
Section titled “2. Set the model to the served name”The model field does not choose a model: a server serves the one it was started with.
The answer echoes the name you sent, so set it to the served name to keep your logs right.
GET /v1/models lists it:
curl -s http://127.0.0.1:8000/v1/modelsRun against the CPU stand-in at v0.35.0 on 2026-10-26. It printed:
{
"models": [
{
"name": "decisio-qwen3.6-35b-a3b-letters",
"description": "letters readout, served default",
"release_date": "2026-09-27"
}
]
}
| Model | Served name |
|---|---|
| Gemma 4 31B, the default | decisio-gemma-4-31b-it-letters |
| Gemma 4 12B | decisio-gemma-4-12b-it-letters |
| Gemma 4 12B in FP8 | decisio-gemma-4-12b-it-fp8-letters |
| Qwen3.6-35B-A3B | decisio-qwen3.6-35b-a3b-letters |
3. Check what answers
Section titled “3. Check what answers”GET /health names the model the server runs, its checkpoint and its revision:
curl -s http://127.0.0.1:8000/healthRun against the CPU stand-in at v0.35.0 on 2026-10-26. It printed, trimmed to the fields this page uses:
{
"ok": true,
"base": "qwen3.6-35b-a3b"
}
What changes
Section titled “What changes”| What you send | System One | decisio |
|---|---|---|
A request without model | refused with 422 | answered, and the answer names the served model |
| A field it does not know | refused with 400 | accepted and ignored, so check that a field you rely on is in the HTTP API |
| A score with more than 10 levels | refused with 422 | answered |
box questions | supported | refused with 422 |
| Probabilities | rounded to two decimals | at full precision |
- No authentication. The server accepts any API key and ignores it: keep it on
127.0.0.1or behind a proxy that authenticates. - No rate limit. The SDK’s retries on 429 never fire; it still retries 408 and 5xx.
- Tokens.
usage.input_tokensis counted in the model’s own tokenizer, so counts differ from another provider’s;usage.output_tokensis 1 per question. - Errors keep their codes. 422 for a request the server cannot read, 400 for one the model cannot answer, each with a
detail. - Timeouts. The SDK gives up after 10 s by default; raise its
timeoutfor the first request after a server starts, which warms the model.
What decisio adds
Section titled “What decisio adds”- Teach a task: teach a question you ask again and again from your own labelled examples, and certify its answers.
- Operate:
GET /healthand thex-decisio-*headers on every answer, which give the server’s time and what answered. - How it works: decisio reads every option’s probability from the model in one pass, instead of generating text.
What next
Section titled “What next”- Call it from your code: the same request from curl, Python, JavaScript and the frameworks.
- Requirements and limits: the context, the options per question and what was measured on what.
- The HTTP API: every route, request field and response field.