openapi: 3.1.0
info:
  title: Capsule Security Webhook Events API
  description: >
    Real-time event ingestion for AI agent security monitoring.

    Send agent lifecycle events to Capsule's detection pipeline for prevention
    and observability.
  version: 1.0.0
  contact:
    name: Capsule Security Support
    email: support@capsule.security
  license:
    name: Proprietary
    url: https://capsule.security/license
servers:
  - url: https://api.capsule.security
    description: Production API server
  - url: https://staging.api.capsule.security
    description: Staging API server
security:
  - bearerAuth: []
paths:
  /v1/generic-webhook/hooks/events:
    post:
      summary: Send webhook event
      description: >
        Ingests agent lifecycle events for security analysis.

        Blocking events (`tool_invocation`, `user_message`) return an
        allow/block decision.

        Observational events (`tool_result`, `agent_message`, `session_start`,
        `session_end`) return `202 Accepted`.
      operationId: sendWebhookEvent
      tags:
        - Webhook Events
      parameters:
        - name: x-correlation-id
          in: header
          required: false
          schema:
            type: string
          description: Trace ID for request correlation
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WebhookEvent'
      responses:
        '200':
          description: Blocking event decision (tool_invocation, user_message)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BlockingResponse'
              examples:
                allowed:
                  summary: Action allowed
                  value:
                    apiVersion: '1'
                    response:
                      action: allow
                blocked:
                  summary: Action blocked
                  value:
                    apiVersion: '1'
                    response:
                      action: block
                      reason: 'Policy violation: query accesses sensitive table'
        '202':
          description: >-
            Observational event accepted (tool_result, agent_message,
            session_start, session_end)
        '400':
          description: Malformed request body
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Problem'
              example:
                type: https://api.capsule.security/problems/invalid-request
                title: Invalid Request
                status: 400
                detail: The request payload is not valid according to the schema.
        '401':
          description: Invalid or expired JWT
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Problem'
              example:
                type: https://api.capsule.security/problems/unauthorized
                title: Unauthorized
                status: 401
                detail: The provided JWT token is invalid or expired.
        '408':
          description: Request timeout — treat as allow (fail-open)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Problem'
              example:
                type: https://api.capsule.security/problems/timeout
                title: Request Timeout
                status: 408
                detail: The request exceeded the processing timeout.
        '500':
          description: Server error — treat as allow (fail-open)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Problem'
              example:
                type: https://api.capsule.security/problems/internal-error
                title: Internal Server Error
                status: 500
                detail: An unexpected error occurred.
