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

# Ask Evelin in a chat

> Only this API key or OAuth grant can access this chat. Requires current owner/admin membership. Chats retain a ceiling of the permissions granted at creation; added permissions require a new chat. Private app chats and other clients are isolated. External integrations such as Linear are unavailable. Starts asynchronous work using the existing AI credit policy. Poll get_evelin_chat_turn with the returned sessionId and id. Reuse the same idempotency key for uncertain retries. A failed turn can be retried using retryOfTurnId and a new key only while it is the latest turn. All changes need separate action confirmation; no messages are sent.

Ask a question or follow up in an existing chat. Poll the returned turn to read the answer.

See [Chat with Evelin](/mcp/evelin#chat-with-evelin) for setup, permissions, retries, and the full workflow.


## OpenAPI

````yaml POST /ai/assistant/sessions/{sessionId}/turns
openapi: 3.1.0
info:
  title: Protodesk API
  version: 0.1.0
  description: >
    The Protodesk Platform API: sync your customers in, attach your own business
    objects (orders, bookings, listings) to conversations, post and read
    messages across channels, and receive every workspace event via signed
    webhooks or a resumable SSE stream.


    Authenticate every request with a workspace-scoped API key: `Authorization:
    Bearer pk_...`. Operations that support retry protection document an
    `Idempotency-Key` header. Reuse it only with an identical request. List
    pagination is described on each endpoint.


    Task-oriented guides: [docs.protodesk.io](https://docs.protodesk.io).
servers:
  - url: https://api.protodesk.io/v1
    description: Production
  - url: http://localhost:8080/v1
    description: Local development
security: []
tags:
  - name: Evelin
    description: >-
      Human-owned AI connections using the existing Evelin runtime. Generation
      never sends a customer message.
  - name: Customers
    description: People or companies contacting a workspace across channels.
  - name: Conversations
    description: Customer conversations attached to channels and external business objects.
  - name: Messages
    description: Customer, agent, AI, system, and internal messages inside conversations.
  - name: Attachments
    description: Scoped file transfer for messages.
  - name: Channel identities
    description: >-
      The same customer across WhatsApp, email, chat, and more — linked
      identities per channel.
  - name: Statuses & priorities
    description: The workspace's conversation statuses and priority levels.
  - name: Assignments
    description: >-
      Who a conversation has been assigned to, over time. Assign via POST
      /conversations/{conversationId}/assign.
  - name: Webhooks
    description: Webhook subscriptions for receiving workspace events.
  - name: Realtime
    description: Server-sent event stream of workspace events.
  - name: API Keys
    description: Create, list, and revoke workspace API keys.
  - name: Account
    description: The workspace and scopes behind your API key.
  - name: System
    description: Service metadata and health endpoints.
paths:
  /ai/assistant/sessions/{sessionId}/turns:
    post:
      tags:
        - Evelin
      summary: Ask Evelin in a chat
      description: >-
        Only this API key or OAuth grant can access this chat. Requires current
        owner/admin membership. Chats retain a ceiling of the permissions
        granted at creation; added permissions require a new chat. Private app
        chats and other clients are isolated. External integrations such as
        Linear are unavailable. Starts asynchronous work using the existing AI
        credit policy. Poll get_evelin_chat_turn with the returned sessionId and
        id. Reuse the same idempotency key for uncertain retries. A failed turn
        can be retried using retryOfTurnId and a new key only while it is the
        latest turn. All changes need separate action confirmation; no messages
        are sent.
      operationId: ask_evelin
      parameters:
        - name: sessionId
          in: path
          required: true
          schema:
            type: string
            minLength: 1
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 8
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EvelinChatQuestion'
      responses:
        '202':
          description: Successful operation.
          content:
            application/json:
              schema:
                type: object
                required:
                  - data
                properties:
                  data:
                    $ref: '#/components/schemas/EvelinChatTurn'
        default:
          $ref: '#/components/responses/Error'
      security:
        - ApiKeyAuth: []
components:
  schemas:
    EvelinChatQuestion:
      example:
        question: Summarize this conversation and suggest the next step.
      type: object
      additionalProperties: false
      required:
        - question
      properties:
        question:
          type: string
          minLength: 1
          maxLength: 4000
        retryOfTurnId:
          type: string
          description: >-
            Retry only the latest failed turn, with its identical question and
            attachments.
        clarificationTurnId:
          type: string
          description: >-
            The preceding turn whose clarification is being answered; mutually
            exclusive with retryOfTurnId.
        approvalMode:
          type: string
          enum:
            - ask_before_changes
          default: ask_before_changes
        attachments:
          type: array
          maxItems: 4
          items:
            type: object
            additionalProperties: false
            required:
              - reference
              - filename
              - contentType
              - sizeBytes
            properties:
              reference:
                type: string
                description: >-
                  An existing workspace media reference; arbitrary URLs and
                  other workspaces are rejected.
              filename:
                type: string
              contentType:
                type: string
              sizeBytes:
                type: integer
                minimum: 1
    EvelinChatTurn:
      type: object
      required:
        - id
        - sessionId
        - conversationId
        - runId
        - status
        - question
        - createdAt
        - updatedAt
        - expiresAt
      properties:
        id:
          type: string
        sessionId:
          type: string
        conversationId:
          type: string
        runId:
          type: string
        status:
          type: string
        question:
          type: string
        approvalMode:
          type: string
        retryOfTurnId:
          type: string
        answer:
          type: object
          description: >-
            Completed answer with citations, draft proposals and
            actionProposals. Read the exact action proposal before confirming
            its id. An answer may be withheld if its retained sources are no
            longer accessible.
          additionalProperties: true
          properties:
            answer:
              type: string
              description: Answer text for the user.
            warnings:
              type: array
              items:
                type: string
            citations:
              type: array
              items:
                type: object
                additionalProperties: true
            proposals:
              type: array
              description: Draft suggestions, not executed changes.
              items:
                type: object
                additionalProperties: true
            actionProposals:
              type: array
              items:
                type: object
                additionalProperties: true
                properties:
                  id:
                    type: string
                    description: Use this exact ID for confirmation after user review.
                  type:
                    type: string
                  target:
                    type: object
                    additionalProperties: true
                  before:
                    type: object
                    additionalProperties: true
                  after:
                    type: object
                    additionalProperties: true
                  confirmationRequired:
                    type: boolean
        actionConfirmations:
          type: array
          items:
            $ref: '#/components/schemas/EvelinActionReceipt'
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
        expiresAt:
          type: string
          format: date-time
    EvelinActionReceipt:
      type: object
      description: >-
        Durable receipt of the exact proposed change; check its target, before,
        after and undo status.
      required:
        - id
        - proposalId
        - runId
        - effectId
        - type
        - target
        - before
        - after
        - confirmedAt
      properties:
        id:
          type: string
        proposalId:
          type: string
        runId:
          type: string
        effectId:
          type: string
        type:
          type: string
        target:
          type: object
          additionalProperties: true
        before:
          type: object
          additionalProperties: true
        after:
          type: object
          additionalProperties: true
        confirmedAt:
          type: string
          format: date-time
        undo:
          type: object
          properties:
            status:
              type: string
              enum:
                - available
                - changed
                - unavailable
                - undone
            undoneAt:
              type: string
              format: date-time
    ErrorEnvelope:
      type: object
      required:
        - error
      properties:
        error:
          $ref: '#/components/schemas/Error'
    Error:
      type: object
      required:
        - code
        - message
        - requestId
      properties:
        code:
          type: string
          example: route.not_found
        message:
          type: string
          example: Not found
        requestId:
          type: string
          example: req_x6q5vl75f5d53m7oet2k4r5w6a
  responses:
    Error:
      description: >-
        Error response. All /v1 responses carry RateLimit-Limit,
        RateLimit-Remaining, and RateLimit-Reset headers. A 429
        (rate_limit.exceeded) additionally carries Retry-After. Request bodies
        exceeding the route-class limit (1KB reads, 64KB writes) return 413
        (request.body_too_large).
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
        RateLimit-Limit:
          $ref: '#/components/headers/RateLimitLimit'
        RateLimit-Remaining:
          $ref: '#/components/headers/RateLimitRemaining'
        RateLimit-Reset:
          $ref: '#/components/headers/RateLimitReset'
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
  headers:
    RequestId:
      description: Request id for tracing this request in logs and support.
      schema:
        type: string
        example: req_x6q5vl75f5d53m7oet2k4r5w6a
    RateLimitLimit:
      description: >-
        Request budget for the route class (read or write) applied to this
        request.
      schema:
        type: integer
        example: 40
    RateLimitRemaining:
      description: Requests remaining in the current budget after this request.
      schema:
        type: integer
        example: 39
    RateLimitReset:
      description: Seconds until the budget refills to its full limit.
      schema:
        type: integer
        example: 1
    RetryAfter:
      description: Seconds to wait before retrying, sent with 429 responses.
      schema:
        type: integer
        example: 1
  securitySchemes:
    ApiKeyAuth:
      type: http
      scheme: bearer
      bearerFormat: Protodesk API key
      description: >
        Use a workspace API key in the Authorization header: Bearer pk_....
        Older pk_live_ and pk_test_ keys remain valid; their prefixes do not
        isolate data or select a separate environment.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.