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

# Ask the agent a question

> Ask the agent a question from your backend and get a grounded answer — the same headless answerer that serves email, WhatsApp, Messenger and Instagram.

**Credential: workspace secret key (`sk_…`)**

<Warning>**This returns an answer, not a plan.** It cannot click, type, scroll or drive a UI — there is no browser on the server. It is deliberately not a server-side `/api/act`.

Anything that would need a live page **escalates**, exactly as it does on email and WhatsApp. A consumer that ignores the `escalate` branch has a latent bug.</Warning>

Answers are metered and consume credits like any other conversation turn, and the kill switch silences this endpoint along with every other channel.



## OpenAPI

````yaml /openapi/v1.json post /v1/answer
openapi: 3.1.0
info:
  title: Peeve API
  version: '2026-08-17'
  description: >-
    The `/v1` API. Server-to-server only — no CORS headers are sent, no `Origin`
    is checked, and publishable keys are rejected everywhere.


    Most endpoints take a **user token** (`pv_ut_…`), which carries its owner's
    live workspace role. `/v1/users` and `/v1/answer` take the **workspace
    secret key** (`sk_…`). The credential and the required role are stated on
    every operation — they are not uniform.
servers:
  - url: https://api.peeve.ai
security:
  - userToken: []
tags:
  - name: Sessions
    description: Agent conversations and their transcripts.
  - name: Contacts
    description: >-
      Everyone Peeve knows about: **users** your product identified, and
      anonymous **visitors**. Filter with `?kind=`.
  - name: Users
    description: Push your identified users into Peeve from your backend.
  - name: Ask
    description: Ask the agent a question from your backend and get a grounded answer.
  - name: Leads
    description: >-
      Visitors the agent qualified. Read and re-status only — capture happens
      through Peeve's own channels.
  - name: Meetings
    description: Meetings booked through the agent.
  - name: Hand-offs
    description: Escalations to a human, and their status.
  - name: Analytics
    description: Usage and satisfaction results.
  - name: Configuration
    description: Guardrails and the kill switch.
  - name: Webhooks
    description: >-
      Register and manage the endpoints Peeve delivers events to. Equivalent to
      the Connectors UI — an endpoint created here is the same row, with the
      same guarantees.
paths:
  /v1/answer:
    post:
      tags:
        - Ask
      summary: Ask the agent a question
      description: >-
        Ask the agent a question from your backend and get a grounded answer —
        the same headless answerer that serves email, WhatsApp, Messenger and
        Instagram.


        **Credential: workspace secret key (`sk_…`)**


        <Warning>**This returns an answer, not a plan.** It cannot click, type,
        scroll or drive a UI — there is no browser on the server. It is
        deliberately not a server-side `/api/act`.


        Anything that would need a live page **escalates**, exactly as it does
        on email and WhatsApp. A consumer that ignores the `escalate` branch has
        a latent bug.</Warning>


        Answers are metered and consume credits like any other conversation
        turn, and the kill switch silences this endpoint along with every other
        channel.
      operationId: answer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - message
              properties:
                message:
                  type: string
                  description: The question, in the end user's words.
                external_user_id:
                  type: string
                  description: >-
                    Your id for the person asking, so the answer is grounded in
                    who they are.
                conversation_id:
                  type: string
                  format: uuid
                  description: Continue an existing conversation. Omit to start one.
            example:
              message: How do I add a teammate?
              external_user_id: user_8412
      responses:
        '200':
          description: A discriminated union on `path`. **Handle both branches.**
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    title: answer
                    properties:
                      path:
                        type: string
                        const: answer
                      say:
                        type: string
                        description: The grounded answer.
                      conversation_id:
                        type: string
                        format: uuid
                  - type: object
                    title: escalate
                    properties:
                      path:
                        type: string
                        const: escalate
                      reason:
                        type: string
                        description: Why it could not be answered here.
                      conversation_id:
                        type: string
                        format: uuid
              examples:
                answered:
                  summary: Answered
                  value:
                    path: answer
                    say: You can add a teammate under Settings → Team.
                    conversation_id: 00000000-0000-4000-8000-000000000000
                escalated:
                  summary: Escalated — needs a human or a live page
                  value:
                    path: escalate
                    reason: needs a live page
                    conversation_id: 00000000-0000-4000-8000-000000000000
        '400':
          description: Malformed JSON, or `message` missing.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LegacyError'
              example:
                error: message is required
        '401':
          description: Not a valid secret key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LegacyError'
        '402':
          description: Out of credits.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LegacyError'
        '403':
          description: >-
            The workspace is not entitled to serve — kill switch, expired trial
            or lapsed subscription.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LegacyError'
              example:
                error: workspace_inactive
                reason: kill_switch
        '429':
          description: Rate limited.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LegacyError'
        '503':
          description: Could not open the conversation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LegacyError'
      security:
        - secretKey: []
components:
  schemas:
    LegacyError:
      type: object
      description: >-
        `/v1/users` and `/v1/answer` predate the envelope and return this flat
        shape.
      properties:
        error:
          type: string
        reason:
          type: string
  securitySchemes:
    userToken:
      type: http
      scheme: bearer
      description: >-
        A user token (`pv_ut_…`) as `Authorization: Bearer pv_ut_…`.
        `X-Peeve-Key` is accepted too. **Never a query parameter** — URLs end up
        in proxy logs and `Referer` headers.


        The token carries its owner's **live** workspace role, re-read on every
        call.
    secretKey:
      type: http
      scheme: bearer
      description: >-
        The workspace secret key (`sk_…`) as `Authorization: Bearer sk_…`.
        `X-Peeve-Key` is accepted too.

````