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

# Get a conversation

> Read the newest projected Conversation document, excluding only root messages. This is the same read used by get_conversation. Projection can lag recent writes. Missing projections return 200 with document null; this does not prove the durable Conversation is absent. Requires cxm:conversations.read or an existing broader read/wildcard scope. A write-only scope does not grant read permission. GET accepts no request body. Unknown, repeated, array, and empty query parameters are rejected. Responses are marked no-store.



## OpenAPI

````yaml /api-reference/openapi-v1.json get /api/v1/cxm/tenants/{tenantId}/conversations/{conversationId}
openapi: 3.1.0
info:
  title: Crescendo CXP API
  version: 1.0.0
  description: >-
    Use the Customer Experience Platform API from trusted server-side
    applications to create Conversations, read projected detail and stored
    history, update operational fields, assign work, and add internal notes.
    Writes execute independently; repeating a write may repeat its effects.
servers:
  - url: https://platform.crescendo.ai
    description: Production
security: []
tags:
  - name: Conversations
    description: Create, continue, and manage customer conversations.
paths:
  /api/v1/cxm/tenants/{tenantId}/conversations/{conversationId}:
    get:
      tags:
        - Conversations
      summary: Get a conversation
      description: >-
        Read the newest projected Conversation document, excluding only root
        messages. This is the same read used by get_conversation. Projection can
        lag recent writes. Missing projections return 200 with document null;
        this does not prove the durable Conversation is absent. Requires
        cxm:conversations.read or an existing broader read/wildcard scope. A
        write-only scope does not grant read permission. GET accepts no request
        body. Unknown, repeated, array, and empty query parameters are rejected.
        Responses are marked no-store.
      operationId: getConversation
      parameters:
        - name: tenantId
          in: path
          required: true
          description: Exact tenant-authorized ID without path separators.
          schema:
            type: string
            maxLength: 128
            minLength: 1
          example: tenant_demo
        - name: conversationId
          in: path
          required: true
          description: Exact tenant-authorized ID without path separators.
          schema:
            type: string
            maxLength: 512
            minLength: 1
          example: CX123
      responses:
        '200':
          description: Conversation read completed.
          headers:
            Cache-Control:
              schema:
                type: string
                const: no-store
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ConversationReadResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
          description: >-
            Invalid target, unsupported or repeated query parameter, invalid
            limit/cursor, or a request body on GET.
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/PermissionDenied'
        '429':
          $ref: '#/components/responses/RateLimitExceeded'
        '502':
          $ref: '#/components/responses/BadGateway'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
        '504':
          $ref: '#/components/responses/GatewayTimeout'
      security:
        - BearerApiKey: []
components:
  schemas:
    ConversationReadResponse:
      type: object
      additionalProperties: false
      required:
        - document
        - freshness
      properties:
        document:
          type:
            - object
            - 'null'
          additionalProperties: true
          description: >-
            Newest projected Conversation with all current and future properties
            except root messages; null when no projection is found. Internal
            Conversation fields remain available under read permission.
        freshness:
          type: object
          additionalProperties: false
          required:
            - source
            - projectionUpdatedAt
            - readAt
          properties:
            source:
              type: string
              const: elasticsearch
            projectionUpdatedAt:
              type:
                - string
                - 'null'
              format: date-time
            readAt:
              type: string
              format: date-time
    Error:
      type: object
      additionalProperties: false
      required:
        - code
        - message
      properties:
        code:
          type: string
          enum:
            - BadRequest
            - InvalidCustomField
            - Unauthenticated
            - PermissionDenied
            - EmailChannelNotFound
            - AssigneeNotFound
            - NotFound
            - EmailChannelDisabled
            - ContactIdentityConflict
            - OrganizationAmbiguous
            - AssigneeAmbiguous
            - Conflict
            - PayloadTooLarge
            - RateLimitExceeded
            - BadGateway
            - ServiceUnavailable
            - GatewayTimeout
        message:
          type: string
  responses:
    BadRequest:
      description: The body, a field, an unknown property, or a custom field is invalid.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: BadRequest
            message: message.text is required
    Unauthenticated:
      description: The API key is missing, invalid, or expired.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: Unauthenticated
            message: Authentication required
    PermissionDenied:
      description: The API key does not authorize the tenant or required scope.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: PermissionDenied
            message: API key does not allow this operation
    RateLimitExceeded:
      description: The tenant/API-key/route limit was exceeded.
      headers:
        Retry-After:
          description: Seconds to wait before another request.
          schema:
            type: integer
            minimum: 1
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: RateLimitExceeded
            message: CXM API rate limit exceeded
    BadGateway:
      description: >-
        The gateway could not complete downstream transport. The durable
        mutation outcome may be unknown.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: BadGateway
            message: CXM API downstream request failed
    ServiceUnavailable:
      description: A required service or durable/configuration dependency is unavailable.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: ServiceUnavailable
            message: CXM API is temporarily unavailable
    GatewayTimeout:
      description: >-
        The gateway timed out. The durable mutation outcome may be unknown, and
        retrying can duplicate effects.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: GatewayTimeout
            message: CXM API downstream request timed out
  securitySchemes:
    BearerApiKey:
      type: http
      scheme: bearer
      description: >-
        Tenant API key with `cxm:conversations.write`, `cxm:conversations.*`,
        `cxm:write`, or `cxm:*` scope. Keep it in a trusted backend; do not
        expose it in browser code.

````