---
title: TypeSafe → SIE
description: Run TypeSafe System One code on SIE. Keep the TypeSafe SDK and your questions; change the base URL, the key and the model.
canonical_url: https://superlinked.com/docs/migrate/typesafe
last_updated: 2026-10-16
---

SIE serves TypeSafe's System One API at `POST /v1/systemone`. Code written
with the TypeSafe SDK runs on SIE unchanged: `noul`, `choice` and `score`
questions, text, object and conversation states, `models.list()` and the
async client. You point the SDK at SIE and name an SIE decision model.

## TL;DR

#### Python

```diff
- client = TypeSafeClient(model="jev-latest")
+ client = TypeSafeClient(
+     api_key="sk-sie-…",
+     base_url="https://api.superlinked.com",
+     model="fastino/GLiNER2.5-Decide",
+ )
```

#### Environment

```bash
export TYPESAFE_BASE_URL=https://api.superlinked.com
export TYPESAFE_API_KEY=$SIE_API_KEY
export TYPESAFE_DEFAULT_MODEL=fastino/GLiNER2.5-Decide
```

The Python and TypeScript SDKs both read the three `TYPESAFE_*` variables,
so code that builds its client from the environment needs no edit at all.
The base URL is the API root: the SDK adds `/v1/systemone` itself.

## Before

#### Python

```python
from typesafe_sdk import Choice, Noul, Score, TypeSafeClient

TICKET = "I was charged twice for my March invoice. Please refund one of the charges today."

with TypeSafeClient(model="jev-latest") as client:
    response = client.system_one(
        state=TICKET,
        questions={
            "spam": Noul(instructions="Is this message unsolicited spam?"),
            "intent": Choice(
                instructions="What does the customer want?",
                criteria={
                    "billing": "payments, invoices or refunds",
                    "technical": "something is broken",
                    "other": None,
                },
            ),
            "urgency": Score(
                instructions="How urgent is this request?",
                criteria=["can wait", "this week", "today"],
            ),
        },
    )

print(response.nouls["spam"].noul)
print(response.choices["intent"].choice)
print(response.scores["urgency"].score)
```

#### TypeScript

```typescript
import { TypeSafeClient, choice, noul, score } from "@typesafe-ai/sdk";

const TICKET = "I was charged twice for my March invoice. Please refund one of the charges today.";

const client = new TypeSafeClient({ defaultModel: "jev-latest" });
const { answers } = await client.systemOne({
  state: TICKET,
  questions: {
    spam: noul("Is this message unsolicited spam?"),
    intent: choice("What does the customer want?", {
      billing: "payments, invoices or refunds",
      technical: "something is broken",
      other: null,
    }),
    urgency: score("How urgent is this request?", ["can wait", "this week", "today"]),
  },
});

console.log(answers.spam.noul, answers.intent.choice, answers.urgency.score);
```

## After

Only the client changes. The questions and the way you read the answers stay
as they are.

#### Python

```python
from typesafe_sdk import Choice, Noul, Score, TypeSafeClient

TICKET = "I was charged twice for my March invoice. Please refund one of the charges today."

with TypeSafeClient(
    api_key="sk-sie-…",
    base_url="https://api.superlinked.com",
    model="fastino/GLiNER2.5-Decide",
) as client:
    response = client.system_one(
        state=TICKET,
        questions={
            "spam": Noul(instructions="Is this message unsolicited spam?"),
            "intent": Choice(
                instructions="What does the customer want?",
                criteria={
                    "billing": "payments, invoices or refunds",
                    "technical": "something is broken",
                    "other": None,
                },
            ),
            "urgency": Score(
                instructions="How urgent is this request?",
                criteria=["can wait", "this week", "today"],
            ),
        },
    )

print(response.nouls["spam"].noul)
print(response.choices["intent"].choice)
print(response.scores["urgency"].score)
```

#### TypeScript

```typescript
import { TypeSafeClient, choice, noul, score } from "@typesafe-ai/sdk";

const TICKET = "I was charged twice for my March invoice. Please refund one of the charges today.";

const client = new TypeSafeClient({
  apiKey: "sk-sie-…",
  baseURL: "https://api.superlinked.com",
  defaultModel: "fastino/GLiNER2.5-Decide",
});
const { answers } = await client.systemOne({
  state: TICKET,
  questions: {
    spam: noul("Is this message unsolicited spam?"),
    intent: choice("What does the customer want?", {
      billing: "payments, invoices or refunds",
      technical: "something is broken",
      other: null,
    }),
    urgency: score("How urgent is this request?", ["can wait", "this week", "today"]),
  },
});

console.log(answers.spam.noul, answers.intent.choice, answers.urgency.score);
```

## Choosing a model

`/v1/systemone` answers with SIE's decision models. Each reads a fixed
window of tokens per row:

| Model | Window | What shares it |
|---|---|---|
| `fastino/GLiNER2.5-Decide` | 512 tokens | All of a request's questions (at most 256 tokens) and the state |
| `fastino/GLiNER2.5-Decide-1B` | 2,048 tokens | All of the questions (at most 512 tokens) and the state; for longer text |
| `fastino/GLiNER2.5-multi-Decide` | 2,048 tokens | As Decide-1B, multilingual |
| `convaiinnovations/laya-typed-decisions` | 1,024 tokens | One question and the state, per question |
| `convaiinnovations/laya-multilingual` | 1,024 tokens | As above, multilingual |
| `convaiinnovations/laya` | 512 tokens | As above |

`GLiNER2.5-Decide` runs on SIE Serverless. Self-hosted SIE serves all six.

## What differs from TypeSafe's hosted API

- **Model names.** SIE takes its own model ids and has no aliases such as
  `jev-latest`. Set the model on the client, in `TYPESAFE_DEFAULT_MODEL`, or
  per call with `model=`.
- **Score levels.** A score question takes 1 to 10 levels.
- **Input that does not fit.** SIE refuses a state or question set that does
  not fit the model's window with `422`, which the Python SDK raises as
  `TypeSafeUnprocessableEntityError`. It never truncates text. Use a model
  with a longer window for long states.
- **Other models.** `models.list()` lists every model the server serves. A
  `system_one` call with a model that does not answer typed questions gets
  `422`.
- **Loading.** A model that is still loading answers `503` with a
  `Retry-After` header.

## Run it yourself

GLiNER2.5-Decide is a 340M-parameter encoder, so a CPU serves it:

```bash
docker run -p 8080:8080 ghcr.io/superlinked/sie-server:latest-cpu-transformers5

export TYPESAFE_BASE_URL=http://localhost:8080
export TYPESAFE_DEFAULT_MODEL=fastino/GLiNER2.5-Decide
export TYPESAFE_API_KEY=local   # a local server checks no key
```

The first request downloads and loads the model. The
[`systemone-local` example](https://github.com/superlinked/sie/tree/main/examples/systemone-local)
in the SIE repository runs the TypeSafe SDK through every feature that reaches
the server and reports each case.

Also calling OpenAI's Decisions API? See [OpenAI Decisions → SIE](/docs/migrate/openai-decisions/).
