{
  "openapi": "3.1.0",
  "info": {
    "title": "Vergabezone public CPV reference API",
    "version": "1.0.0",
    "description": "Official CPV2008 main vocabulary:9,454 German/English classifications in45 divisions. File-only reference with source provenance, exact hierarchy and official check digits; no workspace data, database or upstream requests. Counts are classification codes, not tenders, and CSV exports only one bounded page."
  },
  "servers": [
    {
      "url": "https://vergabezone.de"
    }
  ],
  "paths": {
    "/api/index.php": {
      "get": {
        "operationId": "getCpvCatalogue",
        "parameters": [
          {
            "name": "action",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "cpv-catalogue"
              ]
            },
            "description": "Public file-only classification catalogue."
          },
          {
            "name": "lang",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "de",
                "en"
              ],
              "default": "de"
            },
            "description": "Interface language; both official labels remain present."
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 120
            },
            "description": "German/English words or a numeric code prefix. Tokens are matched together; exact code mode is separate."
          },
          {
            "name": "division",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[0-9]{2}$"
            },
            "description": "One of the 45 existing official divisions."
          },
          {
            "name": "parent",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[0-9]{8}$"
            },
            "description": "Return the direct children of an existing official code."
          },
          {
            "name": "code",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[0-9]{8}(-[0-9])?$"
            },
            "description": "Exact existing code, optionally with its official check digit. Exclusive of q, division, parent and nonzero offset."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 40
            },
            "description": "Maximum classification items, not tender results."
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0
            },
            "description": "Result offset; use pagination.nextOffset if hasMore is true."
          },
          {
            "name": "format",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "json",
                "csv"
              ],
              "default": "json"
            },
            "description": "CSV exports the current bounded result page, with official source attribution."
          }
        ],
        "responses": {
          "200": {
            "description": "Catalogue, bounded items, pagination, source, division counts, ancestors/children and related market-hub prefix overlaps. JSON and CSV support content-derived ETags.",
            "headers": {
              "ETag": {
                "schema": {
                  "type": "string"
                }
              },
              "X-Cpv-Count-Unit": {
                "schema": {
                  "type": "string",
                  "const": "classification-codes-not-tenders"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "version",
                    "source",
                    "counts",
                    "items",
                    "pagination",
                    "divisions"
                  ]
                }
              },
              "text/csv": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "304": {
            "description": "Unchanged successful representation; no body."
          },
          "404": {
            "description": "A valid-shaped exact code or parent does not exist."
          },
          "405": {
            "description": "Method not allowed."
          },
          "422": {
            "description": "Malformed, unsupported or competing filters, including an invalid division."
          },
          "503": {
            "description": "Local official reference is unavailable; no upstream fallback."
          }
        }
      },
      "head": {
        "operationId": "headCpvCatalogue",
        "parameters": [
          {
            "name": "action",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "cpv-catalogue"
              ]
            },
            "description": "Public file-only classification catalogue."
          },
          {
            "name": "lang",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "de",
                "en"
              ],
              "default": "de"
            },
            "description": "Interface language; both official labels remain present."
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 120
            },
            "description": "German/English words or a numeric code prefix. Tokens are matched together; exact code mode is separate."
          },
          {
            "name": "division",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[0-9]{2}$"
            },
            "description": "One of the 45 existing official divisions."
          },
          {
            "name": "parent",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[0-9]{8}$"
            },
            "description": "Return the direct children of an existing official code."
          },
          {
            "name": "code",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[0-9]{8}(-[0-9])?$"
            },
            "description": "Exact existing code, optionally with its official check digit. Exclusive of q, division, parent and nonzero offset."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 40
            },
            "description": "Maximum classification items, not tender results."
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0
            },
            "description": "Result offset; use pagination.nextOffset if hasMore is true."
          },
          {
            "name": "format",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "json",
                "csv"
              ],
              "default": "json"
            },
            "description": "CSV exports the current bounded result page, with official source attribution."
          }
        ],
        "responses": {
          "200": {
            "description": "Same headers as GET without a body."
          },
          "304": {
            "description": "Unchanged representation."
          }
        }
      },
      "options": {
        "operationId": "optionsCpvCatalogue",
        "responses": {
          "204": {
            "description": "Public CORS preflight for GET/HEAD/OPTIONS and Accept/If-None-Match. No credentials or cookies."
          }
        }
      }
    }
  },
  "x-attribution": "Official TED and Publications Office sources are identified in every JSON representation and CSV export. Related hub links indicate classification-prefix overlap, not available contracts or eligibility."
}
