{"openapi":"3.1.0","info":{"title":"Pressefeuer API","version":"2026-07-22","summary":"Reporting REST v1, öffentliche PR-Tool-APIs und der Remote-MCP-Endpunkt von Pressefeuer.","description":"Pressefeuer ist eine deutschsprachige PR-Workflow-Plattform für Agenturen und\nKommunikationsteams im DACH-Raum.\n\nDiese Spezifikation beschreibt die drei implementierten externen Schnittstellen:\n\n1. **Reporting REST v1** (`/api/reporting/v1`) — agenturgebundene Kennzahlen,\n   Berichte, asynchrone Exporte, signierte Webhooks und Datenkontrolle.\n   Erfordert einen Agency-Plan-API-Schlüssel.\n2. **Öffentliche Tool-APIs** (`/api/tools/*`) — begrenzte, unauthentifizierte\n   Lead-Magnet-Funktionen mit IP-Rate-Limit.\n3. **Remote MCP** (`/api/mcp`) — JSON-RPC-2.0-Endpunkt für Agenten-Clients.\n\nNicht enthalten, weil nicht vorhanden: eine allgemeine CRUD-API für\nPressemitteilungen, Mandanten oder Newsrooms.\n\nReporting-Herkunft bleibt getrennt: gemessene, extern beobachtete, importierte\nund geschätzte Werte sind nicht austauschbar.","contact":{"name":"Pressefeuer","url":"https://pressefeuer.at/contact"},"license":{"name":"Proprietär","url":"https://pressefeuer.at/agb"},"termsOfService":"https://pressefeuer.at/agb"},"servers":[{"url":"https://pressefeuer.at","description":"Produktion"}],"externalDocs":{"description":"API- und Agenten-Dokumentation","url":"https://pressefeuer.at/api"},"tags":[{"name":"Reporting","description":"Agenturgebundene Reporting REST v1. Authentifizierung per API-Schlüssel, Agency-Plan erforderlich.","externalDocs":{"url":"https://pressefeuer.at/docs/reporting-api"}},{"name":"Tools","description":"Öffentliche PR-Tools ohne Authentifizierung, 5 Requests pro 15 Minuten und IP.","externalDocs":{"url":"https://pressefeuer.at/docs/tools"}},{"name":"MCP","description":"Remote Model-Context-Protocol-Endpunkt für Agenten-Clients.","externalDocs":{"url":"https://pressefeuer.at/docs/agents/mcp"}}],"paths":{"/api/reporting/v1/articles/{pressReleaseId}":{"get":{"tags":["Reporting"],"operationId":"getArticlePerformance","summary":"Kennzahlen einer Pressemitteilung abrufen","description":"Liefert First-Party-Performance und extern beobachtete Insights einer Pressemitteilung der eigenen Agentur.","security":[{"apiKeyHeader":[]},{"bearerAuth":[]}],"parameters":[{"name":"pressReleaseId","in":"path","required":true,"description":"Numerische ID der Pressemitteilung.","schema":{"type":"integer","minimum":1}},{"name":"days","in":"query","required":false,"description":"Auswertungszeitraum in Tagen.","schema":{"type":"integer","minimum":1,"maximum":365,"default":30}}],"responses":{"200":{"description":"Artikelbericht.","headers":{"X-RateLimit-Limit":{"description":"Erlaubte authentifizierte Requests pro Stunde.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Verbleibende Requests im aktuellen Fenster.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix-Zeitpunkt (Sekunden), an dem das Fenster zurückgesetzt wird.","schema":{"type":"integer"}},"X-Pressefeuer-Api-Version":{"description":"Datierte Version des Reporting-Vertrags.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"schemaVersion":{"type":"string","const":"publication-report-v1"},"methodologyVersion":{"type":"string","const":"first-party-v2"},"release":{"type":"object","properties":{"id":{"type":"integer"},"title":{"type":"string"},"status":{"type":"string"},"publishedAt":{"type":["string","null"],"format":"date-time"},"client":{"type":"object","properties":{"agencyId":{"type":"integer"},"name":{"type":"string"}}}}},"performance":{"type":"object","description":"Gemessene First-Party-Kennzahlen (Views, Traffic-Klassen, Interaktionen, Referrer)."},"externalInsights":{"type":"object","description":"Extern beobachtete Signale. Nicht mit gemessenen Werten vermischen."}},"required":["schemaVersion","methodologyVersion","release","performance"]}}}},"400":{"description":"`invalid_parameters` — ID oder `days` außerhalb des gültigen Bereichs.","headers":{"X-RateLimit-Limit":{"description":"Erlaubte authentifizierte Requests pro Stunde.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Verbleibende Requests im aktuellen Fenster.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix-Zeitpunkt (Sekunden), an dem das Fenster zurückgesetzt wird.","schema":{"type":"integer"}},"X-Pressefeuer-Api-Version":{"description":"Datierte Version des Reporting-Vertrags.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Stabiler Fehlercode, z. B. `unauthorized`."},"details":{"type":"object","description":"Nur bei Schema-Verstößen (`invalid_body`): die geflachten Zod-Feldfehler."}},"required":["error"]}}}},"401":{"description":"Kein oder ungültiger API-Schlüssel.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Stabiler Fehlercode, z. B. `unauthorized`."},"details":{"type":"object","description":"Nur bei Schema-Verstößen (`invalid_body`): die geflachten Zod-Feldfehler."}},"required":["error"]}}}},"404":{"description":"`not_found` — Pressemitteilung gehört nicht zur Agentur.","headers":{"X-RateLimit-Limit":{"description":"Erlaubte authentifizierte Requests pro Stunde.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Verbleibende Requests im aktuellen Fenster.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix-Zeitpunkt (Sekunden), an dem das Fenster zurückgesetzt wird.","schema":{"type":"integer"}},"X-Pressefeuer-Api-Version":{"description":"Datierte Version des Reporting-Vertrags.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Stabiler Fehlercode, z. B. `unauthorized`."},"details":{"type":"object","description":"Nur bei Schema-Verstößen (`invalid_body`): die geflachten Zod-Feldfehler."}},"required":["error"]}}}},"429":{"description":"Stundenlimit erschöpft. `X-RateLimit-*` und `Retry-After` beschreiben das Fenster.","headers":{"X-RateLimit-Limit":{"description":"Erlaubte authentifizierte Requests pro Stunde.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Verbleibende Requests im aktuellen Fenster.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix-Zeitpunkt (Sekunden), an dem das Fenster zurückgesetzt wird.","schema":{"type":"integer"}},"X-Pressefeuer-Api-Version":{"description":"Datierte Version des Reporting-Vertrags.","schema":{"type":"string"}},"Retry-After":{"description":"Sekunden bis zum Zurücksetzen des Fensters. Nur auf 429.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","const":"rate_limit_exceeded"},"limit":{"type":"integer","description":"Erlaubte authentifizierte Requests pro Stunde für diesen Plan."}},"required":["error","limit"]}}}},"503":{"description":"Datenbank nicht verfügbar.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Stabiler Fehlercode, z. B. `unauthorized`."},"details":{"type":"object","description":"Nur bei Schema-Verstößen (`invalid_body`): die geflachten Zod-Feldfehler."}},"required":["error"]}}}}}}},"/api/reporting/v1/reports/{reportId}":{"get":{"tags":["Reporting"],"operationId":"getPublicationReport","summary":"Publication-Report-Snapshot abrufen","description":"Liefert einen unveränderlichen Berichts-Snapshot inklusive Methodik und Herkunft.","security":[{"apiKeyHeader":[]},{"bearerAuth":[]}],"parameters":[{"name":"reportId","in":"path","required":true,"description":"UUID des Berichts.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Bericht.","headers":{"X-RateLimit-Limit":{"description":"Erlaubte authentifizierte Requests pro Stunde.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Verbleibende Requests im aktuellen Fenster.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix-Zeitpunkt (Sekunden), an dem das Fenster zurückgesetzt wird.","schema":{"type":"integer"}},"X-Pressefeuer-Api-Version":{"description":"Datierte Version des Reporting-Vertrags.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"report":{"type":"object"}},"required":["report"]}}}},"401":{"description":"Kein oder ungültiger API-Schlüssel.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Stabiler Fehlercode, z. B. `unauthorized`."},"details":{"type":"object","description":"Nur bei Schema-Verstößen (`invalid_body`): die geflachten Zod-Feldfehler."}},"required":["error"]}}}},"404":{"description":"`not_found` — Bericht existiert nicht oder gehört einer anderen Agentur.","headers":{"X-RateLimit-Limit":{"description":"Erlaubte authentifizierte Requests pro Stunde.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Verbleibende Requests im aktuellen Fenster.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix-Zeitpunkt (Sekunden), an dem das Fenster zurückgesetzt wird.","schema":{"type":"integer"}},"X-Pressefeuer-Api-Version":{"description":"Datierte Version des Reporting-Vertrags.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Stabiler Fehlercode, z. B. `unauthorized`."},"details":{"type":"object","description":"Nur bei Schema-Verstößen (`invalid_body`): die geflachten Zod-Feldfehler."}},"required":["error"]}}}},"429":{"description":"Stundenlimit erschöpft. `X-RateLimit-*` und `Retry-After` beschreiben das Fenster.","headers":{"X-RateLimit-Limit":{"description":"Erlaubte authentifizierte Requests pro Stunde.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Verbleibende Requests im aktuellen Fenster.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix-Zeitpunkt (Sekunden), an dem das Fenster zurückgesetzt wird.","schema":{"type":"integer"}},"X-Pressefeuer-Api-Version":{"description":"Datierte Version des Reporting-Vertrags.","schema":{"type":"string"}},"Retry-After":{"description":"Sekunden bis zum Zurücksetzen des Fensters. Nur auf 429.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","const":"rate_limit_exceeded"},"limit":{"type":"integer","description":"Erlaubte authentifizierte Requests pro Stunde für diesen Plan."}},"required":["error","limit"]}}}},"503":{"description":"Datenbank nicht verfügbar.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Stabiler Fehlercode, z. B. `unauthorized`."},"details":{"type":"object","description":"Nur bei Schema-Verstößen (`invalid_body`): die geflachten Zod-Feldfehler."}},"required":["error"]}}}}}}},"/api/reporting/v1/exports":{"post":{"tags":["Reporting"],"operationId":"createReportingExport","summary":"Asynchronen Export anlegen","description":"Legt einen Export-Job an. Der `Idempotency-Key`-Header ist verpflichtend; ein wiederholter Schlüssel liefert den bestehenden Job mit Status 200 statt 202.","security":[{"apiKeyHeader":[]},{"bearerAuth":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Eindeutiger Schlüssel des Aufrufers, 1–100 Zeichen.","schema":{"type":"string","minLength":1,"maxLength":100}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"scopeType":{"type":"string","enum":["article","campaign","portfolio"]},"scopeId":{"description":"Bei `article` die numerische Pressemitteilungs-ID (als Zahl oder als Ziffernfolge, 1 … 2147483647), sonst die UUID der Kampagne bzw. des Portfolios. Eine nicht-numerische `scopeId` bei `article` wird mit 400 `invalid_body` abgelehnt.","oneOf":[{"type":"integer","minimum":1},{"type":"string","minLength":1,"maxLength":100}]},"days":{"type":"integer","minimum":1,"maximum":365,"default":30},"format":{"type":"string","enum":["pdf","csv","json"]}},"required":["scopeType","scopeId","format"]}}}},"responses":{"200":{"description":"Idempotency-Key bereits verwendet; bestehender Job.","headers":{"X-RateLimit-Limit":{"description":"Erlaubte authentifizierte Requests pro Stunde.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Verbleibende Requests im aktuellen Fenster.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix-Zeitpunkt (Sekunden), an dem das Fenster zurückgesetzt wird.","schema":{"type":"integer"}},"X-Pressefeuer-Api-Version":{"description":"Datierte Version des Reporting-Vertrags.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string","const":"existing"},"statusUrl":{"type":"string"}},"required":["id","status","statusUrl"]}}}},"202":{"description":"Export eingereiht.","headers":{"X-RateLimit-Limit":{"description":"Erlaubte authentifizierte Requests pro Stunde.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Verbleibende Requests im aktuellen Fenster.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix-Zeitpunkt (Sekunden), an dem das Fenster zurückgesetzt wird.","schema":{"type":"integer"}},"X-Pressefeuer-Api-Version":{"description":"Datierte Version des Reporting-Vertrags.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string","const":"queued"},"statusUrl":{"type":"string"}},"required":["id","status","statusUrl"]}}}},"400":{"description":"`idempotency_key_required` oder `invalid_body`. Letzteres auch, wenn `scopeType: \"article\"` mit einer nicht-numerischen `scopeId` kombiniert wird.","headers":{"X-RateLimit-Limit":{"description":"Erlaubte authentifizierte Requests pro Stunde.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Verbleibende Requests im aktuellen Fenster.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix-Zeitpunkt (Sekunden), an dem das Fenster zurückgesetzt wird.","schema":{"type":"integer"}},"X-Pressefeuer-Api-Version":{"description":"Datierte Version des Reporting-Vertrags.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Stabiler Fehlercode, z. B. `unauthorized`."},"details":{"type":"object","description":"Nur bei Schema-Verstößen (`invalid_body`): die geflachten Zod-Feldfehler."}},"required":["error"]}}}},"401":{"description":"Kein oder ungültiger API-Schlüssel.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Stabiler Fehlercode, z. B. `unauthorized`."},"details":{"type":"object","description":"Nur bei Schema-Verstößen (`invalid_body`): die geflachten Zod-Feldfehler."}},"required":["error"]}}}},"404":{"description":"`scope_not_found` — Scope gehört nicht zur Agentur.","headers":{"X-RateLimit-Limit":{"description":"Erlaubte authentifizierte Requests pro Stunde.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Verbleibende Requests im aktuellen Fenster.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix-Zeitpunkt (Sekunden), an dem das Fenster zurückgesetzt wird.","schema":{"type":"integer"}},"X-Pressefeuer-Api-Version":{"description":"Datierte Version des Reporting-Vertrags.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Stabiler Fehlercode, z. B. `unauthorized`."},"details":{"type":"object","description":"Nur bei Schema-Verstößen (`invalid_body`): die geflachten Zod-Feldfehler."}},"required":["error"]}}}},"413":{"description":"`payload_too_large` — Body überschreitet 16 KiB.","headers":{"X-RateLimit-Limit":{"description":"Erlaubte authentifizierte Requests pro Stunde.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Verbleibende Requests im aktuellen Fenster.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix-Zeitpunkt (Sekunden), an dem das Fenster zurückgesetzt wird.","schema":{"type":"integer"}},"X-Pressefeuer-Api-Version":{"description":"Datierte Version des Reporting-Vertrags.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Stabiler Fehlercode, z. B. `unauthorized`."},"details":{"type":"object","description":"Nur bei Schema-Verstößen (`invalid_body`): die geflachten Zod-Feldfehler."}},"required":["error"]}}}},"429":{"description":"Stundenlimit erschöpft. `X-RateLimit-*` und `Retry-After` beschreiben das Fenster.","headers":{"X-RateLimit-Limit":{"description":"Erlaubte authentifizierte Requests pro Stunde.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Verbleibende Requests im aktuellen Fenster.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix-Zeitpunkt (Sekunden), an dem das Fenster zurückgesetzt wird.","schema":{"type":"integer"}},"X-Pressefeuer-Api-Version":{"description":"Datierte Version des Reporting-Vertrags.","schema":{"type":"string"}},"Retry-After":{"description":"Sekunden bis zum Zurücksetzen des Fensters. Nur auf 429.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","const":"rate_limit_exceeded"},"limit":{"type":"integer","description":"Erlaubte authentifizierte Requests pro Stunde für diesen Plan."}},"required":["error","limit"]}}}},"500":{"description":"`export_creation_failed` — der Job konnte weder angelegt noch über den Idempotency-Key wiedergefunden werden. Seltener Wettlauf; der Aufruf darf wiederholt werden.","headers":{"X-RateLimit-Limit":{"description":"Erlaubte authentifizierte Requests pro Stunde.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Verbleibende Requests im aktuellen Fenster.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix-Zeitpunkt (Sekunden), an dem das Fenster zurückgesetzt wird.","schema":{"type":"integer"}},"X-Pressefeuer-Api-Version":{"description":"Datierte Version des Reporting-Vertrags.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Stabiler Fehlercode, z. B. `unauthorized`."},"details":{"type":"object","description":"Nur bei Schema-Verstößen (`invalid_body`): die geflachten Zod-Feldfehler."}},"required":["error"]}}}},"503":{"description":"Datenbank nicht verfügbar.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Stabiler Fehlercode, z. B. `unauthorized`."},"details":{"type":"object","description":"Nur bei Schema-Verstößen (`invalid_body`): die geflachten Zod-Feldfehler."}},"required":["error"]}}}}}}},"/api/reporting/v1/exports/{jobId}":{"get":{"tags":["Reporting"],"operationId":"getReportingExport","summary":"Status eines Export-Jobs abrufen","security":[{"apiKeyHeader":[]},{"bearerAuth":[]}],"parameters":[{"name":"jobId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Job-Status. `downloadUrl` ist nur bei `status: completed` gesetzt.","headers":{"X-RateLimit-Limit":{"description":"Erlaubte authentifizierte Requests pro Stunde.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Verbleibende Requests im aktuellen Fenster.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix-Zeitpunkt (Sekunden), an dem das Fenster zurückgesetzt wird.","schema":{"type":"integer"}},"X-Pressefeuer-Api-Version":{"description":"Datierte Version des Reporting-Vertrags.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"job":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"format":{"type":"string","enum":["pdf","csv","json"]},"scopeType":{"type":"string","enum":["article","campaign","portfolio"]},"scopeId":{"type":"string"},"status":{"type":"string"},"reportId":{"type":["string","null"],"format":"uuid"},"error":{"type":["string","null"]},"expiresAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"completedAt":{"type":["string","null"],"format":"date-time"}}},"downloadUrl":{"type":["string","null"]}},"required":["job","downloadUrl"]}}}},"401":{"description":"Kein oder ungültiger API-Schlüssel.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Stabiler Fehlercode, z. B. `unauthorized`."},"details":{"type":"object","description":"Nur bei Schema-Verstößen (`invalid_body`): die geflachten Zod-Feldfehler."}},"required":["error"]}}}},"404":{"description":"`not_found`.","headers":{"X-RateLimit-Limit":{"description":"Erlaubte authentifizierte Requests pro Stunde.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Verbleibende Requests im aktuellen Fenster.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix-Zeitpunkt (Sekunden), an dem das Fenster zurückgesetzt wird.","schema":{"type":"integer"}},"X-Pressefeuer-Api-Version":{"description":"Datierte Version des Reporting-Vertrags.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Stabiler Fehlercode, z. B. `unauthorized`."},"details":{"type":"object","description":"Nur bei Schema-Verstößen (`invalid_body`): die geflachten Zod-Feldfehler."}},"required":["error"]}}}},"429":{"description":"Stundenlimit erschöpft. `X-RateLimit-*` und `Retry-After` beschreiben das Fenster.","headers":{"X-RateLimit-Limit":{"description":"Erlaubte authentifizierte Requests pro Stunde.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Verbleibende Requests im aktuellen Fenster.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix-Zeitpunkt (Sekunden), an dem das Fenster zurückgesetzt wird.","schema":{"type":"integer"}},"X-Pressefeuer-Api-Version":{"description":"Datierte Version des Reporting-Vertrags.","schema":{"type":"string"}},"Retry-After":{"description":"Sekunden bis zum Zurücksetzen des Fensters. Nur auf 429.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","const":"rate_limit_exceeded"},"limit":{"type":"integer","description":"Erlaubte authentifizierte Requests pro Stunde für diesen Plan."}},"required":["error","limit"]}}}},"503":{"description":"Datenbank nicht verfügbar.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Stabiler Fehlercode, z. B. `unauthorized`."},"details":{"type":"object","description":"Nur bei Schema-Verstößen (`invalid_body`): die geflachten Zod-Feldfehler."}},"required":["error"]}}}}}}},"/api/reporting/v1/exports/{jobId}/download":{"get":{"tags":["Reporting"],"operationId":"downloadReportingExport","summary":"Fertigen Export herunterladen","description":"Liefert die Berichtsdatei als Anhang. Jeder Abruf wird im Report-Audit protokolliert.","security":[{"apiKeyHeader":[]},{"bearerAuth":[]}],"parameters":[{"name":"jobId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Berichtsdatei (PDF, CSV oder JSON gemäß Job-Format).","headers":{"X-RateLimit-Limit":{"description":"Erlaubte authentifizierte Requests pro Stunde.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Verbleibende Requests im aktuellen Fenster.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix-Zeitpunkt (Sekunden), an dem das Fenster zurückgesetzt wird.","schema":{"type":"integer"}},"X-Pressefeuer-Api-Version":{"description":"Datierte Version des Reporting-Vertrags.","schema":{"type":"string"}},"Content-Disposition":{"description":"Dateiname des Anhangs.","schema":{"type":"string"}}},"content":{"application/pdf":{"schema":{"type":"string","format":"binary"}},"text/csv":{"schema":{"type":"string"}},"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Kein oder ungültiger API-Schlüssel.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Stabiler Fehlercode, z. B. `unauthorized`."},"details":{"type":"object","description":"Nur bei Schema-Verstößen (`invalid_body`): die geflachten Zod-Feldfehler."}},"required":["error"]}}}},"404":{"description":"`not_found`.","headers":{"X-RateLimit-Limit":{"description":"Erlaubte authentifizierte Requests pro Stunde.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Verbleibende Requests im aktuellen Fenster.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix-Zeitpunkt (Sekunden), an dem das Fenster zurückgesetzt wird.","schema":{"type":"integer"}},"X-Pressefeuer-Api-Version":{"description":"Datierte Version des Reporting-Vertrags.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Stabiler Fehlercode, z. B. `unauthorized`."},"details":{"type":"object","description":"Nur bei Schema-Verstößen (`invalid_body`): die geflachten Zod-Feldfehler."}},"required":["error"]}}}},"409":{"description":"`export_not_ready` — der Job ist nicht abgeschlossen. Das umfasst `queued`, `processing` und **`failed`**; welcher Fall vorliegt, sagt `GET /api/reporting/v1/exports/{jobId}`.","headers":{"X-RateLimit-Limit":{"description":"Erlaubte authentifizierte Requests pro Stunde.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Verbleibende Requests im aktuellen Fenster.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix-Zeitpunkt (Sekunden), an dem das Fenster zurückgesetzt wird.","schema":{"type":"integer"}},"X-Pressefeuer-Api-Version":{"description":"Datierte Version des Reporting-Vertrags.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Stabiler Fehlercode, z. B. `unauthorized`."},"details":{"type":"object","description":"Nur bei Schema-Verstößen (`invalid_body`): die geflachten Zod-Feldfehler."}},"required":["error"]}}}},"410":{"description":"`export_expired` — Snapshot ist abgelaufen.","headers":{"X-RateLimit-Limit":{"description":"Erlaubte authentifizierte Requests pro Stunde.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Verbleibende Requests im aktuellen Fenster.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix-Zeitpunkt (Sekunden), an dem das Fenster zurückgesetzt wird.","schema":{"type":"integer"}},"X-Pressefeuer-Api-Version":{"description":"Datierte Version des Reporting-Vertrags.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Stabiler Fehlercode, z. B. `unauthorized`."},"details":{"type":"object","description":"Nur bei Schema-Verstößen (`invalid_body`): die geflachten Zod-Feldfehler."}},"required":["error"]}}}},"429":{"description":"Stundenlimit erschöpft. `X-RateLimit-*` und `Retry-After` beschreiben das Fenster.","headers":{"X-RateLimit-Limit":{"description":"Erlaubte authentifizierte Requests pro Stunde.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Verbleibende Requests im aktuellen Fenster.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix-Zeitpunkt (Sekunden), an dem das Fenster zurückgesetzt wird.","schema":{"type":"integer"}},"X-Pressefeuer-Api-Version":{"description":"Datierte Version des Reporting-Vertrags.","schema":{"type":"string"}},"Retry-After":{"description":"Sekunden bis zum Zurücksetzen des Fensters. Nur auf 429.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","const":"rate_limit_exceeded"},"limit":{"type":"integer","description":"Erlaubte authentifizierte Requests pro Stunde für diesen Plan."}},"required":["error","limit"]}}}},"503":{"description":"Datenbank nicht verfügbar.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Stabiler Fehlercode, z. B. `unauthorized`."},"details":{"type":"object","description":"Nur bei Schema-Verstößen (`invalid_body`): die geflachten Zod-Feldfehler."}},"required":["error"]}}}}}}},"/api/reporting/v1/webhooks":{"get":{"tags":["Reporting"],"operationId":"listReportingWebhooks","summary":"Webhooks und letzte Zustellungen auflisten","description":"Liefert alle Webhooks der Agentur sowie die letzten 100 Zustellversuche.","security":[{"apiKeyHeader":[]},{"bearerAuth":[]}],"responses":{"200":{"description":"Webhooks und Zustellungen. Das Signing-Secret wird nie erneut ausgegeben.","headers":{"X-RateLimit-Limit":{"description":"Erlaubte authentifizierte Requests pro Stunde.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Verbleibende Requests im aktuellen Fenster.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix-Zeitpunkt (Sekunden), an dem das Fenster zurückgesetzt wird.","schema":{"type":"integer"}},"X-Pressefeuer-Api-Version":{"description":"Datierte Version des Reporting-Vertrags.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"webhooks":{"type":"array","items":{"$ref":"#/components/schemas/ReportingWebhook"}},"deliveries":{"type":"array","items":{"type":"object"}}},"required":["webhooks","deliveries"]}}}},"401":{"description":"Kein oder ungültiger API-Schlüssel.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Stabiler Fehlercode, z. B. `unauthorized`."},"details":{"type":"object","description":"Nur bei Schema-Verstößen (`invalid_body`): die geflachten Zod-Feldfehler."}},"required":["error"]}}}},"429":{"description":"Stundenlimit erschöpft. `X-RateLimit-*` und `Retry-After` beschreiben das Fenster.","headers":{"X-RateLimit-Limit":{"description":"Erlaubte authentifizierte Requests pro Stunde.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Verbleibende Requests im aktuellen Fenster.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix-Zeitpunkt (Sekunden), an dem das Fenster zurückgesetzt wird.","schema":{"type":"integer"}},"X-Pressefeuer-Api-Version":{"description":"Datierte Version des Reporting-Vertrags.","schema":{"type":"string"}},"Retry-After":{"description":"Sekunden bis zum Zurücksetzen des Fensters. Nur auf 429.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","const":"rate_limit_exceeded"},"limit":{"type":"integer","description":"Erlaubte authentifizierte Requests pro Stunde für diesen Plan."}},"required":["error","limit"]}}}},"503":{"description":"Datenbank nicht verfügbar.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Stabiler Fehlercode, z. B. `unauthorized`."},"details":{"type":"object","description":"Nur bei Schema-Verstößen (`invalid_body`): die geflachten Zod-Feldfehler."}},"required":["error"]}}}}}},"post":{"tags":["Reporting"],"operationId":"createReportingWebhook","summary":"Webhook registrieren","description":"Registriert einen HTTPS-Endpunkt. Das Signing-Secret wird ausschließlich in dieser Antwort zurückgegeben. Interne und nicht auflösbare Ziele werden abgelehnt.","security":[{"apiKeyHeader":[]},{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"endpointUrl":{"type":"string","format":"uri","maxLength":2000},"events":{"type":"array","minItems":1,"items":{"$ref":"#/components/schemas/ReportingWebhookEvent"}}},"required":["endpointUrl","events"]}}}},"responses":{"201":{"description":"Webhook angelegt.","headers":{"X-RateLimit-Limit":{"description":"Erlaubte authentifizierte Requests pro Stunde.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Verbleibende Requests im aktuellen Fenster.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix-Zeitpunkt (Sekunden), an dem das Fenster zurückgesetzt wird.","schema":{"type":"integer"}},"X-Pressefeuer-Api-Version":{"description":"Datierte Version des Reporting-Vertrags.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"endpointUrl":{"type":"string","format":"uri"},"events":{"type":"array","items":{"$ref":"#/components/schemas/ReportingWebhookEvent"}},"signingSecret":{"type":"string","description":"Nur einmal sichtbar. Präfix `pfr_whsec_`."}},"required":["id","endpointUrl","events","signingSecret"]}}}},"400":{"description":"`invalid_body` oder `unsafe_endpoint`.","headers":{"X-RateLimit-Limit":{"description":"Erlaubte authentifizierte Requests pro Stunde.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Verbleibende Requests im aktuellen Fenster.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix-Zeitpunkt (Sekunden), an dem das Fenster zurückgesetzt wird.","schema":{"type":"integer"}},"X-Pressefeuer-Api-Version":{"description":"Datierte Version des Reporting-Vertrags.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Stabiler Fehlercode, z. B. `unauthorized`."},"details":{"type":"object","description":"Nur bei Schema-Verstößen (`invalid_body`): die geflachten Zod-Feldfehler."}},"required":["error"]}}}},"401":{"description":"Kein oder ungültiger API-Schlüssel.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Stabiler Fehlercode, z. B. `unauthorized`."},"details":{"type":"object","description":"Nur bei Schema-Verstößen (`invalid_body`): die geflachten Zod-Feldfehler."}},"required":["error"]}}}},"409":{"description":"`endpoint_already_registered`.","headers":{"X-RateLimit-Limit":{"description":"Erlaubte authentifizierte Requests pro Stunde.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Verbleibende Requests im aktuellen Fenster.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix-Zeitpunkt (Sekunden), an dem das Fenster zurückgesetzt wird.","schema":{"type":"integer"}},"X-Pressefeuer-Api-Version":{"description":"Datierte Version des Reporting-Vertrags.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Stabiler Fehlercode, z. B. `unauthorized`."},"details":{"type":"object","description":"Nur bei Schema-Verstößen (`invalid_body`): die geflachten Zod-Feldfehler."}},"required":["error"]}}}},"413":{"description":"`payload_too_large` — Body überschreitet 16 KiB.","headers":{"X-RateLimit-Limit":{"description":"Erlaubte authentifizierte Requests pro Stunde.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Verbleibende Requests im aktuellen Fenster.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix-Zeitpunkt (Sekunden), an dem das Fenster zurückgesetzt wird.","schema":{"type":"integer"}},"X-Pressefeuer-Api-Version":{"description":"Datierte Version des Reporting-Vertrags.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Stabiler Fehlercode, z. B. `unauthorized`."},"details":{"type":"object","description":"Nur bei Schema-Verstößen (`invalid_body`): die geflachten Zod-Feldfehler."}},"required":["error"]}}}},"429":{"description":"Stundenlimit erschöpft. `X-RateLimit-*` und `Retry-After` beschreiben das Fenster.","headers":{"X-RateLimit-Limit":{"description":"Erlaubte authentifizierte Requests pro Stunde.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Verbleibende Requests im aktuellen Fenster.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix-Zeitpunkt (Sekunden), an dem das Fenster zurückgesetzt wird.","schema":{"type":"integer"}},"X-Pressefeuer-Api-Version":{"description":"Datierte Version des Reporting-Vertrags.","schema":{"type":"string"}},"Retry-After":{"description":"Sekunden bis zum Zurücksetzen des Fensters. Nur auf 429.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","const":"rate_limit_exceeded"},"limit":{"type":"integer","description":"Erlaubte authentifizierte Requests pro Stunde für diesen Plan."}},"required":["error","limit"]}}}},"503":{"description":"Datenbank nicht verfügbar.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Stabiler Fehlercode, z. B. `unauthorized`."},"details":{"type":"object","description":"Nur bei Schema-Verstößen (`invalid_body`): die geflachten Zod-Feldfehler."}},"required":["error"]}}}}}}},"/api/reporting/v1/webhooks/{webhookId}":{"delete":{"tags":["Reporting"],"operationId":"disableReportingWebhook","summary":"Webhook deaktivieren","description":"Setzt den Webhook auf inaktiv. Bereits erfolgte Zustellungen bleiben zur Nachvollziehbarkeit erhalten.","security":[{"apiKeyHeader":[]},{"bearerAuth":[]}],"parameters":[{"name":"webhookId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Webhook deaktiviert.","headers":{"X-RateLimit-Limit":{"description":"Erlaubte authentifizierte Requests pro Stunde.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Verbleibende Requests im aktuellen Fenster.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix-Zeitpunkt (Sekunden), an dem das Fenster zurückgesetzt wird.","schema":{"type":"integer"}},"X-Pressefeuer-Api-Version":{"description":"Datierte Version des Reporting-Vertrags.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","const":true}},"required":["success"]}}}},"401":{"description":"Kein oder ungültiger API-Schlüssel.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Stabiler Fehlercode, z. B. `unauthorized`."},"details":{"type":"object","description":"Nur bei Schema-Verstößen (`invalid_body`): die geflachten Zod-Feldfehler."}},"required":["error"]}}}},"404":{"description":"`not_found`.","headers":{"X-RateLimit-Limit":{"description":"Erlaubte authentifizierte Requests pro Stunde.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Verbleibende Requests im aktuellen Fenster.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix-Zeitpunkt (Sekunden), an dem das Fenster zurückgesetzt wird.","schema":{"type":"integer"}},"X-Pressefeuer-Api-Version":{"description":"Datierte Version des Reporting-Vertrags.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Stabiler Fehlercode, z. B. `unauthorized`."},"details":{"type":"object","description":"Nur bei Schema-Verstößen (`invalid_body`): die geflachten Zod-Feldfehler."}},"required":["error"]}}}},"429":{"description":"Stundenlimit erschöpft. `X-RateLimit-*` und `Retry-After` beschreiben das Fenster.","headers":{"X-RateLimit-Limit":{"description":"Erlaubte authentifizierte Requests pro Stunde.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Verbleibende Requests im aktuellen Fenster.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix-Zeitpunkt (Sekunden), an dem das Fenster zurückgesetzt wird.","schema":{"type":"integer"}},"X-Pressefeuer-Api-Version":{"description":"Datierte Version des Reporting-Vertrags.","schema":{"type":"string"}},"Retry-After":{"description":"Sekunden bis zum Zurücksetzen des Fensters. Nur auf 429.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","const":"rate_limit_exceeded"},"limit":{"type":"integer","description":"Erlaubte authentifizierte Requests pro Stunde für diesen Plan."}},"required":["error","limit"]}}}},"503":{"description":"Datenbank nicht verfügbar.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Stabiler Fehlercode, z. B. `unauthorized`."},"details":{"type":"object","description":"Nur bei Schema-Verstößen (`invalid_body`): die geflachten Zod-Feldfehler."}},"required":["error"]}}}}}}},"/api/reporting/v1/conversions":{"post":{"tags":["Reporting"],"operationId":"recordReportingConversion","summary":"Conversion-Event melden","description":"Meldet ein extern gemessenes Conversion-Event zu einer Pressemitteilung.\n\nZusätzlich zum API-Schlüssel ist eine HMAC-SHA-256-Signatur verpflichtend:\n\n- `X-Pressefeuer-Timestamp`: Unix-Zeit in **Sekunden**. Mehr als 5 Minuten\n  Abweichung von der Serverzeit wird abgelehnt.\n- `X-Pressefeuer-Signature`: `hex(HMAC_SHA256(apiKey, timestamp + \".\" + rawBody))`\n  — der Schlüssel ist das HMAC-Secret, signiert wird der Zeitstempel, ein\n  Punkt und der **rohe** Request-Body, Byte für Byte wie gesendet. Ergebnis:\n  64 Hex-Zeichen. Andere Kodierung oder Länge wird abgelehnt.\n\n`eventId` macht den Aufruf idempotent — ein bereits bekanntes Event\nantwortet mit 200 und `duplicate: true`.","security":[{"apiKeyHeader":[]},{"bearerAuth":[]}],"parameters":[{"name":"X-Pressefeuer-Timestamp","in":"header","required":true,"description":"Unix-Zeitstempel der Signatur in Sekunden, maximal 5 Minuten von der Serverzeit entfernt.","schema":{"type":"string","pattern":"^[0-9]+$"}},{"name":"X-Pressefeuer-Signature","in":"header","required":true,"description":"`hex(HMAC_SHA256(apiKey, timestamp + \".\" + rawBody))`, 64 Hex-Zeichen.","schema":{"type":"string","pattern":"^[a-fA-F0-9]{64}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"eventId":{"type":"string","minLength":1,"maxLength":100},"pressReleaseId":{"type":"integer","minimum":1},"kind":{"type":"string","minLength":1,"maxLength":80},"value":{"type":"number","minimum":0},"currency":{"type":"string","minLength":3,"maxLength":3},"externalReference":{"type":"string","maxLength":500,"description":"Wird nur als Hash gespeichert, nie im Klartext."},"occurredAt":{"type":"string","format":"date-time","pattern":"Z$","description":"ISO-8601 **in UTC mit `Z`-Suffix** (z. B. `2026-08-22T09:15:00Z`). Zeitzonen-Offsets wie `+02:00` werden mit 400 `invalid_payload` abgelehnt. Höchstens 30 Tage von der Serverzeit entfernt."}},"required":["eventId","pressReleaseId","kind","occurredAt"]}}}},"responses":{"200":{"description":"`eventId` bereits bekannt; nichts gespeichert.","headers":{"X-RateLimit-Limit":{"description":"Erlaubte authentifizierte Requests pro Stunde.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Verbleibende Requests im aktuellen Fenster.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix-Zeitpunkt (Sekunden), an dem das Fenster zurückgesetzt wird.","schema":{"type":"integer"}},"X-Pressefeuer-Api-Version":{"description":"Datierte Version des Reporting-Vertrags.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":["string","null"]},"duplicate":{"type":"boolean","const":true}},"required":["id","duplicate"]}}}},"201":{"description":"Event gespeichert.","headers":{"X-RateLimit-Limit":{"description":"Erlaubte authentifizierte Requests pro Stunde.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Verbleibende Requests im aktuellen Fenster.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix-Zeitpunkt (Sekunden), an dem das Fenster zurückgesetzt wird.","schema":{"type":"integer"}},"X-Pressefeuer-Api-Version":{"description":"Datierte Version des Reporting-Vertrags.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":["string","null"],"format":"uuid"},"duplicate":{"type":"boolean","const":false}},"required":["id","duplicate"]}}}},"400":{"description":"`invalid_json`, `invalid_payload` oder `occurred_at_out_of_range`.","headers":{"X-RateLimit-Limit":{"description":"Erlaubte authentifizierte Requests pro Stunde.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Verbleibende Requests im aktuellen Fenster.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix-Zeitpunkt (Sekunden), an dem das Fenster zurückgesetzt wird.","schema":{"type":"integer"}},"X-Pressefeuer-Api-Version":{"description":"Datierte Version des Reporting-Vertrags.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Stabiler Fehlercode, z. B. `unauthorized`."},"details":{"type":"object","description":"Nur bei Schema-Verstößen (`invalid_body`): die geflachten Zod-Feldfehler."}},"required":["error"]}}}},"401":{"description":"Kein oder ungültiger API-Schlüssel.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Stabiler Fehlercode, z. B. `unauthorized`."},"details":{"type":"object","description":"Nur bei Schema-Verstößen (`invalid_body`): die geflachten Zod-Feldfehler."}},"required":["error"]}}}},"404":{"description":"`release_not_found`.","headers":{"X-RateLimit-Limit":{"description":"Erlaubte authentifizierte Requests pro Stunde.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Verbleibende Requests im aktuellen Fenster.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix-Zeitpunkt (Sekunden), an dem das Fenster zurückgesetzt wird.","schema":{"type":"integer"}},"X-Pressefeuer-Api-Version":{"description":"Datierte Version des Reporting-Vertrags.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Stabiler Fehlercode, z. B. `unauthorized`."},"details":{"type":"object","description":"Nur bei Schema-Verstößen (`invalid_body`): die geflachten Zod-Feldfehler."}},"required":["error"]}}}},"413":{"description":"`payload_too_large` — Body überschreitet 16 KiB.","headers":{"X-RateLimit-Limit":{"description":"Erlaubte authentifizierte Requests pro Stunde.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Verbleibende Requests im aktuellen Fenster.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix-Zeitpunkt (Sekunden), an dem das Fenster zurückgesetzt wird.","schema":{"type":"integer"}},"X-Pressefeuer-Api-Version":{"description":"Datierte Version des Reporting-Vertrags.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Stabiler Fehlercode, z. B. `unauthorized`."},"details":{"type":"object","description":"Nur bei Schema-Verstößen (`invalid_body`): die geflachten Zod-Feldfehler."}},"required":["error"]}}}},"429":{"description":"Stundenlimit erschöpft. `X-RateLimit-*` und `Retry-After` beschreiben das Fenster.","headers":{"X-RateLimit-Limit":{"description":"Erlaubte authentifizierte Requests pro Stunde.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Verbleibende Requests im aktuellen Fenster.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix-Zeitpunkt (Sekunden), an dem das Fenster zurückgesetzt wird.","schema":{"type":"integer"}},"X-Pressefeuer-Api-Version":{"description":"Datierte Version des Reporting-Vertrags.","schema":{"type":"string"}},"Retry-After":{"description":"Sekunden bis zum Zurücksetzen des Fensters. Nur auf 429.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","const":"rate_limit_exceeded"},"limit":{"type":"integer","description":"Erlaubte authentifizierte Requests pro Stunde für diesen Plan."}},"required":["error","limit"]}}}},"503":{"description":"Datenbank nicht verfügbar.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Stabiler Fehlercode, z. B. `unauthorized`."},"details":{"type":"object","description":"Nur bei Schema-Verstößen (`invalid_body`): die geflachten Zod-Feldfehler."}},"required":["error"]}}}}}}},"/api/reporting/v1/data":{"get":{"tags":["Reporting"],"operationId":"exportReportingData","summary":"Vollständigen Reporting-Datenbestand exportieren","description":"Liefert alle Reporting-Daten der Agentur: Berichte, Audits, Kampagnen, Portfolios, Zeitpläne, Medienresonanz, Search- und KI-Sichtbarkeit, Conversions, Export-Jobs, Provider-Verbindungen und Webhooks.","security":[{"apiKeyHeader":[]},{"bearerAuth":[]}],"responses":{"200":{"description":"Datenexport.","headers":{"X-RateLimit-Limit":{"description":"Erlaubte authentifizierte Requests pro Stunde.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Verbleibende Requests im aktuellen Fenster.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix-Zeitpunkt (Sekunden), an dem das Fenster zurückgesetzt wird.","schema":{"type":"integer"}},"X-Pressefeuer-Api-Version":{"description":"Datierte Version des Reporting-Vertrags.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"exportedAt":{"type":"string","format":"date-time"},"agencyId":{"type":"integer"},"reports":{"type":"array","items":{"type":"object"}},"audits":{"type":"array","items":{"type":"object"}},"campaigns":{"type":"array","items":{"type":"object"}},"portfolios":{"type":"array","items":{"type":"object"}},"schedules":{"type":"array","items":{"type":"object"}},"mediaMentions":{"type":"array","items":{"type":"object"}},"searchVisibility":{"type":"array","items":{"type":"object"}},"aiVisibility":{"type":"object"},"conversions":{"type":"array","items":{"type":"object"}},"exportJobs":{"type":"array","items":{"type":"object"}},"providerConnections":{"type":"array","items":{"type":"object"}},"webhooks":{"type":"array","items":{"type":"object"}},"webhookDeliveries":{"type":"array","items":{"type":"object"}}},"required":["exportedAt","agencyId"]}}}},"401":{"description":"Kein oder ungültiger API-Schlüssel.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Stabiler Fehlercode, z. B. `unauthorized`."},"details":{"type":"object","description":"Nur bei Schema-Verstößen (`invalid_body`): die geflachten Zod-Feldfehler."}},"required":["error"]}}}},"429":{"description":"Stundenlimit erschöpft. `X-RateLimit-*` und `Retry-After` beschreiben das Fenster.","headers":{"X-RateLimit-Limit":{"description":"Erlaubte authentifizierte Requests pro Stunde.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Verbleibende Requests im aktuellen Fenster.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix-Zeitpunkt (Sekunden), an dem das Fenster zurückgesetzt wird.","schema":{"type":"integer"}},"X-Pressefeuer-Api-Version":{"description":"Datierte Version des Reporting-Vertrags.","schema":{"type":"string"}},"Retry-After":{"description":"Sekunden bis zum Zurücksetzen des Fensters. Nur auf 429.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","const":"rate_limit_exceeded"},"limit":{"type":"integer","description":"Erlaubte authentifizierte Requests pro Stunde für diesen Plan."}},"required":["error","limit"]}}}},"503":{"description":"Datenbank nicht verfügbar.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Stabiler Fehlercode, z. B. `unauthorized`."},"details":{"type":"object","description":"Nur bei Schema-Verstößen (`invalid_body`): die geflachten Zod-Feldfehler."}},"required":["error"]}}}}}},"delete":{"tags":["Reporting"],"operationId":"deleteReportingData","summary":"Reporting-Datenbestand löschen","description":"Löscht die Reporting-Daten der Agentur unwiderruflich. Erfordert zusätzlich den Header `X-Pressefeuer-Confirm: DELETE REPORTING DATA`.","security":[{"apiKeyHeader":[]},{"bearerAuth":[]}],"parameters":[{"name":"X-Pressefeuer-Confirm","in":"header","required":true,"description":"Muss exakt `DELETE REPORTING DATA` lauten.","schema":{"type":"string","const":"DELETE REPORTING DATA"}}],"responses":{"200":{"description":"Anzahl gelöschter Datensätze je Bereich.","headers":{"X-RateLimit-Limit":{"description":"Erlaubte authentifizierte Requests pro Stunde.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Verbleibende Requests im aktuellen Fenster.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix-Zeitpunkt (Sekunden), an dem das Fenster zurückgesetzt wird.","schema":{"type":"integer"}},"X-Pressefeuer-Api-Version":{"description":"Datierte Version des Reporting-Vertrags.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"object","additionalProperties":{"type":"integer"}}},"required":["deleted"]}}}},"400":{"description":"`confirmation_required` — Bestätigungs-Header fehlt oder ist falsch.","headers":{"X-RateLimit-Limit":{"description":"Erlaubte authentifizierte Requests pro Stunde.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Verbleibende Requests im aktuellen Fenster.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix-Zeitpunkt (Sekunden), an dem das Fenster zurückgesetzt wird.","schema":{"type":"integer"}},"X-Pressefeuer-Api-Version":{"description":"Datierte Version des Reporting-Vertrags.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Stabiler Fehlercode, z. B. `unauthorized`."},"details":{"type":"object","description":"Nur bei Schema-Verstößen (`invalid_body`): die geflachten Zod-Feldfehler."}},"required":["error"]}}}},"401":{"description":"Kein oder ungültiger API-Schlüssel.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Stabiler Fehlercode, z. B. `unauthorized`."},"details":{"type":"object","description":"Nur bei Schema-Verstößen (`invalid_body`): die geflachten Zod-Feldfehler."}},"required":["error"]}}}},"429":{"description":"Stundenlimit erschöpft. `X-RateLimit-*` und `Retry-After` beschreiben das Fenster.","headers":{"X-RateLimit-Limit":{"description":"Erlaubte authentifizierte Requests pro Stunde.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Verbleibende Requests im aktuellen Fenster.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix-Zeitpunkt (Sekunden), an dem das Fenster zurückgesetzt wird.","schema":{"type":"integer"}},"X-Pressefeuer-Api-Version":{"description":"Datierte Version des Reporting-Vertrags.","schema":{"type":"string"}},"Retry-After":{"description":"Sekunden bis zum Zurücksetzen des Fensters. Nur auf 429.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","const":"rate_limit_exceeded"},"limit":{"type":"integer","description":"Erlaubte authentifizierte Requests pro Stunde für diesen Plan."}},"required":["error","limit"]}}}},"503":{"description":"Datenbank nicht verfügbar.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Stabiler Fehlercode, z. B. `unauthorized`."},"details":{"type":"object","description":"Nur bei Schema-Verstößen (`invalid_body`): die geflachten Zod-Feldfehler."}},"required":["error"]}}}}}}},"/api/tools/crisis-pr":{"post":{"tags":["Tools"],"operationId":"generateCrisisStatement","summary":"Krisen-Erststatement generieren","description":"Öffentliches Lead-Magnet-Tool. Keine Authentifizierung, 5 Requests pro 15 Minuten und IP.","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"problem":{"type":"string","minLength":10,"description":"Beschreibung der Krisenlage. Die Mindestlänge wird auf dem **getrimmten** Wert gemessen — führende und nachgestellte Leerzeichen zählen nicht mit."}},"required":["problem"]}}}},"responses":{"200":{"description":"Generiertes Statement.","content":{"application/json":{"schema":{"type":"object","properties":{"statement":{"type":"string"}},"required":["statement"]}}}},"400":{"description":"Ungültige oder zu kurze Eingabe.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"429":{"description":"IP-Rate-Limit erreicht (5 Requests pro 15 Minuten).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"500":{"description":"Verarbeitung fehlgeschlagen.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"502":{"description":"KI-Antwort unbrauchbar.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"503":{"description":"KI-Service vorübergehend nicht verfügbar.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/tools/headline-generator":{"post":{"tags":["Tools"],"operationId":"generateHeadlines","summary":"Fünf Pressemitteilungs-Headlines generieren","description":"Öffentliches Lead-Magnet-Tool. Keine Authentifizierung, 5 Requests pro 15 Minuten und IP.","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"topic":{"type":"string","minLength":1,"maxLength":500,"description":"Thema der Pressemitteilung. Beide Grenzen werden auf dem **getrimmten** Wert gemessen."}},"required":["topic"]}}}},"responses":{"200":{"description":"Headline-Vorschläge.","content":{"application/json":{"schema":{"type":"object","properties":{"headlines":{"type":"array","items":{"type":"string"}}},"required":["headlines"]}}}},"400":{"description":"Ungültige oder zu kurze Eingabe.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"429":{"description":"IP-Rate-Limit erreicht (5 Requests pro 15 Minuten).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"500":{"description":"Verarbeitung fehlgeschlagen.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"503":{"description":"KI-Service vorübergehend nicht verfügbar.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/tools/seo-checker":{"post":{"tags":["Tools"],"operationId":"checkPressReleaseSeo","summary":"Pressemitteilung auf SEO-Kriterien prüfen","description":"Öffentliches Lead-Magnet-Tool. Keine Authentifizierung, 5 Requests pro 15 Minuten und IP.","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"text":{"type":"string","minLength":50,"description":"Der zu prüfende Text. Die Mindestlänge wird auf dem **getrimmten** Wert gemessen. Es gibt keine Obergrenze, aber nur die **ersten 3000 Zeichen** werden analysiert — längere Texte werden ohne Hinweis in der Antwort gekürzt."}},"required":["text"]}}}},"responses":{"200":{"description":"SEO-Bewertung. Die Werte stammen aus einem Sprachmodell und werden serverseitig auf diese Form normalisiert: `score` wird auf 0–100 gerundet und begrenzt, ein unbekannter `status` wird zu `verbesserbar`, ein fehlender `topTip` aus den Kriterien abgeleitet. Eine Antwort ohne brauchbaren Score oder ohne ein einziges Kriterium wird mit 502 abgewiesen.","content":{"application/json":{"schema":{"type":"object","properties":{"score":{"type":"integer","minimum":0,"maximum":100},"criteria":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"status":{"type":"string","enum":["gut","verbesserbar","schlecht"]},"note":{"type":"string"}},"required":["name","status","note"]}},"topTip":{"type":"string"}},"required":["score","criteria","topTip"]}}}},"400":{"description":"Ungültige oder zu kurze Eingabe.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"429":{"description":"IP-Rate-Limit erreicht (5 Requests pro 15 Minuten).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"500":{"description":"Verarbeitung fehlgeschlagen.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"502":{"description":"KI-Antwort unbrauchbar.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"503":{"description":"KI-Service vorübergehend nicht verfügbar.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/mcp":{"get":{"tags":["MCP"],"operationId":"getMcpServerInfo","summary":"MCP-Server-Discovery","description":"Health- und Discovery-Endpunkt. MCP-Clients prüfen ihn vor dem Verbindungsaufbau.","security":[],"responses":{"200":{"description":"Serverbeschreibung.","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","const":"pressefeuer-mcp"},"version":{"type":"string"},"protocol":{"type":"string","description":"Unterstützte MCP-Protokollversion."},"status":{"type":"string","const":"healthy"},"tools":{"type":"integer","description":"Anzahl bereitgestellter Tools."}},"required":["name","version","protocol","status","tools"]}}}}}},"post":{"tags":["MCP"],"operationId":"callMcpEndpoint","summary":"MCP-JSON-RPC-Aufruf","description":"Streamable-HTTP-Transport des Model Context Protocol. Der Body ist eine\nJSON-RPC-2.0-Nachricht (`initialize`, `tools/list`, `tools/call`, …).\nDie einzelnen Tools sind unter /docs/agents/tools dokumentiert.\n\nAuthentifizierung mit dem Agentur-API-Schlüssel als `X-API-Key`-Header,\n`Authorization: Bearer <key>` oder Query-Parameter `?token=`. MCP akzeptiert\n`X-Pressefeuer-Key` NICHT — das ist der Header von Reporting REST v1. Das\nStundenlimit wird mit Reporting REST v1 geteilt. Benachrichtigungen wie\n`notifications/initialized` antworten mit 204 ohne Body.","security":[{"mcpApiKeyHeader":[]},{"bearerAuth":[]},{"mcpTokenQuery":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"jsonrpc":{"type":"string","const":"2.0"},"id":{"type":["string","integer"]},"method":{"type":"string"},"params":{"type":"object"}},"required":["jsonrpc","method"]}}}},"responses":{"200":{"description":"JSON-RPC-Antwort. Protokoll- und Authentifizierungsfehler kommen hier als `error`-Objekt zurück, nicht als HTTP-Statuscode. Rate-Limit-Header nur bei authentifizierten Aufrufen.","headers":{"X-RateLimit-Limit":{"description":"Erlaubte authentifizierte Requests pro Stunde.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Verbleibende Requests im aktuellen Fenster.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix-Zeitpunkt (Sekunden), an dem das Fenster zurückgesetzt wird.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"jsonrpc":{"type":"string","const":"2.0"},"id":{"type":["string","integer"]},"result":{"type":"object"},"error":{"type":"object","properties":{"code":{"type":"integer"},"message":{"type":"string"}}}},"required":["jsonrpc"]}}}},"204":{"description":"Benachrichtigung angenommen (z. B. `notifications/initialized`). Kein Body.","headers":{"X-RateLimit-Limit":{"description":"Erlaubte authentifizierte Requests pro Stunde.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Verbleibende Requests im aktuellen Fenster.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix-Zeitpunkt (Sekunden), an dem das Fenster zurückgesetzt wird.","schema":{"type":"integer"}}}},"429":{"description":"Stundenlimit erschöpft. Der Body ist ein JSON-RPC-Fehlerobjekt mit Code -32029.","headers":{"X-RateLimit-Limit":{"description":"Erlaubte authentifizierte Requests pro Stunde.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Verbleibende Requests im aktuellen Fenster.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix-Zeitpunkt (Sekunden), an dem das Fenster zurückgesetzt wird.","schema":{"type":"integer"}},"Retry-After":{"description":"Sekunden bis zum Zurücksetzen des Fensters. Nur auf 429.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object"}}}},"500":{"description":"Interner Fehler. Der Body ist ein JSON-RPC-Fehlerobjekt mit Code -32603.","content":{"application/json":{"schema":{"type":"object"}}}}}}}},"components":{"securitySchemes":{"apiKeyHeader":{"type":"apiKey","in":"header","name":"X-Pressefeuer-Key","description":"Agentur-API-Schlüssel aus dem Dashboard für Reporting REST v1. Nur im Agency-Plan verfügbar (500 Requests pro Stunde, geteilt mit MCP). Der MCP-Endpunkt akzeptiert diesen Header NICHT — dort `X-API-Key` verwenden."},"bearerAuth":{"type":"http","scheme":"bearer","description":"Derselbe Agentur-API-Schlüssel als `Authorization: Bearer <key>`. Gilt für Reporting REST v1 und MCP."},"mcpApiKeyHeader":{"type":"apiKey","in":"header","name":"X-API-Key","description":"Agentur-API-Schlüssel für den MCP-Endpunkt. MCP liest `X-API-Key` — nicht `X-Pressefeuer-Key`, das nur Reporting REST v1 akzeptiert."},"mcpTokenQuery":{"type":"apiKey","in":"query","name":"token","description":"Derselbe Schlüssel als Query-Parameter `?token=` für MCP-Clients, die keine Header setzen können. Header bevorzugen — Query-Parameter landen in Logs."}},"schemas":{"ReportingWebhookEvent":{"type":"string","enum":["report.export.completed","report.export.failed","report.delivery.failed"]},"ReportingWebhook":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"endpointUrl":{"type":"string","format":"uri"},"secretHint":{"type":"string","description":"Letzte acht Zeichen des Signing-Secrets."},"events":{"type":"array","items":{"$ref":"#/components/schemas/ReportingWebhookEvent"}},"isActive":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","endpointUrl","events","isActive"]}}},"security":[{"apiKeyHeader":[]},{"bearerAuth":[]}]}