> ## Documentation Index
> Fetch the complete documentation index at: https://docs.flowra.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Python SDK

> Install flowra-sdk with examples for tools, workflows, connections, chat, files, sandbox, and usage.

This guide walks through the `flowra` Python package ([`flowra-sdk` on PyPI](https://pypi.org/project/flowra-sdk/)). Overview: [SDKs](/guides/sdk). Full method map: [SDK namespaces](/guides/sdk-namespaces). Every method: [SDK method examples](/guides/sdk-method-examples). Source: [github.com/flowradev/sdk](https://github.com/flowradev/sdk).

## Install

PyPI name is [`flowra-sdk`](https://pypi.org/project/flowra-sdk/). Import stays `flowra`. Do **not** `pip install flowra` — that name belongs to a different project.

```bash theme={null}
pip install flowra-sdk
```

From the [SDK repo](https://github.com/flowradev/sdk) (optional): `pip install -e "./python"`.

Requires Python 3.10+. Stdlib only (no extra runtime deps).

## Create a client

```python theme={null}
import os
from flowra import Flowra

flowra = Flowra(
    api_key=os.environ["FLOWRA_API_KEY"],
    # base_url="https://flowra.dev",
    # username="customer_alice",
    # timeout=60.0,
)
```

| Option | Meaning |
| - | - |
| `api_key` | Project API key (`x-api-key`) — required |
| `base_url` | API origin (default `https://flowra.dev`) |
| `username` | Optional external user (`x-username`) |
| `timeout` | Request timeout in seconds (default `60`) |

Scope to another end user:

```python theme={null}
alice = flowra.as_user("customer_alice")
alice.connections.list()
alice.knowledge.list()
```

See [Multi-tenancy](/guides/multi-tenancy).

## Profile and tools

Copy tool slugs from `tools.list`. Do not invent them. Catalog actions are typically `UPPER_SNAKE`.

```python theme={null}
profile = flowra.get_profile()

tools = flowra.tools.list(limit=10, toolkitSlug="slack", q="send message")
items = tools.get("data") or tools.get("items") or []
tool_id = (items[0] or {}).get("id", "TOOL_ID") if items else "TOOL_ID"
tool = flowra.tools.get(tool_id)

slug = (items[0] or {}).get("slug", "SLACK_SEND_MESSAGE") if items else "SLACK_SEND_MESSAGE"
result = flowra.tools.execute(
    slug,
    {
        "arguments": {
            "channel": "#general",
            "text": "Hello from the flowra SDK",
        },
        # "connectedAccountId": "...",
    },
)

logs = flowra.tools.execution_logs(limit=20)
```

List toolkits (with nested tools):

```python theme={null}
kits = flowra.toolkits.list_with_tools(q="slack", limit=5)
channels = flowra.toolkits.messaging_channels()
categories = flowra.toolkits.list_categories()
```

## Run a workflow

```python theme={null}
import time

listed = flowra.workflows.list(limit=10, q="support")
items = listed.get("items") or listed.get("data") or []
workflow_id = (items[0] or {}).get("id", "WORKFLOW_ID") if items else "WORKFLOW_ID"

run = flowra.workflows.run(
    workflow_id,
    {"input": {"message": "Summarize open tickets"}},
)
thread_id = run["threadId"]

status = flowra.workflows.status(thread_id)
while status.get("status") == "running":
    time.sleep(1.5)
    status = flowra.workflows.status(thread_id)

if status.get("status") == "paused":
    flowra.workflows.resume(thread_id, {"resumeValue": {"approved": True}})

detail = flowra.workflows.execution(run["executionId"])
stats = flowra.workflows.statistics(workflow_id)
```

Recipe: [Run a workflow](/recipes/run-a-workflow). HITL: [Human in the loop](/guides/human-in-the-loop).

## Connect an account

```python theme={null}
configs = flowra.auth_configs.list(toolkitSlug="slack")
cfg_items = configs.get("items") or configs.get("data") or []
auth_config_id = (cfg_items[0] or {}).get("id", "AUTH_CONFIG_ID") if cfg_items else "AUTH_CONFIG_ID"

link = flowra.connections.create_link(
    {
        "toolkitSlug": "slack",
        "authConfigId": auth_config_id,
    }
)
# Open the returned URL in a browser for OAuth

accounts = flowra.connections.list()
grouped = flowra.connections.list_grouped()
```

Per end user:

```python theme={null}
alice = flowra.as_user("customer_alice")
alice.connections.create_link(
    {"toolkitSlug": "slack", "authConfigId": auth_config_id}
)
```

Recipe: [Connect an account](/recipes/connect-an-account).

## External users and triggers

```python theme={null}
flowra.users.create({"username": "customer_alice"})
user = flowra.users.get_by_username("customer_alice")

flowra.triggers.list()
flowra.triggers.upsert("SOME_TRIGGER_SLUG", {})
logs = flowra.triggers.invocation_logs(limit=10)
```

## Chat thread and stream

```python theme={null}
thread = flowra.chat.create_thread({"metadata": {"ticketId": "T-100"}})
thread_id = thread["thread_id"]

body = {
    "input": {
        "messages": [{"role": "user", "content": "What can you help with?"}]
    }
}

for event in flowra.chat.stream(thread_id, body, as_events=True):
    print(event["event"], event.get("data"))

history = flowra.chat.history(thread_id, {})
state = flowra.chat.state(thread_id)
runs = flowra.chat.list_runs(thread_id)
```

SSE helpers: [Chat streaming](/guides/sdk-chat-streaming).

## Skills and MCP

```python theme={null}
skills = flowra.skills.list()
flowra.skills.registry_search(q="pdf")
flowra.skills.add_to_library(skill_id)

servers = flowra.mcp.list()
server = flowra.mcp.create({...})
install_config = flowra.mcp.config(server["id"])
```

## Knowledge and database (per user)

```python theme={null}
alice = flowra.as_user("customer_alice")

collection = alice.knowledge.create({"name": "Help center"})
alice.knowledge.ingest_url(collection["id"], {"url": "https://docs.yoursite.com/faq"})
collections = alice.knowledge.list()
collection_id = (collections[0] or {}).get("id", collection["id"]) if collections else collection["id"]
alice.knowledge.search(collection_id, {"query": "refund policy"})
alice.knowledge.chunks(collection_id, limit=20)

tables = alice.database.list()
table_id = (tables[0] or {}).get("id", "TABLE_ID") if tables else "TABLE_ID"
alice.database.documents(table_id, limit=50)
alice.database.create_document(table_id, {...})
```

## Files

```python theme={null}
files = flowra.files.list(limit=20)
flowra.files.upload("document", "/path/to/file.pdf")
raw = flowra.files.download(file_id)  # bytes
storage = flowra.files.storage_breakdown()
```

## Sandbox, browser, LLM

```python theme={null}
preview = flowra.sandbox.run_ephemeral(
    {
        "language": "javascript",
        "source": "return { ok: true, n: 1 + 1 };",
        "timeoutMs": 8000,
    }
)

session = flowra.sandbox.create_session({})
flowra.sandbox.execute(
    session["id"],
    {"language": "python", "source": "print(2 + 2)"},
)
flowra.sandbox.release_session(session["id"])

flowra.browser.status(session_id)
flowra.browser.touch(session_id)
flowra.browser.view(session_id)
flowra.browser.close(session_id)

models = flowra.llm.models()
chat = flowra.llm.chat(
    {"messages": [{"role": "user", "content": "Say hello in one sentence."}]}
)
text = flowra.llm.generate({...})
```

## Usage and credits

```python theme={null}
balance = flowra.usage.balance()
ledger = flowra.usage.list(
    threadId=thread_id,
    **{"from": "2026-08-01T00:00:00.000Z"},
)
run_usage = flowra.usage.for_execution(execution_id)
```

Details: [Usage and credits](/guides/usage-and-credits).

## Escape hatch: `request`

Call any public API path:

```python theme={null}
flowra.request("GET", "/api/v1/toolkits", query={"limit": 5})
flowra.request(
    "POST",
    "/api/v1/tools/execute/SLACK_SEND_MESSAGE",
    json={"arguments": {}},
)
```

Schemas: [API reference](/api-reference).

## Errors

HTTP failures raise `FlowraAPIError` with `status_code` and `body`:

```python theme={null}
from flowra import FlowraAPIError

try:
    flowra.get_profile()
except FlowraAPIError as err:
    print(err.status_code, err.body)
```

## Next

* [SDK method examples](/guides/sdk-method-examples) — Every facade method
* [TypeScript SDK](/guides/sdk-typescript) — Parallel examples
* [Chat streaming](/guides/sdk-chat-streaming)
* [SDK namespaces](/guides/sdk-namespaces)
* [Run a workflow](/recipes/run-a-workflow)
* [Connect an account](/recipes/connect-an-account)
* [API reference](/api-reference)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.