# uip traces feedback

> Syntax and options for `uip traces feedback`, which creates and manages LLM Observability feedback attached to a trace or span.

`uip traces feedback` manages LLM Observability feedback — a positive/negative rating, comment, and category tags attached to a trace or span. Use it to record human review of an agent's output, or to pull recorded feedback back out for reporting.

This page is part of the [`uip traces`](./uip-traces.md) tool — see that page for `spans get`.

## Synopsis

```text
uip traces feedback create --trace-id <id> (--positive | --negative) --folder-key <guid> [--span-id <id>] [--comment <text> | --comment-file <path>] [--category <tag>...] [--agent-id <guid>] [--agent-version <str>]
uip traces feedback get <id> [--folder-key <guid>]
uip traces feedback list [--agent-id <guid>] [--agent-version <str>] [--trace-id <id>] [--span-id <id>] [--status <value>...] [--positive | --negative] [--limit <n>] [--offset <n>] [--folder-key <guid>]
uip traces feedback list detailed [--agent-id <guid>] [--agent-version <str>] [--trace-id <id>] [--span-id <id>] [--status <value>...] [--positive | --negative] [--category-id <guid>...] [--after <iso> | --since <duration>] [--before <iso>] [--sort-by <field>] [--sort-order <dir>] [--limit <n>] [--offset <n>] [--folder-key <guid>]
uip traces feedback update <id> (--positive | --negative) --folder-key <guid> [--comment <text> | --comment-file <path>] [--metadata <json> | --metadata-file <path>] [--category <tag>...]
uip traces feedback delete <id> --folder-key <guid> -y
```

All verbs honor the [global options](./global-options.md) and the standard [exit codes](./exit-codes.md).

## uip traces feedback create

Create feedback for a trace (or a specific span within it).

### Options

| Flag | Description |
|---|---|
| `--trace-id <id>` | **Required.** Trace ID (32-char hex or GUID). |
| `--positive` / `--negative` | **Required — exactly one.** Sentiment of the feedback. |
| `--folder-key <guid>` | **Required.** Orchestrator folder key. |
| `--span-id <id>` | Span ID. Defaults to the trace's root span when omitted. |
| `--comment <text>` | Free-text annotation (max 1,048,576 characters). Mutually exclusive with `--comment-file`. |
| `--comment-file <path>` | Read the comment from a file; pass `-` to read from stdin. Mutually exclusive with `--comment`. |
| `--category <tag>` | Category tag. Repeatable. The platform recognizes built-in tags like `Output`, `Agent Error`, and `Agent Plan Execution`, but any string is accepted. |
| `--agent-id <guid>` | Agent reference ID. |
| `--agent-version <str>` | Agent version (max 100 characters). |

### Example

```bash
uip traces feedback create \
  --trace-id 4bf92f3577b34da6a3ce929d0e0e4736 \
  --positive \
  --folder-key a1b2c3d4-0000-0000-0000-000000000001
```

### Data shape

```json
{
  "Code": "FeedbackCreate",
  "Data": { "Id": "a1b2c3d4-0000-0000-0000-000000000002" }
}
```

`Data` is an unmodified pass-through of whatever the Feedback API returns — the CLI doesn't project it to a fixed field set, so the real response can carry more fields than shown here.

## uip traces feedback get

Get a single feedback record by ID.

### Arguments

- `<id>` *(required)* — Feedback record ID (GUID). Fails client-side with "Invalid feedback ID format" if it isn't a GUID.

### Options

| Flag | Description |
|---|---|
| `--folder-key <guid>` | Orchestrator folder key. The server generally requires this to authorize the read even though the CLI doesn't hard-fail without it client-side. |

### Example

```bash
uip traces feedback get a1b2c3d4-0000-0000-0000-000000000002 \
  --folder-key a1b2c3d4-0000-0000-0000-000000000001
```

### Data shape

```json
{
  "Code": "FeedbackGet",
  "Data": {
    "Id": "a1b2c3d4-0000-0000-0000-000000000002",
    "IsPositive": true
  }
}
```

Like `create`, `Data` is a raw pass-through — the real response typically carries more fields (comment, metadata, categories, timestamps) than this minimal example shows.

## uip traces feedback list

List feedback entries, filtered by trace, span, agent, status, or sentiment.

### Options

| Flag | Description |
|---|---|
| `--agent-id <guid>` | Filter by agent ID. |
| `--agent-version <str>` | Filter by agent version. |
| `--trace-id <id>` | Filter by trace ID. |
| `--span-id <id>` | Filter by span ID. |
| `--status <value>` | Filter by status: `Pending`, `Approved`, `Dismissed`. Repeatable. |
| `--positive` / `--negative` | Return only positive or only negative feedback. Mutually exclusive. |
| `--limit <n>` | Max results. Defaults to `20`, capped at `100`. |
| `--offset <n>` | Results to skip. Defaults to `0`. |
| `--folder-key <guid>` | Orchestrator folder key. |

### Example

```bash
uip traces feedback list --trace-id 4bf92f3577b34da6a3ce929d0e0e4736
```

### Data shape

```json
{
  "Code": "FeedbackList",
  "Data": [
    {
      "Id": "a1b2c3d4-0000-0000-0000-000000000002",
      "IsPositive": true
    }
  ]
}
```

An empty result prints "No feedback found. Use 'uip traces feedback create' to add feedback."

## uip traces feedback list detailed

List feedback with extended filters (time window, category, sort) and span context. This is a **subcommand of `list`**, not a top-level verb — the invocation is `uip traces feedback list detailed`, with the space, not `list-detailed`.

### Options

