> ## 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.

# SDKs

> Official TypeScript and Python clients for the Flowra API — install, auth, common examples, and namespaces.

Official Flowra SDKs wrap the **public API-key surface** (the same operations as the [API reference](/api-reference)). Use them from your backend instead of hand-writing HTTP for common flows.

Source: [github.com/flowradev/sdk](https://github.com/flowradev/sdk).

| Package | Language | Notes |
| - | - | - |
| [`@flowra/sdk`](https://www.npmjs.com/package/@flowra/sdk) | TypeScript / Node 18+ | OpenAPI-generated client + product facade |
| [`flowra-sdk`](https://pypi.org/project/flowra-sdk/) | Python 3.10+ | Hand-written facade (stdlib HTTP, no extra deps). Import stays `flowra`. |
| [`@flowra/cli`](https://www.npmjs.com/package/@flowra/cli) | Terminal | Discover → connect → execute when MCP is not connected |

## When to use the SDK vs MCP vs CLI vs curl

| Approach | Use when |
| - | - |
| **SDK** | Your app/backend calls Flowra (list tools, run workflows, manage skills, knowledge, MCP servers, …) |
| **MCP** | An IDE or agent runtime (Cursor, Claude Desktop) should discover and call tools. Prefer OAuth (URL only); API key is the fallback — see [MCP](/guides/mcp) |
| **CLI** | A terminal agent can run shell commands and MCP is not connected (`flowra discover` → `connect` → `execute`) |
| **HTTP / curl** | Quick checks, languages without an SDK yet — [Quickstart](/quickstart) and [API reference](/api-reference) |

The SDKs are **not** a Composio-style agent framework. For agent-side tool access, prefer MCP.

## Install

**TypeScript** — [`@flowra/sdk` on npm](https://www.npmjs.com/package/@flowra/sdk)

```bash theme={null}
npm install @flowra/sdk
# or: pnpm add @flowra/sdk
```

From the [SDK repo](https://github.com/flowradev/sdk) (optional): `pnpm --dir typescript install && pnpm --dir typescript build`.

**Python**

PyPI name is [`flowra-sdk`](https://pypi.org/project/flowra-sdk/). Import stays `flowra`. Do **not** `pip install flowra` — that name is an unrelated package.

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

Requires Python 3.10+. Stdlib only (no extra runtime deps). From the SDK repo: `pip install -e "./python"`.

**CLI** — [`@flowra/cli` on npm](https://www.npmjs.com/package/@flowra/cli)

```bash theme={null}
pnpm add -g @flowra/cli
flowra --help
```

## Authenticate

Both clients send your **project API key** as `x-api-key`. Optionally set an external user with `username` / `x-username` for [multi-tenancy](/guides/multi-tenancy).

<CodeGroup>
  ```ts theme={null}
  import { Flowra } from '@flowra/sdk';

  const flowra = new Flowra({
    apiKey: process.env.FLOWRA_API_KEY!,
    // username: 'customer_alice',
  });
  ```

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

  flowra = Flowra(
      api_key=os.environ["FLOWRA_API_KEY"],
      # username="customer_alice",
  )
  ```
</CodeGroup>

Create keys in the dashboard — [Authentication](/authentication) · [Projects and API keys](/product/projects-and-keys).

## Common examples

Copy tool slugs from `tools.list` (or DISCOVER). Do not invent them. Catalog actions are typically `UPPER_SNAKE` (`GMAIL_SEND_EMAIL`, `SLACK_SEND_MESSAGE`).

### List tools and execute one

<CodeGroup>
  ```ts theme={null}
  const tools = await flowra.tools.list({ limit: 10, toolkitSlug: 'slack' });
  const slug = tools.data?.[0]?.slug ?? tools.items?.[0]?.slug ?? 'SLACK_SEND_MESSAGE';
  await flowra.tools.execute(slug, {
    arguments: { channel: '#general', text: 'Hi' },
  });
  ```

  ```python theme={null}
  tools = flowra.tools.list(limit=10, toolkitSlug="slack")
  items = tools.get("data") or tools.get("items") or []
  slug = (items[0] or {}).get("slug", "SLACK_SEND_MESSAGE") if items else "SLACK_SEND_MESSAGE"
  flowra.tools.execute(
      slug,
      {"arguments": {"channel": "#general", "text": "Hi"}},
  )
  ```
</CodeGroup>

### Run a workflow and poll status

<CodeGroup>
  ```ts theme={null}
  const run = await flowra.workflows.run(workflowId, {
    input: { message: 'smoke test' },
    mode: 'production',
  });
  const status = await flowra.workflows.status(run.threadId);
  ```

  ```python theme={null}
  run = flowra.workflows.run(workflow_id, {"input": {"message": "smoke test"}, "mode": "production"})
  status = flowra.workflows.status(run["threadId"])
  ```
</CodeGroup>

### Act as an end user

<CodeGroup>
  ```ts theme={null}
  const alice = flowra.asUser('customer_alice');
  await alice.connections.createLink({
    authConfigId: 'AUTH_CONFIG_ID',
  });
  ```

  ```python theme={null}
  alice = flowra.as_user("customer_alice")
  alice.connections.create_link({"authConfigId": "AUTH_CONFIG_ID"})
  ```
</CodeGroup>

### Create a knowledge collection and ingest a URL

<CodeGroup>
  ```ts theme={null}
  const collection = await flowra.knowledge.create({ name: 'Help center' });
  await flowra.knowledge.ingestUrl(collection.id, {
    url: 'https://docs.yoursite.com/faq',
  });
  ```

  ```python theme={null}
  collection = flowra.knowledge.create({"name": "Help center"})
  flowra.knowledge.ingest_url(collection["id"], {"url": "https://docs.yoursite.com/faq"})
  ```
</CodeGroup>

### Chat stream (Python events)

```python theme={null}
thread = flowra.chat.create_thread({})
for event in flowra.chat.stream(
    thread["thread_id"],
    {"input": {"messages": [{"role": "user", "content": "Hello"}]}},
    as_events=True,
):
    print(event["event"])
```

More: [Chat streaming](/guides/sdk-chat-streaming) · [TypeScript tutorial](/guides/sdk-typescript) · [Python tutorial](/guides/sdk-python).

### One shot from a terminal

When MCP isn't connected: **discover → connect → execute**. Never invent the slug.

```bash theme={null}
flowra login
flowra discover "Gmail list recent inbox emails"
flowra connect gmail
flowra execute GMAIL_SEND_EMAIL -d '{"recipient_email":"you@example.com","subject":"Hi","body":"Test"}'
```

If `connect` returns `redirectUrl`, open it, then run connect again.

## Namespaces

High-level helpers cover the main product areas (camelCase in TypeScript, snake\_case in Python):

`tools`, `toolkits`, `skills`, `workflows`, `connections`, `authConfigs` / `auth_configs`, `users`, `triggers`, `chat`, `files`, `knowledge`, `database`, `sandbox`, `mcp`, `llm`, `browser`, `usage`

Full method map: [SDK namespaces](/guides/sdk-namespaces). **Every method with examples:** [SDK method examples](/guides/sdk-method-examples). Credits: [Usage and credits](/guides/usage-and-credits).

Escape hatches:

* TypeScript: `flowra.raw` (generated OpenAPI operations)
* Python: `flowra.request(method, path, ...)`

## Tutorials

<CardGroup cols={2}>
  <Card title="TypeScript SDK" icon="js" href="/guides/sdk-typescript">
    Full examples: tools, workflows, chat, files, sandbox, usage, raw client.
  </Card>

  <Card title="Python SDK" icon="python" href="/guides/sdk-python">
    Full examples: tools, workflows, chat stream, files, sandbox, errors.
  </Card>
</CardGroup>

<CardGroup cols={2}>
  <Card title="Chat streaming" icon="comments" href="/guides/sdk-chat-streaming">
    SSE runs and usage events.
  </Card>

  <Card title="Usage and credits" icon="coins" href="/guides/usage-and-credits">
    Balance, ledger, workflow usage.
  </Card>
</CardGroup>

<Card title="All method examples" icon="book" href="/guides/sdk-method-examples">
  TypeScript and Python snippets for every facade method.
</Card>

## Related

* [Quickstart](/quickstart) — First request (curl + SDK)
* [Run a workflow](/recipes/run-a-workflow)
* [Connect an account](/recipes/connect-an-account)
* [Multi-tenant basics](/recipes/multi-tenant-basics)
* [API reference](/api-reference)
* [MCP](/guides/mcp)


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