API Reference

Logs

The Logs API returns individual tool execution events, one record per tool call. Use it to debug failures, inspect request/response payloads, and trace specific user activity. For aggregated counts (how many tool calls happened), use the Usage API instead.

All endpoints in this section require a project API key (x-api-key) or a valid session cookie.

List logs

from composio import Composio

composio = Composio()

page = composio.logs.search(
    limit=20,
    time_range={"from": 1744848000000, "to": 1744934400000},
    filters=[
        {"field": "toolkit_slug", "operator": "==", "value": "gmail"},
        {"field": "status", "operator": "==", "value": "failed"},
    ],
)
print(page.logs, page.next_cursor)

The response contains a page of log entries and a next_cursor:

{
  "logs": [
    {
      "id": "log_-jRTWClpBoVo",
      "timestamp": "2026-04-17T10:25:00.000Z",
      "type": "tool.execution",
      "status": "failed",
      "level": "error",
      "message": "GMAIL_SEND_EMAIL failed: invalid recipient",
      "metadata": { /* tool, toolkit, user_id, connected_account_id, ... */ },
      "metrics": { "duration_ms": 202 },
      "parent": null
    }
  ],
  "next_cursor": "eyJwYWdlIjoyfQ=="
}

Pass next_cursor back as cursor on the next request to paginate. When next_cursor is null, you've reached the end.

Filter fields

Pass one or more filters in the filters array. Filters are AND-combined.

FieldWhat it matches
tool_slugThe specific tool that was called (e.g. GMAIL_SEND_EMAIL)
toolkit_slugThe toolkit (e.g. gmail, slack, github)
connected_account_idThe connected account used for the call
auth_config_idThe auth config (integration) behind the connected account
statussuccess or failed
user_idEntity that initiated the call
session_idTool router session, if routed through a session
sandbox_idSandbox the call ran in, if applicable
request_idRequest ID (useful for correlating with your own logs)
log_idExact log ID (equivalent to the detail endpoint)

Operators

OperatorMeaning
==Exact match
!=Not equal
containsSubstring match
not_containsSubstring does not match

Parameters

FieldTypeDefaultNotes
limitnumber20Max 100
cursorstring | nullnullOpaque pagination token from previous response
filtersarray[]AND-combined
time_range.fromnumber—Epoch milliseconds
time_range.tonumber—Epoch milliseconds

Get a single log

Fetch one log by ID to get the full payload, including request/response bodies, timing breakdowns, and source metadata:

from composio import Composio

composio = Composio()

log = composio.logs.get("log_-jRTWClpBoVo")
print(log.status, log.data)

The detail response includes everything from the list shape plus:

  • timings: start_time and end_time in epoch ms
  • context: session_id, trace_id, request_id
  • source: host (e.g. mcp, sdk, api), framework, language
  • data: the full request payload and response body

This is the endpoint to call when you need to reconstruct exactly what happened, for example when debugging a 500 from a user report.

Recipes

Find failed Gmail tool calls in the last hour

import time

from composio import Composio

composio = Composio()

now = int(time.time() * 1000)
page = composio.logs.search(
    time_range={"from": now - 3_600_000, "to": now},
    filters=[
        {"field": "toolkit_slug", "operator": "==", "value": "gmail"},
        {"field": "status", "operator": "==", "value": "failed"},
    ],
)

Get failures for a specific user

from composio import Composio

composio = Composio()

page = composio.logs.search(
    filters=[
        {"field": "user_id", "operator": "==", "value": "user_abc123"},
        {"field": "status", "operator": "==", "value": "failed"},
    ],
)

Fetch a single log's full request/response

from composio import Composio

composio = Composio()

log = composio.logs.get("log_-jRTWClpBoVo")
print(log.status, log.data)

Endpoints

EndpointQuick Link
POST /api/v3.1/logs/tool_executionSearch and retrieve tool execution logs
GET /api/v3.1/logs/tool_execution/{id}Get log details by ID