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

# Append Session Message

> Persist one verbatim chat turn into the conversation-history store.

This is the chat-history write path (ADR-0020). It writes ONLY to
``conversation_messages`` via the conversation writer
(:func:`append_message`); it never touches the EDN memory engine
(``memory_records``). The two stores are independent by design and
this endpoint runs alongside, never through, ``POST
/api/v1/memory/ingest``.

The writer is caller-commits, so this endpoint owns the commit,
mirroring ``create_session``. ``append_message`` validates ``role``
in {user, assistant} (422), caps ``content`` at 100000 chars (422),
enforces session ownership via ``ensure_session_owned_or_create``
(404 on another user's session, creates the session row on first
use), and bumps the session's denormalised sidebar fields.

# IDOR AUDIT PASS — append_message gates on session ownership scoped
# to the authenticated user_id before any write.



## OpenAPI

````yaml post /api/v1/sessions/{session_id}/messages
openapi: 3.1.0
info:
  title: EDN Memory Engine
  version: 0.1.0
servers:
  - description: EDN evaluation endpoint
    url: https://api.tensorpro.ai
security:
  - EDNApiKey: []
paths:
  /api/v1/sessions/{session_id}/messages:
    post:
      summary: Append Session Message
      description: |-
        Persist one verbatim chat turn into the conversation-history store.

        This is the chat-history write path (ADR-0020). It writes ONLY to
        ``conversation_messages`` via the conversation writer
        (:func:`append_message`); it never touches the EDN memory engine
        (``memory_records``). The two stores are independent by design and
        this endpoint runs alongside, never through, ``POST
        /api/v1/memory/ingest``.

        The writer is caller-commits, so this endpoint owns the commit,
        mirroring ``create_session``. ``append_message`` validates ``role``
        in {user, assistant} (422), caps ``content`` at 100000 chars (422),
        enforces session ownership via ``ensure_session_owned_or_create``
        (404 on another user's session, creates the session row on first
        use), and bumps the session's denormalised sidebar fields.

        # IDOR AUDIT PASS — append_message gates on session ownership scoped
        # to the authenticated user_id before any write.
      operationId: append_session_message_api_v1_sessions__session_id__messages_post
      parameters:
        - in: path
          name: session_id
          required: true
          schema:
            title: Session Id
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AppendMessageRequest'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MessageItem'
          description: Successful Response
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
          description: Validation Error
components:
  schemas:
    AppendMessageRequest:
      properties:
        content:
          title: Content
          type: string
        records_used:
          anyOf:
            - type: integer
            - type: 'null'
          title: Records Used
        role:
          title: Role
          type: string
        round_id:
          anyOf:
            - type: string
            - type: 'null'
          title: Round Id
        sip_text:
          anyOf:
            - type: string
            - type: 'null'
          title: Sip Text
      required:
        - role
        - content
      title: AppendMessageRequest
      type: object
    MessageItem:
      properties:
        content:
          title: Content
          type: string
        created_at:
          title: Created At
          type: string
        id:
          title: Id
          type: string
        records_used:
          anyOf:
            - type: integer
            - type: 'null'
          title: Records Used
        role:
          title: Role
          type: string
        round_id:
          anyOf:
            - type: string
            - type: 'null'
          title: Round Id
        sip_text:
          anyOf:
            - type: string
            - type: 'null'
          title: Sip Text
      required:
        - id
        - role
        - content
        - created_at
      title: MessageItem
      type: object
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          title: Detail
          type: array
      title: HTTPValidationError
      type: object
    ValidationError:
      properties:
        ctx:
          title: Context
          type: object
        input:
          title: Input
        loc:
          items:
            anyOf:
              - type: string
              - type: integer
          title: Location
          type: array
        msg:
          title: Message
          type: string
        type:
          title: Error Type
          type: string
      required:
        - loc
        - msg
        - type
      title: ValidationError
      type: object
  securitySchemes:
    EDNApiKey:
      description: >-
        EDN API key presented as 'Bearer <key>' in the Authorization header.
        Create and manage keys from the Console.
      in: header
      name: Authorization
      type: apiKey

````