# Traces API

> Read your agents' execution traces programmatically.

Source: https://docs.runbear.io/api/traces

Last updated: 2026-10-07

The **Traces API** lets you read your agents' execution traces programmatically — list recent runs and fetch a single run in detail, including the model, latency, input/output, intermediate steps, and user reactions. Use it to debug agent behavior or to feed traces into your own analysis and improvement pipelines.

Authenticate with a bearer API key, created under **Settings → API keys** (where available). If your organization doesn't show that item, open **Settings → Members**, which opens your organization's account page, and manage keys in its **API Keys** section; see [API keys](/api/api-keys.md). Full request/response schemas live in the [OpenAPI reference](https://api.runbear.io/v1/docs); MCP clients can read the same data through the [MCP server](/api/mcp-server.md)'s `list_recent_agent_traces` and `get_agent_trace` tools.

## Endpoints

| Endpoint                                              | Purpose                                     |
| ----------------------------------------------------- | ------------------------------------------- |
| `GET /v1/agents/{agentId}/traces`                     | List recent traces for an agent             |
| `GET /v1/agents/{agentId}/traces/{traceId}`           | Read a single trace in detail               |
| `GET /v1/agents/{agentId}/messages/{messageId}/trace` | Resolve the trace behind a specific message |
| `GET /v1/agents/{agentId}/traces/export`              | Bulk-export whole traces over a long window |

Traces are retained for 90 days. They cover Classic, Anthropic and OpenAI Responses agents, and every channel the agent answers on, not only the API. An agent that uses [HIPAA data handling](/security/hipaa.md) is covered too, read from its separate protected tracing path.

> **Warning**
>
> Claude Agent SDK agents are the exception for now: their traces may be missing from the list, and looking one up can answer `404`.

## Rate limits

| Endpoints                                                  | Limit                                   |
| ---------------------------------------------------------- | --------------------------------------- |
| The list endpoint and the message-trace endpoint, together | 30 requests per minute per organization |
| The export endpoint                                        | 20 requests per minute per organization |
| `GET /v1/agents/{agentId}/traces/{traceId}`                | No limit                                |

The limits are counted on each API server separately, so the budget you observe can be higher than the number above. Every response from a limited endpoint carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the window resets), and a `429` includes `Retry-After`. Pace yourself by the headers rather than by a fixed count. See [Errors and limits](/api/errors-and-limits.md#rate-limits).

## Listing traces

`GET /v1/agents/{agentId}/traces` returns trace summaries, newest first, with `meta` holding `page`, `limit`, `totalItems` and `totalPages`.

| Query parameter | Meaning                                                     |
| --------------- | ----------------------------------------------------------- |
| `page`          | Page number, starting at 1                                  |
| `limit`         | Traces per page, up to 100. Defaults to 50                  |
| `sessionId`     | Only traces from one conversation (the channel's thread id) |
| `fromTimestamp` | ISO 8601 start of the window. Defaults to 90 days ago       |
| `toTimestamp`   | ISO 8601 end of the window. Defaults to now                 |

A page can hold slightly fewer traces than `limit`. For large pulls, use the export endpoint instead.

## Reading one trace

`GET /v1/agents/{agentId}/traces/{traceId}` returns the trace in detail: the model, latency, input and output, each step with its tool calls, and user reactions. When the caller passed [`config.userContext`](/api/chat.md#user-context) for the turn, the trace includes it as `userContext`.

`GET /v1/agents/{agentId}/messages/{messageId}/trace` returns the same detail for a message, given the message `id` from [`GET /v1/threads/{threadId}/messages`](/api/chat.md#reading-a-conversation). It answers `404` when no trace can be found for the message: the trace is older than the 90-day retention, the message belongs to a different agent than the one in the path, or the message wasn't produced by an agent run. A `messageId` that isn't a UUID is refused with `400`.

## Exporting traces

`GET /v1/agents/{agentId}/traces/export` returns whole traces, newest first, for loading into a warehouse or analytics pipeline.

- Set the window with `fromTimestamp` and `toTimestamp` (ISO 8601; `toTimestamp` is exclusive). `fromTimestamp` defaults to, and is clamped at, 90 days ago. `toTimestamp` defaults to now.
- Follow `meta.cursor`: pass it back as `cursor` until it is `null`. Once you pass a cursor, `toTimestamp` is ignored, so keep the window fixed for the whole export.
- A page holds whole traces only, never part of one, so page sizes vary.
- A trace becomes exportable about 2 to 3 minutes after its turn ends. For a reproducible extract, set `toTimestamp` at least 15 minutes in the past.
- Exported traces don't include `reactions`, `threadId` or `sessionStartHook`. Read a single trace for those.

## Session-start hook outcome

For organizations with the **session-start hook** feature enabled, the trace detail response includes a `sessionStartHook` field with the outcome of the hook for the trace's thread. The hook runs at most once per thread, so every trace in the same thread reports the same object; the field is `null` when the agent has no hook or the hook never ran for the thread.

```json
{
  "sessionStartHook": {
    "fetchedAt": "2026-07-22T19:03:58.412Z",
    "status": "ok",
    "contexts": [
      { "name": "Session Context", "context": "tier: enterprise" }
    ]
  }
}
```

| Field       | Meaning                                                                                                                                                       |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `fetchedAt` | ISO 8601 timestamp of when the hook was attempted                                                                                                             |
| `status`    | `ok` — the hook completed successfully. `degraded` — the hook failed (timeout, error, or invalid response) and the session proceeded without injected context |
| `contexts`  | Context entries injected into the system prompt, one per result the hook returned                                                                             |

Note that `ok` does not guarantee context was injected: a hook tool that returns no content is a successful no-op, reported as `ok` with an empty `contexts` array. When `status` is `degraded`, `contexts` is always empty.

> **Feature availability**
>
> The session-start hook is not generally available yet. Organizations without the feature do not see the `sessionStartHook` field in their responses at all.

## Related

- [Credits API](/api/credits.md) — group credit usage by `traceId`
- [Chat](/api/chat.md) — the threads and messages traces belong to
- [Errors and limits](/api/errors-and-limits.md)
