{
  "openapi": "3.1.0",
  "info": {
    "title": "MBCT3 Die Lage API",
    "version": "1.0.0",
    "summary": "Versionierte Lese-Schnittstelle für gespeicherte Lagebilder und Kartenebenen.",
    "description": "Die API liefert ausschließlich bereits von MBCT3 gespeicherte Datenstände. Sie ist Entscheidungsunterstützung, kein amtliches Warnsystem. Zeitangaben sind ISO 8601. Ampelwerte: green = Beobachten, yellow = Erhöht, red = Kritisch.",
    "termsOfService": "https://lage.mbct3.org/rechtliches.php#api-nutzung",
    "contact": {"name": "Martin Bäumler", "email": "martin@mbct3.org"}
  },
  "servers": [{"url": "https://lage.mbct3.org/api/v1", "description": "Produktivsystem"}],
  "externalDocs": {"description": "Verständliche Schnittstellendokumentation", "url": "https://lage.mbct3.org/api-dokumentation.php"},
  "tags": [
    {"name": "System", "description": "Verfügbarkeit und Metadaten"},
    {"name": "Lage", "description": "Aktuelles und historische Lagebilder"},
    {"name": "Themen", "description": "Themenliste und Themenverlauf"},
    {"name": "Kartenebenen", "description": "Aktuelle, in der MBCT3-Datenbank gespeicherte externe Layer"}
  ],
  "paths": {
    "/": {
      "get": {
        "tags": ["System"], "summary": "API-Metadaten", "security": [],
        "responses": {"200": {"description": "Metadaten und Dokumentationslinks", "content": {"application/json": {"schema": {"type": "object"}}}}}
      }
    },
    "/status": {
      "get": {
        "tags": ["System"], "summary": "Dienst- und Datenstatus", "operationId": "getStatus",
        "responses": {"200": {"description": "Status des Lagebilds und der fünf Kartenebenen", "$ref": "#/components/responses/EnvelopeResponse"}, "401": {"$ref": "#/components/responses/Unauthorized"}, "429": {"$ref": "#/components/responses/RateLimited"}}
      }
    },
    "/lage/latest": {
      "get": {
        "tags": ["Lage"], "summary": "Aktuelles Lagebild", "operationId": "getLatestLage",
        "responses": {"200": {"description": "Aktuelles Lagebild mit drei priorisierten Themen", "content": {"application/json": {"schema": {"allOf": [{"$ref": "#/components/schemas/Envelope"}, {"type": "object", "properties": {"data": {"$ref": "#/components/schemas/Lage"}}}]}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "404": {"$ref": "#/components/responses/NotFound"}, "429": {"$ref": "#/components/responses/RateLimited"}}
      }
    },
    "/history": {
      "get": {
        "tags": ["Lage"], "summary": "Historische Lagebilder", "operationId": "getHistory",
        "parameters": [
          {"name": "limit", "in": "query", "description": "Anzahl der Lagebilder", "schema": {"type": "integer", "minimum": 1, "maximum": 100, "default": 24}},
          {"name": "before", "in": "query", "description": "Nur Lagebilder vor diesem ISO-8601-Zeitpunkt", "schema": {"type": "string", "format": "date-time"}}
        ],
        "responses": {"200": {"description": "Absteigend sortierte Lagebilder; next_before kann als nächster before-Wert verwendet werden", "$ref": "#/components/responses/EnvelopeResponse"}, "400": {"$ref": "#/components/responses/BadRequest"}, "401": {"$ref": "#/components/responses/Unauthorized"}, "429": {"$ref": "#/components/responses/RateLimited"}}
      }
    },
    "/topics": {
      "get": {
        "tags": ["Themen"], "summary": "Themen auflisten", "operationId": "listTopics",
        "parameters": [
          {"name": "status", "in": "query", "schema": {"type": "string", "enum": ["active", "all"], "default": "active"}},
          {"name": "severity", "in": "query", "schema": {"$ref": "#/components/schemas/Severity"}},
          {"name": "limit", "in": "query", "schema": {"type": "integer", "minimum": 1, "maximum": 100, "default": 50}}
        ],
        "responses": {"200": {"description": "Themen mit jeweils jüngster Beobachtung", "$ref": "#/components/responses/EnvelopeResponse"}, "400": {"$ref": "#/components/responses/BadRequest"}, "401": {"$ref": "#/components/responses/Unauthorized"}, "429": {"$ref": "#/components/responses/RateLimited"}}
      }
    },
    "/topics/{key}": {
      "get": {
        "tags": ["Themen"], "summary": "Thema und Verlauf", "operationId": "getTopic",
        "parameters": [
          {"name": "key", "in": "path", "required": true, "description": "Stabiler Themen-Schlüssel", "schema": {"type": "string", "pattern": "^[a-z0-9][a-z0-9-]{2,79}$"}},
          {"name": "limit", "in": "query", "schema": {"type": "integer", "minimum": 1, "maximum": 120, "default": 50}}
        ],
        "responses": {"200": {"description": "Thema mit jüngsten Beobachtungen und Quellen", "$ref": "#/components/responses/EnvelopeResponse"}, "400": {"$ref": "#/components/responses/BadRequest"}, "401": {"$ref": "#/components/responses/Unauthorized"}, "404": {"$ref": "#/components/responses/NotFound"}, "429": {"$ref": "#/components/responses/RateLimited"}}
      }
    },
    "/layers": {
      "get": {
        "tags": ["Kartenebenen"], "summary": "Kartenebenen zusammenfassen", "operationId": "listLayers",
        "responses": {"200": {"description": "Status, Datenstand, Anzahl und Zusammenfassung aller Layer", "$ref": "#/components/responses/EnvelopeResponse"}, "401": {"$ref": "#/components/responses/Unauthorized"}, "429": {"$ref": "#/components/responses/RateLimited"}}
      }
    },
    "/layers/{layer}": {
      "get": {
        "tags": ["Kartenebenen"], "summary": "Eine Kartenebene abrufen", "operationId": "getLayer",
        "parameters": [{"name": "layer", "in": "path", "required": true, "schema": {"$ref": "#/components/schemas/LayerKey"}}],
        "responses": {"200": {"description": "Vollständiger aktueller, in der MBCT3-Datenbank gespeicherter Layer", "$ref": "#/components/responses/EnvelopeResponse"}, "401": {"$ref": "#/components/responses/Unauthorized"}, "404": {"$ref": "#/components/responses/NotFound"}, "429": {"$ref": "#/components/responses/RateLimited"}}
      }
    }
  },
  "components": {
    "securitySchemes": {
      "BearerApiKey": {"type": "http", "scheme": "bearer", "bearerFormat": "API key", "description": "Bevorzugt: Authorization: Bearer <API_KEY>"},
      "HeaderApiKey": {"type": "apiKey", "in": "header", "name": "X-API-Key", "description": "Alternative zum Bearer-Header"}
    },
    "schemas": {
      "Severity": {"type": "string", "enum": ["green", "yellow", "red"], "description": "green = Beobachten, yellow = Erhöht, red = Kritisch"},
      "LayerKey": {"type": "string", "enum": ["weather", "water", "traffic", "wildfire", "air"]},
      "Source": {
        "type": "object", "required": ["title", "url", "publisher", "published_at"],
        "properties": {"title": {"type": "string"}, "url": {"type": "string", "format": "uri"}, "publisher": {"type": ["string", "null"]}, "published_at": {"type": ["string", "null"], "format": "date-time"}}
      },
      "Geography": {
        "type": "object", "required": ["scope", "affected_regions", "national_relevance"],
        "properties": {"scope": {"type": "string", "enum": ["local", "regional", "multi_state", "nationwide", "unknown"]}, "affected_regions": {"type": "array", "items": {"type": "string"}}, "national_relevance": {"type": "boolean"}}
      },
      "Observation": {
        "type": "object", "required": ["rank", "headline", "analysis", "severity", "confidence", "geography", "observed_at", "sources"],
        "properties": {
          "rank": {"type": "integer", "minimum": 1}, "headline": {"type": "string"}, "analysis": {"type": "string"},
          "severity": {"$ref": "#/components/schemas/Severity"}, "confidence": {"type": "integer", "minimum": 0, "maximum": 100},
          "geography": {"$ref": "#/components/schemas/Geography"}, "observed_at": {"type": "string", "format": "date-time"},
          "sources": {"type": "array", "items": {"$ref": "#/components/schemas/Source"}}
        }
      },
      "TopicObservation": {
        "allOf": [{"$ref": "#/components/schemas/Observation"}, {"type": "object", "required": ["key", "label", "first_seen_at", "last_seen_at", "active"], "properties": {"key": {"type": "string"}, "label": {"type": "string"}, "first_seen_at": {"type": "string", "format": "date-time"}, "last_seen_at": {"type": "string", "format": "date-time"}, "active": {"type": "boolean"}}}]
      },
      "Lage": {
        "type": "object", "required": ["overall_severity", "executive_summary", "source_count", "published_at", "topics"],
        "properties": {"overall_severity": {"$ref": "#/components/schemas/Severity"}, "executive_summary": {"type": "string"}, "source_count": {"type": "integer"}, "published_at": {"type": "string", "format": "date-time"}, "topics": {"type": "array", "items": {"$ref": "#/components/schemas/TopicObservation"}}}
      },
      "Envelope": {
        "type": "object", "required": ["api_version", "data_updated_at", "generated_at", "disclaimer", "links", "data"],
        "properties": {
          "api_version": {"type": "string", "const": "v1"}, "data_updated_at": {"type": ["string", "null"], "format": "date-time"}, "generated_at": {"type": "string", "format": "date-time"},
          "disclaimer": {"type": "string"}, "links": {"type": "object", "additionalProperties": {"type": "string", "format": "uri"}}, "data": {}
        }
      },
      "Error": {
        "type": "object", "required": ["api_version", "error"],
        "properties": {"api_version": {"type": "string", "const": "v1"}, "error": {"type": "object", "required": ["status", "code", "message", "request_id"], "properties": {"status": {"type": "integer"}, "code": {"type": "string"}, "message": {"type": "string"}, "request_id": {"type": "string"}}}}
      }
    },
    "responses": {
      "EnvelopeResponse": {"description": "Erfolgreiche Antwort im einheitlichen Envelope", "headers": {"ETag": {"schema": {"type": "string"}}, "Last-Modified": {"schema": {"type": "string"}}, "X-RateLimit-Limit": {"schema": {"type": "integer"}}, "X-RateLimit-Remaining": {"schema": {"type": "integer"}}, "X-RateLimit-Reset": {"schema": {"type": "integer"}}}, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Envelope"}}}},
      "BadRequest": {"description": "Ungültiger Parameter", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}},
      "Unauthorized": {"description": "API-Schlüssel fehlt oder ist ungültig", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}},
      "NotFound": {"description": "Ressource wurde nicht gefunden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}},
      "RateLimited": {"description": "Rate-Limit erreicht", "headers": {"Retry-After": {"schema": {"type": "integer"}}}, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}
    }
  },
  "security": [{"BearerApiKey": []}, {"HeaderApiKey": []}]
}
