Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

to11ai-sdk

Python SDK for to11.ai — the AI engineering platform for prompt management, tracing, and evals.

Use it to render managed prompts at runtime, wire your provider client (OpenAI, Anthropic, …) to the to11 gateway with the right auth/trace headers, and group model calls into sessions, conversations, and turns for tracing. Synchronous, snake_case, Python 3.10+. Only runtime dependency: Pydantic.

Installation

pip install to11ai-sdk
# or: uv add to11ai-sdk  ·  poetry add to11ai-sdk

The SDK's only runtime dependency is Pydantic. The provider client libraries used in the examples below (openai, anthropic) are not dependencies — install whichever you use yourself, e.g. pip install openai.

Upgrading from 1.x

2.0 reshapes prompt access around a single render() call and trims the public surface to what we keep stable. prompts.resolve() is gone, the per-call env argument is now label, and routing rules are no longer exported. See Migrating from 1.x to 2.0 for the full list of renames and removals.

Quick start

Create a client, render a prompt for the current environment, and send it through the gateway with your normal provider client:

import os
from to11ai_sdk import create_client
from openai import OpenAI

to11 = create_client(
    # Each also resolves from an env var, so on a server you can pass nothing:
    base_url=os.environ.get("TO11_API_URL"),        # -> https://api.to11.ai
    api_key=os.environ.get("TO11_API_KEY"),         # -> TO11_API_KEY
    project_id=os.environ.get("TO11_PROJECT_ID"),   # -> TO11_PROJECT_ID
    env=os.environ.get("TO11_ENV"),                 # "prod", "staging", … -> TO11_ENV
)

# Render the prompt's `latest` version for the client's project, shaped for OpenAI.
prompt = to11.prompts.render("welcome-message", variables={"name": "Ada"}, format="openai")

# Point your provider client at the gateway and send it.
openai = OpenAI(**to11.openai_options())
completion = openai.chat.completions.create(
    **prompt["config"],
    messages=prompt["messages"],
    extra_headers=to11.turn().headers(prompt),  # auth + trace id + prompt provenance
)

prompt["config"] carries the model parameters, prompt["messages"] the rendered messages, and turn().headers(prompt) the headers that authenticate the gateway call and record which prompt produced the trace. config["model"] is sent as written, and the hosted gateway needs it to name a provider — set the prompt's model as <provider-slug>::<model> (for example openai::gpt-4o, where openai is the provider's routing identifier in to11).

Configuring the client

create_client(...) takes keyword-only args. Each URL/credential resolves option → environment variable → built-in default, so a server app can construct it from the environment alone:

Argument Resolves from Default
base_url option → TO11_API_URL https://api.to11.ai
gateway_url option → TO11_GATEWAY_URL https://gw.to11.ai
api_key option → TO11_API_KEY — (required)
project_id option → TO11_PROJECT_ID —
env option → TO11_ENV — (gateway routing via x-to11-env; lowercase-kebab, 1–63 chars)
provider_api_key option — (BYOK; carried by openai_options()/anthropic_options())
format option — ("openai" | "anthropic"; omit for the neutral result)
on_unknown_role option "drop"
timeout_s / max_retries option 30.0 / 3
behavior_overrides option None

The client exposes the resolved values as read-only attributes — to11.base_url, to11.gateway_url, to11.api_key, to11.project_id, and to11.env. Use the non-secret ones (base_url/gateway_url/project_id/env) for diagnostics; api_key is exposed to build manual auth headers — treat it as a secret and never log it. provider_api_key (BYOK) is deliberately not exposed back off the client.

Fetching prompts

prompts.render(slug, ...) resolves the prompt's latest version for the client's project_id in one request. Set format (on the client or per call) to get a result shaped for that provider; omit it for the provider-neutral result.

