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

# Decide a request

> Approves or denies one of the conversation’s `approval` items, or answers a `question` item, as your team (the API key, or the member signed in). Send exactly one of `approval`, `answer` or `action`. No agent is named, so it works in any conversation, including the one a task run without an agent gets. The decision reaches the task waiting on it, and a reply paused for it (`requires_action`) carries on by itself: follow it with GET /v1/responses/{response_id}, or decide with POST /v1/agents/{agent_id}/responses to stream it instead. Answers at once, with the request as decided. 409 with `code: already_decided` and `decided_by` when someone decided first, or `not_pending` when its task has ended, so nothing would act on it.



## OpenAPI

````yaml /api-reference/openapi.json post /v1/conversations/{conversation_id}/decisions
openapi: 3.1.0
info:
  title: Eager API
  version: 1.0.0
  description: >-
    Train AI agents like new hires: hand an agent your files and coach it, and
    it writes its own procedures and works in any software, even without an API.
    Talk to your agents one message at a time (POST
    /v1/agents/{agent_id}/responses): they answer from their files, procedures
    and your HTTP tools, and run tasks on their own cloud browser or your linked
    computers when an answer needs a website or a desktop app. Manage agents
    (versioned: save a draft, publish it), their procedures, browser and
    computers; follow conversations and tasks, answer approvals, and fetch
    history and recordings. Run tasks yourself on a session: a customer’s
    computer through an invite link, or a cloud browser. Test agents with evals:
    chat, browser and desktop test cases, run several times against your agents
    and judged on the answer. Every change is in the org’s audit log.
servers:
  - url: https://guidinghand.ai
    description: Production
  - url: https://dev.guidinghand.ai
    description: Development (Stripe test mode)
security:
  - bearerAuth: []
tags:
  - name: Agents
  - name: Agent files
  - name: Agent tools
  - name: Agent folders
  - name: Computers
    description: >-
      Computers your org links with the Eager app, and pools of them, for
      agents’ desktop tasks. Attach them to an agent in its
      `resources.computers`.
  - name: Phone numbers
    description: >-
      Bring your own Twilio numbers: connect the account, add its numbers, and
      pick the agent that answers each. Calls are answered by the agent's
      published version.
  - name: Sessions
  - name: Tasks
  - name: Webhooks
  - name: Audit log
  - name: Test cases
  - name: Test sets
  - name: Test runs
  - name: Start states
  - name: Runners
  - name: Responses
    description: >-
      Talk to an agent: each call is one turn of a conversation. The agent
      answers with its files, procedures and tools (and, with Run code, its own
      sandbox), asks for details with forms, and runs browser and desktop tasks
      when an answer needs a website or a desktop app.
  - name: Conversations
    description: >-
      The history of each conversation: messages, tool calls and the tasks the
      agent started, in order.
  - name: Uploads
    description: >-
      Files for conversations: attach them to a message, and download what the
      agent’s code made. Kept as long as their conversation.
  - name: Procedures
    description: >-
      An agent’s playbooks: when to use each and its steps. The agent finds and
      follows them; ones it writes from a first run are marked written_by:
      agent.
  - name: Categories
    description: The kinds of request an org’s procedures and test cases are sorted into.
  - name: Escalations
    description: >-
      What needs your team: an approval only the team can give or a question
      only it can answer, in a real conversation; a procedure run that failed;
      and one that worked another way, with the procedure rewritten to match (a
      proposed change). Test chats never escalate; evals do, without webhooks.
  - name: Schedules
    description: >-
      Run an agent’s procedure on a cron expression, in a time zone, with the
      inputs it needs. Each run is a conversation of its own with nobody in it
      (`channel` `schedule` in its variables): the procedure’s steps without AI
      run outright when it has them, else the model follows it to its end. Its
      record says how it ended, what the agent said last and what it cost; the
      team hears by webhook (`schedule.run_completed`, `schedule.run_failed`),
      email and Slack or Teams, as the schedule says.
