{
  "openapi": "3.2.0",
  "info": {
    "title": "ValGuard API",
    "version": "1.0.0",
    "description": "Canonical API contract for ValGuard: production chat completions, operational health checks, and the public spec endpoint."
  },
  "jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
  "servers": [
    {
      "url": "/"
    }
  ],
  "security": [
    {
      "BearerAuth": []
    },
    {
      "ApiKeyHeader": []
    }
  ],
  "tags": [
    {
      "name": "Operations",
      "description": "Public API entry points and spec discovery."
    },
    {
      "name": "Completions",
      "description": "OpenAI-compatible chat completions."
    }
  ],
  "paths": {
    "/healthz": {
      "get": {
        "tags": ["Operations"],
        "summary": "Liveness probe",
        "responses": {
          "200": {
            "description": "Service is alive",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string",
                  "example": "ok"
                }
              }
            }
          }
        }
      }
    },
    "/readyz": {
      "get": {
        "tags": ["Operations"],
        "summary": "Readiness probe",
        "responses": {
          "200": {
            "description": "Service is ready",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string",
                  "example": "ready"
                }
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/openapi.json": {
      "get": {
        "tags": ["Operations"],
        "summary": "Canonical OpenAPI specification",
        "responses": {
          "200": {
            "description": "Canonical spec document",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpenAPISpec"
                }
              }
            }
          }
        }
      }
    },
    "/v1/chat/completions": {
      "post": {
        "tags": ["Completions"],
        "summary": "Create a chat completion",
        "description": "OpenAI-compatible chat completions with ValGuard validation, org-aware limits, and production observability headers.",
        "security": [
          {
            "BearerAuth": []
          },
          {
            "ApiKeyHeader": []
          }
        ],
        "parameters": [
          {
            "name": "X-VG-Agent",
            "in": "header",
            "required": false,
            "description": "Agent slug to execute. Mutually exclusive with X-VG-Flow.",
            "schema": {
              "type": "string",
              "minLength": 1
            }
          },
          {
            "name": "X-VG-Flow",
            "in": "header",
            "required": false,
            "description": "Orchestration flow slug to execute. Mutually exclusive with X-VG-Agent.",
            "schema": {
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChatCompletionRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Chat completion response",
            "headers": {
              "X-VG-Request-Id": {
                "description": "Request correlation identifier",
                "schema": {
                  "type": "string"
                }
              },
              "X-VG-Validation-Status": {
                "description": "Validation outcome for the request or completion",
                "schema": {
                  "type": "string",
                  "enum": ["pass", "warn", "block", "shadow"]
                }
              },
              "X-VG-Latency-ms": {
                "description": "End-to-end latency in milliseconds",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChatCompletionResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "vg_live_*"
      },
      "ApiKeyHeader": {
        "type": "apiKey",
        "in": "header",
        "name": "X-VG-Api-Key"
      }
    },
    "responses": {
      "BadRequest": {
        "description": "The request payload or headers were invalid",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "Missing or invalid API key",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "Forbidden": {
        "description": "The caller is authenticated but not allowed to access the resource",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "NotFound": {
        "description": "The requested resource was not found",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "PayloadTooLarge": {
        "description": "The request body exceeded the allowed size",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "TooManyRequests": {
        "description": "The caller exceeded a rate or quota limit",
        "headers": {
          "Retry-After": {
            "description": "Seconds until the request may be retried",
            "schema": {
              "type": "string"
            }
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "ServiceUnavailable": {
        "description": "The service is temporarily unavailable",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      }
    },
    "schemas": {
      "OpenAPISpec": {
        "type": "object",
        "required": ["openapi", "info", "paths"],
        "properties": {
          "openapi": {
            "type": "string",
            "const": "3.2.0"
          },
          "info": {
            "type": "object"
          },
          "paths": {
            "type": "object"
          }
        }
      },
      "ChatCompletionRequest": {
        "type": "object",
        "required": ["model", "messages"],
        "properties": {
          "model": {
            "type": "string",
            "minLength": 1,
            "examples": ["openai/gpt-4o-mini"]
          },
          "messages": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/ChatMessage"
            }
          },
          "stream": {
            "type": "boolean",
            "default": false
          },
          "temperature": {
            "type": "number",
            "minimum": 0,
            "maximum": 2
          },
          "max_tokens": {
            "type": "integer",
            "minimum": 1
          }
        },
        "additionalProperties": false
      },
      "ChatMessage": {
        "type": "object",
        "required": ["role", "content"],
        "properties": {
          "role": {
            "type": "string",
            "enum": ["system", "user", "assistant", "tool"]
          },
          "content": {
            "type": "string"
          }
        },
        "additionalProperties": false
      },
      "ChatCompletionResponse": {
        "type": "object",
        "required": ["id", "object", "created", "model", "choices"],
        "properties": {
          "id": {
            "type": "string"
          },
          "object": {
            "type": "string",
            "const": "chat.completion"
          },
          "created": {
            "type": "integer",
            "format": "int64"
          },
          "model": {
            "type": "string"
          },
          "choices": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChatChoice"
            }
          },
          "usage": {
            "$ref": "#/components/schemas/ChatUsage"
          }
        }
      },
      "ChatChoice": {
        "type": "object",
        "required": ["index"],
        "properties": {
          "index": {
            "type": "integer"
          },
          "message": {
            "$ref": "#/components/schemas/ChatMessage"
          },
          "finish_reason": {
            "type": ["string", "null"]
          }
        }
      },
      "ChatUsage": {
        "type": "object",
        "required": ["prompt_tokens", "completion_tokens", "total_tokens"],
        "properties": {
          "prompt_tokens": {
            "type": "integer"
          },
          "completion_tokens": {
            "type": "integer"
          },
          "total_tokens": {
            "type": "integer"
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "required": ["error"],
        "properties": {
          "error": {
            "type": "object",
            "required": ["message"],
            "properties": {
              "type": {
                "type": "string"
              },
              "code": {
                "type": ["string", "integer", "null"]
              },
              "message": {
                "type": "string"
              }
            }
          }
        }
      }
    }
  }
}