---
title: "Get agent conversation by ID"
method: GET
path: "/agents/{agentKey}/conversations/{conversationId}"
tags: ["Agents"]
---

# Get agent conversation by ID

`GET /agents/{agentKey}/conversations/{conversationId}`

Returns the conversation with paginated/sorted messages and filter metadata.

**Message Pagination:**

Messages are paginated newest-first: `page=1` returns the most recent
batch. Increment `page` to load older batches (used by the infinite-scroll
"load older messages" feature).

- `page`: Page number (default: 1)
- `limit`: Messages per page (default: 20, max: 100)

## Path parameters

- `agentKey` string, required
- `conversationId` string, objectId, required

## Query parameters

- `page` integer
- `limit` integer
- `sortBy` 'createdAt' | 'messageType' | 'content'
- `sortOrder` 'asc' | 'desc'
- `startDate` string, date-time
- `endDate` string, date-time
- `messageType` 'user_query' | 'bot_response' | 'error' | 'feedback' | 'system'

## Response `200`

Agent conversation detail

- AgentConversationDetailResponse — Envelope returned by `GET /agents/{agentKey}/conversations/{conversationId}`.
  - `conversation` AgentConversationDetail, required — Reduced conversation view returned by the by-id GET route. This is not the raw `AgentConversation` document shape: fields like `agentKey`, `userId`, `orgId`, `conversationSource`, and root-level `messages` metadata outside the selected slice are omitted.
    - `id` string, objectId, required
    - `title` string
    - `initiator` string, objectId
    - `createdAt` string, date-time, required
    - `isShared` boolean, required
    - `sharedWith` object[], required
      - `userId` string, objectId
      - `accessLevel` 'read' | 'write'
    - `status` 'None' | 'Inprogress' | 'Complete' | 'Failed'
    - `failReason` string
    - `messages` AgentConversationDetailMessage[], required
      - `_id` string, objectId
      - `messageType` 'user_query' | 'bot_response' | 'error' | 'feedback' | 'system'
      - `content` string
      - `contentFormat` 'MARKDOWN' | 'JSON' | 'HTML'
      - `citations` AgentConversationDetailMessageCitation[]
        - `citationId` string, objectId
        - `citationData` Citation — A populated citation document. Represents a single chunk of source content (e.g. a passage from a document or record) referenced by an AI response, together with its provenance metadata.
          - `_id` string, objectId, required
          - `content` string, required — The cited text chunk
          - `chunkIndex` integer, required — Index of this chunk within the source record
          - `citationType` string, required — Source type identifier (e.g. `vectordb|document`)
          - `metadata` PersistedSemanticSearchCitationMetadata, required — Citation metadata as persisted in MongoDB. Required fields mirror the Mongoose schema's `required: true` flags; the rest are optional and may come through as `null` because the AI retrieval service emits explicit nulls for absent fields.
            - `orgId` string, required
            - `mimeType` string, required
            - `recordId` string, required
            - `recordName` string, required
            - `origin` string, required
            - `recordVersion` integer, nullable
            - `extension` string, nullable
            - `webUrl` string, nullable
            - `previewRenderable` boolean, nullable
            - `hideWeburl` boolean, nullable
            - `connector` string, nullable
            - `recordType` string, nullable
            - `blockNum` number[], nullable
            - `pageNum` number[], nullable
            - `sheetNum` number, nullable
            - `sheetName` string, nullable
            - `bounding_box` PersistedSemanticSearchBoundingBox[], nullable
              - …
            - `blockType` string, nullable — Block type for this citation. Common values: `text`, `image`, `table_row`, `table`, `record_summary` (whole-record semantic summary chunk).
            - `blockText` string, nullable
            - `departments` string[], nullable
            - `languages` string[], nullable
            - `topics` string[], nullable
          - `createdAt` string, date-time, required
          - `updatedAt` string, date-time, required
      - `confidence` 'Very High' | 'High' | 'Medium' | 'Low' | 'Unknown', nullable — AI confidence in the answer. Present only on `bot_response` messages, and only when the model emitted a trailing confidence block. This field is now optional and nullable; it was previously always present and non-nullable. Treat a missing or `null` value as "no confidence reported" and guard before using it. Change effective in SDK v1.3.0 (v1.2.0 and earlier always populated it).
      - `followUpQuestions` FollowUpQuestion[]
        - `question` string — The suggested question text
        - `confidence` string — Confidence level for this suggestion
        - `reasoning` string — Why this question might be relevant
      - `feedback` MessageFeedback[]
        - `isHelpful` boolean — Overall helpfulness rating
        - `ratings` object
          - `accuracy` integer — How accurate was the information (1-5)
          - `relevance` integer — How relevant was the response (1-5)
          - `completeness` integer — How complete was the answer (1-5)
          - `clarity` integer — How clear was the explanation (1-5)
        - `categories` string[] — Categories of issues or positive attributes identified
        - `comments` object
          - `positive` string — What was good about the response
          - `negative` string — What could be improved
          - `suggestions` string — Specific suggestions for improvement
        - `citationFeedback` object[] — Feedback on individual citations
          - `_id` string, objectId — Auto-generated sub-document identifier
          - `citationId` string, objectId
          - `isRelevant` boolean
          - `relevanceScore` integer
          - `comment` string
        - `followUpQuestionsHelpful` boolean — Were the suggested follow-up questions helpful
        - `unusedFollowUpQuestions` string[] — Follow-up questions that were suggested but not used by the user
        - `source` 'user' | 'system' | 'admin' | 'auto' — Origin of the feedback. Always present in responses (server applies the default `user`).
        - `feedbackProvider` string, objectId — User who submitted the feedback
        - `timestamp` integer — Time the feedback was created, stored as a Number (epoch milliseconds) with a server-side default of `Date.now`, so always present in responses. Not an ISO 8601 datetime.
        - `revisions` object[] — Audit trail of edits to this feedback entry
          - `_id` string, objectId — Auto-generated sub-document identifier
          - `updatedFields` string[] — Names of feedback fields modified in this revision
          - `previousValues` object — Map of previously-set values for the fields named in `updatedFields`, keyed by field name. Stored as a Mongoose Map of Mixed values.
          - `updatedBy` string, objectId
          - `updatedAt` integer — Time the revision was recorded, as epoch milliseconds.
        - `metrics` object — Optional telemetry captured alongside the feedback
          - `timeToFeedback` number — Time from response delivery to feedback submission
          - `userInteractionTime` number — Total time the user spent reviewing the response
          - `feedbackSessionId` string
          - `userAgent` string
          - `platform` string
      - `referenceData` object[] — Reference identifiers surfaced from tool responses, used to scope follow-up queries.
        - `name` string — Display name shown to the user.
        - `id` string — Technical identifier (numeric ID, UUID, etc.).
        - `type` string — Item type (e.g. `project`, `issue`, `file`, `notebook`, `page`).
        - `app` string — Source application (e.g. `jira`, `confluence`, `sharepoint`, `slack`, `drive`, `gmail`).
        - `webUrl` string — URL to open the item in a browser.
        - `metadata` object — App-specific fields keyed by name (e.g. `key` for a Jira project, `siteId` for a SharePoint document).
      - `attachments` ChatAttachmentRef[] — Files uploaded for this message turn (see `POST /agents/{agentKey}/conversations/attachments/upload`).
        - `recordId` string, required — Attachment record id returned from the upload endpoint.
        - `recordName` string — Original display name of the file when known.
        - `mimeType` string — MIME type of the uploaded file.
        - `extension` string — File extension (e.g. `pdf`).
        - `virtualRecordId` string — Optional synthetic record id used by the graph layer.
      - `tools` object[] — Tool call results invoked during this message turn.
        - `toolName` string
        - `toolResult` unknown
      - `modelInfo` ConversationModelInfo — AI model configuration recorded against a conversation or message.
        - `modelKey` string — Stable identifier of the configured model record
        - `modelName` string — Provider-facing model name (e.g. `gpt-4o-mini`)
        - `modelProvider` string — Provider key (e.g. `openai`, `anthropic`)
        - `modelFriendlyName` string — Human-readable display name
        - `chatMode` string — Chat mode used for this turn (e.g. `quick`, `internal_search`)
      - `appliedFilters` AppliedFilters — Rich filter state selected by the user, used for display and persistence only. This mirrors the active selection shown in the UI and is distinct from the machine-readable `filters` field used for retrieval scoping.
        - `apps` AppliedFilterNode[] — Applied app/connector filter nodes
          - `id` string — Unique identifier of the filter node
          - `name` string — Display name of the filter node
          - `nodeType` string — Type of the node (e.g. app, recordGroup, folder, record)
          - `connector` string — Connector identifier associated with this node
        - `kb` AppliedFilterNode[] — Applied knowledge-base filter nodes
          - `id` string — Unique identifier of the filter node
          - `name` string — Display name of the filter node
          - `nodeType` string — Type of the node (e.g. app, recordGroup, folder, record)
          - `connector` string — Connector identifier associated with this node
      - `metadata` object
        - `processingTimeMs` number
        - `modelVersion` string
        - `aiTransactionId` string
      - `createdAt` string, date-time
      - `updatedAt` string, date-time
    - `modelInfo` ConversationModelInfo — AI model configuration recorded against a conversation or message.
      - `modelKey` string — Stable identifier of the configured model record
      - `modelName` string — Provider-facing model name (e.g. `gpt-4o-mini`)
      - `modelProvider` string — Provider key (e.g. `openai`, `anthropic`)
      - `modelFriendlyName` string — Human-readable display name
      - `chatMode` string — Chat mode used for this turn (e.g. `quick`, `internal_search`)
    - `pagination` AgentConversationDetailPagination, required — Message pagination returned inside the `conversation` object. The handler paginates backwards from the end of the stored message array, then sorts the selected page in memory before serialization.
      - `page` integer, required
      - `limit` integer, required
      - `totalCount` integer, required
      - `totalPages` integer, required
      - `hasNextPage` boolean, required — True when older messages exist outside the returned page
      - `hasPrevPage` boolean, required — True when newer messages exist outside the returned page
      - `messageRange` object, required
        - `start` integer, required
        - `end` integer, required
    - `access` AgentConversationDetailAccess, required
      - `isOwner` boolean
      - `accessLevel` 'read' | 'write'
  - `filters` SemanticSearchHistoryFilters, required
    - `applied` SemanticSearchHistoryFiltersApplied, required — Echo of which filters the caller actually supplied, built by `buildFiltersMetadata` (utils.ts:430-486). `page` and `limit` always appear because they are normalised to defaults before being recorded, so `filters` is never empty and `values` always contains at least `{ page, limit }`. Other keys appear only when the matching query param was non-empty (or, for `dateRange`, when `createdAt` was set on the Mongo filter). `values` keys are scalar strings rather than typed primitives (`'true'`/`'false'`, `'5'`, etc.) because they are passed through from `req.query` as Express parsed them — only `page` and `limit` are coerced to integers via `safeParsePagination`.
      - `filters` string[], required
      - `values` object, required
        - `page` integer
        - `limit` integer
        - `search` string
        - `shared` string
        - `tags` string
        - `minMessages` string
        - `sortBy` string
        - `sortOrder` string
        - `startDate` string
        - `endDate` string
        - `messageType` string
        - `dateRange` SemanticSearchHistoryAppliedDateRange — Echoed back only when the caller passed `startDate` and/or `endDate`. Each bound is an ISO 8601 string when set; the field is absent when the corresponding query param was omitted (utils.ts:480-486 reads `appliedFilters.createdAt.$gte?.toISOString()` directly, so missing bounds become `undefined` and drop out of the JSON).
          - `start` string, date-time
          - `end` string, date-time
    - `available` SemanticSearchHistoryFiltersAvailable, required — Catalogue of filters the endpoint supports, plus their current values and `applied` flags. Built by `buildFiltersMetadata` (utils.ts:430-624).
      - `shared` SemanticSearchHistoryFilterToggle, required — Generic "filter X is available, current value is Y" block used for `shared`, `tags`, `minMessages`, `search`, and `messageType`. Either `type` (free-form value) or `values` (enum of allowed strings) is present, not both. `current` is the caller-supplied value passed through from `req.query`, hence string-or-null even when `type` is `'number'`.
        - `type` string
        - `values` string[]
        - `description` string, required
        - `current` string, nullable, required
        - `applied` boolean, required
      - `tags` SemanticSearchHistoryFilterToggle, required — Generic "filter X is available, current value is Y" block used for `shared`, `tags`, `minMessages`, `search`, and `messageType`. Either `type` (free-form value) or `values` (enum of allowed strings) is present, not both. `current` is the caller-supplied value passed through from `req.query`, hence string-or-null even when `type` is `'number'`.
        - `type` string
        - `values` string[]
        - `description` string, required
        - `current` string, nullable, required
        - `applied` boolean, required
      - `minMessages` SemanticSearchHistoryFilterToggle, required — Generic "filter X is available, current value is Y" block used for `shared`, `tags`, `minMessages`, `search`, and `messageType`. Either `type` (free-form value) or `values` (enum of allowed strings) is present, not both. `current` is the caller-supplied value passed through from `req.query`, hence string-or-null even when `type` is `'number'`.
        - `type` string
        - `values` string[]
        - `description` string, required
        - `current` string, nullable, required
        - `applied` boolean, required
      - `search` SemanticSearchHistoryFilterToggle, required — Generic "filter X is available, current value is Y" block used for `shared`, `tags`, `minMessages`, `search`, and `messageType`. Either `type` (free-form value) or `values` (enum of allowed strings) is present, not both. `current` is the caller-supplied value passed through from `req.query`, hence string-or-null even when `type` is `'number'`.
        - `type` string
        - `values` string[]
        - `description` string, required
        - `current` string, nullable, required
        - `applied` boolean, required
      - `pagination` object, required
        - `page` SemanticSearchHistoryPaginationField, required
          - `type` string, required
          - `current` integer, required
          - `min` integer, required
          - `max` integer, required
          - `default` integer, required
          - `description` string, required
          - `applied` boolean, required
        - `limit` SemanticSearchHistoryPaginationField, required
          - `type` string, required
          - `current` integer, required
          - `min` integer, required
          - `max` integer, required
          - `default` integer, required
          - `description` string, required
          - `applied` boolean, required
      - `sorting` object, required
        - `sortBy` SemanticSearchHistorySortField, required — Used for `available.sorting.{sortBy,sortOrder}` and `available.sortingMessages.{sortBy,sortOrder}`. The `applied` flag is present on `sorting.*` and absent on `sortingMessages.*`, so it is optional here.
          - `values` string[], required
          - `default` string, required
          - `description` string, required
          - `current` string, required
          - `applied` boolean
        - `sortOrder` SemanticSearchHistorySortField, required — Used for `available.sorting.{sortBy,sortOrder}` and `available.sortingMessages.{sortBy,sortOrder}`. The `applied` flag is present on `sorting.*` and absent on `sortingMessages.*`, so it is optional here.
          - `values` string[], required
          - `default` string, required
          - `description` string, required
          - `current` string, required
          - `applied` boolean
      - `dateFilters` object, required
        - `dateRange` SemanticSearchHistoryDateRange, required
          - `type` string, required
          - `description` string, required
          - `format` string, required
          - `current` object, required
            - `start` string, nullable, required
            - `end` string, nullable, required
          - `applied` boolean, required
      - `messageFilters` object, required
        - `messageType` SemanticSearchHistoryFilterToggle, required — Generic "filter X is available, current value is Y" block used for `shared`, `tags`, `minMessages`, `search`, and `messageType`. Either `type` (free-form value) or `values` (enum of allowed strings) is present, not both. `current` is the caller-supplied value passed through from `req.query`, hence string-or-null even when `type` is `'number'`.
          - `type` string
          - `values` string[]
          - `description` string, required
          - `current` string, nullable, required
          - `applied` boolean, required
      - `sortingMessages` object, required
        - `sortBy` SemanticSearchHistorySortField, required — Used for `available.sorting.{sortBy,sortOrder}` and `available.sortingMessages.{sortBy,sortOrder}`. The `applied` flag is present on `sorting.*` and absent on `sortingMessages.*`, so it is optional here.
          - `values` string[], required
          - `default` string, required
          - `description` string, required
          - `current` string, required
          - `applied` boolean
        - `sortOrder` SemanticSearchHistorySortField, required — Used for `available.sorting.{sortBy,sortOrder}` and `available.sortingMessages.{sortBy,sortOrder}`. The `applied` flag is present on `sorting.*` and absent on `sortingMessages.*`, so it is optional here.
          - `values` string[], required
          - `default` string, required
          - `description` string, required
          - `current` string, required
          - `applied` boolean
  - `meta` AgentConversationDetailMeta, required — Request-scoped metadata returned by the by-id GET route. `requestId` is omitted when upstream middleware did not attach one.
    - `requestId` string
    - `timestamp` string, date-time, required
    - `duration` integer, required
    - `conversationId` string, objectId, required
    - `messageCount` integer, required

## Other responses

- `401` — Unauthorized
- `404` — Conversation not found

---

[API](https://skmtc.net/pipeshub-ai/apis/pipeshub-api.md) · [All operations](https://skmtc.net/pipeshub-ai/apis/pipeshub-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/pipeshub-ai/pipeshub-api/revisions/abd27cfefc73/schema)
