{
  "openapi": "3.1.0",
  "info": {
    "title": "VeroniQA public API",
    "summary": "Ask VeroniQA about the demo API, read the measured results, and fetch the demo spec.",
    "description": "A keyless, rate-limited sandbox for the VeroniQA public demo. Answers come from the demo Orders API's requirement documents and cite their sources; models are simulated, so answers are extracts, not a model's prose. Errors are RFC 9457 problem documents (`application/problem+json`) with a stable `code` and a `hint`. Rate limits are reported with `RateLimit-Policy` and `RateLimit` headers. Guide: https://veroniqa.vercel.app/developers",
    "contact": {
      "name": "Rowan Kendal",
      "url": "https://github.com/Zapkid/agentqa/issues"
    },
    "license": {
      "name": "See repository",
      "url": "https://github.com/Zapkid/agentqa"
    },
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "https://veroniqa.vercel.app/api",
      "description": "Public demo (sandbox)"
    }
  ],
  "paths": {
    "/": {
      "get": {
        "tags": [
          "service"
        ],
        "summary": "API index",
        "description": "Links to the API's description, guide and endpoints.",
        "operationId": "getIndex",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "type": "object",
                  "title": "Response Getindex"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (`rate_limited`)",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "500": {
            "description": "Internal error (`internal_error`)",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/status": {
      "get": {
        "tags": [
          "service"
        ],
        "summary": "Service status",
        "operationId": "getStatus",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Status"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (`rate_limited`)",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "500": {
            "description": "Internal error (`internal_error`)",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/results": {
      "get": {
        "tags": [
          "service"
        ],
        "summary": "Measured results",
        "description": "The numbers on the home page, from the latest benchmark results in the repository.",
        "operationId": "getResults",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Results"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (`rate_limited`)",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "500": {
            "description": "Internal error (`internal_error`)",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/ask": {
      "post": {
        "tags": [
          "knowledge"
        ],
        "summary": "Ask about the demo API",
        "description": "Answers a question from the demo Orders API's requirement documents, with numbered citations. Returns found=false when the documents do not cover the question.",
        "operationId": "ask",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AskIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AskOut"
                }
              }
            }
          },
          "422": {
            "description": "Invalid request (`invalid_request`)",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (`rate_limited`)",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "500": {
            "description": "Internal error (`internal_error`)",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/demo/openapi.json": {
      "get": {
        "tags": [
          "demo"
        ],
        "summary": "OpenAPI spec of the demo API",
        "description": "The OpenAPI description of the bundled Orders API that the demo tests run against.",
        "operationId": "getDemoSpec",
        "responses": {
          "200": {
            "description": "An OpenAPI document",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "429": {
            "description": "Too many requests (`rate_limited`)",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "500": {
            "description": "Internal error (`internal_error`)",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "AskIn": {
        "properties": {
          "question": {
            "type": "string",
            "maxLength": 500,
            "minLength": 3,
            "title": "Question",
            "description": "A question about the demo Orders API",
            "examples": [
              "What is the p95 latency target for the order list?"
            ]
          }
        },
        "type": "object",
        "required": [
          "question"
        ],
        "title": "AskIn"
      },
      "AskOut": {
        "properties": {
          "answer": {
            "type": "string",
            "title": "Answer"
          },
          "found": {
            "type": "boolean",
            "title": "Found",
            "description": "False when the documents do not answer the question"
          },
          "grounded": {
            "type": "boolean",
            "title": "Grounded",
            "description": "True when every cited passage was actually retrieved"
          },
          "citations": {
            "items": {
              "$ref": "#/components/schemas/Citation"
            },
            "type": "array",
            "title": "Citations"
          },
          "note": {
            "type": "string",
            "title": "Note",
            "description": "Caveats, e.g. dropped citations",
            "default": ""
          },
          "knowledge": {
            "type": "string",
            "title": "Knowledge",
            "description": "The knowledge the answer is drawn from"
          }
        },
        "type": "object",
        "required": [
          "answer",
          "found",
          "grounded",
          "citations",
          "knowledge"
        ],
        "title": "AskOut"
      },
      "Citation": {
        "properties": {
          "n": {
            "type": "integer",
            "title": "N",
            "description": "Passage number as cited in the answer, e.g. [2]"
          },
          "source": {
            "type": "string",
            "title": "Source",
            "description": "Document the passage comes from"
          },
          "section": {
            "type": "string",
            "title": "Section",
            "description": "Heading the passage sits under"
          },
          "text": {
            "type": "string",
            "title": "Text",
            "description": "The passage"
          }
        },
        "type": "object",
        "required": [
          "n",
          "source",
          "section",
          "text"
        ],
        "title": "Citation"
      },
      "Results": {
        "properties": {
          "benchmark": {
            "type": "string",
            "title": "Benchmark",
            "description": "Where the numbers come from"
          },
          "recall_pct": {
            "type": "integer",
            "title": "Recall Pct",
            "description": "Share of planted bugs found with cost-aware routing"
          },
          "cost_pct": {
            "type": "integer",
            "title": "Cost Pct",
            "description": "Cost relative to using the strongest model for everything"
          },
          "perf_caught": {
            "type": "integer",
            "title": "Perf Caught",
            "description": "Performance defects caught"
          },
          "perf_total": {
            "type": "integer",
            "title": "Perf Total",
            "description": "Performance defects planted"
          },
          "planted_bugs": {
            "type": "integer",
            "title": "Planted Bugs",
            "description": "Functional bugs planted in the demo API"
          },
          "cost_levers": {
            "type": "integer",
            "title": "Cost Levers",
            "description": "Cost mechanisms measured one at a time (ablations)"
          },
          "tiles": {
            "items": {
              "$ref": "#/components/schemas/Tile"
            },
            "type": "array",
            "title": "Tiles"
          }
        },
        "type": "object",
        "required": [
          "benchmark",
          "recall_pct",
          "cost_pct",
          "perf_caught",
          "perf_total",
          "planted_bugs",
          "cost_levers",
          "tiles"
        ],
        "title": "Results"
      },
      "Status": {
        "properties": {
          "status": {
            "type": "string",
            "title": "Status",
            "examples": [
              "ok"
            ]
          },
          "service": {
            "type": "string",
            "title": "Service",
            "examples": [
              "VeroniQA public API"
            ]
          },
          "version": {
            "type": "string",
            "title": "Version",
            "examples": [
              "1.0.0"
            ]
          },
          "models": {
            "type": "string",
            "title": "Models",
            "description": "simulated: answers are extracts, not a model's prose"
          },
          "authentication": {
            "type": "string",
            "title": "Authentication",
            "examples": [
              "none"
            ]
          },
          "docs": {
            "type": "string",
            "title": "Docs"
          },
          "openapi": {
            "type": "string",
            "title": "Openapi"
          }
        },
        "type": "object",
        "required": [
          "status",
          "service",
          "version",
          "models",
          "authentication",
          "docs",
          "openapi"
        ],
        "title": "Status"
      },
      "Tile": {
        "properties": {
          "value": {
            "type": "string",
            "title": "Value",
            "examples": [
              "94%"
            ]
          },
          "caption": {
            "type": "string",
            "title": "Caption",
            "examples": [
              "of planted bugs found"
            ]
          }
        },
        "type": "object",
        "required": [
          "value",
          "caption"
        ],
        "title": "Tile"
      },
      "Problem": {
        "description": "An RFC 9457 problem document, with a stable machine-readable code and a hint.",
        "properties": {
          "type": {
            "description": "URI identifying the problem type; documented on /developers",
            "title": "Type",
            "type": "string"
          },
          "title": {
            "description": "Short, human-readable summary of the problem type",
            "title": "Title",
            "type": "string"
          },
          "status": {
            "description": "The HTTP status code",
            "title": "Status",
            "type": "integer"
          },
          "detail": {
            "description": "What went wrong in this request",
            "title": "Detail",
            "type": "string"
          },
          "instance": {
            "description": "The request path",
            "title": "Instance",
            "type": "string"
          },
          "code": {
            "description": "Stable error code, e.g. not_found or rate_limited",
            "title": "Code",
            "type": "string"
          },
          "hint": {
            "description": "How to fix the request",
            "title": "Hint",
            "type": "string"
          },
          "errors": {
            "anyOf": [
              {
                "items": {
                  "additionalProperties": true,
                  "type": "object"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "Field-level validation errors (code invalid_request only)",
            "title": "Errors"
          }
        },
        "required": [
          "type",
          "title",
          "status",
          "detail",
          "instance",
          "code",
          "hint"
        ],
        "title": "Problem",
        "type": "object"
      }
    }
  },
  "tags": [
    {
      "name": "service",
      "description": "Status and published results"
    },
    {
      "name": "knowledge",
      "description": "Cited answers from the demo documents"
    },
    {
      "name": "demo",
      "description": "The bundled demo API that VeroniQA tests"
    }
  ]
}