components:
  schemas:
    WebhookEvent:
      oneOf:
        - $ref: '#/components/schemas/ToolInvocationEvent'
        - $ref: '#/components/schemas/UserMessageEvent'
        - $ref: '#/components/schemas/ToolResultEvent'
        - $ref: '#/components/schemas/AgentMessageEvent'
        - $ref: '#/components/schemas/SessionStartEvent'
        - $ref: '#/components/schemas/SessionEndEvent'
      discriminator:
        propertyName: event_type
        mapping:
          tool_invocation: '#/components/schemas/ToolInvocationEvent'
          user_message: '#/components/schemas/UserMessageEvent'
          tool_result: '#/components/schemas/ToolResultEvent'
          agent_message: '#/components/schemas/AgentMessageEvent'
          session_start: '#/components/schemas/SessionStartEvent'
          session_end: '#/components/schemas/SessionEndEvent'
    BaseEvent:
      type: object
      required:
        - event_type
        - session_id
        - timestamp
        - agent
        - user
      properties:
        event_type:
          type: string
        session_id:
          type: string
          description: Unique session identifier
          example: sess-abc123
        timestamp:
          type: string
          format: date-time
          description: ISO 8601 timestamp
          example: '2026-03-03T10:30:00Z'
        agent:
          $ref: '#/components/schemas/AgentInfo'
        user:
          $ref: '#/components/schemas/UserInfo'
    ToolInvocationEvent:
      description: >-
        Sent before a tool executes. Blocks until Capsule responds with
        allow/block.
      allOf:
        - $ref: '#/components/schemas/BaseEvent'
        - type: object
          required:
            - event_type
            - tool
          properties:
            event_type:
              type: string
              const: tool_invocation
            tool:
              $ref: '#/components/schemas/ToolInfo'
      example:
        event_type: tool_invocation
        session_id: sess-abc123
        timestamp: '2026-03-03T10:30:00Z'
        agent:
          id: support-agent
          name: Customer Support Agent
        user:
          email: user@example.com
        tool:
          name: database_query
          input:
            query: SELECT * FROM users
    UserMessageEvent:
      description: >-
        Sent before a user prompt is processed. Blocks until Capsule responds
        with allow/block.
      allOf:
        - $ref: '#/components/schemas/BaseEvent'
        - type: object
          required:
            - event_type
            - message
          properties:
            event_type:
              type: string
              const: user_message
            message:
              $ref: '#/components/schemas/MessageInfo'
      example:
        event_type: user_message
        session_id: sess-abc123
        timestamp: '2026-03-03T10:30:00Z'
        agent:
          id: support-agent
          name: Customer Support Agent
        user:
          email: user@example.com
        message:
          content: Show me all customer records from the last month
    ToolResultEvent:
      description: Sent after tool execution completes. Fire-and-forget.
      allOf:
        - $ref: '#/components/schemas/BaseEvent'
        - type: object
          required:
            - event_type
            - tool
          properties:
            event_type:
              type: string
              const: tool_result
            tool:
              $ref: '#/components/schemas/ToolResultInfo'
      example:
        event_type: tool_result
        session_id: sess-abc123
        timestamp: '2026-03-03T10:30:05Z'
        agent:
          id: support-agent
          name: Customer Support Agent
        user:
          email: user@example.com
        tool:
          name: database_query
          input:
            query: SELECT * FROM users
          output:
            row_count: 42
    AgentMessageEvent:
      description: Sent after the agent produces a response. Fire-and-forget.
      allOf:
        - $ref: '#/components/schemas/BaseEvent'
        - type: object
          required:
            - event_type
            - message
          properties:
            event_type:
              type: string
              const: agent_message
            message:
              $ref: '#/components/schemas/MessageInfo'
      example:
        event_type: agent_message
        session_id: sess-abc123
        timestamp: '2026-03-03T10:30:06Z'
        agent:
          id: support-agent
          name: Customer Support Agent
        user:
          email: user@example.com
        message:
          content: Here are the 42 customer records from the last month...
    SessionStartEvent:
      description: Sent when a session begins. Fire-and-forget.
      allOf:
        - $ref: '#/components/schemas/BaseEvent'
        - type: object
          required:
            - event_type
          properties:
            event_type:
              type: string
              const: session_start
      example:
        event_type: session_start
        session_id: sess-abc123
        timestamp: '2026-03-03T10:29:55Z'
        agent:
          id: support-agent
          name: Customer Support Agent
        user:
          email: user@example.com
    SessionEndEvent:
      description: Sent when a session terminates. Fire-and-forget.
      allOf:
        - $ref: '#/components/schemas/BaseEvent'
        - type: object
          required:
            - event_type
          properties:
            event_type:
              type: string
              const: session_end
      example:
        event_type: session_end
        session_id: sess-abc123
        timestamp: '2026-03-03T10:45:00Z'
        agent:
          id: support-agent
          name: Customer Support Agent
        user:
          email: user@example.com
    AgentInfo:
      type: object
      required:
        - id
        - name
      properties:
        id:
          type: string
          description: Agent identifier
          example: support-agent
        name:
          type: string
          description: Human-readable agent name
          example: Customer Support Agent
    UserInfo:
      type: object
      required:
        - email
      properties:
        email:
          type: string
          description: User email address
          example: user@example.com
    ToolInfo:
      type: object
      required:
        - name
        - input
      properties:
        name:
          type: string
          description: Tool name
          example: database_query
        input:
          type: object
          description: Tool input parameters
          example:
            query: SELECT * FROM users
    ToolResultInfo:
      type: object
      required:
        - name
        - input
        - output
      properties:
        name:
          type: string
          description: Tool name
          example: database_query
        input:
          type: object
          description: Tool input parameters
          example:
            query: SELECT * FROM users
        output:
          type: object
          description: Tool execution output
          example:
            row_count: 42
    MessageInfo:
      type: object
      required:
        - content
      properties:
        content:
          type: string
          description: Message content
          example: Show me all customer records from the last month
    BlockingResponse:
      type: object
      required:
        - apiVersion
        - response
      properties:
        apiVersion:
          type: string
          const: '1'
          example: '1'
        response:
          type: object
          required:
            - action
          properties:
            action:
              type: string
              enum:
                - allow
                - block
              description: Whether the action is allowed or blocked
            reason:
              type: string
              description: Reason for blocking (present when action is "block")
              example: 'Policy violation: query accesses sensitive table'
    Problem:
      type: object
      properties:
        type:
          type: string
          format: uri
          description: A URI reference that identifies the problem type.
          example: https://api.capsule.security/problems/invalid-request
        title:
          type: string
          description: A short, human-readable summary of the problem type.
          example: Invalid Request
        status:
          type: integer
          description: The HTTP status code.
          example: 400
        detail:
          type: string
          description: >-
            A human-readable explanation specific to this occurrence of the
            problem.
          example: The request payload is not valid according to the schema.
        instance:
          type: string
          format: uri
          description: >-
            A URI reference that identifies the specific occurrence of the
            problem.
          example: /problems/invalid-request/1234
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: JWT Bearer token for API access
