Ando Messages API

Message and conversation message routes.

OpenAPI Specification

ando-messages-api-openapi.yml Raw ↑
openapi: 3.0.3
info:
  description: Generated from Ando's accepted public API v1 contract metadata. Current routes preserve legacy /api/v1 response envelopes while converging on the public https://api.ando.so/v1 shape.
  title: Ando Public Calls Messages API
  version: v1
servers:
- description: Canonical public API host.
  url: https://api.ando.so/v1
tags:
- description: Message and conversation message routes.
  name: Messages
paths:
  /conversation-messages/{messageId}:
    get:
      description: Returns a single conversation message by identifier.
      operationId: getConversationMessage
      parameters:
      - description: Message identifier.
        in: path
        name: messageId
        required: true
        schema:
          description: Message identifier.
          type: string
      responses:
        '200':
          content:
            application/json:
              examples:
                message:
                  summary: Message details.
                  value:
                    id: msg_01jzn7e61x3a7v9h2r7t2m3q4p
                    conversation_id: conv_01jzn7e61x3a7v9h2r7t2m3q4p
                    conversation_name: Launch planning
                    authorWorkspaceMembershipId: mem_01jzn7e61x3a7v9h2r7t2m3q4p
                    author_id: mem_01jzn7e61x3a7v9h2r7t2m3q4p
                    author_name: Alex Kim
                    content: Validated the route migration.
                    image_urls: []
                    reactions:
                    - emoji_text: ':thumbsup:'
                      count: 2
                    replies_count: 1
                    created_at: '2026-05-14T08:00:00.000Z'
                    data:
                      id: msg_01jzn7e61x3a7v9h2r7t2m3q4p
                      conversation_id: conv_01jzn7e61x3a7v9h2r7t2m3q4p
                      conversation_name: Launch planning
                      authorWorkspaceMembershipId: mem_01jzn7e61x3a7v9h2r7t2m3q4p
                      author_id: mem_01jzn7e61x3a7v9h2r7t2m3q4p
                      author_name: Alex Kim
                      content: Validated the route migration.
                      image_urls: []
                      reactions:
                      - emoji_text: ':thumbsup:'
                        count: 2
                      replies_count: 1
                      created_at: '2026-05-14T08:00:00.000Z'
              schema:
                $ref: '#/components/schemas/MessageResultResponse'
          description: Message details.
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
      security:
      - AndoApiKey: []
      - BearerApiKey: []
      summary: Get a message
      tags:
      - Messages
      x-ando-compatibility-mode: standard_public
      x-ando-migration-target: standard_public
      x-ando-rate-limit-policy: declared
      x-ando-route-id: api.api_v1_conversation_messages_by_messageid.get
      x-ando-canonical-host: api.ando.so
      x-ando-documentation-owner: api_platform
      x-ando-principal-kind: workspace_api_key
      x-ando-public-api-route-class: public_data
      x-ando-public-path: /v1/conversation-messages/:messageId
      x-ando-runtime-owner: api_platform
      x-ando-status-probe-owner: public_api_messaging
      x-ando-rollback-runtime: express
      x-ando-selected-runtime: convex_http
      x-ando-target-runtime: convex_http
  /conversation-messages/{messageId}/replies:
    get:
      description: Returns replies for a thread root message.
      operationId: listThreadReplies
      parameters:
      - description: Thread root message identifier.
        in: path
        name: messageId
        required: true
        schema:
          description: Thread root message identifier.
          type: string
      - description: Maximum number of records to return.
        in: query
        name: limit
        schema:
          description: Maximum number of records to return.
          type: integer
          minimum: 1
      - description: Cursor or ISO timestamp after which results should be returned.
        in: query
        name: after
        schema:
          description: Cursor or ISO timestamp after which results should be returned.
          type: string
      responses:
        '200':
          content:
            application/json:
              examples:
                replies:
                  summary: Thread replies.
                  value:
                    data:
                      thread_root_id: msg_01jzn7e61x3a7v9h2r7t2m3q4p
                      conversation_id: conv_01jzn7e61x3a7v9h2r7t2m3q4p
                      conversation_name: Launch planning
                      items:
                      - id: msg_01jzn7e61x3a7v9h2r7t2m3q4r
                        conversation_id: conv_01jzn7e61x3a7v9h2r7t2m3q4p
                        conversation_name: Launch planning
                        authorWorkspaceMembershipId: mem_01jzn7e61x3a7v9h2r7t2m3q4p
                        author_id: mem_01jzn7e61x3a7v9h2r7t2m3q4p
                        author_name: Alex Kim
                        content: Follow-up looks good.
                        image_urls: []
                        reactions:
                        - emoji_text: ':thumbsup:'
                          count: 2
                        replies_count: 0
                        created_at: '2026-05-14T08:05:00.000Z'
                      page_info:
                        end_cursor: '2026-05-14T08:05:00.000Z'
                        has_next_page: false
                        has_previous_page: false
                        next_cursor: '2026-05-14T08:05:00.000Z'
                        start_cursor: '2026-05-14T08:05:00.000Z'
                    thread_root_id: msg_01jzn7e61x3a7v9h2r7t2m3q4p
                    conversation_id: conv_01jzn7e61x3a7v9h2r7t2m3q4p
                    conversation_name: Launch planning
                    items:
                    - id: msg_01jzn7e61x3a7v9h2r7t2m3q4r
                      conversation_id: conv_01jzn7e61x3a7v9h2r7t2m3q4p
                      conversation_name: Launch planning
                      authorWorkspaceMembershipId: mem_01jzn7e61x3a7v9h2r7t2m3q4p
                      author_id: mem_01jzn7e61x3a7v9h2r7t2m3q4p
                      author_name: Alex Kim
                      content: Follow-up looks good.
                      image_urls: []
                      reactions:
                      - emoji_text: ':thumbsup:'
                        count: 2
                      replies_count: 0
                      created_at: '2026-05-14T08:05:00.000Z'
                    pageInfo:
                      hasNextPage: false
                      hasPreviousPage: false
                      startCursor: '2026-05-14T08:05:00.000Z'
                      endCursor: '2026-05-14T08:05:00.000Z'
              schema:
                $ref: '#/components/schemas/ThreadRepliesResponse'
          description: Thread replies.
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
      security:
      - AndoApiKey: []
      - BearerApiKey: []
      summary: List thread replies
      tags:
      - Messages
      x-ando-compatibility-mode: standard_public
      x-ando-migration-target: standard_public
      x-ando-rate-limit-policy: declared
      x-ando-route-id: api.api_v1_conversation_messages_by_messageid_replies.get
      x-ando-canonical-host: api.ando.so
      x-ando-documentation-owner: api_platform
      x-ando-principal-kind: workspace_api_key
      x-ando-public-api-route-class: public_data
      x-ando-public-path: /v1/conversation-messages/:messageId/replies
      x-ando-runtime-owner: api_platform
      x-ando-status-probe-owner: public_api_messaging
      x-ando-rollback-runtime: express
      x-ando-selected-runtime: convex_http
      x-ando-target-runtime: convex_http
  /conversations/{conversationId}/messages:
    get:
      description: Returns messages in a conversation.
      operationId: listConversationMessages
      parameters:
      - description: Conversation identifier.
        in: path
        name: conversationId
        required: true
        schema:
          description: Conversation identifier.
          type: string
      - description: Maximum number of records to return.
        in: query
        name: limit
        schema:
          description: Maximum number of records to return.
          type: integer
          minimum: 1
      - description: Cursor or ISO timestamp before which results should be returned.
        in: query
        name: before
        schema:
          description: Cursor or ISO timestamp before which results should be returned.
          type: string
      responses:
        '200':
          content:
            application/json:
              examples:
                messages:
                  summary: Conversation messages.
                  value:
                    data:
                      conversation_id: conv_01jzn7e61x3a7v9h2r7t2m3q4p
                      conversation_name: Launch planning
                      items:
                      - id: msg_01jzn7e61x3a7v9h2r7t2m3q4p
                        conversation_id: conv_01jzn7e61x3a7v9h2r7t2m3q4p
                        conversation_name: Launch planning
                        authorWorkspaceMembershipId: mem_01jzn7e61x3a7v9h2r7t2m3q4p
                        author_id: mem_01jzn7e61x3a7v9h2r7t2m3q4p
                        author_name: Alex Kim
                        content: Validated the route migration.
                        image_urls: []
                        reactions:
                        - emoji_text: ':thumbsup:'
                          count: 2
                        replies_count: 1
                        created_at: '2026-05-14T08:00:00.000Z'
                      page_info:
                        end_cursor: '2026-05-14T07:45:00.000Z'
                        has_next_page: true
                        has_previous_page: false
                        next_cursor: '2026-05-14T08:00:00.000Z'
                        start_cursor: '2026-05-14T08:00:00.000Z'
                    conversation_id: conv_01jzn7e61x3a7v9h2r7t2m3q4p
                    conversation_name: Launch planning
                    items:
                    - id: msg_01jzn7e61x3a7v9h2r7t2m3q4p
                      conversation_id: conv_01jzn7e61x3a7v9h2r7t2m3q4p
                      conversation_name: Launch planning
                      authorWorkspaceMembershipId: mem_01jzn7e61x3a7v9h2r7t2m3q4p
                      author_id: mem_01jzn7e61x3a7v9h2r7t2m3q4p
                      author_name: Alex Kim
                      content: Validated the route migration.
                      image_urls: []
                      reactions:
                      - emoji_text: ':thumbsup:'
                        count: 2
                      replies_count: 1
                      created_at: '2026-05-14T08:00:00.000Z'
                    pageInfo:
                      hasNextPage: true
                      hasPreviousPage: false
                      startCursor: '2026-05-14T08:00:00.000Z'
                      endCursor: '2026-05-14T07:45:00.000Z'
              schema:
                $ref: '#/components/schemas/ConversationMessagesResponse'
          description: Conversation messages.
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
      security:
      - AndoApiKey: []
      - BearerApiKey: []
      summary: List conversation messages
      tags:
      - Messages
      x-ando-compatibility-mode: standard_public
      x-ando-migration-target: standard_public
      x-ando-rate-limit-policy: declared
      x-ando-route-id: api.api_v1_conversations_by_conversationid_messages.get
      x-ando-canonical-host: api.ando.so
      x-ando-documentation-owner: api_platform
      x-ando-principal-kind: workspace_api_key
      x-ando-public-api-route-class: public_data
      x-ando-public-path: /v1/conversations/:conversationId/messages
      x-ando-runtime-owner: api_platform
      x-ando-status-probe-owner: public_api_messaging
      x-ando-rollback-runtime: express
      x-ando-selected-runtime: convex_http
      x-ando-target-runtime: convex_http
    post:
      description: Creates a message in a conversation using the authenticated API-key workspace membership as the author.
      operationId: createConversationMessage
      parameters:
      - description: Conversation identifier.
        in: path
        name: conversationId
        required: true
        schema:
          description: Conversation identifier.
          type: string
      - description: Required idempotency key for safely retrying this write.
        in: header
        name: Idempotency-Key
        required: true
        schema:
          description: Idempotency key.
          type: string
          maxLength: 255
      requestBody:
        content:
          application/json:
            examples:
              message:
                summary: Create a top-level message.
                value:
                  markdown_content: Can you review this?
                  explicit_context_message_ids: []
                  image_urls: []
                  suppressed_link_preview_urls: []
                  thread_root_id: null
            schema:
              $ref: '#/components/schemas/CreateConversationMessageBody'
        required: true
      responses:
        '200':
          content:
            application/json:
              examples:
                created:
                  summary: Created message.
                  value:
                    success: true
                    data:
                      id: msg_01jzn7e61x3a7v9h2r7t2m3q4p
                      conversation_id: conv_01jzn7e61x3a7v9h2r7t2m3q4p
                      conversation_name: Launch planning
                      authorWorkspaceMembershipId: mem_01jzn7e61x3a7v9h2r7t2m3q4p
                      author_id: mem_01jzn7e61x3a7v9h2r7t2m3q4p
                      author_name: Alex Kim
                      content: Validated the route migration.
                      image_urls: []
                      reactions:
                      - emoji_text: ':thumbsup:'
                        count: 2
                      replies_count: 1
                      created_at: '2026-05-14T08:00:00.000Z'
                    legacy_data: null
              schema:
                $ref: '#/components/schemas/CreateConversationMessageResponse'
          description: Created message.
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
      security:
      - AndoApiKey: []
      - BearerApiKey: []
      summary: Create a conversation message
      tags:
      - Messages
      x-ando-compatibility-mode: standard_public
      x-ando-migration-target: standard_public
      x-ando-rate-limit-policy: declared
      x-ando-route-id: api.api_v1_conversations_by_conversationid_messages.post
      x-ando-canonical-host: api.ando.so
      x-ando-documentation-owner: api_platform
      x-ando-principal-kind: workspace_api_key
      x-ando-public-api-route-class: durable_ingress
      x-ando-public-path: /v1/conversations/:conversationId/messages
      x-ando-runtime-owner: api_platform
      x-ando-status-probe-owner: public_api_messaging
      x-ando-rollback-runtime: express
      x-ando-selected-runtime: convex_http
      x-ando-target-runtime: convex_http
