openapi: "3.0.3"
info:
  title: AgentSkeptic commercial license API
  version: "1.0.0"
  contact:
    url: https://agentskeptic.com
  x-agentskeptic-distribution:
    repository: https://github.com/jwekavanagh/agentskeptic
    npmPackage: https://www.npmjs.com/package/agentskeptic
    openApi: https://agentskeptic.com/openapi-commercial-v1.yaml
  description: "State verification engine: read-only SQL checks that database state matches expectations from structured tool activity (not arbitrary logs)—not proof of execution\n\nMachine-readable contract for license preflight used by the published npm CLI.\nBase URL is your deployed app origin (same as NEXT_PUBLIC_APP_URL).\n"
externalDocs:
  description: "First-run integration guide"
  url: https://agentskeptic.com/integrate
servers:
  - url: https://agentskeptic.com
    description: Replace with your deployment origin
paths:
  /api/v1/usage/reserve:
    post:
      operationId: reserveUsage
      summary: Reserve one verification or enforcement run (license preflight)
      description: >
        Called by the commercial CLI before contract verify, quick verify, or enforce.
        Requires Bearer API key. Body run_id must be idempotent per key.
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ReserveRequest"
      responses:
        "200":
          description: Allowed; quota consumed or duplicate run_id returned without double-charge
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ReserveAllowed"
        "400":
          description: Bad request (missing/invalid body, skewed issued_at)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ReserveError"
        "401":
          description: Invalid or revoked API key
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ReserveError"
        "403":
          description: Quota exceeded or entitlement denied
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ReserveError"
        "503":
          description: Server error during reservation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ReserveError"
  /api/v1/commercial/plans:
    get:
      operationId: getCommercialPlans
      summary: Public commercial plan catalog (no secrets)
      responses:
        "200":
          description: Plan metadata for display and integration
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CommercialPlansResponse"
  /api/public/verification-reports:
    post:
      operationId: createPublicVerificationReport
      summary: Persist a shareable verification report (public ingestion; size-limited; optional env disable)
      tags:
        - PublicVerificationReports
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PublicVerificationReportCreate"
      responses:
        "201":
          description: Report stored; URL is canonical origin + /r/{id}
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PublicVerificationReportCreated"
        "400":
          description: Invalid JSON or failed schema validation
        "413":
          description: Request body exceeds maximum allowed size
        "503":
          description: Public report ingestion disabled or server unavailable
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API key
  schemas:
    PublicVerificationReportCreate:
      description: >
        Discriminated envelope (schemaVersion 1). Workflow branch includes WorkflowResult + truth report text.
        Quick branch includes QuickVerifyReport + human report text + workflowDisplayId for labeling.
      type: object
      additionalProperties: true
    PublicVerificationReportCreated:
      type: object
      additionalProperties: false
      required:
        - schemaVersion
        - id
        - url
      properties:
        schemaVersion:
          type: integer
          const: 1
        id:
          type: string
          format: uuid
        url:
          type: string
          format: uri
          description: GET this URL to render the stored report (HTML)
    ReserveRequest:
      type: object
      required:
        - run_id
        - issued_at
      properties:
        run_id:
          type: string
          maxLength: 256
        issued_at:
          type: string
          format: date-time
          description: ISO8601; server rejects if skew from now exceeds 300 seconds
        intent:
          type: string
          enum: [verify, enforce]
          default: verify
          description: enforce requires paid plan with active subscription; verify requires active subscription on individual/team/business/enterprise
    ReserveAllowed:
      type: object
      required:
        - allowed
        - plan
        - limit
        - used
      properties:
        allowed:
          type: boolean
          enum: [true]
        plan:
          type: string
          enum: [starter, individual, team, business, enterprise]
        limit:
          type: integer
        used:
          type: integer
    ReserveError:
      type: object
      properties:
        allowed:
          type: boolean
          enum: [false]
        code:
          type: string
          description: >
            Examples BAD_REQUEST, INVALID_KEY, QUOTA_EXCEEDED, VERIFICATION_REQUIRES_SUBSCRIPTION,
            ENFORCEMENT_REQUIRES_PAID_PLAN, SUBSCRIPTION_INACTIVE, BILLING_PRICE_UNMAPPED, SERVER_ERROR
        message:
          type: string
        upgrade_url:
          type: string
          format: uri
          description: Present for some 403 entitlement responses
    CommercialPlansResponse:
      type: object
      required:
        - schemaVersion
        - plans
      properties:
        schemaVersion:
          type: integer
        plans:
          type: object
          additionalProperties:
            $ref: "#/components/schemas/PublicPlan"
    PublicPlan:
      type: object
      properties:
        includedMonthly:
          oneOf:
            - type: integer
            - type: "null"
        monthlyUsdCents:
          oneOf:
            - type: integer
            - type: "null"
        displayPrice:
          type: string
        marketingHeadline:
          type: string
        audience:
          type: string
        valueUnlock:
          type: string