| Flag | Description |
|---|---|
| `--agent-id <guid>` | Filter by agent ID. |
| `--agent-version <str>` | Filter by agent version. |
| `--trace-id <id>` | Filter by trace ID. |
| `--span-id <id>` | Filter by span ID. |
| `--status <value>` | Filter by status: `Pending`, `Approved`, `Dismissed`. Repeatable. |
| `--positive` / `--negative` | Return only positive or only negative feedback. Mutually exclusive. |
| `--category-id <guid>` | Filter by category ID. Repeatable. |
| `--after <iso>` | Created after this ISO 8601 timestamp. |
| `--before <iso>` | Created before this ISO 8601 timestamp. |
| `--since <duration>` | Relative lookback shorthand for `--after` — for example `1h`, `24h`, `7d`. Only `h` (hours) and `d` (days) units are accepted. |
| `--sort-by <field>` | Sort field: `createdAt` or `updatedAt`. Defaults to `createdAt`. |
| `--sort-order <dir>` | Sort direction: `asc` or `desc`. Defaults to `desc`. |
| `--limit <n>` | Max results. Defaults to `20`, capped at `200` (higher than plain `list`'s cap of 100). |
| `--offset <n>` | Results to skip. Defaults to `0`. |
| `--folder-key <guid>` | Orchestrator folder key. |

:::note
`--since` and `--after` both set the same underlying start-time filter — `--since` is evaluated relative to "now" at the moment the command runs.
:::

### Example

```bash
uip traces feedback list detailed --since 24h
```

### Data shape

```json
{
  "Code": "FeedbackListDetailed",
  "Data": [
    {
      "Id": "a1b2c3d4-0000-0000-0000-000000000002",
      "IsPositive": true,
      "TraceId": "4bf92f3577b34da6a3ce929d0e0e4736"
    }
  ]
}
```

The underlying API response is paginated (`{ items, totalCount }`), but the CLI only emits the `items` array as `Data` — the total match count (`totalCount`) is not surfaced. To know whether more results exist beyond `--limit`, compare the returned count to `--limit` rather than relying on a total.

## uip traces feedback update

Update an existing feedback record's sentiment, comment, metadata, or categories.

:::important
The API replaces the whole record rather than patching it, so the CLI reads the existing record first and carries over any field you didn't pass — except `--category`: omitting it leaves existing categories untouched, but this read-then-write is not atomic. A concurrent edit landing between the read and the write is silently lost.
:::

### Arguments

- `<id>` *(required)* — Feedback record ID (GUID).

### Options

| Flag | Description |
|---|---|
| `--positive` / `--negative` | **Required — exactly one.** New sentiment. |
| `--folder-key <guid>` | **Required.** Orchestrator folder key. |
| `--comment <text>` | Updated comment (max 1,048,576 characters). Mutually exclusive with `--comment-file`. Omit to keep the existing comment. |
| `--comment-file <path>` | Read the updated comment from a file; pass `-` for stdin. Mutually exclusive with `--comment`. |
| `--metadata <json>` | Updated metadata; must be valid JSON (max 1,048,576 characters). Mutually exclusive with `--metadata-file`. Omit to keep the existing metadata. |
| `--metadata-file <path>` | Read updated metadata from a file; pass `-` for stdin. Mutually exclusive with `--metadata`. |
| `--category <tag>` | Replacement category tags. Repeatable. Omit entirely to leave existing categories as they are — passing it replaces the full set, it doesn't merge. |

### Examples

```bash
# change sentiment and add a comment
uip traces feedback update a1b2c3d4-0000-0000-0000-000000000002 \
  --negative \
  --comment "Wrong output" \
  --folder-key a1b2c3d4-0000-0000-0000-000000000001

# attach metadata read from a file
uip traces feedback update a1b2c3d4-0000-0000-0000-000000000002 \
  --positive \
  --metadata-file review.json \
  --folder-key a1b2c3d4-0000-0000-0000-000000000001
```

### Data shape

```json
{
  "Code": "FeedbackUpdate",
  "Data": {
    "Id": "a1b2c3d4-0000-0000-0000-000000000002",
    "IsPositive": false
  }
}
```

## uip traces feedback delete

Delete a feedback record by ID. This is a **destructive** operation — it requires `-y, --yes`; the CLI never prompts.

### Arguments

- `<id>` *(required)* — Feedback record ID (GUID).

### Options

| Flag | Description |
|---|---|
| `--folder-key <guid>` | **Required.** Orchestrator folder key. |
| `-y, --yes` | Confirm this irreversible operation. Required — the CLI never prompts. |

### Example

```bash
uip traces feedback delete a1b2c3d4-0000-0000-0000-000000000002 \
  --folder-key a1b2c3d4-0000-0000-0000-000000000001 \
  --yes
```

### Data shape

```json
{
  "Code": "FeedbackDelete",
  "Data": { "Id": "a1b2c3d4-0000-0000-0000-000000000002" }
}
```

## Error behavior

- `401` from the Feedback API: `Failure: "Not authenticated. Run 'uip auth login' first."`.
- `403`: `Failure: "Insufficient permissions. Ensure you have Logs.View / Logs.Create / Logs.Delete on this folder."`.
- `404`: `Failure` naming the missing feedback ID.
- An id that isn't a GUID (`get`, `update`, `delete`): `Failure: "Invalid feedback ID format: <id>"`, checked client-side before any network call.

## Related

- [`uip traces spans get`](./uip-traces.md#uip-traces-spans-get) — source of the `--trace-id`/`--span-id` values used above.
- [Tools (plugins)](./concepts-tools.md) — install, update, uninstall the `traces-tool` package.
- [`uip login`](./uip-login.md) — session used to authenticate every verb on this page.

## See also

- [`uip traces`](./uip-traces.md)
