> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.recursiv.io/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.recursiv.io/_mcp/server.

# Connect Python

There is no Python SDK for Recursiv. The `@recursiv/sdk` is TypeScript only. From Python you connect directly to the REST API at `https://api.recursiv.io/api/v1` using any HTTP client. This guide uses `requests` for plain calls and `httpx` for streaming.

The REST API exposes the same resources as the SDK. Project-scoped responses use a `{ "data": ... }` envelope, and some return `{ "data": ..., "meta": ... }`.

## Install

```bash
pip install requests httpx
```

## Configure the key

No account yet? [Sign up](https://recursiv.io/register) and mint a key at [recursiv.io/account/api-keys](https://recursiv.io/account/api-keys).

```bash
export RECURSIV_API_KEY=sk_live_...
```

Send the key as a bearer token on every request:

```python
import os
import requests

API_BASE = "https://api.recursiv.io/api/v1"
API_KEY = os.environ["RECURSIV_API_KEY"]

HEADERS = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json",
}
```

## First authenticated call

Most resources hang off a project. Create one, then run a query. Project IDs are UUIDs, so always use the `id` the API returns.

```python
# Create a project
resp = requests.post(
    f"{API_BASE}/projects",
    headers=HEADERS,
    json={"name": "my-app"},
)
resp.raise_for_status()
project = resp.json()["data"]
project_id = project["id"]

# Ensure a database
requests.post(
    f"{API_BASE}/databases/ensure",
    headers=HEADERS,
    json={"project_id": project_id, "name": "main"},
).raise_for_status()

# Run a query
resp = requests.post(
    f"{API_BASE}/databases/query",
    headers=HEADERS,
    json={"project_id": project_id, "sql": "SELECT NOW() as time"},
)
resp.raise_for_status()
print(resp.json()["data"]["rows"])
```

## Run an agent

Create an agent against any model, then chat with it. The `model` field is model agnostic. Pass any supported model id.

```python
# Create an agent
resp = requests.post(
    f"{API_BASE}/agents",
    headers=HEADERS,
    json={
        "project_id": project_id,
        "name": "Support Bot",
        "model": "anthropic/claude-sonnet-4.6",
        "instructions": "You are a helpful assistant.",
    },
)
resp.raise_for_status()
agent_id = resp.json()["data"]["id"]

# Non-streaming chat
resp = requests.post(
    f"{API_BASE}/agents/{agent_id}/chat",
    headers=HEADERS,
    json={"message": "Help me build a landing page"},
)
resp.raise_for_status()
print(resp.json()["data"])
```

## Stream an agent

The streaming endpoint returns Server-Sent Events. Use `httpx` to read the stream line by line. Each `data:` line is a JSON chunk with a `type`. Text arrives as `text_delta` chunks; the stream ends with `[DONE]`.

```python
import json
import httpx

with httpx.stream(
    "POST",
    f"{API_BASE}/agents/{agent_id}/chat/stream",
    headers=HEADERS,
    json={"message": "Help me build a landing page"},
    timeout=None,
) as resp:
    resp.raise_for_status()
    for line in resp.iter_lines():
        if not line or not line.startswith("data:"):
            continue
        payload = line[len("data:"):].strip()
        if payload == "[DONE]":
            break
        chunk = json.loads(payload)
        if chunk.get("type") == "text_delta" and chunk.get("delta"):
            print(chunk["delta"], end="", flush=True)
```

## Run code in a sandbox

The sandbox runs code without an account. It returns a `{ "data", "meta" }` envelope. This call needs no `Authorization` header.

```python
resp = requests.post(
    f"{API_BASE}/sandbox/try",
    headers={"Content-Type": "application/json"},
    json={"code": "console.log(1 + 1)", "language": "typescript"},
)
resp.raise_for_status()
body = resp.json()
print(body["data"]["output"])  # "2\n"
print(body["meta"]["remaining_executions"], "executions remaining today")
```

## Where to go next

* [Quickstart](/guides/start-here/quickstart) for the canonical first calls
* [API Reference](/api-reference) for every REST endpoint, request shape, and response envelope
* Recursiv ships hundreds of data integrations (Slack, email, databases, and more) that agents can call as tools