Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

composio-client for Python

composio-client replaces the Stainless-generated package without requiring you to rewrite existing 1.43.x calls.

from composio_client import Composio, ProjectAuth

client = Composio(auth=ProjectAuth("ak_..."))

session = client.tool_router.session.create(user_id="user@example.com")
result = client.tool_router.session.execute(
    session.session_id,
    tool_slug="GITHUB_CREATE_ISSUE",
    arguments={"owner": "composiohq", "repo": "composio", "title": "Example"},
)

The owned client preserves the public Python contract from composio-client==1.43.0 and adds the rest of the v3.1 API. You get all 113 operations, including the 64 operations published by Stainless and 49 additive operations generated from the checked-in OpenAPI document.

The September 2026 schema adds client.session_configs.list() and client.session_configs.retrieve(id), premium usage settings, workbench tool-execution controls, and trigger egress overrides. Generated public request and response types include new fields while retaining existing Stainless declarations.

Install the client

pip install composio-client

With uv:

uv add composio-client

Authenticate and scope the client

auth is required and says which Composio credential the client sends:

auth Sends
NoAuth() No Composio credential. x-api-key and its siblings are then ordinary headers you may set
ProjectAuth(key) x-api-key on every request
UserAuth(key) x-user-api-key on every request
OrganizationAuth(key) x-org-api-key on every request
AutoAuth(project=, user=, organization=) One of the configured keys per operation, chosen from the operation's declared security schemes, falling back to the project key

A fixed mode never consults the operation table. A request carries at most one credential, and only to the configured API origin.

A credential is a key or a function returning one. The function is called once per logical call and its key is reused across that call's retries and same-origin redirects. AsyncComposio also accepts an async function:

client = Composio(auth=UserAuth(lambda: vault.read("composio-user-key")))

scope routes every request to an organization, a project, or both, sent as x-org-id and x-project-id:

from composio_client import Composio, Scope, UserAuth

client = Composio(auth=UserAuth("uak_..."), scope=Scope(organization_id="org_...", project_id="pr_..."))

A header a configured owner writes cannot also come through generic headers: with auth other than NoAuth(), x-api-key, x-user-api-key and x-org-api-key are refused in default_headers, COMPOSIO_CUSTOM_HEADERS, a raw call's headers= and request_options headers; with scope set, so are x-org-id and x-project-id. Use with_options(auth=...) or with_options(scope=...) to derive a client that sends something else. with_options re-runs every constructor check; scope=None there clears the scope.

The few operations that declare x-user-api-key or x-org-id as a parameter (for example client._internal.org.consumer.project.resolve(x_user_api_key=..., x_org_id=...)) keep their keywords. The key you pass replaces the configured auth for that call, and an x_org_id that disagrees with the configured scope fails before anything is sent.

client.auth_mode and client.scope say how a client is configured. No attribute reads a credential back; keep your own copy of a key you need.

Configure from the environment

The constructor reads nothing from the process. from_env reads the mapping you hand it:

import os

client = Composio.from_env(os.environ, environment="staging")
Variable Becomes
COMPOSIO_API_KEY, COMPOSIO_USER_API_KEY, COMPOSIO_ORG_API_KEY auth: one set is that fixed mode, several are AutoAuth, none is NoAuth()
COMPOSIO_BASE_URL base_url
COMPOSIO_CUSTOM_HEADERS default_headers, held to the reserved-header rule
COMPOSIO_ORG_ID, COMPOSIO_PROJECT_ID Not read: scope is always an explicit argument

A keyword argument replaces the whole field it names: auth=NoAuth() means no credential whatever the mapping holds, and default_headers= replaces COMPOSIO_CUSTOM_HEADERS rather than merging into it.

Identify the calling product

A product built on the client passes a ClientIdentity instead of setting headers by hand:

from composio_client import ClientIdentity, Composio, ProjectAuth

client = Composio(
    auth=ProjectAuth("ak_..."),
    identity=ClientIdentity(product="composio", version="0.9.0", source="PYTHON_SDK", framework="openai"),
)

product and version are sent as x-client-provenance and x-client-version (version also as x-sdk-version); source, framework and runtime as x-source, x-framework and x-runtime. The library headers (x-client-library, x-client-library-version, x-client-language) are the package's own and are refused in default_headers, COMPOSIO_CUSTOM_HEADERS and request_options headers; once identity is set, so is every identity header. A refused name raises ComposioError. ClientIdentity is frozen and validates that every value is non-empty printable ASCII.

