Sub-skill of opper — start there for discovery and setup guidance.
Source: https://github.com/opper-ai/opper-skills/blob/main/opper-sdks/SKILL.md
Opper SDKs
The Python and TypeScript SDKs for Opper live in a single monorepo: github.com/opper-ai/opper-sdks. Both publish as opperai (PyPI / npm). Agents are part of the SDK — there is no separate opperai-agents package.
The upstream READMEs (python/README.md, typescript/README.md) and the numbered example files are the source of truth. This skill points at them; it does not duplicate them.
Pick your primitive
The unified opperai package exposes a few different shapes. Pick by what you're building:
- One-shot structured task (input → typed output): the recommended path is a compat chat endpoint with
response_format, called through the provider SDK you already know — point the OpenAI SDK's base_url at https://api.opper.ai/v3/compat and pass your Pydantic / Zod model via chat.completions.parse(...). Seeds below; full shape in the opper-api skill.
- Streaming:
stream: true on the same compat call — standard OpenAI SSE semantics.
- Multi-turn chat or message-thread style: the compat chat endpoints are message-native — carry the
messages array forward.
- Tool-using agent, multi-step reasoning, multi-agent, MCP: the Agent SDK (
Agent, tool, Conversation, Hooks, mcp) is recommended for any "model decides what to do next" flow. Use agent.run(...) for a single shot or agent.stream(...) for live progress.
- Knowledge bases / RAG:
opper.knowledge.* — create, query, add, etc.
opper.call(...) / opper.stream(...) are legacy. They ride Opper's /call surface, which is being sunset — don't start new work on them, and don't use them in examples. The opperai SDK itself is being reworked to no longer use /call; a future release drops it. Existing code migrates to compat + response_format; the field-by-field mapping (name → X-Opper-Name header, output_schema → response_format, result.data → parsed message content) is in the opper-api skill's references/migration.md.
Pick a path
| You are… |
Read |
| Writing Python (calls, streaming, schemas, knowledge, tracing) |
references/python.md |
| Writing TypeScript / JavaScript |
references/typescript.md |
| Building an agent in either language |
references/agents.md |
| Calling Opper without an SDK (curl, fetch) |
switch to the opper-api skill |
Install
pip install opperai # Python — has one runtime dep: httpx
npm install opperai # TypeScript — zero runtime deps; zod and @modelcontextprotocol/sdk are optional peers
Authentication: both SDKs read OPPER_API_KEY from the environment, or accept api_key= / apiKey: in the constructor.
Canonical seed — Python
One-shot tasks go through the compat endpoint with the stock OpenAI SDK; X-Opper-Name keeps named-function tracing:
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.opper.ai/v3/compat",
api_key=os.environ["OPPER_API_KEY"],
default_headers={"X-Opper-Name": "summarise"},
)
resp = client.chat.completions.create(
model="openai/gpt-5-mini",
messages=[
{"role": "system", "content": "Summarise the article in two sentences."},
{"role": "user", "content": "..."},
],
)
print(resp.choices[0].message.content)
For typed output, use client.chat.completions.parse(..., response_format=YourPydanticModel) and read resp.choices[0].message.parsed.
Canonical seed — TypeScript
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.opper.ai/v3/compat",
apiKey: process.env.OPPER_API_KEY,
defaultHeaders: { "X-Opper-Name": "summarise" },
});
const resp = await client.chat.completions.create({
model: "openai/gpt-5-mini",
messages: [
{ role: "system", content: "Summarise the article in two sentences." },
{ role: "user", content: "..." },
],
});
console.log(resp.choices[0].message.content);
For typed output, pass response_format: { type: "json_schema", json_schema: { name, schema } } (generate the schema from Zod v4 with z.toJSONSchema(...)) and JSON.parse the message content.
For the agent seeds (Agent, tool, agent.run(...)), see references/agents.md.
Picking a model
The SDK uses the project's default model when model: is omitted — set the default once via a Control Plane Route rule at platform.opper.ai so the same code works across environments without edits. Pin a specific model: "provider/name" only when you need to override.
- Browse models for the user: link them at opper.ai/models — the human catalog.
- Discover models in code:
GET https://api.opper.ai/v3/models (no auth required). Never hardcode model lists — they change.
The numbered examples are the highest-bandwidth reference
Both python/examples/ and typescript/examples/ hold parallel numbered files. Read by topic. Caveat: many of the getting-started examples still demonstrate the legacy opper.call surface — treat them as reference for existing code, not as the pattern for new work (that's compat + response_format, above).
Getting started (examples/getting-started/):
| Topic |
File pattern |
| First call |
00_your_first_call.{py,ts} |
| Schemas — Pydantic / Zod / dataclass / TypedDict / raw JSON Schema |
01a_* and 01b_* |
| Streaming |
02_stream.{py,ts} |
| Tools — call & stream |
03a_*, 03b_* (TS-only 03c-server-side-tools.ts) |
| Images, audio, video |
04a/04b/04c, 05, 06 |
| Embeddings |
07_* |
| Function management |
08_* |
| Observability / tracing |
09, 09b_manual_tracing, 09c_traces |
| Models |
10_models.{py,ts} |
| Real-time |
TS-only: 11-real-time.ts |
| Knowledge base |
12_knowledge_base.{py,ts} |
| Web tools |
13_web_tools.{py,ts} |
Agents (examples/agents/, numbered 00..10): first agent → output schema → tools → streaming → hooks (logging / timing / streaming) → agent-as-tool → multi-agent → MCP (stdio) → conversation. See references/agents.md for the topic↔file table.
Type definitions: python/src/opperai/types.py and typescript/src/types.ts.
Non-obvious gotchas
opper.call rides the legacy /call surface, which is being sunset — and the SDK is being reworked to drop it. Recommend it to no one; migrate existing opper.call code to a compat endpoint with response_format (mapping in the opper-api skill's references/migration.md).
- No required schema library. Both SDKs accept plain JSON Schema dicts and don't need any third-party schema package. Pydantic (Python) and Zod (TS) are bundled integrations for convenience — most users will reach for them, but they are optional.
- If you use Zod with the TS SDK, it must be v4.
npm install zod@4. The zod@3.25.x dual-mode package is not supported. (Zod is an optional peer dependency.)
- Python depends on
httpx (not zero-dep at runtime); TypeScript is zero-dep at runtime.
opperai is the unified package. Old separate opperai-agents (PyPI) and @opperai/agents (npm) are deprecated; Agent, tool, Conversation, Hooks, etc. are all re-exported from the top-level opperai.
- Migration from earlier versions is documented at
python/MIGRATION.md and typescript/MIGRATION.md upstream.
- For API signature questions, fetch the live OpenAPI spec at
https://api.opper.ai/v3/openapi.yaml. The SDK shape mirrors the spec.
Where to look next
| For |
Look at |
| Install, quick start, full READMEs |
opper-sdks repo — python/README.md, typescript/README.md |
| Working examples (numbered, progressive) |
python/examples/, typescript/examples/ in the repo |
| Type definitions |
python/src/opperai/types.py, typescript/src/types.ts |
| Live API spec |
https://api.opper.ai/v3/openapi.yaml |
| Migrating from older SDK versions |
python/MIGRATION.md, typescript/MIGRATION.md |
| Repo-level workflows (OpenAPI sync, beta endpoints) |
CLAUDE.md in the opper-sdks repo |
| Models available, gateway concepts, raw HTTP, Realtime |
the opper-api skill |
| Browsable model catalog (for user-facing recommendations) |
opper.ai/models |
| Control Plane (Route / Observe / Steer / Guard / Comply) |
docs.opper.ai/control-plane/overview |
| Calling Opper from a terminal |
the opper-cli skill |
1---2name: opper-sdks3description: Use the unified Opper SDKs (`opperai` package for both Python and TypeScript, with built-in agent support) for AI task completion, structured output with Pydantic / Zod / JSON Schema, knowledge base semantic search, streaming, tracing, tool use, and multi-agent composition. Use this skill whenever the user is writing Python or TypeScript code that imports `opperai`, builds an Opper agent, needs to migrate code off the legacy `opper.call`, or asks how to do anything Opper-related in code — even if they don't explicitly name the SDK. Both languages live in one repo with parallel numbered examples; agents are part of the SDK, not a separate package.4---56> Sub-skill of [`opper`](https://skills.opper.ai/) — start there for discovery and setup guidance.7> Source: https://github.com/opper-ai/opper-skills/blob/main/opper-sdks/SKILL.md89# Opper SDKs1011The Python and TypeScript SDKs for Opper live in a single monorepo: [github.com/opper-ai/opper-sdks](https://github.com/opper-ai/opper-sdks). Both publish as `opperai` (PyPI / npm). **Agents are part of the SDK** — there is no separate `opperai-agents` package.1213The upstream READMEs (`python/README.md`, `typescript/README.md`) and the numbered example files are the source of truth. This skill points at them; it does not duplicate them.1415## Pick your primitive1617The unified `opperai` package exposes a few different shapes. Pick by what you're building:1819- **One-shot structured task** (input → typed output): the recommended path is a **compat chat endpoint with `response_format`**, called through the provider SDK you already know — point the OpenAI SDK's `base_url` at `https://api.opper.ai/v3/compat` and pass your Pydantic / Zod model via `chat.completions.parse(...)`. Seeds below; full shape in the **`opper-api` skill**.20- **Streaming**: `stream: true` on the same compat call — standard OpenAI SSE semantics.21- **Multi-turn chat or message-thread style**: the compat chat endpoints are message-native — carry the `messages` array forward.22- **Tool-using agent, multi-step reasoning, multi-agent, MCP**: the **Agent SDK** (`Agent`, `tool`, `Conversation`, `Hooks`, `mcp`) is recommended for any "model decides what to do next" flow. Use **`agent.run(...)`** for a single shot or **`agent.stream(...)`** for live progress.23- **Knowledge bases / RAG**: **`opper.knowledge.*`** — `create`, `query`, `add`, etc.24- **`opper.call(...)` / `opper.stream(...)` are legacy.** They ride Opper's `/call` surface, which is **being sunset** — don't start new work on them, and don't use them in examples. The `opperai` SDK itself is being reworked to no longer use `/call`; a future release drops it. Existing code migrates to compat + `response_format`; the field-by-field mapping (`name` → `X-Opper-Name` header, `output_schema` → `response_format`, `result.data` → parsed message content) is in the `opper-api` skill's `references/migration.md`.2526## Pick a path2728| You are… | Read |29|---|---|30| Writing Python (calls, streaming, schemas, knowledge, tracing) | [references/python.md](references/python.md) |31| Writing TypeScript / JavaScript | [references/typescript.md](references/typescript.md) |32| Building an agent in either language | [references/agents.md](references/agents.md) |33| Calling Opper without an SDK (curl, fetch) | switch to the `opper-api` skill |3435## Install3637```bash38pip install opperai # Python — has one runtime dep: httpx39npm install opperai # TypeScript — zero runtime deps; zod and @modelcontextprotocol/sdk are optional peers40```4142Authentication: both SDKs read `OPPER_API_KEY` from the environment, or accept `api_key=` / `apiKey:` in the constructor.4344## Canonical seed — Python4546One-shot tasks go through the compat endpoint with the stock OpenAI SDK; `X-Opper-Name` keeps named-function tracing:4748```python49import os50from openai import OpenAI5152client = OpenAI(53 base_url="https://api.opper.ai/v3/compat",54 api_key=os.environ["OPPER_API_KEY"],55 default_headers={"X-Opper-Name": "summarise"},56)5758resp = client.chat.completions.create(59 model="openai/gpt-5-mini",60 messages=[61 {"role": "system", "content": "Summarise the article in two sentences."},62 {"role": "user", "content": "..."},63 ],64)65print(resp.choices[0].message.content)66```6768For typed output, use `client.chat.completions.parse(..., response_format=YourPydanticModel)` and read `resp.choices[0].message.parsed`.6970## Canonical seed — TypeScript7172```ts73import OpenAI from "openai";7475const client = new OpenAI({76 baseURL: "https://api.opper.ai/v3/compat",77 apiKey: process.env.OPPER_API_KEY,78 defaultHeaders: { "X-Opper-Name": "summarise" },79});8081const resp = await client.chat.completions.create({82 model: "openai/gpt-5-mini",83 messages: [84 { role: "system", content: "Summarise the article in two sentences." },85 { role: "user", content: "..." },86 ],87});88console.log(resp.choices[0].message.content);89```9091For typed output, pass `response_format: { type: "json_schema", json_schema: { name, schema } }` (generate the schema from Zod v4 with `z.toJSONSchema(...)`) and `JSON.parse` the message content.9293For the agent seeds (`Agent`, `tool`, `agent.run(...)`), see [references/agents.md](references/agents.md).9495### Picking a model9697The SDK uses the project's default model when `model:` is omitted — set the default once via a Control Plane **Route** rule at [platform.opper.ai](https://platform.opper.ai) so the same code works across environments without edits. Pin a specific `model: "provider/name"` only when you need to override.9899- **Browse models for the user**: link them at [opper.ai/models](https://opper.ai/models) — the human catalog.100- **Discover models in code**: `GET https://api.opper.ai/v3/models` (no auth required). **Never hardcode model lists** — they change.101102## The numbered examples are the highest-bandwidth reference103104Both `python/examples/` and `typescript/examples/` hold parallel numbered files. Read by topic. **Caveat:** many of the getting-started examples still demonstrate the legacy `opper.call` surface — treat them as reference for existing code, not as the pattern for new work (that's compat + `response_format`, above).105106**Getting started** (`examples/getting-started/`):107108| Topic | File pattern |109|---|---|110| First call | `00_your_first_call.{py,ts}` |111| Schemas — Pydantic / Zod / dataclass / TypedDict / raw JSON Schema | `01a_*` and `01b_*` |112| Streaming | `02_stream.{py,ts}` |113| Tools — call & stream | `03a_*`, `03b_*` (TS-only `03c-server-side-tools.ts`) |114| Images, audio, video | `04a/04b/04c`, `05`, `06` |115| Embeddings | `07_*` |116| Function management | `08_*` |117| Observability / tracing | `09`, `09b_manual_tracing`, `09c_traces` |118| Models | `10_models.{py,ts}` |119| Real-time | TS-only: `11-real-time.ts` |120| Knowledge base | `12_knowledge_base.{py,ts}` |121| Web tools | `13_web_tools.{py,ts}` |122123**Agents** (`examples/agents/`, numbered `00..10`): first agent → output schema → tools → streaming → hooks (logging / timing / streaming) → agent-as-tool → multi-agent → MCP (stdio) → conversation. See [references/agents.md](references/agents.md) for the topic↔file table.124125Type definitions: `python/src/opperai/types.py` and `typescript/src/types.ts`.126127## Non-obvious gotchas128129- **`opper.call` rides the legacy `/call` surface, which is being sunset — and the SDK is being reworked to drop it.** Recommend it to no one; migrate existing `opper.call` code to a compat endpoint with `response_format` (mapping in the `opper-api` skill's `references/migration.md`).130- **No required schema library.** Both SDKs accept plain JSON Schema dicts and don't need any third-party schema package. Pydantic (Python) and Zod (TS) are bundled integrations for convenience — most users will reach for them, but they are optional.131- **If you use Zod with the TS SDK, it must be v4.** `npm install zod@4`. The `zod@3.25.x` dual-mode package is *not* supported. (Zod is an *optional peer dependency*.)132- **Python depends on `httpx`** (not zero-dep at runtime); TypeScript is zero-dep at runtime.133- **`opperai` is the unified package.** Old separate `opperai-agents` (PyPI) and `@opperai/agents` (npm) are deprecated; `Agent`, `tool`, `Conversation`, `Hooks`, etc. are all re-exported from the top-level `opperai`.134- **Migration from earlier versions** is documented at `python/MIGRATION.md` and `typescript/MIGRATION.md` upstream.135- **For API signature questions**, fetch the live OpenAPI spec at `https://api.opper.ai/v3/openapi.yaml`. The SDK shape mirrors the spec.136137## Where to look next138139| For | Look at |140|---|---|141| Install, quick start, full READMEs | [opper-sdks repo](https://github.com/opper-ai/opper-sdks) — `python/README.md`, `typescript/README.md` |142| Working examples (numbered, progressive) | `python/examples/`, `typescript/examples/` in the repo |143| Type definitions | `python/src/opperai/types.py`, `typescript/src/types.ts` |144| Live API spec | `https://api.opper.ai/v3/openapi.yaml` |145| Migrating from older SDK versions | `python/MIGRATION.md`, `typescript/MIGRATION.md` |146| Repo-level workflows (OpenAPI sync, beta endpoints) | `CLAUDE.md` in the opper-sdks repo |147| Models available, gateway concepts, raw HTTP, Realtime | the `opper-api` skill |148| Browsable model catalog (for user-facing recommendations) | [opper.ai/models](https://opper.ai/models) |149| Control Plane (Route / Observe / Steer / Guard / Comply) | [docs.opper.ai/control-plane/overview](https://docs.opper.ai/control-plane/overview) |150| Calling Opper from a terminal | the `opper-cli` skill |