prompt = to11.prompts.render(
    "weather-concierge",
    variables={"city": "New York", "units": "fahrenheit"},
    # label=...      # pin a label for this call (defaults to "latest", the one label a prompt carries)
    # fallback=...   # a previously-rendered RenderedPrompt served on a network error
    # format="openai" | "anthropic"
    # on_unknown_role="drop" | "warn" | "error"
)
  • With format the result is spread-ready: {"messages": ..., "config": ..., "metadata": ...} (config = the version's model params; metadata = prompt/version provenance). For Anthropic it also carries a top-level "system".
  • Without format you get the neutral RenderedPrompt: .messages, .tools, .tool_choice, .prompt_id, .version, .version_id, .content_hash, .label, .slug, .block_render_record, .model_config_ (trailing underscore avoids Pydantic's reserved name).

Authored developer blocks come back as-is; the SDK maps them per provider (OpenAI keeps developer; Anthropic folds system/developer into the top-level system). on_unknown_role controls how an unrecognized role is handled during provider conversion.

Sending through the gateway

openai_options() / anthropic_options() return spread-ready kwargs (base_url, api_key, default_headers) for a provider client pointed at the gateway; default_headers carries the static tenant auth. Add turn().headers(prompt) per call for the trace id and prompt provenance:

from anthropic import Anthropic
anthropic = Anthropic(**to11.anthropic_options())

By default the gateway runs the call on the project's configured provider credential (managed). For BYOK, set provider_api_key on create_client.

Sessions, conversations & turns

Group model calls for tracing. to11.turn() uses the client's default session; create explicit ones with to11.session(id=None) / to11.conversation(id=None). turn().headers(prompt=None) emits the session/conversation ids + a fresh traceparent (plus prompt provenance when a rendered/shaped prompt is passed) — for the gateway call you make. (This is separate from the SDK's OTel-based traceparent on its own control-plane requests.)

Managing prompts, versions & labels

Beyond render(), the prompts namespace covers the control-plane lifecycle. All of these default project_id from the client — pass it per call only to override:

to11 = create_client(api_key="...", project_id="proj_abc123")

to11.prompts.list()                                        # uses the bound project_id
to11.prompts.get(prompt_id="prompt_1")
to11.prompts.get_version(prompt_id="prompt_1", version_number=3)
to11.prompts.list_labels(prompt_id="prompt_1")             # [PromptLabelPointer(label="latest", version_id="ver_9", …)]

Full set: create, list, get, update, archive, create_version, list_versions, get_version, list_labels. Creating a version moves latest; there is no label to move by hand. to11.project_environments exposes the project-environments registry.

Error handling

To11aiError is the base; catch it broadly or match a subclass:

from to11ai_sdk import To11aiRateLimitError, PromptNotFoundError

try:
    prompt = to11.prompts.render("welcome-message")
except To11aiRateLimitError as exc:
    ...  # exc.retry_after_seconds
except PromptNotFoundError:
    ...
Class When
To11aiApiError non-2xx API response (status_code, error_code, details)
To11aiAuthError 401/403
To11aiRateLimitError 429 (retry_after_seconds)
To11aiValidationError 400
To11aiNetworkError network failure / timeout
PromptNotFoundError · LabelNotFoundError · PromptHasNoVersionsError · PromptPolicyViolationError typed prompt-resolution errors
UnknownRoleError an unrecognized message role with on_unknown_role="error"
To11aiResponseValidationError a 2xx body that fails schema validation

Documentation

Full reference: https://to11.ai/docs/reference/python-sdk. Licensed under MPL-2.0.

Metadata

Release files for to11ai-sdk 3.0.0rc3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for to11ai-sdk 3.0.0rc3
File Size Uploaded Provenance
to11ai_sdk-3.0.0rc3.tar.gz 120.8 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for to11ai-sdk 3.0.0rc3
File Interpreter ABI Platform
to11ai_sdk-3.0.0rc3-py3-none-any.whl Python 3 none any Details

Total release size: 171.9 kB

Release files / to11ai_sdk-3.0.0rc3.tar.gz

Download URL to11ai_sdk-3.0.0rc3.tar.gz
Size 120.8 kB
Tags Source
SHA-256 checksum
How to use checksums
fe9072a0417f0e6b0aa9bf61b2ea6f9c6eb83be5aa36699d1902d6f168a3c45f
BLAKE2b-256 checksum
How to use checksums
7d43fbc3fc26180f0599fbd9cbc80b61d3c5a18e117cdc9af2bf662b6ebfcf91
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / to11ai_sdk-3.0.0rc3-py3-none-any.whl

Download URL to11ai_sdk-3.0.0rc3-py3-none-any.whl
Size 51.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e795ec6bb643bd965cfe4ef9cffb489fdacf7f30d5e0d3e3fa4fdb5090f7cebb
BLAKE2b-256 checksum
How to use checksums
df9de2dc2e1bb5543c6de80a862b2dce15fa54ff757a1e7a1659a73a68313725
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for to11ai-sdk 3.0.0rc3

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page