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

# Agent Observations API

> Query LLM calls, tool calls, retrievals, and agent steps with an observation-centric API.

## List Agent Observations

```
GET https://api.squasher.ai/v1/projects/{project_id}/agent-observations
```

Returns paginated agent operations for a project. Each row is one generation,
tool call, retrieval, agent step, or session-scoped operation.

### Query Parameters

| Parameter          | Type     | Default  | Description                                                                                                  |
| ------------------ | -------- | -------- | ------------------------------------------------------------------------------------------------------------ |
| `from`             | datetime | last 24h | Start of time range                                                                                          |
| `to`               | datetime | now      | End of time range                                                                                            |
| `trace_id`         | string   | -        | Filter to one trace                                                                                          |
| `session_id`       | string   | -        | Filter to one session                                                                                        |
| `user_id`          | string   | -        | Filter to one user                                                                                           |
| `agent_id`         | string   | -        | Filter to one agent                                                                                          |
| `workflow_id`      | string   | -        | Filter to one workflow                                                                                       |
| `observation_type` | string   | -        | `generation`, `tool_call`, `retrieval`, `agent_step`, `agent_session`                                        |
| `status`           | string   | -        | Filter by observation status                                                                                 |
| `model`            | string   | -        | Filter by model name                                                                                         |
| `tool_name`        | string   | -        | Filter by tool name                                                                                          |
| `q`                | string   | -        | Case-insensitive search on message, observation name, tool name, prompt/output JSON, and propagated metadata |
| `limit`            | integer  | `50`     | Results per page (max 200)                                                                                   |
| `offset`           | integer  | `0`      | Pagination offset                                                                                            |

### Response

```json theme={null}
{
  "data": [
    {
      "observation_id": "gen-span-1",
      "parent_observation_id": "root-span",
      "trace_id": "trace_123",
      "span_id": "gen-span-1",
      "session_id": "session_123",
      "user_id": "user_123",
      "distinct_id": "user_123",
      "visitor_id": "",
      "agent_id": "support-agent",
      "workflow_id": "incident_response",
      "step_id": "step-2",
      "observation_type": "generation",
      "observation_name": "planner.generate",
      "message": "generation completed",
      "level": "info",
      "status": "completed",
      "source": "sdk",
      "model": "gpt-4.1",
      "provider": "openai",
      "tool_name": "",
      "duration_ms": 42,
      "prompt_tokens": 120,
      "completion_tokens": 45,
      "total_tokens": 165,
      "cost_usd": 0.018,
      "started_at": "2026-03-28T17:00:00Z",
      "received_at": "2026-03-28T17:00:00Z",
      "environment": "production",
      "release": "2026.03.28"
    }
  ],
  "total": 1,
  "limit": 50,
  "offset": 0
}
```

***

## Get Agent Observation

```
GET https://api.squasher.ai/v1/projects/{project_id}/agent-observations/{observation_id}
```

Returns the full record for one observation including structured inputs,
outputs, tags, and propagated attributes.

### Response

```json theme={null}
{
  "observation_id": "gen-span-1",
  "parent_observation_id": "root-span",
  "trace_id": "trace_123",
  "span_id": "gen-span-1",
  "session_id": "session_123",
  "user_id": "user_123",
  "distinct_id": "user_123",
  "visitor_id": "",
  "agent_id": "support-agent",
  "workflow_id": "incident_response",
  "step_id": "step-2",
  "observation_type": "generation",
  "observation_name": "planner.generate",
  "message": "generation completed",
  "level": "info",
  "status": "completed",
  "source": "sdk",
  "model": "gpt-4.1",
  "provider": "openai",
  "tool_name": "",
  "duration_ms": 42,
  "prompt_tokens": 120,
  "completion_tokens": 45,
  "total_tokens": 165,
  "cost_usd": 0.018,
  "input_json": { "prompt": "Summarize the incident" },
  "output_json": { "text": "Summary" },
  "tags": { "workflow": "incident_response" },
  "attributes": { "region": "us-east-1" },
  "started_at": "2026-03-28T17:00:00Z",
  "received_at": "2026-03-28T17:00:00Z",
  "environment": "production",
  "release": "2026.03.28"
}
```

## Audit telemetry completeness

```text theme={null}
GET https://api.squasher.ai/v1/projects/{project_id}/agent-observations/quality
```

Returns content-free coverage counters for trace linkage, generation inputs,
system prompts, completed outputs, model/provider attribution, token usage, and
cost. The `privacy_posture` object reports privacy-mode coverage plus the count
and percentage of content-bearing, reasoning-bearing, and tool-payload-bearing
observations. It never returns the captured content. Use this endpoint as an
instrumentation and privacy-policy release gate without exporting prompts,
responses, reasoning, or tool payloads.

The default window is the last 24 hours. Windows are capped at 31 days and can
be filtered by `agent_id`, `workflow_id`, `model`, `provider`, `release`, or
`environment`. Pass `include_missing_examples=true` to return up to 20
observation IDs for each incomplete field without returning prompt or response
content.

```bash theme={null}
squasher agent-observations quality \
  --project "$SQUASHER_PROJECT_ID" \
  --agent-id chat-agent \
  --workflow-id support-chat \
  --include-missing-examples \
  --fail-under 100 \
  --min-observations 500 \
  --min-scored-observations 25 \
  --min-scores 30 \
  --require-privacy-mode \
  --max-content-bearing-percent 0 \
  --environment production \
  --from 2026-03-27T17:00:00Z \
  --to 2026-03-28T17:00:00Z
```

Each field under `coverage` includes `captured`, `eligible`, `missing`, and
`percent`. Output, token, and cost coverage use successful generations as the
denominator. Generation input, model, and provider coverage use all generations.
System-prompt coverage uses chat/system-capable generations, so prompt-only
requests are not incorrectly reported as missing a separate system message.

