openapi: 3.1.0
info:
  title: Agent911 verdict API
  version: 1.0.0
  description: |
    The HTTP surface of the Agent911 verdict engine. The OpenClaw plugin uses
    these endpoints; any other agent runtime can call them directly, but note
    that today Agent911 can only *enforce* verdicts inside OpenClaw. On other
    runtimes you receive the verdict and decide yourself what to do with it.

    Plans: on Free the check endpoint reports what would have been blocked
    (`would_block`) while returning `Allow`; on Pro the verdict is the one the
    plugin enforces. Limits and plans: https://agent911.nanocorp.app/#pricing
servers:
  - url: https://agent911.nanocorp.app
paths:
  /api/v1/register:
    post:
      summary: Register an agent
      description: >
        Registers an agent without an account or email and returns its token
        plus the private dashboard link, which is the only key to that
        dashboard. Keep both secrets.
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  maxLength: 60
                  default: my-agent
      responses:
        '200':
          description: Agent registered
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok: { type: boolean, const: true }
                  agent: { type: string }
                  token: { type: string }
                  dashboard_url: { type: string, format: uri }
                  check_url: { type: string, format: uri }
                  message: { type: string }
  /api/v1/check:
    post:
      summary: Score one tool call
      description: >
        Ask for a verdict before an agent performs a tool call. The call to
        this endpoint should happen before the tool runs; on Pro the expected
        behavior is to not run the tool when the verdict is Block, Quarantine
        or Freeze, and to pause for the owner on Approval.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CheckPayload'
      responses:
        '200':
          description: Verdict for the tool call
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Verdict'
        '401':
          description: Missing or unknown agent token
  /api/v1/claim:
    post:
      summary: Attach an owner email to a dashboard
      description: >
        Links a private dashboard (by its dashboard token) to an owner email so
        alerts can be delivered once they exist. Only called from the agent's
        own dashboard.
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                dash_token: { type: string }
                email: { type: string, format: email }
      responses:
        '200':
          description: Email attached
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok: { type: boolean, const: true }
                  name: { type: string }
        '400': { description: Invalid input }
        '404': { description: Unknown dashboard token }
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: The agent token returned by /api/v1/register.
  schemas:
    CheckPayload:
      type: object
      properties:
        tool:
          type: string
          description: >
            Tool about to run. Known values: shell, fs.read, fs.write, fs.edit,
            fs.delete, email, payment, network, calendar, other.
          examples: [shell, email, payment]
        target:
          type: string
          description: What the tool acts on (a path, a URL, a command line, an address).
        cost_eur: { type: number, description: Euros this call will spend, for payments and paid APIs. }
        email_to: { type: string, description: Recipient address, for email calls. }
        new_recipient: { type: boolean, description: True if the recipient was never contacted before. }
        deletions: { type: integer, description: Number of files this call deletes. }
        domain: { type: string, description: Domain contacted, for network calls. }
        new_domain: { type: boolean, description: True if this domain is new for this agent today. }
        session: { type: string, description: Free-form session identifier. }
      required: [tool, target]
    Verdict:
      type: object
      properties:
        verdict:
          type: string
          enum: [Allow, Warn, Approval, Block, Quarantine, Freeze]
          description: >
            On Free this is always Allow with `would_block` set on what Pro
            would have blocked. On Pro, Block / Quarantine / Freeze mean the
            tool call must not run, and Approval means it waits for the owner.
        would_block: { type: boolean }
        risk_score: { type: integer, minimum: 0, maximum: 100 }
        risk_points: { type: integer, description: Risk points this call spends from the daily Autonomy Budget. }
        reason: { type: string }
