# 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.

Source: https://opendecisio.com/docs/migrating/

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:8000
export TYPESAFE_API_KEY=unused
export TYPESAFE_DEFAULT_MODEL=decisio-gemma-4-31b-it-letters
```

 

Run against the CPU stand-in at v0.35.0 on 2026-10-26: sets the variables the SDK reads.

 

[Figure: An existing client changes where it sends, and the model name; nothing else. To move a System One client to a decisio server, change its base URL to the server's address and its model to the served name (decisio-gemma-4-31b-it-letters). The route and the request and answer fields stay.]

 

## 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.96
print(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

 

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/models
```

 

Run 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

 

`GET /health` names the model the server runs, its checkpoint and its revision:

 

```
curl -s http://127.0.0.1:8000/health
```

 

Run 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

  

| 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](https://opendecisio.com/docs/api/) |
| A score with more than 10 levels | refused with 422 | answered |
| `box` [questions](https://opendecisio.com/docs/glossary/#question) | supported | refused with 422 |
| [Probabilities](https://opendecisio.com/docs/glossary/#probability) | rounded to two decimals | at full precision |

 

- **No authentication.** The server accepts any API key and ignores it: keep it on `127.0.0.1` or 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_tokens` is counted in the model’s own tokenizer, so counts differ from another provider’s; `usage.output_tokens` is 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 `timeout` for the first request after a server starts, which warms the model.

 

## What decisio adds

 

- [Teach a task](https://opendecisio.com/docs/tasks/): teach a question you ask again and again from your own labelled examples, and certify its answers.
- [Operate](https://opendecisio.com/docs/operating/#2-watch-it): `GET /health` and the `x-decisio-*` headers on every answer, which give the server’s time and what answered.
- [How it works](https://opendecisio.com/docs/how-it-works/): decisio reads every [option](https://opendecisio.com/docs/glossary/#option)’s probability from the model in one pass, instead of generating text.

 

## What next

 

- [Call it from your code](https://opendecisio.com/docs/use-from/): the same request from curl, Python, JavaScript and the frameworks.
- [Requirements and limits](https://opendecisio.com/docs/limits/): the context, the options per question and what was measured on what.
- [The HTTP API](https://opendecisio.com/docs/api/): every route, request field and response field.
