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

# Send a message to the AI assistant (experimental — Soul Document V2 prompt)

> Second-generation experimental variant of `/api/ai/personal/qanda`.
Identical request / response contract to the V1 experimental endpoint,
but uses the **Soul Document V2** prompt generator
(`getSoulDocumentPromptV2` / `getSoulDocumentPromptV2Bypassed`) which
refines the cohesive-anchor architecture introduced in V1. Used for
three-way A/B testing alongside classic `/api/ai/personal/qanda` and
the V1 experimental endpoint.

Behavior is otherwise identical to `/api/ai/experimental/personal/qanda`:
- Same `inputs[]` + `requestArgs` request shape (`QandARequest`).
- Same Socket.IO streaming via optional `requestArgs.socketId`.
- Same downstream middleware chain (`creditCheck`,
  `contentFilterCheck`, `creditPayment`, `saveToHistory`,
  `sendResponse`).
- Same handler-level `User.findOne({_id})` re-load (the
  `resolveInstitution` middleware still runs upstream, but the
  handler operates on the freshly re-loaded user object).
- `req.locals.experimental = true` and `req.locals.promptMode = 'soul-v2'`
  are stamped on the history record so the A/B harness can distinguish
  V1 from V2 runs.

See `docs/plans/2026-02-01-soul-document-experiment-design.md` and the
three-way comparison runner in `test/soul-comparison/`.




## OpenAPI

````yaml /mdx/api-reference/runtime/runtime-api.json post /api/ai/experimental/personal/qanda-v2
openapi: 3.0.0
info:
  title: Pria Runtime API
  version: 2.0.1
  description: >-
    Pria API Documentation Praxis's developer platform is a core part of our
    mission to empower organizations to grow better. Our APIs are designed to
    enable teams of any shape or size to build robust integrations that help
    them customize and get the most value out of Pria. All Pria APIs are built
    using REST conventions and designed to have a predictable URL structure.
    <br/>  <br/>They use many standard HTTP features, including methods (POST,
    GET, PUT, DELETE) and error response codes.  <br/> <br/>All API calls are
    made under https://hiimpria.ai/api and all responses return standard JSON.
    In these docs, you'll find lists of all available endpoints for a given API,
    along with interactive code blocks for building requests. For walkthroughs
    of basic usage for these APIs, check out the API guides.
servers:
  - url: https://pria.praxislxp.com
    description: Pria API Server
security: []
tags:
  - name: Authentication
    description: User authentication, registration, and password management (/api/auth)
  - name: OAuth
    description: OAuth authentication providers - Google, GitHub, SSO (/api/auth/oauth)
  - name: User
    description: User profile management and account operations (/api/user)
  - name: User Institutions
    description: User institution memberships and switching (/api/user/institution)
  - name: User Tools
    description: Available tools for authenticated users (/api/user/tools)
  - name: Institutions
    description: Institution settings and configuration (/api/user/institution)
  - name: Conversation
    description: AI conversation and Q&A endpoints (/api/ai)
  - name: Realtime
    description: Real-time voice AI and WebRTC sessions (/api/ai/rt)
  - name: Assistant
    description: AI assistant configuration and management (/api/user/assistant)
  - name: History
    description: Conversation history and favorites (/api/user/history)
  - name: RAG
    description: >-
      Document upload, embedding, and retrieval-augmented generation
      (/api/user/files, /api/user/rag)
  - name: Setting
    description: Instance variables and settings management (/api/user/setting)
  - name: Branding
    description: Digital twin branding and customization (/api/agent/branding)
  - name: Agent
    description: Agent engagement and session management (/api/agent)
  - name: SDK Launch
    description: >-
      SDK launch token signing and verification for secure iframe embedding
      (/api/auth/sdk-sign, /api/auth/sdk-verify)
  - name: Testing
    description: Health checks, diagnostics, and test endpoints (/api/test)
  - name: Admin Accounts
    description: Account management for super admins (/api/admin/account)
  - name: Admin Institutions
    description: Institution management for admins (/api/admin/institution)
  - name: Admin Users
    description: User management for admins (/api/admin/user)
  - name: Admin Entitlements
    description: >-
      User-institution relationships and permissions
      (/api/admin/userInstitution)
  - name: Admin Sessions
    description: Session management for admins (/api/admin/session)
  - name: Admin Histories
    description: Conversation history management and analytics (/api/admin/history)
  - name: Admin Assistants
    description: AI assistant management for admins (/api/admin/assistant)
  - name: Admin Questions
    description: Institution question and prompt management (/api/admin/question)
  - name: Admin Tools
    description: Tool configuration management (/api/admin/tool)
  - name: Admin AI Models
    description: AI model configuration (/api/admin/aimodel)
  - name: Admin MCP Servers
    description: Model Context Protocol server management (/api/admin/mcpserver)
  - name: Admin Feedbacks
    description: User feedback management (/api/admin/feedback)
  - name: Admin Uploads
    description: Upload management (/api/admin/upload)
  - name: Admin Charts
    description: Analytics and visualization chart management (/api/admin/chart)
  - name: Audio Notes
    description: Capture and ingest spoken notes into the personal vault
  - name: Memory
    description: User-facing memory parameters (personal + shared instance memory).
  - name: My Data
    description: >-
      GDPR controls — personal-scope counts, async ZIP-by-email export, and
      scoped soft-delete. Every endpoint pins `user = req.user._id` AND
      `institution: null`; institution-scoped data is governed by the
      institution's own retention policy and never reached from here.
  - name: Questions
    description: >-
      User-facing read of the onboarding question bank used by the "create a
      digital twin" wizard.
  - name: Transcription
    description: >-
      One-shot speech-to-text for in-place dictation. Audio blob in, transcript
      out — no Upload / History / RAG embeddings are persisted. Use
      `/audio-notes` for anything durable.
