---
title: "Read conversation metadata"
method: GET
path: "/conversations/{conversationId}"
tags: ["Conversations"]
---

# Read conversation metadata

`GET /conversations/{conversationId}`

## Request

- Base URL: `https://platform-api.visitoai.com/m2m/v1`
- URL: `https://platform-api.visitoai.com/m2m/v1/conversations/{conversationId}`
- Auth: HTTP bearer

Use for one conversation's contact identity, summary, needsReply, response policy and current handoff/review pointers. Discover conversationId with list_conversations. For message contents use list_conversation_messages; for historical handoff/review lifecycle use list_conversation_handoffs. Requires `conversations:read`. Returns metadata only. `conversation.needsReply` is the authoritative signal that operator action is required; `lastMessageRole` describes chronology only. Optional conversation.aiSummary describes main topics and current state. Read summaries first; fetch messages when the summary is absent, isStale is true, or supporting detail is needed. Summaries do not replace authoritative needsReply, booking, payment or delivery fields.

## Path parameters

- `conversationId` string, required

## Response `200`

Conversation detail

- ConversationMetadataResponse
  - `conversation` Conversation, required
    - `conversationId` string, required
    - `conversationKey` string
    - `tenantId` string, required
    - `channel` 'whatsapp' | 'instagram' | 'messenger' | 'tiktok' | 'webchat', required
    - `participant` ConversationParticipant, required
      - `id` string, required
      - `displayName` string
      - `email` string
      - `phone` string
      - `username` string
      - `avatarUrl` string, uri
      - `updatedAt` string, date-time
    - `unreadCount` integer, required
    - `needsReply` boolean, required
    - `lastMessageAt` string, date-time, required
    - `lastMessageText` string, required
    - `lastMessageRole` string, required
    - `latestReplyStatus` 'queued' | 'sent' | 'failed' | 'blocked' | 'publish_failed'
    - `policyStatus` 'active' | 'waiting_tool' | 'handoff_requested' | 'closed' | 'archived' | 'blocked'
    - `responseMode` 'ai' | 'manual' | 'frozen'
    - `messageCount` integer, required
    - `frozenUntilAt` string, date-time: Optional timed AI pause expiry. Absence means no stored timer; a past timestamp is expired. Other policy restrictions may still prevent AI replies.
    - `needsReplySince` string, date-time
    - `needsReplyReason` string
    - `needsReplyDetail` string
    - `unreadUpdatedAt` string, date-time
    - `handoffStatus` 'none' | 'requested' | 'active' | 'resolved'
    - `activeHandoffCaseId` string
    - `handoffRequestedAt` string, date-time
    - `handoffResolvedAt` string, date-time
    - `handoffReasonCode` string
    - `handoffReasonDetail` string
    - `handoffIntentId` string
    - `handoffTitleKey` string
    - `handoffTitleFallback` string
    - `handoffOperatorNote` string
    - `handoffPropertyId` string
    - `handoffPropertyDisplayName` string
    - `handoffSeverity` 'hard' | 'soft'
    - `handoffCapturedFieldsDisplay` object[]
      - `id` string
      - `label` string
      - `value` string
    - `handoffMissingFieldsDisplay` object[]
      - `id` string
      - `label` string
    - `reviewStatus` 'none' | 'requested' | 'resolved' | 'cancelled'
    - `activeReviewCaseId` string
    - `reviewReasonCode` string
    - `reviewNote` string
    - `reviewRequestedAt` string, date-time
    - `reviewResolvedAt` string, date-time
    - `assignedOperatorId` string
    - `assignedOperatorName` string
    - `assignedAt` string, date-time
    - `latestReplyAt` string, date-time
    - `manualEnabled` boolean
    - `optedOut` boolean
    - `optedOutAt` string, date-time
    - `optedOutReason` 'user_stop'
    - `lastMessageEventId` string
    - `senderId` string
    - `recipientId` string
    - `handoffAvailability` HandoffAvailability
      - `status` 'within_hours' | 'outside_hours' | 'not_configured'
      - `timezone` string
      - `evaluatedAtLocal` string
      - `currentWindow` object
        - `date` string
        - `day` string
        - `start` string
        - `end` string
      - `nextWindow` object
        - `date` string
        - `day` string
        - `start` string
        - `end` string
    - `aiSummary` ConversationAiSummary
      - `text` string, required: Main topics and current state in one short paragraph; claims are informational.
      - `generatedAt` string, date-time, required
      - `throughMessageAt` string, date-time, required: Timestamp of the latest external message included in the summary.
      - `isStale` boolean, required: True while newer activity or incomplete history awaits processing.

## Other responses

- `404`: Conversation not found
- `default`: Structured error

---

[API](https://skmtc.dev/visitoai/apis/visito-m2m-api.md) - [All operations](https://skmtc.dev/visitoai/apis/visito-m2m-api/llms.txt) - [OpenAPI document](https://skmtc.dev/visitoai/apis/visito-m2m-api/revisions/98377d35c234?raw)