Use the async client

import asyncio

from composio_client import AsyncComposio, ProjectAuth


async def main() -> None:
    async with AsyncComposio(auth=ProjectAuth("ak_...")) as client:
        session = await client.tool_router.session.create(user_id="user@example.com")
        print(session.session_id)


asyncio.run(main())

Read raw response metadata

Every released resource keeps the Stainless raw and streaming accessors:

from composio_client import Composio, ProjectAuth

client = Composio(auth=ProjectAuth("ak_..."))

response = client.tool_router.session.with_raw_response.retrieve("sess_123")
print(response.status_code)
session = response.parse()

with client.tool_router.session.with_streaming_response.retrieve("sess_123") as response:
    print(response.headers)

The async resource exposes the corresponding async response objects and context managers.

Handle API errors

The exception hierarchy matches the Stainless package. Existing except blocks keep working:

from composio_client import Composio, NotFoundError, ProjectAuth

client = Composio(auth=ProjectAuth("ak_..."))

try:
    client.tool_router.session.retrieve("missing")
except NotFoundError as error:
    print(error.status_code)

Migrate pre-release owned-client calls

Earlier owned-client builds accepted aggregate body, query, and headers values. Those calls remain valid during the transition:

client.tool_router.session.create({"user_id": "user@example.com"})
client.tool_router.session.config_history("sess_123", query={"limit": 25})

Prefer the flat Stainless form in new code:

client.tool_router.session.create(user_id="user@example.com")
client.tool_router.session.config_history("sess_123", limit=25)

See the Python migration guide for compatibility details and the stricter credential transport rules.

Moved in 2.0.0-rc.22

The operations the spec tags x-internal (CLI login sessions, realtime credentials, the execution and trigger logs, the consumer-project routes) are published for Composio's own CLI and SDKs and carry no compatibility promise. They moved under client._internal; their signatures, their type modules (composio_client.types.cli_create_session_params, ...) and the wire are unchanged. The Stainless compatibility check verifies the moved 1.43 methods at their new path (RESOURCE_RELOCATIONS in scripts/check_stainless_compatibility.py).

Moved Now
client.cli.create_session, get_session client._internal.cli.create_session, get_session
client.cli.realtime.* client._internal.cli.realtime.*
client.logs.tools.*, client.logs.triggers.* client._internal.logs.tools.*, client._internal.logs.triggers.*
client.org.consumer.* client._internal.org.consumer.*

Changed in 2.0.0rc22

Change Migration
Session execute, execute_meta and proxy_execute can return blocked results Handle result.result_type == "blocked" before accessing data, error, status or headers. The new variants are SessionExecuteBlockedResponse, SessionExecuteMetaBlockedResponse and SessionProxyExecuteBlockedResponse. Read reason.type, reason.hook_id and message; log_id is optional on blocked tool executions. A request_blocked tool did not run; a response_blocked tool ran but its response was withheld
Execution outcomes may carry hook_results Treat it as optional. An evaluated entry has outcome (continue or block); an unavailable entry does not
Trigger types require types, and consumer project resolve requires user_id Include those fields when constructing response models or fixtures. types is a non-empty list of webhook and/or poll; the old type is deprecated. user_id identifies the authenticated user, separately from consumer_user_id
Saved session configurations include approval lists Accept toolkit/tool entries containing only require_approval, as well as approval lists beside enable/disable filters and tags
Project creation drops config.require_mcp_api_key Stop passing this key. The upstream schema declares no replacement; enable_instant is unrelated to MCP authentication

Removed in 2.0.0-rc.20

Root exports that existed only to mirror the Stainless build. The Stainless compatibility check declares each by name (ROOT_EXPORT_REMOVALS and CLIENT_METHOD_REMOVALS in scripts/check_stainless_compatibility.py).

Removed Migration
client.copy(...) client.with_options(...), same keywords. A subclass that overrode copy overrides with_options
Client, AsyncClient Composio, AsyncComposio
Stream, AsyncStream None: no operation streams. A raw call with stream=True takes your own stream_cls
DefaultAioHttpClient and the aiohttp extra Pass any httpx.AsyncClient as http_client=
Transport, ProxiesTypes, DEFAULT_CONNECTION_LIMITS httpx.BaseTransport, httpx's own proxy types, httpx.Limits(max_connections=100, max_keepalive_connections=20)

