openapi: 3.1.0
info:
  title: Capsule Security LiteLLM Hooks API
  description: |
    Webhook endpoints for the Capsule LiteLLM gateway plugin.

    The plugin calls `events/pre` synchronously before forwarding a
    completion/chat request to the upstream model provider, blocking on the
    allow/deny verdict. After the upstream call settles (success or failure),
    it calls `events/post` for token and latency telemetry. Both endpoints are
    JWT-authenticated; the token is scoped to a single tenant and environment.
  version: 1.0.0
  contact:
    name: Capsule Security Support
    email: support@capsule.security
  license:
    name: Proprietary
    url: https://capsule.security/license
servers:
  - url: https://agents.capsule.security
    description: Production agentsecurity server
security:
  - bearerAuth: []
paths:
  /v1/litellm/hooks/events/pre:
    post:
      summary: Pre-call policy check
      description: |
        Sent before LiteLLM forwards a completion request to the upstream model
        provider. Capsule evaluates the model and messages against tenant
        policies and returns an allow/deny verdict. The plugin rejects the
        request when `decision` is `deny` and blocking is enabled.
      operationId: liteLlmPreHook
      tags:
        - LiteLLM Hooks
      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/PreHookRequest'
      responses:
        '200':
          description: Policy verdict for the completion request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PreHookResponse'
              examples:
                allowed:
                  summary: Request allowed
                  value:
                    decision: allow
                denied:
                  summary: Request denied
                  value:
                    decision: deny
                    reason: 'Policy violation: prompt references restricted data'
                    triggeredPolicyIds:
                      - pol_01HZX9...
        '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 — the plugin treats this as allow when fail-open is
            enabled
          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.
  /v1/litellm/hooks/events/post:
    post:
      summary: Post-call telemetry
      description: |
        Fire-and-forget telemetry sent after the upstream model call settles.
        Carries token usage, latency, and success/error detail. Always returns
        `200` with `{ "ok": true }` once accepted.
      operationId: liteLlmPostHook
      tags:
        - LiteLLM Hooks
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PostHookRequest'
      responses:
        '200':
          description: Telemetry accepted
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PostHookResponse'
              example:
                ok: true
        '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.
components:
  schemas:
    PreHookRequest:
      type: object
      required:
        - requestId
        - model
      properties:
        requestId:
          type: string
          description: LiteLLM-issued request id, propagated for end-to-end tracing
          example: chatcmpl-abc123
        model:
          type: string
          description: Foundational model being called
          example: gpt-4o
        messages:
          type: array
          description: Chat messages submitted with the request
          items:
            $ref: '#/components/schemas/ChatMessage'
        user:
          type: string
          description: End-user identifier forwarded by the calling application, if any
          example: user@example.com
      example:
        requestId: chatcmpl-abc123
        model: gpt-4o
        messages:
          - role: user
            content: Summarize the attached customer records
        user: user@example.com
    ChatMessage:
      type: object
      required:
        - role
        - content
      properties:
        role:
          type: string
          description: Message role (e.g. system, user, assistant)
          example: user
        content:
          type: string
          description: Message content
          example: Summarize the attached customer records
    PreHookResponse:
      type: object
      required:
        - decision
      properties:
        decision:
          type: string
          enum:
            - allow
            - deny
          description: Whether the completion request is allowed or denied
        reason:
          type: string
          description: Reason for denial (present when decision is "deny")
          example: 'Policy violation: prompt references restricted data'
        triggeredPolicyIds:
          type: array
          description: Identifiers of the policies that produced the verdict
          items:
            type: string
    PostHookRequest:
      type: object
      required:
        - requestId
        - model
        - durationMs
        - success
      properties:
        requestId:
          type: string
          example: chatcmpl-abc123
        model:
          type: string
          example: gpt-4o
        durationMs:
          type: integer
          description: Wall-clock milliseconds spent on the upstream model call
          example: 842
        promptTokens:
          type: integer
          example: 128
        completionTokens:
          type: integer
          example: 256
        totalTokens:
          type: integer
          example: 384
        success:
          type: boolean
          example: true
        errorCode:
          type: string
          description: Error class/code (present when success is false)
          example: RateLimitError
        errorMessage:
          type: string
          description: Error detail (present when success is false)
      example:
        requestId: chatcmpl-abc123
        model: gpt-4o
        durationMs: 842
        promptTokens: 128
        completionTokens: 256
        totalTokens: 384
        success: true
    PostHookResponse:
      type: object
      required:
        - ok
      properties:
        ok:
          type: boolean
          const: true
          example: true
    Problem:
      type: object
      properties:
        type:
          type: string
          format: uri
          description: A URI reference that identifies the problem type.
          example: https://api.capsule.security/problems/unauthorized
        title:
          type: string
          description: A short, human-readable summary of the problem type.
          example: Unauthorized
        status:
          type: integer
          description: The HTTP status code.
          example: 401
        detail:
          type: string
          description: >-
            A human-readable explanation specific to this occurrence of the
            problem.
          example: The provided JWT token is invalid or expired.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: JWT Bearer token scoped to a tenant and environment
