Extending sessions capabilities

Proxy execute

session.proxyExecute() calls any HTTP endpoint on a toolkit your session can already reach, and Composio injects the authentication (OAuth token, API key, basic auth, and so on) on the server side. Your code never handles raw credentials.

The session is already scoped to a userID, so you pass a toolkit slug rather than an account ID. Composio resolves the user's connected account for that toolkit and signs the request with it.

Proxy execute is a building block, not just a fallback. Use it to build experiences on top of Composio that reach past predefined tools, like the Pi + Slack bot example, which drops down to the proxy for the Slack Web API calls the toolkit doesn't wrap as tools. We'll link more examples here as we add them.

Use a scoped API key

Proxy execute is gated behind its own permission. Authenticate with a scoped project API key that has the Proxy execute permission granted. Default full-access keys already include it.

When to use it

  • Endpoints with no predefined tool. You need a specific endpoint (an unusual GitHub, LinkedIn, or Notion route) that isn't exposed as a Composio tool. Send it through the proxy instead of extracting the raw token and calling the API yourself.
  • Request shapes a tool can't express. Custom query parameters, partial field masks, or advanced filters on Gmail, Drive, Sheets, and similar. The proxy gives you the full HTTP surface of the upstream API while Composio keeps managing auth.

Quick start

from composio import Composio

composio = Composio(api_key="your_api_key")
session = composio.create("user_123", toolkits=["github"])

response = session.proxy_execute(
    toolkit="github",
    endpoint="/repos/composiohq/composio/issues/1",
    method="GET",
    parameters=[
        {"name": "Accept", "value": "application/vnd.github.v3+json", "in": "header"},
    ],
)

print(response.status)
print(response.data)
const { status, data } = await session.proxyExecute({
  toolkit: 'github',
  endpoint: '/repos/composiohq/composio/issues/1',
  method: 'GET',
  parameters: [
    { name: 'Accept', value: 'application/vnd.github.v3+json', in: 'header' },
  ],
});

console.log(status);
console.log(data);

The endpoint is a path relative to the toolkit's base URL (/repos/... resolves against api.github.com). Pass an absolute URL only when you need a host that isn't the toolkit's standard API, such as a regional Salesforce or Zendesk domain.

Proxy execute rejects cross-domain requests. The endpoint must resolve to the same domain as the toolkit's connected account (a GitHub connection can only call api.github.com paths). This is an intentional security boundary, not a quota, so you can't work around it by reshaping the request.

Parameters

ParameterRequiredTypeDescription
toolkitYesstringToolkit slug (github, gmail, and so on). Composio uses the session user's connected account for this toolkit.
endpointYesstringPath relative to the toolkit's base URL, or an absolute URL.
methodYes"GET" | "POST" | "PUT" | "PATCH" | "DELETE"HTTP verb.
bodyNoobjectJSON request body. Used with POST, PUT, and PATCH.
parametersNoArray<{ name, value, in }>Extra headers or query parameters. in is "header" or "query".

Response shape

The call returns the upstream response verbatim:

FieldTypeDescription
statusnumberHTTP status code from the upstream API.
dataunknownParsed JSON body the API returned.
headersRecord<string, string>Response headers.
binaryDataobjectPresent only when the upstream returns a file (url, contentType, size, expiresAt).

Don't set the Authorization header yourself through parameters. Composio injects the correct one from the connected account's auth scheme, and setting it manually overrides that credential and usually produces a 401.

Error handling

status and data reflect exactly what the toolkit API returned, so check status and branch on the common failures.

StatusTypical causeHow to resolve
400 Bad RequestMalformed endpoint path, invalid body, or unsupported method.Check the upstream API docs for the expected shape. The proxy doesn't validate upstream schemas.
401 UnauthorizedThe connected account's token expired or was revoked.Re-authenticate the user, or import fresh credentials.
403 ForbiddenThe user's OAuth scopes or API key don't cover this endpoint.Update the auth config scopes and have the user re-consent.
429 Too Many RequestsUpstream rate limit (GitHub, Google, and so on).Honor the Retry-After header and back off. Composio doesn't retry automatically.

Next

Custom tools and toolkits

Define in-process tools and toolkits that run alongside Composio tools