Activity

Read back everything done with your account, from operations and tool calls to API requests, across every user.

Everything your keys, sessions and agents do is recorded and readable from the SDK, with the same filters the developer console uses. Four logs cover it:

LogWhat's in it
noclick.Operationlong-running work: agent turns, connect links, approvals, calls
noclick.ToolCallevery operation run, capability call and agent tool call
noclick.ApiRequestthe writes and failed requests made with your keys and sessions
noclick.HumanRequestevery question, approval and notice sent to a person

Filter

from datetime import datetime, timedelta, timezone
import noclick

yesterday = datetime.now(timezone.utc) - timedelta(days=1)

noclick.Operation.list(status="failed", created_after=yesterday)
noclick.Operation.list(kind="agent.message", status="live", agent=support)
noclick.ToolCall.list(tool="gmail.*", status="error", source="agent")
noclick.ApiRequest.list(method="POST", status="4xx", key="nk_live_ab12")
noclick.HumanRequest.list(status="pending", kind="approve")
  • status="live" on operations means any status that isn't final.
  • tool takes a name or a * pattern. A tool call is named as policy names it, so a pattern finds what it would hold: an agent's search and fetch capabilities are search and fetch, whatever its model's tool is called (exa__search, say, in its stream), and exa.search is a direct run of Exa's operation.
  • source separates your own calls ("api") from your agents' ("agent") and the calls MCP clients make through your hosted MCP servers ("mcp_server", each with its mcp_server_id).
  • key takes a key id or its prefix.
  • Times are timezone-aware datetimes.

noclick.ApiRequest shows what changed and what failed. Reads that succeed or find nothing (a 404) aren't logged, and a burst of rate-limited requests is logged at most once a second. Requests are kept for 30 days.

Count instead of listing

noclick.Operation.summary(kind="agent.message", created_after=yesterday)   # total and by_status
noclick.ToolCall.summary(since=yesterday)                                  # total, success, error

Across users

A read acts for the user you're acting for, like everything else. To read across users without acting as one, use user_filter:

noclick.Operation.list(status="failed", user_filter=noclick.ALL_USERS)   # every user, plus your account
noclick.Agent.list(user_filter=noclick.NO_USER)                          # your account's own only
noclick.Sandbox.list(user_filter="user_42")                              # one user, by id

Every list of things users own takes user_filter. It's only a filter: the call still acts as your account.

Pages

list() fetches everything that matches, page by page, or stops at limit. list_page() returns one page and a cursor, for your own pagination:

page = noclick.ToolCall.list_page(status="error", limit=100)
while True:
    for call in page.data:
        print(call.tool_name, call.error)
    if page.next_cursor is None:
        break
    page = noclick.ToolCall.list_page(status="error", limit=100, cursor=page.next_cursor)

A page holds at most 100 rows (200 for tool calls, API requests and messages). A larger limit on list_page is refused, not trimmed.

In the console

The developer console reads the same logs. Operations, agents and users have a console_url that opens them there.