---
title: "Fetch the canonical analysis input for a completed session"
method: GET
path: "/v1/sessions/{session_id}/analysis-input"
tags: ["sessions"]
---

# Fetch the canonical analysis input for a completed session

`GET /v1/sessions/{session_id}/analysis-input`

Returns the ``SessionAnalysisInput`` shape defined in
``src/knowledge_gap/analysis_schemas.py``.

- ``404`` — session not found, or owned by a different organization.
- ``409`` — session is not in a terminal state (still active /
  paused / waiting for human / etc.). The analyzer should only be run
  on completed sessions.

## Path parameters

- `session_id` string, uuid, required

## Response `200`

Successful Response

- SessionAnalysisInput — Canonical analyzer input built from one completed session. Required fields are populated for every analysed completed session. Conditionally-required fields populate when the corresponding capture succeeded (e.g., ``rag_traces`` when retrieval ran). Nullable enrichment fields are best-effort. Consumers should consult ``missing_evidence_reasons`` before attempting evidence-backed classifications.
  - `analyzer_input_schema_version` integer
  - `session_id` string, uuid, required
  - `organization_id` string, uuid, required
  - `agent_id` string, uuid, nullable, required
  - `channel` string, required
  - `started_at` string, date-time, required
  - `ended_at` string, date-time, nullable, required
  - `completion_reason` string, nullable, required
  - `knowledge_gap_analysis_outcome` 'resolved' | 'unresolved' | 'transferred' | 'expired' | 'error' | 'abandoned' | 'voicemail' | 'escalated' | 'call_failed', required — Canonical, analyzer-friendly outcome of a completed session. Derived from ``(SessionStatus, SessionTerminationReason)`` at close time and persisted on ``ConvSessionMeta.knowledge_gap_analysis_outcome``. Free-form ``termination_reason`` is preserved alongside for forensic detail.
  - `messages` MessageEntry[]
    - `turn_id` string, uuid, required
    - `role` string, required
    - `timestamp` string, date-time, required
    - `content` string, required
    - `tool_calls` ToolCall[], nullable
      - `id` string, required
      - `type` string
      - `function` ToolCallFunction, required
        - `name` string, required
        - `arguments` string, required
    - `tool_results` ToolResult
      - `tool_call_id` string, required
      - `output` string, required
      - `error` string, nullable
    - `model_used` string, nullable
    - `latency_ms` integer, nullable
    - `truncated` boolean
    - `original_char_count` integer, nullable
  - `rag_traces` RagTraceEntry[]
    - `rag_query_id` string, uuid, required
    - `assistant_turn_id` string, uuid, required
    - `query_hash` string, nullable
    - `kb_ids` string[]
    - `retrieved` RetrievedChunk[]
      - `chunk_id` string, required
      - `doc_id` string, required
      - `version_id` string, nullable
      - `score` number, nullable
    - `top_score` number, nullable
    - `hit` boolean, nullable
    - `latency_ms` integer, nullable
    - `answerability` RagTraceAnswerability — Answerability verdict subset persisted on a RAG trace (ENG-671/672). Present only when the gate ran (mode shadow/enforce); legacy / off-mode traces leave :attr:`RagTraceEntry.answerability` ``None``. Every field is optional so a partial or older JSONB payload coerces rather than raising. ``raw_top_score`` is the pre-normalization top score the retro retrieval- failure detector prefers over the display ``top_score``.
      - `label` string, nullable
      - `reason_code` string, nullable
      - `raw_top_score` number, nullable
      - `score_basis` string, nullable
      - `mode` string, nullable
      - `action` string, nullable
      - `threshold_low` number, nullable
      - `threshold_high` number, nullable
  - `citations` CitedChunk[]
    - `assistant_turn_id` string, uuid, required
    - `kb_id` string, uuid, required
    - `doc_id` string, required
    - `chunk_id` string, required
    - `version_id` string, nullable
  - `tool_calls` ToolCallEntry[]
    - `tool_call_id` string, required
    - `assistant_turn_id` string, uuid, required
    - `name` string, required
    - `arguments` string, required
    - `arguments_parsed` unknown
    - `result` string, nullable
    - `error` string, nullable
    - `latency_ms` integer, nullable
  - `handoff_events` HandoffEvent[]
    - `timestamp` string, date-time, required
    - `transferred_to_agent_id` string, uuid, nullable
    - `reason` string, nullable
  - `kb_snapshot` KbSnapshotEntry — KB state captured at the moment of the session's first retrieval. Maps each KB used in the session to the active document-version count (as a coarse fingerprint of "what was the KB at the time"). The fine-grained per-doc version of a retrieved chunk is on ``RetrievedChunk.version_id``.
    - `captured_at` string, date-time, required
    - `kb_versions` object
  - `user_feedback` FeedbackEntry — Free-form user feedback against a session. Nullable in v1 — no capture surface yet. Shape is reserved so downstream consumers can plan against it.
    - `timestamp` string, date-time, required
    - `rating` integer, nullable
    - `comment` string, nullable
  - `csat` CSATEntry — CSAT score against a session. Nullable in v1 (no capture surface).
    - `timestamp` string, date-time, required
    - `score` integer, required
    - `scale_max` integer
  - `reopen` ReopenEntry — Ticket reopen event. Nullable in v1 (no capture surface).
    - `timestamp` string, date-time, required
    - `reason` string, nullable
  - `customer_metadata` object, nullable
  - `missing_evidence_reasons` MissingEvidenceReason[]

## Other responses

- `400` — Bad request
- `401` — Authentication required
- `422` — Validation Error

---

[API](https://skmtc.net/oneloop-hq/apis/feather-api.md) · [All operations](https://skmtc.net/oneloop-hq/apis/feather-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/oneloop-hq/feather-api/versions/888bdd5c076e/schema)
