---
title: "Python SDK reference"
description: "Public types and behavior for the Meerkat Python SDK."
icon: "book"
---

## Version

```python
from meerkat import CONTRACT_VERSION
print(CONTRACT_VERSION)  # "0.6.19"
```

## Primary handles

```python
from meerkat import MeerkatClient, Session, DeferredSession, LiveChannel, Mob
```

- `MeerkatClient` owns the runtime process and transport.
- `Session` is a live multi-turn handle.
- `DeferredSession` is a created session that has not run its first turn yet.
- `LiveChannel` is the session-bound wrapper for the `live/*` RPC surface.
- `Mob` is a first-class mob control handle.

## Session result and metadata types

### `RunResult`

Returned by `session.turn()`, `deferred.start_turn()`, and available as `events.result` after streaming.

Fields:

- `session_id: str`
- `text: str`
- `turns: int`
- `tool_calls: int`
- `usage: Usage`
- `session_ref: str | None`
- `structured_output: Any | None`
- `schema_warnings: list[SchemaWarning] | None`
- `skill_diagnostics: SkillRuntimeDiagnostics | None`

### `SessionSummary`

Returned by `client.list_sessions(...)`.

- `session_id: str`
- `session_ref: str | None`
- `created_at: int`
- `updated_at: int`
- `message_count: int`
- `total_tokens: int`
- `labels: dict[str, str]`
- `is_active: bool`

### `SessionDetails`

Returned by `client.read_session(session_id)`.

- `session_id: str`
- `session_ref: str | None`
- `created_at: int`
- `updated_at: int`
- `message_count: int`
- `labels: dict[str, str]`
- `is_active: bool`
- `model: str`
- `provider: str`
- `last_assistant_text: str | None`

### `SessionInfo`

Base shared metadata type for session identity/timestamps/state.

## Config API contract

`get_config`, `set_config`, and `patch_config` return `ConfigEnvelope`:

```python
from meerkat import ConfigEnvelope
```

Fields:

- `config: dict[str, Any]`
- `generation: int`
- `realm_id: str | None`
- `instance_id: str | None`
- `backend: str | None`
- `resolved_paths: dict[str, str] | None`

## Models and schedules

### Models catalog

```python
from meerkat import ModelsCatalogResponse
```

- `contract_version: {"major": int, "minor": int, "patch": int}`
- `providers: list[ProviderCatalog]`

### Schedule wrappers

Public methods:

- `create_schedule(request)`
- `get_schedule(schedule_id)`
- `list_schedules(labels=None, limit=None, offset=None)`
- `update_schedule(request)`
- `pause_schedule(schedule_id)`
- `resume_schedule(schedule_id)`
- `delete_schedule(schedule_id)`
- `list_schedule_occurrences(schedule_id, include_terminal=None)`
- `list_schedule_tools()`
- `call_schedule_tool({"name": "...", "arguments": ...})`

Return payloads are JSON-shaped schedule contracts with typed top-level wrappers:

- `ScheduleListResult`
- `ScheduleOccurrencesResult`
- `ScheduleToolsResult`

## Session runtime input helpers

### `inject_context`

```python
await client.inject_context(session_id, text, source=None, idempotency_key=None)
await session.inject_context(text, source=None, idempotency_key=None)
```

### `send_external_event`

```python
await client.send_external_event(session_id, event_type, payload, blocks=None)
await session.send_external_event(event_type, payload, blocks=None)
```

Returns `ExternalEventOutcome` (runtime admission outcome payload).

## Additional client wrappers

The Python SDK also exposes:

- realm helpers: `list_realms()`, `get_realm(...)`
- auth helpers: `list_auth_profiles(...)`, `get_auth_profile(...)`, `create_auth_profile(...)`, `delete_auth_profile(...)`, `auth_login_*`, `auth_provision_api_key(...)`, `auth_status(...)`, `auth_logout(...)`
- blob/skill/MCP helpers: `get_blob(...)`, `list_skills()`, `mcp_add(...)`, `mcp_remove(...)`, `mcp_reload(...)`
- comms helpers: `session.send(...)`, `session.peers()`
- typed ingress helper: `send_peer_response_terminal(...)`

## Mob profile and events surfaces

### Mob event history

```python
await client.read_mob_events(mob_id, after_cursor=0, limit=100)
await mob.read_events(after_cursor=0, limit=100)
```

Returns `MobEventsResult`.

### Realm profile CRUD

```python
await client.create_mob_profile(name, profile)
await client.get_mob_profile(name)               # StoredMobProfile | None
await client.list_mob_profiles()                 # list[StoredMobProfile]
await client.update_mob_profile(name, profile, expected_revision=...)
await client.delete_mob_profile(name, expected_revision=...)
```

Types:

- `MobProfile`, `MobProfileTools`
- `StoredMobProfile`
- `DeletedMobProfile`

## Streaming

`EventStream` is returned by `session.stream(...)` and `client.create_session_streaming(...)`.

- synchronous constructor style (`session.stream(...)` returns stream object)
- request is sent on `async with` entry
- `events.result` is available after iteration
- `BackgroundJobCompleted.terminal_status` carries background job completion semantics; `legacy_status` is only the optional wire `status` display mirror

## Live channels

`RealtimeChannel` and the old realtime convenience helpers are no longer public
SDK handles. The current helper is `LiveChannel.session(client, session_id, ...)`,
which binds a session id and stores the `channel_id` returned by `live/open`.

```python
from meerkat import LiveChannel, MeerkatClient

client = MeerkatClient()
await client.connect(live_ws=True)
session = await client.create_session("Open a live channel")
channel = LiveChannel.session(client, session.id, turning_mode="explicit_commit")
opened = await channel.open()
await channel.send_input_text("hello")
await channel.commit_input(response_modality="text")
await channel.refresh()
await channel.close()
await client.close()
```

Direct `MeerkatClient` helper names mirror the RPC methods:

- `live_open(session_id, turning_mode=None)`
- `live_status(channel_id)`
- `live_close(channel_id)`
- `live_send_input_text(channel_id, text)`
- `live_send_input_audio(channel_id, data_base64, sample_rate_hz, channels)`
- `live_send_input_image(channel_id, mime, data_base64)`
- `live_send_input_video_frame(channel_id, codec, data_base64, timestamp_ms)`
- `live_commit_input(channel_id, response_modality=None)`
- `live_interrupt(channel_id)`
- `live_truncate(channel_id, item_id, content_index, audio_played_ms)`
- `live_refresh(channel_id)`

## Capability and error model

Capabilities:

```python
client.capabilities
client.has_capability("comms")
client.require_capability("comms")
```

Errors:

```python
from meerkat import MeerkatError, CapabilityUnavailableError, SessionNotFoundError, SkillNotFoundError
```

All SDK errors derive from `MeerkatError`.
