Connect Python

Connect from Python over the REST API, make your first authenticated call, and stream an agent

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

$pip install requests httpx

Configure the key

No account yet? Sign up and mint a key at recursiv.io/account/api-keys.

$export RECURSIV_API_KEY=sk_live_...

Send the key as a bearer token on every request:

1import os
2import requests
3
4API_BASE = "https://api.recursiv.io/api/v1"
5API_KEY = os.environ["RECURSIV_API_KEY"]
6
7HEADERS = {
8 "Authorization": f"Bearer {API_KEY}",
9 "Content-Type": "application/json",
10}

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.

1# Create a project
2resp = requests.post(
3 f"{API_BASE}/projects",
4 headers=HEADERS,
5 json={"name": "my-app"},
6)
7resp.raise_for_status()
8project = resp.json()["data"]
9project_id = project["id"]
10
11# Ensure a database
12requests.post(
13 f"{API_BASE}/databases/ensure",
14 headers=HEADERS,
15 json={"project_id": project_id, "name": "main"},
16).raise_for_status()
17
18# Run a query
19resp = requests.post(
20 f"{API_BASE}/databases/query",
21 headers=HEADERS,
22 json={"project_id": project_id, "sql": "SELECT NOW() as time"},
23)
24resp.raise_for_status()
25print(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.

1# Create an agent
2resp = requests.post(
3 f"{API_BASE}/agents",
4 headers=HEADERS,
5 json={
6 "project_id": project_id,
7 "name": "Support Bot",
8 "model": "anthropic/claude-sonnet-4.6",
9 "instructions": "You are a helpful assistant.",
10 },
11)
12resp.raise_for_status()
13agent_id = resp.json()["data"]["id"]
14
15# Non-streaming chat
16resp = requests.post(
17 f"{API_BASE}/agents/{agent_id}/chat",
18 headers=HEADERS,
19 json={"message": "Help me build a landing page"},
20)
21resp.raise_for_status()
22print(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].

1import json
2import httpx
3
4with httpx.stream(
5 "POST",
6 f"{API_BASE}/agents/{agent_id}/chat/stream",
7 headers=HEADERS,
8 json={"message": "Help me build a landing page"},
9 timeout=None,
10) as resp:
11 resp.raise_for_status()
12 for line in resp.iter_lines():
13 if not line or not line.startswith("data:"):
14 continue
15 payload = line[len("data:"):].strip()
16 if payload == "[DONE]":
17 break
18 chunk = json.loads(payload)
19 if chunk.get("type") == "text_delta" and chunk.get("delta"):
20 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.

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

Where to go next

  • Quickstart for the canonical first calls
  • 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