{
  "openapi": "3.1.0",
  "info": {
    "title": "geistesblick Public Content API",
    "version": "1.0.0",
    "description": "Rein lesender Zugriff auf veröffentlichte Website-Inhalte. Keine CMS-, Preview-, Kontakt-, Buchungs- oder Bezahlfunktion."
  },
  "servers": [{ "url": "https://geistesblick.de" }],
  "security": [],
  "externalDocs": { "url": "https://geistesblick.de/agent-api/guide.md" },
  "paths": {
    "/api/public/pages": {
      "head": {
        "operationId": "headPublicPages",
        "summary": "Header des öffentlichen Seitenverzeichnisses prüfen",
        "responses": {
          "200": { "description": "Wie GET, ohne Antwortkörper." },
          "400": { "description": "Ungültige Anfrage oder Preview-Cookie, ohne Antwortkörper." }
        }
      },
      "get": {
        "operationId": "listPublicPages",
        "summary": "Öffentliche Seiten auflisten",
        "description": "Gibt die feste Liste freigegebener Seiten zurück. Keine Query-Parameter.",
        "responses": {
          "200": {
            "description": "Freigegebene Seiten",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["pages"],
                  "additionalProperties": false,
                  "properties": {
                    "pages": { "type": "array", "items": { "$ref": "#/components/schemas/PublicPageSummary" } }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/InvalidRequest" },
          "405": { "$ref": "#/components/responses/MethodNotAllowed" }
        }
      }
    },
    "/api/public/page": {
      "head": {
        "operationId": "headPublicPage",
        "summary": "Header einer öffentlichen Seite prüfen",
        "parameters": [{
          "name": "path", "in": "query", "required": true,
          "schema": { "$ref": "#/components/schemas/PublicPath" }
        }],
        "responses": {
          "200": { "description": "Wie GET, ohne Antwortkörper." },
          "400": { "description": "Ungültige Anfrage oder Preview-Cookie, ohne Antwortkörper." },
          "404": { "description": "Nicht freigegebener Pfad, ohne Antwortkörper." },
          "503": {
            "description": "Öffentlicher Inhalt vorübergehend nicht verfügbar, ohne Antwortkörper.",
            "headers": { "Retry-After": { "schema": { "type": "string", "const": "5" } } }
          }
        }
      },
      "get": {
        "operationId": "getPublicPage",
        "summary": "Eine öffentliche Seite als Markdown lesen",
        "description": "Nur genau ein path aus dem Seitenverzeichnis. Keine externen URLs oder weiteren Query-Parameter. Privater oder nicht erfolgreicher Inhalt wird nicht zurückgegeben.",
        "parameters": [{
          "name": "path",
          "in": "query",
          "required": true,
          "description": "Exakter path aus GET /api/public/pages, URL-kodiert.",
          "schema": { "$ref": "#/components/schemas/PublicPath" },
          "example": "/portfolio"
        }],
        "responses": {
          "200": {
            "description": "Öffentlicher Seiteninhalt",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PublicPage" } } }
          },
          "400": { "$ref": "#/components/responses/InvalidRequest" },
          "404": { "$ref": "#/components/responses/UnknownPage" },
          "405": { "$ref": "#/components/responses/MethodNotAllowed" },
          "503": { "$ref": "#/components/responses/ContentUnavailable" }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "PublicReadError": {
        "type": "object",
        "required": ["error"],
        "additionalProperties": false,
        "properties": {
          "error": { "type": "string", "enum": ["invalid_request", "preview_not_supported", "unknown_page", "method_not_allowed", "content_unavailable"] }
        }
      },
      "PublicPath": {
        "type": "string",
        "enum": [
          "/", "/about", "/service", "/portfolio", "/kontakt", "/impressum", "/datenschutz",
          "/service/webdesign", "/service/ki-strategie", "/service/grafikdesign",
          "/service/illustration", "/service/videoediting", "/service/motiondesign",
          "/service/headless-cms-migration", "/service/corporate-llm"
        ]
      },
      "PublicPageSummary": {
        "type": "object",
        "required": ["path", "title", "url"],
        "additionalProperties": false,
        "properties": {
          "path": { "$ref": "#/components/schemas/PublicPath" },
          "title": { "type": "string", "minLength": 1 },
          "url": { "type": "string", "format": "uri", "description": "Kanonische HTTPS-Quelladresse der Seite." }
        }
      },
      "PublicPage": {
        "type": "object",
        "required": ["path", "title", "url", "contentType", "content"],
        "additionalProperties": false,
        "properties": {
          "path": { "$ref": "#/components/schemas/PublicPath" },
          "title": { "type": "string", "minLength": 1 },
          "url": { "type": "string", "format": "uri", "description": "Kanonische HTTPS-Quelladresse für Zitate." },
          "contentType": { "type": "string", "const": "text/markdown" },
          "content": { "type": "string", "minLength": 1 },
          "lastModified": { "type": "string", "format": "date-time", "description": "Nur wenn ein belegtes Änderungsdatum aus der öffentlichen Seitenantwort vorliegt." }
        }
      }
    },
    "responses": {
      "InvalidRequest": {
        "description": "invalid_request: Parameter fehlen, sind doppelt, nicht unterstützt oder URL ist zu lang. preview_not_supported: Preview-Cookie vorhanden.",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PublicReadError" } } }
      },
      "UnknownPage": {
        "description": "unknown_page: Der angefragte Pfad steht nicht im öffentlichen Seitenverzeichnis.",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PublicReadError" } } }
      },
      "MethodNotAllowed": {
        "description": "method_not_allowed: Unterstützt sind ausschließlich GET und HEAD.",
        "headers": { "Allow": { "schema": { "type": "string", "const": "GET, HEAD" } } },
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PublicReadError" } } }
      },
      "ContentUnavailable": {
        "description": "content_unavailable: Die öffentliche Quellseite ist vorübergehend nicht abrufbar. Keine automatische Umleitung auf ein anderes Fetch-Ziel.",
        "headers": { "Retry-After": { "schema": { "type": "string", "const": "5" } } },
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PublicReadError" } } }
      }
    }
  }
}