components:
  responses:
    Forbidden:
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/LegacyErrorResponse'
      description: Forbidden.
    RateLimited:
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/PublicApiErrorResponse'
      description: Rate limit or quota exceeded.
    NotFound:
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/LegacyErrorResponse'
      description: Not found.
    InternalError:
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/LegacyErrorResponse'
      description: Internal server error.
    Conflict:
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/LegacyErrorResponse'
      description: Conflict.
    Unauthorized:
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/LegacyErrorResponse'
      description: Missing or invalid API key.
    BadRequest:
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/LegacyErrorResponse'
      description: Bad request.
  schemas:
    MessageReactionSummary:
      additionalProperties: false
      description: Emoji reaction count for a message.
      properties:
        count:
          description: Number of reactions for this emoji.
          type: integer
        emoji_text:
          description: Emoji text.
          type: string
      required:
      - emoji_text
      - count
      type: object
    PublicApiPageInfo:
      additionalProperties: false
      description: Target public API pagination metadata with snake_case field names.
      properties:
        end_cursor:
          description: Cursor for the last item.
          type: string
          nullable: true
        has_next_page:
          description: Whether another page exists after this page.
          type: boolean
        has_previous_page:
          description: Whether another page exists before this page.
          type: boolean
        next_cursor:
          description: Cursor for the next page.
          type: string
          nullable: true
        previous_cursor:
          description: Cursor for the previous page.
          type: string
          nullable: true
        start_cursor:
          description: Cursor for the first item.
          type: string
          nullable: true
      required:
      - has_next_page
      type: object
    LegacyErrorResponse:
      additionalProperties: false
      description: Current compatibility error envelope used by legacy /api/v1 routes.
      properties:
        error:
          description: Error message.
          type: string
        error_code:
          description: Optional machine-readable error code.
          type: string
          nullable: true
        missing_scopes:
          description: Missing scopes.
          items:
            description: Scope.
            type: string
          type: array
      required:
      - error
      type: object
    MessageResult:
      additionalProperties: false
      description: Public message result. This intentionally omits reply lineage fields such as thread_root_id and replied_to_message_id; use the thread replies route and its thread_root_id payload field to validate thread grouping.
      properties:
        authorWorkspaceMembershipId:
          description: Canonical author workspace membership identifier. Matches legacy author_id during the compatibility window.
          type: string
          example: 01jzn7e61x3a7v9h2r7t2m3q4p
        author_id:
          description: 'Author workspace member identifier. Deprecated: read authorWorkspaceMembershipId instead.'
          type: string
          example: 01jzn7e61x3a7v9h2r7t2m3q4p
          deprecated: true
        author_name:
          description: Author workspace member display name.
          type: string
          nullable: true
        content:
          description: Message markdown content.
          type: string
          nullable: true
        conversation_id:
          description: Conversation identifier.
          type: string
          example: 01jzn7e61x3a7v9h2r7t2m3q4p
        conversation_name:
          description: Conversation name.
          type: string
          nullable: true
        created_at:
          description: Message creation timestamp.
          type: string
          example: '2026-05-14T08:00:00.000Z'
          format: date-time
        id:
          description: Message identifier.
          type: string
          example: 01jzn7e61x3a7v9h2r7t2m3q4p
        image_urls:
          description: Image URLs extracted from the message.
          items:
            description: Image URL.
            type: string
            format: uri
          type: array
        reactions:
          description: Emoji reaction counts on the message.
          items:
            $ref: '#/components/schemas/MessageReactionSummary'
          type: array
        replies_count:
          description: Number of thread replies.
          type: integer
      required:
      - id
      - conversation_id
      - conversation_name
      - authorWorkspaceMembershipId
      - author_id
      - author_name
      - content
      - image_urls
      - reactions
      - replies_count
      - created_at
      type: object
    ConversationMessagesResponse:
      additionalProperties: false
      description: Conversation messages response with the standard public data envelope plus legacy top-level aliases.
      properties:
        conversation_id:
          description: Conversation identifier.
          type: string
          example: 01jzn7e61x3a7v9h2r7t2m3q4p
        conversation_name:
          description: Conversation name.
          type: string
          nullable: true
        data:
          $ref: '#/components/schemas/ConversationMessagesData'
        items:
          description: Messages.
          items:
            $ref: '#/components/schemas/MessageResult'
          type: array
        pageInfo:
          $ref: '#/components/schemas/LegacyPageInfo'
      required:
      - data
      - conversation_id
      - conversation_name
      - items
      - pageInfo
      type: object
    CreateConversationMessageResponse:
      additionalProperties: false
      description: Create-message response with the standard public data envelope plus legacy compatibility aliases.
      properties:
        data:
          $ref: '#/components/schemas/MessageResult'
        legacy_data:
          additionalProperties: true
          description: Legacy extended conversation message. New clients should read the standard data message result.
          nullable: true
          type: object
        success:
          description: Compatibility command flag.
          type: boolean
      required:
      - success
      - data
      type: object
    ThreadRepliesResponse:
      additionalProperties: false
      description: Thread replies response with the standard public data envelope plus legacy top-level aliases. The response-level thread_root_id identifies the requested root; individual MessageResult items do not expose reply lineage metadata.
      properties:
        conversation_id:
          description: Conversation identifier.
          type: string
          example: 01jzn7e61x3a7v9h2r7t2m3q4p
        conversation_name:
          description: Conversation name.
          type: string
          nullable: true
        data:
          $ref: '#/components/schemas/ThreadRepliesData'
        items:
          description: Thread reply messages.
          items:
            $ref: '#/components/schemas/MessageResult'
          type: array
        pageInfo:
          $ref: '#/components/schemas/LegacyPageInfo'
        thread_root_id:
          description: Thread root message identifier.
          type: string
          example: 01jzn7e61x3a7v9h2r7t2m3q4p
      required:
      - data
      - thread_root_id
      - conversation_id
      - conversation_name
      - items
      - pageInfo
      type: object
    PublicApiErrorResponse:
      additionalProperties: false
      description: Target public API error envelope.
      properties:
        error:
          additionalProperties: false
          description: Error details.
          properties:
            code:
              description: Machine-readable error code.
              type: string
            message:
              description: Human-readable error message.
              type: string
            request_id:
              description: Request identifier.
              type: string
              nullable: true
          required:
          - code
          - message
          type: object
      required:
      - error
      type: object
    ConversationMessagesData:
      additionalProperties: false
      description: Standard conversation messages payload.
      properties:
        conversation_id:
          description: Conversation identifier.
          type: string
          example: 01jzn7e61x3a7v9h2r7t2m3q4p
        conversation_name:
          description: Conversation name.
          type: string
          nullable: true
        items:
          description: Messages.
          items:
            $ref: '#/components/schemas/MessageResult'
          type: array
        page_info:
          $ref: '#/components/schemas/PublicApiPageInfo'
      required:
      - conversation_id
      - conversation_name
      - items
      - page_info
      type: object
    MessageResultResponse:
      additionalProperties: false
      description: Message detail response with the standard public data envelope plus legacy top-level aliases.
      properties:
        authorWorkspaceMembershipId:
          description: Canonical author workspace membership identifier. Matches legacy author_id during the compatibility window.
          type: string
          example: 01jzn7e61x3a7v9h2r7t2m3q4p
        author_id:
          description: 'Author workspace member identifier. Deprecated: read authorWorkspaceMembershipId instead.'
          type: string
          example: 01jzn7e61x3a7v9h2r7t2m3q4p
          deprecated: true
        author_name:
          description: Author workspace member display name.
          type: string
          nullable: true
        content:
          description: Message markdown content.
          type: string
          nullable: true
        conversation_id:
          description: Conversation identifier.
          type: string
          example: 01jzn7e61x3a7v9h2r7t2m3q4p
        conversation_name:
          description: Conversation name.
          type: string
          nullable: true
        created_at:
          description: Message creation timestamp.
          type: string
          example: '2026-05-14T08:00:00.000Z'
          format: date-time
        data:
          $ref: '#/components/schemas/MessageResult'
        id:
          description: Message identifier.
          type: string
          example: 01jzn7e61x3a7v9h2r7t2m3q4p
        image_urls:
          description: Image URLs extracted from the message.
          items:
            description: Image URL.
            type: string
            format: uri
          type: array
        reactions:
          description: Emoji reaction counts on the message.
          items:
            $ref: '#/components/schemas/MessageReactionSummary'
          type: array
        replies_count:
          description: Number of thread replies.
          type: integer
      required:
      - data
      - id
      - conversation_id
      - conversation_name
      - authorWorkspaceMembershipId
      - author_id
      - author_name
      - content
      - image_urls
      - reactions
      - replies_count
      - created_at
      type: object
    LegacyPageInfo:
      additionalProperties: false
      description: Current compatibility pagination metadata with camelCase field names.
      properties:
        endCursor:
          description: Cursor for the last item.
          type: string
          nullable: true
        hasNextPage:
          description: Whether another page exists after this page.
          type: boolean
        hasPreviousPage:
          description: Whether another page exists before this page.
          type: boolean
        startCursor:
          description: Cursor for the first item.
          type: string
          nullable: true
      required:
      - hasNextPage
      - hasPreviousPage
      type: object
    CreateConversationMessageBody:
      additionalProperties: false
      description: Create a conversation message. The authenticated API-key workspace member is the author; author_id is accepted only for legacy body compatibility and is ignored.
      properties:
        markdown_content:
          description: Message markdown content.
          type: string
          nullable: true
        explicit_context_message_ids:
          description: Message identifiers to include as explicit context.
          items:
            description: Message identifier.
            type: string
          type: array
        image_urls:
          description: Image URLs to attach to the message.
          items:
            description: Image URL.
            type: string
            format: uri
          type: array
        suppressed_link_preview_urls:
          description: URLs whose link previews should be suppressed.
          items:
            description: URL.
            type: string
            format: uri
          type: array
        initiator_id:
          description: Initiating workspace member identifier.
          type: string
          nullable: true
        thread_root_id:
          description: Thread root message identifier.
          type: string
          nullable: true
        replied_to_message_id:
          description: Immediate parent message identifier inside an existing thread. For the first reply to a root message, send thread_root_id only; if replied_to_message_id equals thread_root_id, the server normalizes it as the first reply.
          type: string
          nullable: true
        call_root_id:
          description: Call root identifier.
          type: string
          nullable: true
        optimistic_id:
          description: Client optimistic identifier.
          type: string
        client_request_id:
          description: Legacy body idempotency value. Public v1 clients should use the Idempotency-Key header.
          type: string
          nullable: true
        author_id:
          description: 'Ignored legacy body author workspace member identifier. Deprecated: the authenticated API-key workspace member is always the author.'
          type: string
          deprecated: true
      required:
      - markdown_content
      type: object
    ThreadRepliesData:
      additionalProperties: false
      description: Standard thread replies payload. Use thread_root_id here to validate thread grouping; individual MessageResult items intentionally omit thread_root_id and replied_to_message_id.
      properties:
        conversation_id:
          description: Conversation identifier.
          type: string
          example: 01jzn7e61x3a7v9h2r7t2m3q4p
        conversation_name:
          description: Conversation name.
          type: string
          nullable: true
        items:
          description: Thread reply messages.
          items:
            $ref: '#/components/schemas/MessageResult'
          type: array
        page_info:
          $ref: '#/components/schemas/PublicApiPageInfo'
        thread_root_id:
          descr

# --- truncated at 32 KB (32 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/ando/refs/heads/main/openapi/ando-messages-api-openapi.yml