Usage
September 17, 2026 · View on GitHub
Calling the System One API
- Async
- Sync
import asyncio
from typesafe_sdk import AsyncTypeSafeClient, Choice, Noul, Score
async def main() -> None:
async with AsyncTypeSafeClient() as client:
result = await client.system_one(
"I was charged twice. Please help ASAP.",
{
"billing": Noul(instructions="Is this about billing?"),
"tone": Choice(
instructions="What is the tone?",
criteria={"calm": None, "angry": None},
),
"urgency": Score(
instructions="How urgent is this?",
criteria=["low", "medium", "high"],
),
},
)
print(
result.nouls["billing"].noul,
result.choices["tone"].choice,
result.scores["urgency"].score,
)
asyncio.run(main())
from typesafe_sdk import Choice, Noul, Score, TypeSafeClient
client = TypeSafeClient()
state = "I was charged twice. Please help ASAP."
questions = {
"billing": Noul(instructions="Is this about billing?"),
"tone": Choice(
instructions="What is the tone?", criteria={"calm": None, "angry": None}
),
"urgency": Score(
instructions="How urgent is this?", criteria=["low", "medium", "high"]
),
}
result = client.system_one(state, questions)
print(
result.nouls["billing"].noul,
result.choices["tone"].choice,
result.scores["urgency"].score,
)
Choosing a model
Inspect the available models:``` from typesafe_sdk import TypeSafeClient
print(TypeSafeClient().models.list())
Select the model when constructing a client:```
client = TypeSafeClient(model="jev")
See theModels resource referencefor details.
Retries
Pass a customRetryPolicyasretryon the client or per call.- Client
- Per-call
from typesafe_sdk import RetryPolicy, TypeSafeClient
client = TypeSafeClient(retry=RetryPolicy(max_retries=3, backoff_max=0.2, timeout=1.0))
from typesafe_sdk import RetryPolicy
client.system_one(
state, questions, retry=RetryPolicy(max_retries=3, backoff_max=0.2, timeout=1.0)
)
Error handling
Handleexceptionsraised by the SDK:``` from typesafe_sdk import TypeSafeAPIError
try: client.system_one(state, questions) except TypeSafeAPIError as error: print(error.status, error.request_id)
## Logging
The SDK logs to the`typesafe_sdk`logger. Configure it according to[standard logging](https://docs.python.org/3/library/logging.html)guide:```
import logging
logging.getLogger("typesafe_sdk").setLevel(logging.DEBUG)
Or setTYPESAFE_LOG_LEVELto one ofdebug,info,warning,error, oroffbefore importing the SDK.infologs one summary line per request;debugalso logs request and response headers and bodies. Secret headers — authorization, API keys, cookies, and any header whose name containstokenorsecret— are redacted from log output. Request and response bodies arenotredacted.
Environment variables
The SDK reads and uses the following environment variables:| Variable | Configures | Default | | --- | --- | --- | | TYPESAFE_API_KEY | API key (required) | — | | TYPESAFE_BASE_URL | API root URL | https://api.typesafe.ai | | TYPESAFE_DEFAULT_MODEL | Default model | jev-latest | | TYPESAFE_LOG_LEVEL | typesafe_sdk logger level, applied once at import | unset |
See theconstants referencefor SDK defaults.
Forward compatibility
The SDK keeps working as the TypeSafe API evolves, so you can adopt new API features before an SDK release adds first-class support for them.
Extra request fields
Send request fields this SDK version predates withextra_body:``` from typesafe_sdk import Noul, TypeSafeClient
with TypeSafeClient() as client: client.system_one( "I was charged twice.", {"billing": Noul(instructions="About billing?")}, extra_body={"beam_width": 4}, )
### Raw question dictionaries
Pass a question as a plain dictionary to include fields this SDK version does not model yet:```
from typesafe_sdk import TypeSafeClient
with TypeSafeClient() as client:
client.system_one(
"I was charged twice.",
{"billing": {"type": "noul", "instructions": "About billing?", "weight": 2}},
)
Unknown answer kinds
The SDK logs a warning and skips unrecognized answer kinds. Useraw_http_responseto inspect the complete API response, including those answers:```
raw_answers = result.raw_http_response.json()["answers"]
### Unknown response fields
Unknown extra fields on recognized responses are ignored.