{
  "openapi": "3.1.0",
  "info": {
    "title": "Bundespuls Public API",
    "version": "1.0.0",
    "description": "Öffentliche, schlüssellose Schnittstellen von Bundespuls. RSS-Feeds, CSV-Exporte, JSON-Suche und Dataset-Downloads zu Bundestags-Vorgängen, Abgeordneten, Lobbyregister und Plenarprotokollen. Keine Authentifizierung, faire Frequenz erwartet (Rate-Limit 60 Requests/Minute pro IP auf RSS-Feeds, 5-30 Min Server-Cache empfohlen).",
    "contact": {
      "name": "Bundespuls",
      "url": "https://bundespuls.de/entwickler",
      "email": "hi@bundespuls.de"
    },
    "license": {
      "name": "CC-BY 4.0 (Bundespuls-eigene Aufbereitung)",
      "url": "https://creativecommons.org/licenses/by/4.0/deed.de"
    }
  },
  "servers": [
    {
      "url": "https://bundespuls.de",
      "description": "Produktion"
    }
  ],
  "tags": [
    { "name": "Feeds", "description": "RSS-2.0-Feeds für Reader und Watchlist-Ersatz" },
    { "name": "Export", "description": "CSV-Exporte für Tabellenkalkulation und Data-Science" },
    { "name": "Datasets", "description": "Große Open-Data-Datensätze (Volltext, Metadaten)" },
    { "name": "Search", "description": "Volltext-Suche über Bundespuls-Inhalte" },
    { "name": "Raw", "description": "Pass-Through zu Original-Datenquellen" },
    { "name": "Site", "description": "Sitemap, robots, llms-Manifeste" }
  ],
  "paths": {
    "/feed": {
      "get": {
        "tags": ["Feeds"],
        "summary": "Gesammelter RSS-Feed (Vorgänge + Abstimmungen + Plenarprotokolle)",
        "responses": { "200": { "description": "RSS 2.0", "content": { "application/rss+xml": {} } } }
      }
    },
    "/feed/vorgang": {
      "get": {
        "tags": ["Feeds"],
        "summary": "Neue parlamentarische Vorgänge der 21. Wahlperiode",
        "responses": { "200": { "description": "RSS 2.0", "content": { "application/rss+xml": {} } } }
      }
    },
    "/feed/abstimmung": {
      "get": {
        "tags": ["Feeds"],
        "summary": "Neue namentliche Abstimmungen",
        "description": "Quelle: abgeordnetenwatch.de (CC0 1.0).",
        "responses": { "200": { "description": "RSS 2.0", "content": { "application/rss+xml": {} } } }
      }
    },
    "/feed/plenarprotokoll": {
      "get": {
        "tags": ["Feeds"],
        "summary": "Neue Plenarprotokolle mit Volltext-PDF-Link",
        "responses": { "200": { "description": "RSS 2.0", "content": { "application/rss+xml": {} } } }
      }
    },
    "/feed/vorgang/{slug}": {
      "get": {
        "tags": ["Feeds"],
        "summary": "Pro-Vorgang-Feed: jede neue Verfahrens-Station ein Item",
        "parameters": [
          { "name": "slug", "in": "path", "required": true, "schema": { "type": "string", "pattern": "^[0-9]+$" }, "description": "DIP-Vorgangs-ID (numerisch)" }
        ],
        "responses": {
          "200": { "description": "RSS 2.0", "content": { "application/rss+xml": {} } },
          "400": { "description": "Slug nicht numerisch" },
          "404": { "description": "Vorgang nicht gefunden" }
        }
      }
    },
    "/feed/abgeordnete/{slug}": {
      "get": {
        "tags": ["Feeds"],
        "summary": "Pro-MdB-Feed: neue DIP-Aktivitäten dieses Abgeordneten",
        "parameters": [
          { "name": "slug", "in": "path", "required": true, "schema": { "type": "string", "pattern": "^[0-9]+$" }, "description": "DIP-Personen-ID" }
        ],
        "responses": {
          "200": { "description": "RSS 2.0", "content": { "application/rss+xml": {} } },
          "404": { "description": "Person nicht gefunden" }
        }
      }
    },
    "/feed/thema/{slug}": {
      "get": {
        "tags": ["Feeds"],
        "summary": "Pro-Thema-Feed: neue Vorgänge zum Themen-Dossier",
        "parameters": [
          { "name": "slug", "in": "path", "required": true, "schema": { "type": "string" }, "description": "Themen-Slug (z. B. klima, mietrecht)" }
        ],
        "responses": {
          "200": { "description": "RSS 2.0", "content": { "application/rss+xml": {} } },
          "404": { "description": "Thema nicht gefunden" }
        }
      }
    },
    "/feed/lobby/{registerNr}": {
      "get": {
        "tags": ["Feeds"],
        "summary": "Pro-Lobby-Akteur-Feed: meldet Aktualisierungen am Lobbyregister-Eintrag",
        "parameters": [
          { "name": "registerNr", "in": "path", "required": true, "schema": { "type": "string", "pattern": "^R\\d{6}$" }, "description": "Lobbyregister-Nummer im Format R000123" }
        ],
        "responses": {
          "200": { "description": "RSS 2.0", "content": { "application/rss+xml": {} } },
          "400": { "description": "Register-Nr ungültig" },
          "404": { "description": "Eintrag nicht gefunden" }
        }
      }
    },
    "/api/search": {
      "get": {
        "tags": ["Search"],
        "summary": "Quer-Suche über Vorgänge, Abgeordnete, Plenarprotokolle, Themen, Glossar",
        "parameters": [
          { "name": "q", "in": "query", "required": true, "schema": { "type": "string", "minLength": 2 }, "description": "Suchbegriff" }
        ],
        "responses": { "200": { "description": "JSON-Ergebnisse gruppiert nach Typ", "content": { "application/json": {} } } }
      }
    },
    "/api/og": {
      "get": {
        "tags": ["Site"],
        "summary": "Dynamisches OG-Bild (1200×630 PNG)",
        "parameters": [
          { "name": "title", "in": "query", "required": true, "schema": { "type": "string" } },
          { "name": "kicker", "in": "query", "required": false, "schema": { "type": "string" } },
          { "name": "date", "in": "query", "required": false, "schema": { "type": "string", "format": "date" } }
        ],
        "responses": { "200": { "description": "PNG", "content": { "image/png": {} } } }
      }
    },
    "/api/dip-raw/{type}/{id}": {
      "get": {
        "tags": ["Raw"],
        "summary": "DIP-Rohdaten-Pass-Through für unabhängige Verifikation",
        "parameters": [
          { "name": "type", "in": "path", "required": true, "schema": { "type": "string", "enum": ["vorgang", "vorgangsposition", "person", "plenarprotokoll", "drucksache", "aktivitaet"] } },
          { "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }
        ],
        "responses": { "200": { "description": "DIP-Originalantwort (JSON)", "content": { "application/json": {} } } }
      }
    },
    "/api/export/parteispenden.csv": {
      "get": {
        "tags": ["Export"],
        "summary": "Großspenden ab 35.000 € nach § 25 PartG",
        "parameters": [
          { "name": "jahr", "in": "query", "schema": { "type": "integer", "minimum": 2024 }, "description": "Jahr (default: aktuelles Jahr)" }
        ],
        "responses": { "200": { "description": "CSV", "content": { "text/csv": {} } } }
      }
    },
    "/api/export/abstimmungen.csv": {
      "get": {
        "tags": ["Export"],
        "summary": "Namentliche Abstimmungen aus abgeordnetenwatch.de (CC0)",
        "responses": { "200": { "description": "CSV", "content": { "text/csv": {} } } }
      }
    },
    "/api/export/themen.csv": {
      "get": {
        "tags": ["Export"],
        "summary": "Themen-Dossiers-Metadaten",
        "responses": { "200": { "description": "CSV", "content": { "text/csv": {} } } }
      }
    },
    "/api/dataset/plenarprotokolle-fts5.db": {
      "get": {
        "tags": ["Datasets"],
        "summary": "SQLite-FTS5-Volltextarchiv aller Plenarprotokolle WP 1-21 (~2 GB)",
        "description": "Inhalte sind amtliche Werke (§ 5 UrhG, gemeinfrei). Index-/Aufbereitungsschicht steht unter CC0 1.0. SHA-256 und Beispiel-Queries auf /entwickler/datasets/plenarprotokolle-fts5.",
        "responses": {
          "200": {
            "description": "SQLite-3-Datei mit FTS5-Index",
            "content": { "application/vnd.sqlite3": {} },
            "headers": {
              "X-Bundespuls-License": { "schema": { "type": "string" }, "description": "Lizenz-Hinweis: CC0-1.0 (index) + UrhG-5 (content)" },
              "Content-Disposition": { "schema": { "type": "string" } }
            }
          },
          "503": { "description": "Dataset wird gerade aufgebaut" }
        }
      }
    },
    "/sitemap.xml": {
      "get": {
        "tags": ["Site"],
        "summary": "Sitemap-Index mit Sub-Sitemaps",
        "responses": { "200": { "description": "Sitemap-Index", "content": { "application/xml": {} } } }
      }
    },
    "/robots.txt": {
      "get": {
        "tags": ["Site"],
        "summary": "Crawler-Direktiven mit getrenntem Allow/Disallow für KI-Search vs. KI-Training",
        "responses": { "200": { "description": "Robots-Direktiven", "content": { "text/plain": {} } } }
      }
    },
    "/llms.txt": {
      "get": {
        "tags": ["Site"],
        "summary": "LLM-Site-Manifest (llmstxt.org-Konvention)",
        "responses": { "200": { "description": "Markdown", "content": { "text/markdown": {} } } }
      }
    },
    "/llms-full.txt": {
      "get": {
        "tags": ["Site"],
        "summary": "LLM-Volltext-Manifest mit Glossar und Methodik",
        "responses": { "200": { "description": "Markdown", "content": { "text/markdown": {} } } }
      }
    }
  },
  "components": {
    "schemas": {
      "DataProvenance": { "$ref": "/schemas/data-provenance.schema.json" },
      "VorgangStation": { "$ref": "/schemas/vorgang-station.schema.json" },
      "AwSidejob": { "$ref": "/schemas/aw-sidejob.schema.json" },
      "Parteispende": { "$ref": "/schemas/parteispende.schema.json" }
    }
  }
}
