> ## Documentation Index
> Fetch the complete documentation index at: https://opentracy.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# GET /v1/traces

> Search captured requests by model, time, status, or metadata

The management API's trace search endpoint. Returns rows from ClickHouse
matching the filters you pass as query parameters.

```http theme={null}
GET /v1/traces?limit=50&model_id=gpt-4o HTTP/1.1
Host: localhost:8000
```

## Query parameters

| Param        | Type     | Default | Notes                                          |
| ------------ | -------- | ------- | ---------------------------------------------- |
| `limit`      | `int`    | `100`   | Max rows to return. Hard cap: `1000`.          |
| `offset`     | `int`    | `0`     | For pagination.                                |
| `start_date` | ISO 8601 | —       | Inclusive lower bound on `created_at`.         |
| `end_date`   | ISO 8601 | —       | Exclusive upper bound on `created_at`.         |
| `source`     | `string` | —       | Filter by `source` / tenant / integration tag. |
| `model_id`   | `string` | —       | Filter by concrete model (e.g. `gpt-4o-mini`). |
| `status`     | `string` | —       | `success`, `error`, or `timeout`.              |

## Response

```json theme={null}
{
  "traces": [
    {
      "request_id": "t_af91",
      "model": "gpt-4o-mini",
      "provider": "openai",
      "tokens_in": 214,
      "tokens_out": 88,
      "cost_usd": 0.00046,
      "latency_ms": 612.3,
      "status": "success",
      "created_at": "2026-04-19T12:04:07Z"
    }
  ],
  "total": 5423,
  "has_more": true
}
```

`total` is the full match count ignoring `limit`/`offset`, so you can
render pagination UI without a second query.

## Curl

```bash theme={null}
# Last 50 gpt-4o-mini calls
curl -s "http://localhost:8000/v1/traces?limit=50&model_id=gpt-4o-mini" | jq .

# Errors in the last 24h
curl -s "http://localhost:8000/v1/traces?status=error&start_date=2026-04-18T00:00:00Z" | jq .

# Cost by day for the last week — lean on jq
curl -s "http://localhost:8000/v1/traces?limit=1000&start_date=2026-04-12T00:00:00Z" \
  | jq '[.traces[] | {day: .created_at[0:10], cost: .cost_usd}] | group_by(.day) | map({day: .[0].day, total: (map(.cost) | add)})'
```

## Full trace content

The list endpoint returns a summary row. To fetch the full prompt and
response text for one trace, hit:

```bash theme={null}
curl -s "http://localhost:8000/v1/traces/t_af91" | jq .
```

```json theme={null}
{
  "request_id": "t_af91",
  "input_text": "...the full user message...",
  "output_text": "...the full assistant response...",
  "metadata": { "user_id": "u_42", "feature": "ticket_classifier" },
  /* plus all summary fields */
}
```

<Warning>
  If the engine is running with `OPENTRACY_TRACE_CONTENT=false`, the
  `input_text` and `output_text` fields are omitted — the row keeps its
  cost/latency/metadata, but the content was never persisted. See
  [Traces → Privacy](/concepts/traces#privacy-and-pii).
</Warning>

## Errors

| Status | `error.code`      | Meaning                                            |
| ------ | ----------------- | -------------------------------------------------- |
| `400`  | `invalid_request` | Bad date format or `limit` out of range.           |
| `404`  | `trace_not_found` | Specific `request_id` not in ClickHouse.           |
| `503`  | `clickhouse_down` | `OPENTRACY_CH_ENABLED=false` or connection failed. |