Removed in 2.0.0-rc.19

The TypeScript twins are in the root README. On this side the Stainless compatibility check carves out default_query and set_default_query by name (scripts/check_stainless_compatibility.py).

Removed Migration
Composio(default_query=...), copy/with_options(default_query=..., set_default_query=...) None: generated methods own their query, and the raw methods (get, post, ...) take query=
client.default_query None
client.api_key, user_api_key, org_api_key (read-only since rc.18) Keep your own copy of the key; client.auth_mode says which mode is configured
Assigning client.base_url, max_retries or timeout client.with_options(...), which re-runs every validation. The three stay readable

environment= stays, as sugar over base_url.

Removed in 2.0.0-rc.18

Each row is a deliberate removal of this release. The TypeScript twins are declared in packages/codegen/assignability-ledger.json; on this side the Stainless compatibility check carves out the api_key keyword by name (scripts/check_stainless_compatibility.py).

Removed Migration
Composio(api_key=k) Composio(auth=ProjectAuth(k))
Composio(user_api_key=k), Composio(org_api_key=k) auth=UserAuth(k), auth=OrganizationAuth(k)
Several of api_key, user_api_key, org_api_key together auth=AutoAuth(project=..., user=..., organization=...), today's per-operation selection
No credential at all (api_key=None) auth=NoAuth()
x-user-api-key, x-org-api-key (and an x-api-key override) in default_headers while a key is configured auth; generic credential headers are allowed only under NoAuth()
x-org-id, x-project-id in default_headers scope=Scope(organization_id=..., project_id=...) (allowed as plain headers only while scope is unset)
The constructor reading COMPOSIO_API_KEY, COMPOSIO_USER_API_KEY, COMPOSIO_ORG_API_KEY, COMPOSIO_BASE_URL and COMPOSIO_CUSTOM_HEADERS from os.environ Composio.from_env(os.environ)
from_env(..., api_key=None) from_env(..., auth=NoAuth()); and default_headers= there now replaces COMPOSIO_CUSTOM_HEADERS instead of merging
copy(api_key=k) / with_options(api_key=k) with_options(auth=ProjectAuth(k))
Assigning client.api_key (or user_api_key, org_api_key) client.with_options(auth=...); the three read back until 2.0.0-rc.19

Develop the Python package

Generate from the repository root:

pnpm generate:python
pnpm codegen:check

Run Python checks from python/:

uv run ruff check
uv run ruff format --check
uv run mypy src scripts
uv run pytest
uv run python scripts/check_stainless_compatibility.py
uv build
uv run python scripts/check_stainless_compatibility.py --wheel dist/*.whl

The normal compatibility check is offline. It reads the committed 1.43.0 fixture and does not install or call the Stainless client.

Metadata

Release files for composio-client 2.0.0rc22

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for composio-client 2.0.0rc22
File Size Uploaded Provenance Actions
composio_client-2.0.0rc22.tar.gz 579.6 kB With provenance Details for composio_client-2.0.0rc22.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for composio-client 2.0.0rc22
File Interpreter ABI Platform Actions
composio_client-2.0.0rc22-py3-none-any.whl Python 3 none any Details for composio_client-2.0.0rc22-py3-none-any.whl

Total release size: 1.0 MB

Release files / composio_client-2.0.0rc22.tar.gz

Download URL composio_client-2.0.0rc22.tar.gz
Size 579.6 kB
Tags Source
SHA-256 checksum
How to use checksums
0d8e0adaa202c5bcc6366dc0ab362b61fb1c664530cd2b262e3e8fbb9d5616cd
BLAKE2b-256 checksum
How to use checksums
46d549c1a94b0d3d1afe5460b433f0ab752e1cba06b7ca61ca8cfae6ebc0e704
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.

Transparency log

Release files / composio_client-2.0.0rc22-py3-none-any.whl

Download URL composio_client-2.0.0rc22-py3-none-any.whl
Size 466.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4400522de2311e3b69fa6dca68e55d905b22dfd0c841d873d9ca787e5d78419e
BLAKE2b-256 checksum
How to use checksums
68d1cc5945b9bfebb141577cae13e6eecbb4fbff170e5049907c0fae0d06bf16
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.

Transparency log

Security for composio-client 2.0.0rc22

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for composio_client-2.0.0rc22.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page