paths:
  /api/ai/experimental/personal/qanda-v2:
    post:
      tags:
        - Conversation
      summary: >-
        Send a message to the AI assistant (experimental — Soul Document V2
        prompt)
      description: >
        Second-generation experimental variant of `/api/ai/personal/qanda`.

        Identical request / response contract to the V1 experimental endpoint,

        but uses the **Soul Document V2** prompt generator

        (`getSoulDocumentPromptV2` / `getSoulDocumentPromptV2Bypassed`) which

        refines the cohesive-anchor architecture introduced in V1. Used for

        three-way A/B testing alongside classic `/api/ai/personal/qanda` and

        the V1 experimental endpoint.


        Behavior is otherwise identical to
        `/api/ai/experimental/personal/qanda`:

        - Same `inputs[]` + `requestArgs` request shape (`QandARequest`).

        - Same Socket.IO streaming via optional `requestArgs.socketId`.

        - Same downstream middleware chain (`creditCheck`,
          `contentFilterCheck`, `creditPayment`, `saveToHistory`,
          `sendResponse`).
        - Same handler-level `User.findOne({_id})` re-load (the
          `resolveInstitution` middleware still runs upstream, but the
          handler operates on the freshly re-loaded user object).
        - `req.locals.experimental = true` and `req.locals.promptMode =
        'soul-v2'`
          are stamped on the history record so the A/B harness can distinguish
          V1 from V2 runs.

        See `docs/plans/2026-02-01-soul-document-experiment-design.md` and the

        three-way comparison runner in `test/soul-comparison/`.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/QandARequest'
            example:
              id: 1750660464754
              requestArgs:
                userISODate: '2025-06-23T06:34:24.754Z'
                userTimezone: America/New_York
                socketId: DhXE7OVjCtfUmDFTAAAB
                assistantId: 6856fa89cbafcff8d98680f5
                selectedCourse:
                  course_id: 1750532703472
                  course_name: Research Discussion
                  assistant:
                    _id: 6856fa89cbafcff8d98680f5
                ragOnly: false
                ragIgnore: false
              inputs:
                - What is machine learning?
              outputs: []
      responses:
        '200':
          description: AI response generated successfully (Soul Document V2 system prompt)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/QandAResponse'
              example:
                success: true
                streamingFailed: false
                outputs:
                  - Machine learning is a subset of artificial intelligence...
                usage: 1234
                credits: 5
                query_duration_ms: 2500
                model: gpt-4o
        '400':
          description: >-
            Invalid request — missing `inputs` array, empty prompt after
            join+trim, or missing body
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: >-
            Authentication required — missing `req.user._id` or user not found
            in database
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: >-
            Server error during AI processing (error captured in history and
            emailed with EXPERIMENTAL label)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - apiKeyAuth: []