For CI and release gates, `--fail-under <percent>` exits non-zero when any
applicable coverage dimension falls below the threshold. It also rejects
invalid token totals and, by default, an empty window. Add
`--min-observations <count>` to require enough live evidence before a release
can pass. The JSON report is printed before the failure so CI artifacts retain
the exact coverage and denominators. Use `--min-scored-observations` and
`--min-scores` to require enough human-feedback or evaluation evidence for an
engagement, experiment, or training-data workflow.

Use `--require-privacy-mode` to require every observation in the selected
window to declare privacy mode. Use `--max-content-bearing-percent <percent>`
to bound the percentage of observations whose stored payload shape indicates
prompt, response, reasoning, message, or tool content. The posture report is a
metadata-only policy signal: it checks content presence and known privacy-mode
attributes, not the meaning of captured text.

## Export an evaluation or training dataset

```text theme={null}
GET https://api.squasher.ai/v1/projects/{project_id}/agent-observations/export
```

Returns a deterministic, paginated set of completed generations with their full
structured input, output, cost, token usage, and current scores. Use it to build
offline evaluation sets, supervised fine-tuning examples, or preference/RL
datasets without scraping the dashboard.

This endpoint handles raw prompt and model-output content. API keys need the
explicit `ai:export` scope or `*`; `read`, `write`, and `errors:read` do not
grant access. MCP intentionally does not expose this bulk operation.

| Parameter                 | Type     | Default | Description                                                  |
| ------------------------- | -------- | ------- | ------------------------------------------------------------ |
| `from` / `to`             | datetime | -       | Bound examples by generation time                            |
| `q`                       | string   | -       | Search prompt, output, tags, and attributes                  |
| `model` / `provider`      | string   | -       | Select a model or provider                                   |
| `release` / `environment` | string   | -       | Select an application release or environment                 |
| `status`                  | string   | `ok`    | Select generation status                                     |
| `score_name`              | string   | -       | Require a current score with this name                       |
| `score_source`            | string   | -       | Require `api`, `eval`, or `annotation`                       |
| `score_label`             | string   | -       | Require a categorical label such as `liked` or `regenerated` |
| `min_score`               | number   | -       | Minimum numeric or boolean score                             |
| `max_score`               | number   | -       | Maximum numeric or boolean score                             |
| `require_output`          | boolean  | `true`  | Exclude unfinished/empty generations                         |
| `include_identifiers`     | boolean  | `false` | Include `session_id` and `user_id`                           |
| `include_metadata`        | boolean  | `false` | Include generation and score tags/attributes                 |
| `limit`                   | integer  | `25`    | Bounded page size, maximum `100`                             |
| `offset`                  | integer  | `0`     | Pagination offset; continue while `has_more` is `true`       |

Identifiers and arbitrary metadata are opt-in so a normal training export does
not accidentally carry customer identity or unrelated telemetry. When enabled,
each score includes its own `metadata.attributes` and `metadata.tags`,
preserving feedback reasons, experiment assignments, evaluator context, and
other training signals. Prompt and output content is never reconstructed:
privacy-mode or upstream-redacted fields remain absent/redacted in the export.

```bash theme={null}
squasher agent-observations export \
  --project "$SQUASHER_PROJECT_ID" \
  --score-name message_feedback \
  --score-label liked \
  --format jsonl > liked-generations.jsonl
```

## Common Workflows

* Find all expensive generations by filtering `observation_type=generation` and sorting by `cost_usd` in your client.
* Search prompt text, tool payloads, or model output by passing `q` with a phrase from `input_json` or `output_json`.
* Debug one agent run by filtering `trace_id` or `session_id`.
* Investigate a user's failures by filtering `user_id` and `status=error`.
* Isolate tool performance by filtering `observation_type=tool_call` or `tool_name`.
* Export positively scored generations with `agent-observations export` for an
  eval, SFT, or preference dataset.
* Gate instrumentation releases with `agent-observations quality` and compare
  coverage by agent, workflow, release, environment, model, or provider. Add
  `--include-missing-examples` to jump directly from a failed coverage gate to
  the incomplete observations, then enforce the release with
  `--fail-under 100 --min-observations <expected-volume>`.

## Agent handoff

Use this API when an assistant needs row-level AI workflow evidence:

```text theme={null}
Inspect Squasher agent observations for project <project_id> from <from> to <to>. Start with filters for session_id, trace_id, agent_id, workflow_id, model, tool_name, observation_type, status, or q. Return observation ids, timestamps, costs, token counts, and the next narrow query to run.
```

For terminal workflows, use `squasher agent-observations ...`. For MCP, call `search("agentObservations")`, inspect the schema, then `execute` the exact request.

## Related dashboard endpoints

Squasher's AI dashboard also uses these project-scoped endpoints:

* `GET /v1/projects/{project_id}/ai/stats` for summary metrics, top models, top providers, sessions, and users
* `GET /v1/projects/{project_id}/ai/histogram` for daily request/cost/latency/token charts
* `GET /v1/projects/{project_id}/ai/sessions/{session_id}` for session drill-down
* `GET /v1/projects/{project_id}/ai/users/{user_id}` for user drill-down; accepts optional `from` and `to` ISO timestamp query parameters to keep high-volume users windowed
* `GET /v1/projects/{project_id}/ai/fixes/stats` for hosted fixer dispatch counts by source, requester, status, and webhook delivery
* `GET /v1/projects/{project_id}/ai/fixes/timeline` for hosted fixer dispatch and completion counts over time

These endpoints are designed for dashboards and product analytics. The observation list/detail endpoints above remain the source of truth for row-level inspection.
