> ## 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.

# Add or change procedures

> Makes and changes up to 50 procedures at once, each with the test cases that check it (up to 20 each, 500 in all). All of them are saved, or none: the first that can’t be saved says why (`procedures[1]: …`). With `test_set_id`, also adds every case to that test set. The body can be up to 8 MB. Needs the admin role or an API key.



## OpenAPI

````yaml /api-reference/openapi.json post /v1/agents/{agent_id}/procedures/batch
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/agents/{agent_id}/procedures/batch:
    parameters:
      - name: agent_id
        in: path
        required: true
        description: The agent’s id.
        schema:
          type: string
    post:
      tags:
        - Procedures
      summary: Add or change procedures
      description: >-
        Makes and changes up to 50 procedures at once, each with the test cases
        that check it (up to 20 each, 500 in all). All of them are saved, or
        none: the first that can’t be saved says why (`procedures[1]: …`). With
        `test_set_id`, also adds every case to that test set. The body can be up
        to 8 MB. Needs the admin role or an API key.
      operationId: batchProcedures
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - procedures
              properties:
                procedures:
                  type: array
                  minItems: 1
                  maxItems: 50
                  items:
                    type: object
                    description: >-
                      A procedure to make (no `id`: `title`, `use_when` and
                      `instructions` (or `body`) are required) or to change
                      (`id`: only the fields sent change).
                    properties:
                      id:
                        type: string
                        description: >-
                          The procedure to change (prc_…). Leave it out to make
                          one.
                      revision:
                        type: integer
                        description: >-
                          With `id`: change it only while it is at this revision
                          (409 otherwise).
                      title:
                        type: string
                      use_when:
                        type: string
                      inputs:
                        type: array
                        items:
                          $ref: '#/components/schemas/ProcedureInput'
                        maxItems: 20
                      goal:
                        type: string
                        description: >-
                          What done looks like. Markdown. Links the agent’s
                          tools as `[[tool:<id or name>]]` and its other
                          procedures as `[[procedure:<id or title>]]` (kept by
                          id, so renaming either keeps the link; a tool a
                          procedure links is unlocked with it), and uses an
                          input as `{name}`.
                      context:
                        type: string
                        maxLength: 10000
                        description: >-
                          Background, policy, definitions and notes the steps
                          rely on that aren’t steps themselves; the model reads
                          it before the steps. Markdown. Links the agent’s tools
                          as `[[tool:<id or name>]]` and its other procedures as
                          `[[procedure:<id or title>]]` (kept by id, so renaming
                          either keeps the link; a tool a procedure links is
                          unlocked with it), and uses an input as `{name}`.
                      instructions:
                        type: string
                        description: >-
                          The steps as one numbered Markdown list (`steps` is
                          the same as a list). Sent instead of `steps`, it’s
                          read into steps: one per item, sub-points under their
                          step; prose before step 1 or after the last one joins
                          `context`. Markdown. Links the agent’s tools as
                          `[[tool:<id or name>]]` and its other procedures as
                          `[[procedure:<id or title>]]` (kept by id, so renaming
                          either keeps the link; a tool a procedure links is
                          unlocked with it), and uses an input as `{name}`.
                      steps:
                        type: array
                        maxItems: 100
                        items:
                          oneOf:
                            - type: string
                              description: The step’s text (Markdown).
                            - $ref: '#/components/schemas/ProcedureStepInput'
                        description: >-
                          The steps, in order: each its text, or `{ id, text }`
                          to keep a step’s id (as the procedure gives them
                          back). A step sent as text keeps the id of a step it
                          had with the same text, or of the step it replaces.
                          Not with `instructions` or `body`. A step that links
                          another procedure (`[[procedure:<id or title>]]`)
                          calls it as a subprocedure.
                      checks:
                        type: string
                        description: >-
                          What to confirm before answering, as a list. Markdown.
                          Links the agent’s tools as `[[tool:<id or name>]]` and
                          its other procedures as `[[procedure:<id or title>]]`
                          (kept by id, so renaming either keeps the link; a tool
                          a procedure links is unlocked with it), and uses an
                          input as `{name}`.
                      body:
                        type: string
                        description: >-
                          The whole text instead of its parts (not with them):
                          split into them by its `## Inputs`, `## Goal`, `##
                          Context`, `## Instructions` and `## Checks` headings
                          (or its trailing “Check:” lines), with tool names and
                          quoted procedure titles linked. The parts together are
                          up to 20,000 characters.
                      status:
                        type: string
                        enum:
                          - active
                          - draft
                      kind:
                        type: string
                        enum:
                          - browser
                          - desktop
                          - chat
                      tools:
                        type: array
                        items:
                          type: string
                        description: >-
                          Up to 10 of the agent’s HTTP tools, by name (of its
                          published version). Each stays locked in a task until
                          the agent reads this procedure. The whole list: []
                          detaches them all.
                        maxItems: 10
                      approval:
                        oneOf:
                          - $ref: '#/components/schemas/ProcedureApproval'
                          - type: 'null'
                        description: >-
                          Ask a person in the conversation before a task follows
                          this procedure. `null` or `{ "required": false }`
                          turns it off. The whole setting: fields left out take
                          their defaults.
                      model:
                        type:
                          - string
                          - 'null'
                        enum:
                          - claude-haiku-5-5
                          - claude-sonnet-5-5
                          - claude-opus-5-5
                          - claude-fable-5-1
                          - gpt-6-luna
                          - gpt-6.1-sol
                          - gpt-6-astra
                          - gemini-3.8-flash
                          - gemini-4-argon
                          - null
                        description: >-
                          The model this procedure runs on instead of the
                          agent's (one of the agent `model` values), or `null`
                          for the agent's own. Once a chat reads the procedure,
                          the rest of the conversation runs on this model; a
                          browser or computer task that follows it does too. An
                          eval run that tries the agent on models it picked
                          keeps those. Changing it makes a new revision.
                      plan_mode:
                        type: string
                        enum:
                          - 'off'
                          - test
                          - live
                        description: >-
                          Steps without AI: `off`, `test` (evals and test chats
                          only) or `live`. Turning it on compiles a chat
                          procedure (or records a browser one's next run); it
                          doesn't make a new revision.
                      category:
                        type:
                          - string
                          - 'null'
                        maxLength: 100
                        description: >-
                          The kind of request it's for, from the same set as the
                          test cases' `category` (the eval charts group pass
                          rates by it), or `null` for none. Spelled as a test
                          case or procedure in the org already has it, whatever
                          its capitals. Its test cases are always in it (a
                          `category` sent for one is ignored), and move with it
                          when it changes. Changing only the category makes no
                          new revision. Up to 100 characters.
                      test_cases:
                        type: array
                        maxItems: 20
                        items:
                          $ref: '#/components/schemas/TestCaseInput'
                        description: >-
                          Test cases that check this procedure, tied to it (any
                          `procedure_id` they give is ignored). Each is created,
                          or replaced when its `key` is one you have.
                      file_access:
                        type: string
                        enum:
                          - read_only
                          - read_write
                        description: >-
                          Whether the agent may create, change and delete its
                          own files (write_file, edit_file, delete_file, and
                          with Run code save_sandbox_file, which keeps a file
                          its code made) while a conversation follows this
                          procedure: the one it last read, found or ran on its
                          steps, or a schedule's. `read_only` (the default)
                          keeps them read-only, as everywhere else. Checked on
                          every change, so turning it off holds at once. A test
                          chat's or an eval's changes go to that conversation's
                          own copy, never the real files. Every change keeps the
                          version it replaced (`GET
                          /v1/agents/{agent_id}/file_revisions`). Changing it
                          doesn't make a new revision.
                test_set_id:
                  type: string
                  description: Also add the cases to this test set.
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  object:
                    type: string
                    enum:
                      - list
                  data:
                    type: array
                    description: >-
                      The procedures, in the order sent, each with the test
                      cases sent with it.
                    items:
                      allOf:
                        - $ref: '#/components/schemas/Procedure'
                        - type: object
                          properties:
                            test_cases:
                              type: array
                              items:
                                $ref: '#/components/schemas/TestCase'
                  created:
                    type: integer
                  updated:
                    type: integer
                  unchanged:
                    type: integer
                    description: Procedures sent by `id` that the batch left as they were.
                  test_cases:
                    type: object
                    properties:
                      created:
                        type: integer
                      updated:
                        type: integer
        '400':
          description: Invalid request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '409':
          description: >-
            A procedure is not at the `revision` sent, or the agent would have
            more than 500 procedures.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  schemas:
    ProcedureInput:
      type: object
      description: >-
        Something the procedure needs before it starts. Its text uses it as
        `{name}`; one it uses that isn’t listed is added as required text.
      required:
        - name
      properties:
        name:
          type: string
          pattern: ^[a-z][a-z0-9_]{0,39}$
        type:
          type: string
          enum:
            - text
            - number
            - date
            - email
            - phone
            - url
            - country
            - choice
            - yes_no
          default: text
        description:
          type: string
          maxLength: 300
        required:
          type: boolean
          default: true
        options:
          type: array
          items:
            type: string
          description: A `choice`’s choices.
        example:
          type: string
    ProcedureStepInput:
      type: object
      required:
        - text
      properties:
        id:
          type: string
          description: The id of a step it had, to keep it; left out for a new step.
        text:
          type: string
          maxLength: 4000
    ProcedureApproval:
      type: object
      description: >-
        A person must say yes in the conversation before a task follows this
        procedure. Sending `required: false` (or `null`) turns it off.
      properties:
        required:
          type: boolean
          description: >-
            Always `true` in what the API returns; send `false` to turn the
            approval off.
        by:
          type: string
          enum:
            - anyone
            - team
          default: anyone
          description: >-
            `anyone`: the person in the chat (when the agent lets them approve)
            or the team. `team`: only the team.
        who:
          type: string
          maxLength: 60
          default: ''
          description: >-
            Who signs off, shown on the request, like "services specialist". A
            label, not a permission.
        covers:
          type: array
          items:
            type: string
            enum:
              - purchase
              - send
              - delete
              - install
              - security
              - terms
          default: []
          description: >-
            Which of the agent’s "Ask first" categories the approval covers:
            once it is given, the task’s steps in those categories go ahead
            without asking again.
        note:
          type: string
          maxLength: 500
          default: ''
          description: What to check or bring, shown on the request.
      required:
        - required
    TestCaseInput:
      type: object
      required:
        - name
        - prompt
      properties:
        key:
          type:
            - string
            - 'null'
          pattern: ^(?!tc_)[A-Za-z0-9._-]{1,64}$
          example: DSP-01
          description: >-
            Your own id for the case, unique in the org: 1 to 64 of
            `A-Za-z0-9._-`, not starting with `tc_`. Every `{test_case_id}` in
            the API also takes it.
        name:
          type: string
          minLength: 1
          maxLength: 200
          example: Apps switched to dark mode
        prompt:
          type: string
          minLength: 1
          maxLength: 8000
          example: All my windows suddenly went black. How do I get the white back?
          description: >-
            Chat cases: the person’s first message. Browser and machine cases:
            the task’s prompt.
        start_state:
          type: string
          example: win10-22h2
          description: >-
            Desktop machine cases (required for them): the machine each try
            starts from. Null for chat and browser cases.
        setup_script:
          anyOf:
            - type:
                - string
                - 'null'
              maxLength: 100000
              description: >-
                Runs at the start of every try, elevated, as the signed-in user:
                it breaks the machine the way the case needs.
            - $ref: '#/components/schemas/ScriptBase64'
          description: >-
            Runs at the start of every try, elevated, as the signed-in user: it
            breaks the machine the way the case needs.
        success:
          type: object
          properties:
            check_script:
              anyOf:
                - type:
                    - string
                    - 'null'
                  maxLength: 100000
                  description: >-
                    Runs on the machine (elevated, as the signed-in user) and
                    prints `True` once the problem is fixed. It must print
                    `False` before the task, or the attempt is an `error`. The
                    agent’s final answer is in the `GH_AGENT_ANSWER` environment
                    variable, and `GH_CHECK_PHASE` is `before` or `after` the
                    task.
                - $ref: '#/components/schemas/ScriptBase64'
              description: >-
                Runs on the machine (elevated, as the signed-in user) and prints
                `True` once the problem is fixed. It must print `False` before
                the task, or the attempt is an `error`. The agent’s final answer
                is in the `GH_AGENT_ANSWER` environment variable, and
                `GH_CHECK_PHASE` is `before` or `after` the task.
            rubric:
              type:
                - string
                - 'null'
              maxLength: 8000
              description: >-
                What a fix looks like, in plain language. A model judges it from
                the recorded conversation and the first and last screens.
          description: >-
            How to tell the problem is fixed: a `check_script`, a `rubric`, or
            both (an attempt passes only when each one it has passes). At least
            one.
        customer:
          oneOf:
            - $ref: '#/components/schemas/Customer'
            - type: 'null'
          description: >-
            The simulated customer. Null: the test set’s `customer`, else a
            built-in default.
        operator:
          type: object
          properties:
            approvals:
              type: string
              enum:
                - approve
                - deny
              description: How the agent’s approval requests are decided during the test.
        limits:
          type: object
          properties:
            minutes:
              type: integer
              minimum: 1
              maximum: 60
              default: 10
              description: The task is stopped after this many minutes (1 to 60).
            steps:
              type:
                - integer
                - 'null'
              minimum: 1
              maximum: 500
              description: >-
                Model turns (1 to 500). Null: the agent’s own
                `guardrails.max_steps`.
        runs_on:
          type: string
          example: vm
          description: >-
            `chat`: a conversation with the agent, on Eager’s servers.
            `browser`: one task on a fresh cloud browser from `start_url`. `vm`
            (the default), or one of your runners’ labels: a desktop machine.
            Chat and browser cases are judged on the answer (`expected`,
            `success.rubric`) and whether it’s grounded; machine cases on
            `success.check_script` and/or the rubric.
        category:
          type:
            - string
            - 'null'
          example: Display & graphics
        tags:
          type: array
          items:
            type: string
            maxLength: 64
          maxItems: 50
          example:
            - uac
        metadata:
          $ref: '#/components/schemas/Metadata'
        must_visit:
          type: array
          maxItems: 10
          items:
            type: string
          description: >-
            Chat and browser cases: sites the answer must come from, by host
            (`a.com|b.com` for either; subdomains count). An attempt that didn’t
            open one in a browser task fails, whatever the judge said.
          example:
            - support.example.com|docs.example.com
        expected:
          type:
            - string
            - 'null'
          maxLength: 2000
          description: >-
            Chat and browser cases: the right answer, in plain words. The judge
            passes an answer that has its facts. A chat or browser case needs
            `expected`, a rubric, or both.
        messages:
          type: array
          maxItems: 10
          items:
            type: string
            maxLength: 8000
          description: >-
            Chat cases: follow-up messages, sent in order after the prompt, each
            once the agent has replied.
        start_url:
          type:
            - string
            - 'null'
          format: uri
          description: 'Browser cases: where the browser opens.'
        procedure_id:
          type:
            - string
            - 'null'
          description: >-
            The procedure this case checks (`prc_…`, one of the agent's
            procedures). The procedure then shows its evals: its latest run of
            them, and whether that run tested its current revision.
          example: prc_4mJx0aQe1
        inputs:
          type: array
          maxItems: 50
          items:
            type: object
            maxProperties: 20
            additionalProperties:
              type: string
              maxLength: 1000
          description: >-
            Sets of values for the case's `{placeholders}` (a procedure's
            dynamic variables, like `{mtm}`): names are letters, digits and `_`.
            Each set runs as its own tries (a run's tries per case are
            multiplied by the sets): `{name}` in `prompt`, `messages`,
            `expected`, `success.rubric` and `start_url` is filled from the set,
            and the simulated customer knows the set as facts.
          example:
            - mtm: 20XW
              region: UK
            - mtm: 21DE
              region: US
        objects:
          type: array
          items:
            type: string
          description: >-
            Ids of the AI ontology's objects (types and kinds) the case
            exercises, like `device` or `post_warranty`. Left out, the ontology
            fills it in within a minute: from the procedure the case is tied to,
            else by reading the case. Results of a run are also grouped by them
            (`by_object`).
      description: >-
        Send `start_state` and `success` for a desktop machine case; `expected`
        and/or `success.rubric` for a chat or browser case.
    Procedure:
      type: object
      properties:
        object:
          const: procedure
        id:
          type: string
          example: prc_…
        agent_id:
          type: string
        title:
          type: string
          maxLength: 120
        use_when:
          type: string
          maxLength: 500
        inputs:
          type: array
          items:
            $ref: '#/components/schemas/ProcedureInput'
          maxItems: 20
          description: Left out of lists.
        goal:
          type: string
          description: >-
            What done looks like. Markdown. Links the agent’s tools as
            `[[tool:<id or name>]]` and its other procedures as `[[procedure:<id
            or title>]]` (kept by id, so renaming either keeps the link; a tool
            a procedure links is unlocked with it), and uses an input as
            `{name}`. Left out of lists.
        context:
          type: string
          maxLength: 10000
          description: >-
            Background, policy, definitions and notes the steps rely on that
            aren’t steps themselves; the model reads it before the steps.
            Markdown. Links the agent’s tools as `[[tool:<id or name>]]` and its
            other procedures as `[[procedure:<id or title>]]` (kept by id, so
            renaming either keeps the link; a tool a procedure links is unlocked
            with it), and uses an input as `{name}`. Left out of lists.
        instructions:
          type: string
          description: >-
            The steps as one numbered Markdown list (`steps` is the same as a
            list). Sent instead of `steps`, it’s read into steps: one per item,
            sub-points under their step; prose before step 1 or after the last
            one joins `context`. Markdown. Links the agent’s tools as
            `[[tool:<id or name>]]` and its other procedures as `[[procedure:<id
            or title>]]` (kept by id, so renaming either keeps the link; a tool
            a procedure links is unlocked with it), and uses an input as
            `{name}`. Left out of lists.
        steps:
          type: array
          items:
            $ref: '#/components/schemas/ProcedureStep'
          description: >-
            The steps, in order, each with an id that stays with it when steps
            are added, moved or edited. A step that links another procedure
            calls it: a subprocedure, which runs as it’s set up (its own steps,
            model and Steps without AI) before the next step. Left out of lists.
        checks:
          type: string
          description: >-
            What to confirm before answering, as a list. Markdown. Links the
            agent’s tools as `[[tool:<id or name>]]` and its other procedures as
            `[[procedure:<id or title>]]` (kept by id, so renaming either keeps
            the link; a tool a procedure links is unlocked with it), and uses an
            input as `{name}`. Left out of lists.
        body:
          type: string
          maxLength: 20000
          description: >-
            The whole text as the agent reads it: its parts under ## headings,
            links as the tool’s name and the procedure’s title. Left out of
            lists.
        status:
          type: string
          enum:
            - active
            - draft
            - archived
        kind:
          type: string
          enum:
            - browser
            - desktop
            - chat
          description: >-
            What it needs to run: a browser, a computer, or nothing beyond the
            chat.
        tools:
          type: array
          items:
            type: string
          description: >-
            The agent’s HTTP tools it unlocks, by name: each stays locked in a
            task until the agent reads this procedure. Kept when the agent no
            longer has one.
        approval:
          oneOf:
            - $ref: '#/components/schemas/ProcedureApproval'
            - type: 'null'
          description: >-
            Whether a person must approve in the conversation before a task
            follows this procedure; `null` when not. Changing it makes a new
            revision.
        model:
          type:
            - string
            - 'null'
          enum:
            - claude-haiku-5-5
            - claude-sonnet-5-5
            - claude-opus-5-5
            - claude-fable-5-1
            - gpt-6-luna
            - gpt-6.1-sol
            - gpt-6-astra
            - gemini-3.8-flash
            - gemini-4-argon
            - null
          description: >-
            The model this procedure runs on instead of the agent's (one of the
            agent `model` values), or `null` for the agent's own. Once a chat
            reads the procedure, the rest of the conversation runs on this
            model; a browser or computer task that follows it does too. An eval
            run that tries the agent on models it picked keeps those. Changing
            it makes a new revision.
        plan_mode:
          type: string
          enum:
            - 'off'
            - test
            - live
          description: >-
            Whether Eager runs this procedure without the agent's model: `off`
            (the model follows it), `test` (only in evals and test chats) or
            `live` (every conversation). A chat procedure is compiled into steps
            in the background when it's turned on or a new revision is saved; a
            browser procedure is recorded from the next run of it that works
            (its pages, clicks and typing, the procedure's inputs as blanks) and
            replayed after that, a small model reading the answer off the last
            screen. A step that needs judgement, or that can't be done for sure,
            hands the conversation (or the task) to the model from where it got
            to. Changing it doesn't make a new revision.
        plan:
          type: object
          description: >-
            The procedure's steps without AI (see `plan_mode`). The list of
            procedures gives `steps_count`; one procedure gives its `steps` (and
            a chat procedure's `vars`). A browser procedure's steps are recorded
            actions: `type` (open, click, double_click, type, keypress, scroll,
            drag, wait), with `url`, `text` (the inputs as `{name}` blanks),
            `keys`, `page` (the host and path it ran on), and `target` or
            `focus` (the control's role and label).
          properties:
            mode:
              type: string
              enum:
                - 'off'
                - test
                - live
            status:
              type: string
              enum:
                - 'off'
                - compiling
                - recording
                - ready
                - failed
              description: >-
                `ready` when its steps are there for the current revision;
                `recording`: a browser procedure waiting for a run to record.
            revision:
              type:
                - integer
                - 'null'
              description: The revision the steps were compiled from.
            compiled_at:
              type:
                - string
                - 'null'
              format: date-time
            error:
              type:
                - string
                - 'null'
              description: >-
                Why it couldn't be compiled (`failed`); the model follows the
                procedure meanwhile.
            steps_count:
              type: integer
            vars:
              type: array
              items:
                type: object
                properties:
                  name:
                    type: string
                  description:
                    type: string
                  list:
                    type: boolean
              description: Values read from tool results.
            steps:
              type: array
              items:
                type: object
                properties:
                  id:
                    type: string
                  kind:
                    type: string
                    enum:
                      - ask
                      - call
                      - branch
                      - say
                      - go
                      - ai
                      - end
                    description: >-
                      Ask for inputs, call a tool, decide between options, say a
                      reply, go to another procedure, hand to the model, or end.
                  text:
                    type: string
                  inputs:
                    type: array
                    items:
                      type: string
                  tool:
                    type: string
                  args:
                    type: array
                    items:
                      type: object
                      properties:
                        name:
                          type: string
                        value:
                          type: string
                  options:
                    type: array
                    items:
                      type: object
                      properties:
                        when:
                          type: string
                        next:
                          type: string
                  procedure:
                    type: string
                  next:
                    type: string
                  type:
                    type: string
                    enum:
                      - open
                      - click
                      - double_click
                      - type
                      - keypress
                      - scroll
                      - drag
                      - wait
                  url:
                    type: string
                  page:
                    type: string
                  keys:
                    type: array
                    items:
                      type: string
                  target:
                    type: object
                    properties:
                      role:
                        type: string
                      label:
                        type: string
                  focus:
                    type: object
                    properties:
                      role:
                        type: string
                      label:
                        type: string
            recorded_from:
              type: string
              description: 'A browser procedure''s: the task its steps were recorded from.'
        category:
          type:
            - string
            - 'null'
          description: >-
            The kind of request it's for, from the same set as the test cases'
            `category`; `null` for none. Not versioned.
        written_by:
          type: string
          enum:
            - person
            - agent
        source_task_id:
          type:
            - string
            - 'null'
          description: 'For one the agent wrote: the task it learned from.'
        revision:
          type: integer
        uses_30d:
          type: integer
        last_used_at:
          type:
            - string
            - 'null'
          format: date-time
        avg_run_cents_30d:
          type:
            - number
            - 'null'
          description: >-
            What a run that used it cost on average in the last 30 days, in
            cents at list price (to a tenth of a cent): a conversation, or a
            task on its own, priced by its tasks and chat replies that got it.
            Finished runs only; null when there are none.
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        evals:
          type: object
          description: >-
            Its evals: the test cases tied to it (`procedure_id`), and its
            latest run of them (cold runs left out).
          properties:
            test_cases:
              type: integer
              example: 4
            last_run:
              oneOf:
                - type: 'null'
                - type: object
                  properties:
                    test_run_id:
                      type: string
                    at:
                      type: string
                      format: date-time
                    tries:
                      type: integer
                    passed:
                      type: integer
                    pass_rate:
                      type:
                        - number
                        - 'null'
                    found:
                      type: integer
                      description: Tries whose agent found this procedure.
                    revision:
                      type:
                        - integer
                        - 'null'
                      description: 'The revision they found (null: none did).'
                    current:
                      type:
                        - boolean
                        - 'null'
                      description: >-
                        That revision is the procedure's current one (null: no
                        try found it).
          required:
            - test_cases
            - last_run
        references:
          type: array
          items:
            $ref: '#/components/schemas/ProcedureReference'
          description: Left out of lists.
        file_access:
          type: string
          enum:
            - read_only
            - read_write
          description: >-
            Whether the agent may create, change and delete its own files
            (write_file, edit_file, delete_file, and with Run code
            save_sandbox_file, which keeps a file its code made) while a
            conversation follows this procedure: the one it last read, found or
            ran on its steps, or a schedule's. `read_only` (the default) keeps
            them read-only, as everywhere else. Checked on every change, so
            turning it off holds at once. A test chat's or an eval's changes go
            to that conversation's own copy, never the real files. Every change
            keeps the version it replaced (`GET
            /v1/agents/{agent_id}/file_revisions`). Changing it doesn't make a
            new revision.
    TestCase:
      type: object
      description: >-
        A request to test an agent on, and how to tell the answer or fix is
        right: a chat, a browser task, or a problem on a desktop machine
        (`runs_on`).
      properties:
        object:
          const: test_case
        test_case_id:
          type: string
          example: tc_8Kq2mZ0aLp4x
        key:
          type:
            - string
            - 'null'
          pattern: ^(?!tc_)[A-Za-z0-9._-]{1,64}$
          example: DSP-01
          description: >-
            Your own id for the case, unique in the org: 1 to 64 of
            `A-Za-z0-9._-`, not starting with `tc_`. Every `{test_case_id}` in
            the API also takes it.
        name:
          type: string
          minLength: 1
          maxLength: 200
          example: Apps switched to dark mode
        prompt:
          type: string
          minLength: 1
          maxLength: 8000
          example: All my windows suddenly went black. How do I get the white back?
          description: >-
            Chat cases: the person’s first message. Browser and machine cases:
            the task’s prompt.
        start_state:
          type: string
          example: win10-22h2
          description: >-
            Desktop machine cases (required for them): the machine each try
            starts from. Null for chat and browser cases.
        setup_script:
          type:
            - string
            - 'null'
          maxLength: 100000
          description: >-
            Runs at the start of every try, elevated, as the signed-in user: it
            breaks the machine the way the case needs.
        success:
          type: object
          properties:
            check_script:
              type:
                - string
                - 'null'
              maxLength: 100000
              description: >-
                Runs on the machine (elevated, as the signed-in user) and prints
                `True` once the problem is fixed. It must print `False` before
                the task, or the attempt is an `error`. The agent’s final answer
                is in the `GH_AGENT_ANSWER` environment variable, and
                `GH_CHECK_PHASE` is `before` or `after` the task.
            rubric:
              type:
                - string
                - 'null'
              maxLength: 8000
              description: >-
                What a fix looks like, in plain language. A model judges it from
                the recorded conversation and the first and last screens.
          description: >-
            How to tell the problem is fixed. An attempt passes only when each
            one it has passes.
        customer:
          oneOf:
            - $ref: '#/components/schemas/Customer'
            - type: 'null'
          description: >-
            The simulated customer. Null: the test set’s `customer`, else a
            built-in default.
        operator:
          type: object
          properties:
            approvals:
              type: string
              enum:
                - approve
                - deny
              description: How the agent’s approval requests are decided during the test.
        limits:
          type: object
          properties:
            minutes:
              type: integer
              minimum: 1
              maximum: 60
              default: 10
              description: The task is stopped after this many minutes (1 to 60).
            steps:
              type:
                - integer
                - 'null'
              minimum: 1
              maximum: 500
              description: >-
                Model turns (1 to 500). Null: the agent’s own
                `guardrails.max_steps`.
        runs_on:
          type: string
          example: vm
          description: >-
            `chat`: a conversation with the agent, on Eager’s servers.
            `browser`: one task on a fresh cloud browser from `start_url`. `vm`
            (the default), or one of your runners’ labels: a desktop machine.
            Chat and browser cases are judged on the answer (`expected`,
            `success.rubric`) and whether it’s grounded; machine cases on
            `success.check_script` and/or the rubric.
        category:
          type:
            - string
            - 'null'
          example: Display & graphics
        tags:
          type: array
          items:
            type: string
            maxLength: 64
          maxItems: 50
          example:
            - uac
        metadata:
          $ref: '#/components/schemas/Metadata'
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        must_visit:
          type: array
          maxItems: 10
          items:
            type: string
          description: >-
            Chat and browser cases: sites the answer must come from, by host
            (`a.com|b.com` for either; subdomains count). An attempt that didn’t
            open one in a browser task fails, whatever the judge said.
          example:
            - support.example.com|docs.example.com
        expected:
          type:
            - string
            - 'null'
          maxLength: 2000
          description: >-
            Chat and browser cases: the right answer, in plain words. The judge
            passes an answer that has its facts. A chat or browser case needs
            `expected`, a rubric, or both.
        messages:
          type: array
          maxItems: 10
          items:
            type: string
            maxLength: 8000
          description: >-
            Chat cases: follow-up messages, sent in order after the prompt, each
            once the agent has replied.
        start_url:
          type:
            - string
            - 'null'
          format: uri
          description: 'Browser cases: where the browser opens.'
        procedure_id:
          type:
            - string
            - 'null'
          description: >-
            The procedure this case checks (`prc_…`, one of the agent's
            procedures). The procedure then shows its evals: its latest run of
            them, and whether that run tested its current revision.
          example: prc_4mJx0aQe1
        inputs:
          type: array
          maxItems: 50
          items:
            type: object
            maxProperties: 20
            additionalProperties:
              type: string
              maxLength: 1000
          description: >-
            Sets of values for the case's `{placeholders}` (a procedure's
            dynamic variables, like `{mtm}`): names are letters, digits and `_`.
            Each set runs as its own tries (a run's tries per case are
            multiplied by the sets): `{name}` in `prompt`, `messages`,
            `expected`, `success.rubric` and `start_url` is filled from the set,
            and the simulated customer knows the set as facts.
          example:
            - mtm: 20XW
              region: UK
            - mtm: 21DE
              region: US
        objects:
          type: array
          items:
            type: string
          description: >-
            Ids of the AI ontology's objects (types and kinds) the case
            exercises, like `device` or `post_warranty`. Left out, the ontology
            fills it in within a minute: from the procedure the case is tied to,
            else by reading the case. Results of a run are also grouped by them
            (`by_object`).
    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.'
    ScriptBase64:
      type: object
      required:
        - base64
      additionalProperties: false
      description: >-
        A script, base64-encoded (UTF-8). Use it when a firewall in front of the
        API refuses a request whose body holds a script; it's stored and
        returned as plain text.
      properties:
        base64:
          type: string
    Customer:
      type: object
      description: >-
        The simulated customer who answers the agent during a test: a model with
        this persona, these facts and the machine’s screen. It never sees the
        expected fix or the check.
      properties:
        persona:
          type: string
          example: Retired teacher. Not technical. Short, polite answers.
          description: Who they are and how they answer.
        facts:
          type: object
          maxProperties: 50
          additionalProperties:
            oneOf:
              - type: string
              - type: object
                required:
                  - secret
                properties:
                  secret:
                    type: string
                description: >-
                  A secret: the simulated customer’s model only sees its name,
                  and can type it into the focused field.
          description: >-
            What the customer knows, by name (up to 50). A `{ "secret": … }`
            value is never shown to the model: the customer can only type it
            into the field that has focus.
          example:
            Wi-Fi network: HomeNet
            Wi-Fi password:
              secret: blue-kite-42
        clicks_admin_prompts:
          type: boolean
          description: >-
            When the agent asks, the customer clicks Yes on an admin (UAC)
            prompt.
        does_steps:
          type: boolean
          description: >-
            The customer does steps themselves when the agent asks. When false,
            they ask the agent to do it.
    Metadata:
      type: object
      additionalProperties:
        type: string
        maxLength: 500
      maxProperties: 50
      description: >-
        Your own ids and labels (e.g. a ticket or customer id), returned as
        given.
      example:
        customer_id: cus_42
    ProcedureStep:
      type: object
      required:
        - id
        - text
        - subprocedure
      properties:
        id:
          type: string
          description: The step’s id (st_…), the same for as long as the step is kept.
        text:
          type: string
          maxLength: 4000
          description: What to do, Markdown (sub-points under it are part of it).
        subprocedure:
          oneOf:
            - type: 'null'
            - type: object
              required:
                - id
                - title
                - missing
              properties:
                id:
                  type: string
                title:
                  type:
                    - string
                    - 'null'
                missing:
                  type: boolean
                  description: It was deleted.
          description: The procedure this step calls (the first it links), or null.
    ProcedureReference:
      type: object
      description: >-
        A link in its text, with what it points at now: a tool (`name`) or a
        procedure (`title`). `missing`: the agent no longer has it.
      properties:
        type:
          type: string
          enum:
            - tool
            - procedure
        id:
          type: string
        name:
          type:
            - string
            - 'null'
        title:
          type:
            - string
            - 'null'
        missing:
          type: boolean
    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.'
  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.