components:
  schemas:
    QandARequest:
      type: object
      description: Request payload for AI Q&A conversation
      required:
        - inputs
      properties:
        id:
          type: number
          description: Client-generated request identifier (epoch timestamp)
          example: 1750660464754
        requestArgs:
          $ref: '#/components/schemas/RequestArgs'
        inputs:
          type: array
          items:
            type: string
          description: User messages to send to the AI
          example:
            - What is machine learning?
        outputs:
          type: array
          items:
            type: string
          description: Previous AI responses (for context continuity)
          example: []
    QandAResponse:
      type: object
      description: Response from AI Q&A conversation
      properties:
        success:
          type: boolean
          description: Whether the request completed successfully
        streamingFailed:
          type: boolean
          description: >-
            True if Socket.IO streaming failed (response still contains full
            output)
        streamingError:
          type: string
          description: Error message if streaming failed
        outputs:
          type: array
          items:
            type: string
          description: AI-generated response messages
        usage:
          type: number
          description: Total tokens consumed (input + output)
        credits:
          type: number
          description: Credits consumed for this request
        creditsUsed:
          type: number
          description: User's total credits consumed
        totalCredits:
          type: number
          description: User's remaining credit balance
        query_duration_ms:
          type: number
          description: Total processing time in milliseconds
        model:
          type: string
          description: AI model identifier used for generation
          example: gpt-4o
    ErrorResponse:
      type: object
      properties:
        success:
          type: boolean
          example: false
        message:
          type: string
          description: Human-readable error message
        error:
          type: string
          description: Technical error details
    RequestArgs:
      type: object
      description: Context arguments for AI conversation requests
      properties:
        userISODate:
          type: string
          format: date-time
          description: User's current timestamp in ISO 8601 format
          example: '2025-06-23T06:34:24.754Z'
        userTimezone:
          type: string
          description: User's IANA timezone identifier
          example: America/New_York
        userGPSCoordinates:
          $ref: '#/components/schemas/GPSCoordinates'
        socketId:
          type: string
          description: >-
            Socket.IO session ID for real-time streaming (required for Socket.IO
            mode)
          example: DhXE7OVjCtfUmDFTAAAB
        selectedCourse:
          $ref: '#/components/schemas/ConversationContext'
        ragOnly:
          type: boolean
          description: |
            Knowledge "Search Only" mode. When true (with retrieval on), Pria
            returns raw vault chunks instead of an LLM-rewritten answer.
            Orthogonal to `ragIgnore` / `kagMode`. Persisted as `ragOnlySearch`
            on the user profile.
          default: false
        ragIgnore:
          type: boolean
          description: |
            Knowledge "Disabled" mode. When true, retrieval is skipped entirely
            and the LLM answers from its training only. Takes precedence over
            `kagMode` and `ragOnly`.
          default: false
        kagMode:
          type: boolean
          description: |
            Knowledge "RAG + KAG Fusion" mode. When true with `ragIgnore=false`
            AND the user/institution is KAG-eligible, the knowledge-graph leg
            runs alongside the dense vector leg (merged via Reciprocal Rank
            Fusion). KAG is always an augmentation on top of RAG — there is
            no "KAG without RAG" mode. Sent on requestArgs; persisted as
            `ragKagMode` on the user profile.
          default: false
        institutionPublicId:
          type: string
          format: uuid
          description: >
            Specifies the digital twin (institution) to send the command to.

            The server validates that the authenticated user has a valid
            membership

            in the specified institution. When found, the user's active
            institution

            is switched to this institution in their profile data for the
            duration

            of the request.
          example: f831501f-b645-481a-9cbb-331509aaf8c1
        assistantId:
          type: string
          description: |
            MongoDB ObjectId of the assistant to use for this request.
            Takes priority over selectedCourse.assistant._id (legacy).
            If not provided, the assistant is resolved from selectedCourse or
            the most recent history record for the conversation.
          example: 6856fa89cbafcff8d98680f5
    GPSCoordinates:
      type: object
      description: Geographic location data from device
      properties:
        accuracy:
          type: number
          description: GPS accuracy in meters
          example: 21126.84
        latitude:
          type: number
          description: Latitude coordinate (-90 to 90)
          example: -21.282816
        longitude:
          type: number
          description: Longitude coordinate (-180 to 180)
          example: 55.4139648
        altitude:
          type: number
          nullable: true
          description: Altitude in meters above sea level
        altitudeAccuracy:
          type: number
          nullable: true
          description: Altitude accuracy in meters
        heading:
          type: number
          nullable: true
          description: Direction of travel in degrees (0-360)
        speed:
          type: number
          nullable: true
          description: Speed in meters per second
    ConversationContext:
      type: object
      description: Context for a conversation session (course/topic)
      properties:
        course_id:
          type: number
          description: Unique conversation/course identifier (epoch timestamp)
          example: 1750532703472
        course_name:
          type: string
          description: Display name for the conversation
          example: Research Project Discussion
        assistant:
          $ref: '#/components/schemas/AssistantReference'
        history_count:
          type: integer
          description: Number of dialogue entries in this conversation
          example: 15
        last_dialogue_date:
          type: string
          format: date-time
          description: Timestamp of most recent message
    AssistantReference:
      type: object
      description: Reference to an AI assistant for conversation context
      properties:
        _id:
          type: string
          description: Assistant unique identifier (MongoDB ObjectId)
          example: 6856fa89cbafcff8d98680f5
        name:
          type: string
          description: Assistant display name
          example: Research Assistant
  securitySchemes:
    apiKeyAuth:
      type: apiKey
      in: header
      name: x-access-token
      description: JWT token passed in x-access-token header

````