paths:
  /v1/conversations/{conversation_id}/decisions:
    parameters:
      - name: conversation_id
        in: path
        required: true
        description: The conversation’s id.
        schema:
          type: string
    post:
      tags:
        - Conversations
      summary: Decide a request
      description: >-
        Approves or denies one of the conversation’s `approval` items, or
        answers a `question` item, as your team (the API key, or the member
        signed in). Send exactly one of `approval`, `answer` or `action`. No
        agent is named, so it works in any conversation, including the one a
        task run without an agent gets. The decision reaches the task waiting on
        it, and a reply paused for it (`requires_action`) carries on by itself:
        follow it with GET /v1/responses/{response_id}, or decide with POST
        /v1/agents/{agent_id}/responses to stream it instead. Answers at once,
        with the request as decided. 409 with `code: already_decided` and
        `decided_by` when someone decided first, or `not_pending` when its task
        has ended, so nothing would act on it.
      operationId: decideInConversation
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              description: Exactly one of `approval`, `answer` or `action`.
              properties:
                approval:
                  type: object
                  description: >-
                    Approves or denies an `approval` item of the conversation
                    (its `approval_id`).
                  required:
                    - approval_id
                    - decision
                  properties:
                    approval_id:
                      type: string
                    decision:
                      type: string
                      enum:
                        - approve
                        - deny
                    note:
                      type: string
                      maxLength: 500
                      description: 'For the agent: why, or what to do instead.'
                answer:
                  type: object
                  description: >-
                    Answers a `question` item of the conversation (its
                    `question_id`).
                  required:
                    - question_id
                    - answer
                  properties:
                    question_id:
                      type: string
                    answer:
                      type: string
                      maxLength: 4000
                action:
                  type: object
                  description: >-
                    An A2UI action on a request’s surface (the item’s
                    `surface_id`), as a renderer sends it (or wrapped as `{
                    version: "v0.9", action }`): on an `approval` item’s, `name`
                    is `approve` or `deny` (and `context.note`, if any, the
                    note); on a `question` item’s, its form’s `submit`
                    (`context: { answer: ["<option>"] }`, or `{ answer: "<text>"
                    }` with no options).
                  properties:
                    name:
                      type: string
                      enum:
                        - submit
                        - approve
                        - deny
                    surfaceId:
                      type: string
                    context:
                      type: object
                  required:
                    - surfaceId
      responses:
        '200':
          description: The request, decided.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Decision'
        '400':
          $ref: '#/components/responses/E400'
        '401':
          $ref: '#/components/responses/E401'
        '404':
          description: No such conversation in this org, or no such request in it.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '409':
          description: >-
            Someone decided (or answered) it first: `code: already_decided`,
            with `decided_by`. Or its task has ended: `code: not_pending`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  schemas:
    Decision:
      type: object
      description: >-
        A request decided (POST /v1/conversations/{conversation_id}/decisions,
        or the responses route when no reply was paused for it): the approval or
        question as it is now.
      properties:
        object:
          const: decision
        approval:
          $ref: '#/components/schemas/Approval'
        question:
          $ref: '#/components/schemas/Question'
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - type
            - message
          properties:
            type:
              type: string
              enum:
                - invalid_request
                - authentication
                - payment_required
                - permission
                - not_found
                - conflict
                - rate_limit
                - server_error
            message:
              type: string
            code:
              type: string
              description: >-
                Why it was refused, when there’s more to say than the status.
                Starting a task or a chat reply: `insufficient_balance`,
                `auto_topup_limit_reached` or `card_needs_attention` (402: the
                balance is empty and auto top-up can’t add funds; add funds,
                raise the auto top-up limit, or update the card),
                `concurrency_limit` (429), `model_unavailable` (503: the agent’s
                `model` can’t run on this server; choose another). Deciding a
                conversation’s request: `already_decided` (409: someone decided
                or answered it first; see `decided_by`) or `not_pending` (409:
                its task has ended, so nothing would act on it). POST
                /v1/tasks/{task_id}/respond: `decide_in_conversation` (409:
                decide it in the task’s conversation; see `conversation_id`,
                `agent_id`, and `approval_id` or `question_id`). Deleting a
                start state that test cases use: `in_use` (409, with
                `test_case_ids`).
            test_case_ids:
              type: array
              items:
                type: string
              description: 'With `in_use`: the test cases that use the start state.'
            decided_by:
              description: 'With `already_decided`: who decided first.'
              allOf:
                - $ref: '#/components/schemas/Decider'
            conversation_id:
              type: string
              description: >-
                With `decide_in_conversation`: the conversation to decide it in
                (POST /v1/conversations/{conversation_id}/decisions).
            agent_id:
              type:
                - string
                - 'null'
              description: >-
                With `decide_in_conversation`: the task’s agent (null for a task
                run without one).
            approval_id:
              type: string
              description: 'With `decide_in_conversation`: the approval to decide.'
            question_id:
              type: string
              description: 'With `decide_in_conversation`: the question to answer.'
    Approval:
      type: object
      description: >-
        A request for a yes before something runs: a task from a procedure whose
        Approval is on (`scope: run`), an HTTP tool with `approval: "always"`,
        or one guarded step of a task (`scope: step`). Described by Eager, never
        by the model. Open while `decision` is null; the first decision counts.
      properties:
        approval_id:
          type: string
          example: apr_…
        scope:
          type: string
          enum:
            - run
            - step
          description: '`run`: a whole task (or a tool call). `step`: one step of a task.'
        action:
          type: string
          description: What will happen, in Eager’s words.
        source:
          type:
            - string
            - 'null'
          enum:
            - guardrail
            - safety_check
            - screen_check
            - tool
            - agent
            - null
          description: >-
            What asked for a step’s approval: the agent’s guardrails, its model
            maker’s safety check, the screen check, a tool, or `agent` (the
            task’s own model asked, so `action` is in its words). Null for a
            run’s.
        site:
          type:
            - string
            - 'null'
        app:
          type:
            - string
            - 'null'
        category:
          type:
            - string
            - 'null'
          description: A step’s "Ask first" category (see `GuardrailCategory`).
        risk:
          type:
            - string
            - 'null'
        task_id:
          type:
            - string
            - 'null'
          description: The task it’s for, once there is one.
        procedure_id:
          type:
            - string
            - 'null'
          description: The procedure whose Approval asked for it.
        by:
          type: string
          enum:
            - anyone
            - team
          description: >-
            `anyone`: the person in the chat (when the agent lets them approve)
            or your team. `team`: only your team.
        who:
          type:
            - string
            - 'null'
          description: Who signs off, as the procedure says (a label, not a permission).
        note:
          type:
            - string
            - 'null'
          description: What to check or bring, from the procedure.
        covers:
          type: array
          items:
            $ref: '#/components/schemas/GuardrailCategory'
          description: >-
            A run’s: the "Ask first" categories its task may then do without
            asking again, as they were when it was asked. The surface says so.
        surface_id:
          type: string
          description: Its A2UI surface’s id (`srf_…`), for an `action` that decides it.
        a2ui:
          type: array
          items:
            type: object
          description: >-
            The request as A2UI v0.9 messages: what will happen, what else it
            allows, who signs off, the note, and Approve and Deny buttons (their
            actions are named `approve` and `deny`).
        decision:
          type:
            - object
            - 'null'
          description: Null while it’s open.
          properties:
            decision:
              type: string
              enum:
                - approve
                - deny
            note:
              type: string
              description: The decider’s note to the agent, if any.
            by:
              $ref: '#/components/schemas/Decider'
            at:
              type: string
              format: date-time
    Question:
      type: object
      description: >-
        A question a task asks, drawn as a form: a choice from `options` (or
        something else), or short text. Open while `answer` is null; the first
        answer counts.
      properties:
        question_id:
          type: string
          example: qst_…
        task_id:
          type:
            - string
            - 'null'
        question:
          type: string
        options:
          type: array
          items:
            type: string
        surface_id:
          type: string
          description: Its form’s id (`srf_…`), for an `action` that answers it.
        a2ui:
          type: array
          items:
            type: object
          description: >-
            The form as A2UI v0.9 messages; its one field is `answer` (and
            `answer_other`, for something else).
        answer:
          type:
            - object
            - 'null'
          description: Null while it’s open.
          properties:
            text:
              type: string
            by:
              $ref: '#/components/schemas/Decider'
            at:
              type: string
              format: date-time
    Decider:
      type: object
      description: Who decided a request, or answered a question.
      required:
        - type
      properties:
        type:
          type: string
          enum:
            - person
            - team
            - auto
            - refused
            - timeout
            - operator
            - moved_on
          description: >-
            `person`: the person in the chat (in the Eager app, or a visitor to
            your website’s widget), when the agent lets them
            (`customer_approvals`, `customer_answers`) and the request isn’t for
            your team only. `team`: a member in the console (`email`) or an API
            key (`key_id`). `auto`: the agent’s guardrails approve without
            asking (`mode: auto`). `refused`: its guardrails refuse (`mode:
            unattended`). `timeout`: nobody decided within its
            `approval_timeout_minutes`. `operator`: an eval case’s operator.
            `moved_on`: the person sent a new message instead, so it was
            declined.
        email:
          type: string
          description: '`team`: the member who decided.'
        key_id:
          type: string
          description: '`team`: the API key that decided.'
    GuardrailCategory:
      type: string
      enum:
        - purchase
        - send
        - delete
        - install
        - security
        - terms
      description: >-
        `purchase`: buying or paying. `send`: sending, posting or submitting.
        `delete`: deleting or removing. `install`: installing software.
        `security`: security and account settings. `terms`: accepting terms or
        agreements.
  responses:
    E400:
      description: The request is invalid.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    E401:
      description: Missing or invalid API key.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: An org API key (`gh_live_…`) from Settings → API keys in the console.

````

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