---
title: "Python SDK"
url: "https://docs.caracal.run/sdks/python/"
markdown_url: "https://docs.caracal.run/markdown/sdks/python.md"
description: "Public API reference for caracalai-sdk."
page_type: "page"
concepts: []
requires: []
---

# Python SDK

Canonical URL: https://docs.caracal.run/sdks/python/
Markdown URL: https://docs.caracal.run/markdown/sdks/python.md
Description: Public API reference for caracalai-sdk.
Page type: page
Concepts: none
Requires: none

---

`caracalai-sdk` is the main Python package for async agent lifecycle, delegation, Gateway routing, and ASGI context propagation.

## Install

```bash
pip install caracalai-sdk
```

The package requires Python `>=3.12`.

## Connect and Configure

| API | Use it when |
| --- | --- |
| `Caracal()` | Auto-detect a runtime profile or environment variables. |
| `Caracal.from_env()` | Load only from `CARACAL_*` environment variables. |
| `Caracal.from_config(path)` | Load a Console-generated `caracal.toml`. |
| `Caracal.from_client_secret(...)` | Build a client that refreshes application subject tokens through STS. |

```python
from caracalai import Caracal

caracal = Caracal()
```

## Core methods

| Method | Purpose |
| --- | --- |
| `async with caracal.spawn(...)` | Create and bind an agent session; pass `grant=Grant.narrow(...)` to bound the child's authority. |
| `await caracal.spawn_service(...)` | Start a long-lived service agent; returns a handle with `heartbeat()` and `aclose()`. Pass `grant=Grant.narrow(...)` to bound the handle's authority. |
| `async with caracal.delegate(...)` | Create and bind a delegation edge to an existing agent session. |
| `caracal.headers(allow_root=False, ctx=None)` | Project the bound context (or an explicit `ctx`) into HTTP headers. |
| `async with caracal.bind(ctx)` | Rebind a captured context into a new async task. |
| `async with caracal.bind_from_headers(headers, allow_root=False)` | Bind inbound Caracal envelope headers. |
| `caracal.transport(allow_root=False, ctx=None, scopes=None, **kwargs)` | Return an `httpx.AsyncClient` that injects Caracal headers and Gateway routing. Pass `ctx=` from thread pools or executors; pass `scopes=` to authorize gateway calls with a scoped resource mandate instead of the raw subject token. |
| `caracal.sync_transport(allow_root=False, ctx=None, scopes=None, **kwargs)` | Synchronous `httpx.Client` counterpart. |
| `await caracal.fetch(resource_id, path, ctx=None, scopes=None, ...)` | One-call Gateway request to a resource with context and authority injected. |
| `caracal.context_middleware(verifier=None)` | ASGI middleware factory: propagates context, and enforces at the boundary when a `verifier` is passed. |
| `caracal.gateway_request(resource_id, path="/")` | Build a Gateway URL and `X-Caracal-Resource` header. |
| `caracal.mint_mandate(resource_id, scopes, ctx=None, ttl_seconds=None)` | Mint a cached resource mandate carrying the bound agent session and delegation edge; requires client-secret credentials. |

## Context Propagation

```python
from caracalai import DelegationConstraints

constraints = DelegationConstraints(
    max_hops=1,
    budget=5,
    policy_approved=True,
)
```

`DelegationConstraints` uses Python field names: `resources`, `max_depth`, `max_hops`, `ttl_seconds`, `budget`, `policy_approved`, `expires_at`, and `broad_reason`.

## Protect Inbound Requests

`context_middleware()` is framework-agnostic and runs on any ASGI app (FastAPI, Starlette, Quart, Django ASGI).

Without a verifier it only **propagates**: it binds the inbound Caracal envelope into request context but does not check JWT signatures, audience, scopes, token use, or revocation. Use this when a Gateway already enforced the mandate upstream.

Pass `verifier=` to **enforce at the boundary**. The callable receives the bearer token and must raise on failure; back it with `caracalai_identity.verify_token` so the application sees a request only after the mandate is proven. The SDK never inspects token internals itself.

```python
from caracalai_identity import verify_token
from caracalai import Caracal

caracal = Caracal.from_env()
app = FastAPI()

async def verify(token: str) -> None:
    await verify_token(token, issuer=ISSUER, audience=AUDIENCE)

app.add_middleware(caracal.context_middleware(verifier=verify))
```

See [Enforce, propagate, or attribute](/concepts/authority-model/#enforce-propagate-or-attribute) for which call path verifies authority.

## Related pages

- [Integrate the Python SDK](/guides/sdk-python/)
- [Protect a FastMCP App](/guides/protect-fastmcp/)
- [Verification Layer Overview](/sdks/verification-layer/)
- [MCP Auth Transport](/sdks/transport-mcp/)
