{"openapi":"3.1.0","info":{"title":"GWÖ-Antragsprüfer API","description":"\nÖffentliche API des GWÖ-Antragsprüfers — automatische Gemeinwohl-Bilanzierung\nvon Parlamentsanträgen nach der GWÖ-Matrix 2.0.\n\n## Daten und Lizenz\n\nAlle von dieser API gelieferten Bewertungen, Scores und Aggregate sind unter\n**Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)**\nlizenziert. Originalantragstexte und Wahlprogramme der Parteien sind davon\nausdrücklich **nicht** abgedeckt (siehe DATA-LICENSE im Repository).\n\nEmpfohlene Zitation:\n\n    \"GWÖ-Antragsprüfer · gwoe.toppyr.de · CC BY-SA 4.0\"\n\n## Wöchentlicher Open-Data-Dump\n\nEine maschinenlesbare Wochen-Momentaufnahme aller Bewertungen, Drucksachen,\nVotes, Programme und Targets liegt unter `/opendata/snapshot/snapshot-YYYY-WW.zip`.\nDie Übersichts-Seite `/opendata` listet die jeweils letzten 26 Wochen.\n\n## Rate-Limits\n\nLese-Endpoints sind unlimitiert; Mutations- und LLM-Endpoints sind pro\nClient-IP rate-limited:\n\n  - `POST /api/analyze-drucksache`: 10 Requests / Minute\n  - `POST /api/aktuelle-themen/generate-presse`: 5 Requests / Minute\n  - `POST /api/auswertungen/vote-orphans/auto-rate` (admin-only): 3 Requests / Minute\n\nBei Überschreitung antwortet der Server mit HTTP 429.\n","contact":{"name":"Tobias Rödel","url":"https://gwoe.toppyr.de/","email":"mail@tobiasroedel.de"},"license":{"name":"Daten: CC BY-SA 4.0 · Code: MIT","url":"https://creativecommons.org/licenses/by-sa/4.0/deed.de"},"version":"2.0.0"},"paths":{"/classic":{"get":{"summary":"Classic Index","description":"Klassische Ansicht (v1) — jetzt unter /classic erreichbar.","operationId":"classic_index_classic_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"tags":["frontend"]}},"/":{"get":{"summary":"Index","description":"Startseite — rendert v2-Listenansicht (Default-Flip Phase 2).\n\nAlte /?drucksache=XX-YYYY Deep-Links werden per 301-Redirect auf\n/antrag/XX-YYYY weitergeleitet, damit Bookmarks weiter funktionieren.","operationId":"index__get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"tags":["frontend"]}},"/antrag/{drucksache}":{"get":{"summary":"Antrag Detail","description":"Standard-Antrag-Detail (v3 Bürger:innen-Modus, single column).\n\nBisheriger Profi-Modus (v2, zwei Spalten) ist unter /v2/antrag/{drs}\nweiterhin erreichbar — Link im Admin-Bereich (/v2/admin/stand).","operationId":"antrag_detail_antrag__drucksache__get","parameters":[{"name":"drucksache","in":"path","required":true,"schema":{"type":"string","title":"Drucksache"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["frontend"]}},"/v2/antrag/{drucksache}":{"get":{"summary":"V2 Antrag Redirect","description":"Redirect /v2/antrag/XX → /antrag/XX (kanonische URL).","operationId":"v2_antrag_redirect_v2_antrag__drucksache__get","parameters":[{"name":"drucksache","in":"path","required":true,"schema":{"type":"string","title":"Drucksache"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["frontend"]}},"/v3/antrag/{drucksache}":{"get":{"summary":"Antrag Detail V3","description":"Alias auf den Standard (= /antrag/{drs}), damit alte Bookmarks\nauf v3-URLs weiter funktionieren.","operationId":"antrag_detail_v3_v3_antrag__drucksache__get","parameters":[{"name":"drucksache","in":"path","required":true,"schema":{"type":"string","title":"Drucksache"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["frontend"]}},"/analyze":{"post":{"summary":"Start Analysis","description":"Start analysis job.","operationId":"start_analysis_analyze_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_start_analysis_analyze_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["assessments"]}},"/status/{job_id}":{"get":{"summary":"Get Status","description":"Get job status.","operationId":"get_status_status__job_id__get","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["assessments"]}},"/result/{job_id}":{"get":{"summary":"Get Result","description":"Get analysis result as HTML.","operationId":"get_result_result__job_id__get","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["assessments"]}},"/result/{job_id}/pdf":{"get":{"summary":"Get Pdf","description":"Download PDF report.","operationId":"get_pdf_result__job_id__pdf_get","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["assessments"]}},"/api/queue/status":{"get":{"summary":"Queue Status","description":"Aktueller Queue-Stand: wartende Jobs, geschätzte Wartezeit.","operationId":"queue_status_api_queue_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"tags":["assessments"]}},"/api/auth/me":{"get":{"summary":"Auth Me","description":"User-Info oder null wenn nicht eingeloggt.\n\nDas Frontend ruft diesen Endpoint beim Load auf, um zu entscheiden\nob \"Bewerten\" aktiv oder ausgegraut ist.","operationId":"auth_me_api_auth_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"tags":["meta"]}},"/api/auth/callback":{"get":{"summary":"Auth Callback","description":"OIDC Authorization Code → Access Token Exchange.\n\nKeycloak redirects hierher nach Login mit ?code=... Parameter.\nWir tauschen den Code gegen ein Access Token und setzen es als Cookie.","operationId":"auth_callback_api_auth_callback_get","parameters":[{"name":"code","in":"query","required":false,"schema":{"type":"string","default":"","title":"Code"}},{"name":"state","in":"query","required":false,"schema":{"type":"string","default":"","title":"State"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["meta"]}},"/api/auth/login-url":{"get":{"summary":"Auth Login Url","description":"Keycloak-Login-URL für den Browser-Redirect.","operationId":"auth_login_url_api_auth_login_url_get","parameters":[{"name":"redirect","in":"query","required":false,"schema":{"type":"string","default":"/","title":"Redirect"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["meta"]}},"/api/auth/forgot-password":{"get":{"summary":"Auth Forgot Password","description":"Redirect zur Keycloak-Passwort-Reset-Seite (#143-Folge).\n\nKeycloak bietet bei `resetPasswordAllowed=True` eine eigene Reset-Page,\ndie per Mail einen Link zum Passwort-Setzen schickt. Wir leiten direkt\ndahin um statt eine eigene UI zu bauen.","operationId":"auth_forgot_password_api_auth_forgot_password_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"tags":["meta"]}},"/api/auth/login":{"post":{"summary":"Auth Direct Login","description":"Direct Access Grant Login (#129) — kein Redirect zu Keycloak.\n\nRuft Keycloak per Resource Owner Password Credentials (Direct Access Grant) an.\nSetzt access_token als HttpOnly-Cookie und refresh_token als separates rt-Cookie.\n\nKEYCLOAK-VORAUSSETZUNG: Im Client muss \"Direct Access Grants\" aktiviert sein.\nKeycloak Admin → Realm → Clients → gwoe-antragspruefer → Capability config →\n\"Direct access grants enabled\" = ON.\n\nFehler-Mapping:\n- 401 → {\"error\": \"invalid_credentials\", \"msg\": \"...\"}\n- Keycloak nicht erreichbar / sonstiges → {\"error\": \"unknown\", \"msg\": \"...\"}","operationId":"auth_direct_login_api_auth_login_post","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_auth_direct_login_api_auth_login_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["meta"]}},"/api/auth/logout":{"post":{"summary":"Auth Logout","description":"Logout — löscht access_token + rt-Cookies (HttpOnly, daher server-seitig).","operationId":"auth_logout_api_auth_logout_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"tags":["meta"]}},"/api/auth/refresh":{"post":{"summary":"Auth Refresh","description":"Refresh-Token-Endpoint (#129) — holt neuen access_token via refresh_token-Cookie.\n\nSetzt neuen access_token-Cookie bei Erfolg.","operationId":"auth_refresh_api_auth_refresh_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"tags":["meta"]}},"/api/bookmark":{"post":{"summary":"Bookmark Toggle","description":"Toggle bookmark für einen Antrag.","operationId":"bookmark_toggle_api_bookmark_post","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_bookmark_toggle_api_bookmark_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["assessments"]}},"/api/bookmarks":{"get":{"summary":"Bookmarks List","description":"Liste aller Bookmarks des aktuellen Users.","operationId":"bookmarks_list_api_bookmarks_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"tags":["assessments"]}},"/api/me/merkliste":{"get":{"summary":"Merkliste List Endpoint","description":"Alle Merklisten-Einträge des aktuellen Users. Erfordert Anmeldung.","operationId":"merkliste_list_endpoint_api_me_merkliste_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"tags":["meta"]},"post":{"summary":"Merkliste Add Endpoint","description":"Antrag zur Merkliste hinzufügen (Upsert). Erfordert Anmeldung.","operationId":"merkliste_add_endpoint_api_me_merkliste_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_MerklisteAddBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["meta"]}},"/api/me/merkliste/{antrag_id}":{"delete":{"summary":"Merkliste Remove Endpoint","description":"Antrag aus der Merkliste entfernen. Erfordert Anmeldung.","operationId":"merkliste_remove_endpoint_api_me_merkliste__antrag_id__delete","parameters":[{"name":"antrag_id","in":"path","required":true,"schema":{"type":"string","title":"Antrag Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["meta"]}},"/api/me/merkliste/bulk-import":{"post":{"summary":"Merkliste Bulk Import","description":"Mehrere Einträge auf einmal importieren (für localStorage-Migration).\n\nBody: ``{\"entries\": [{\"antrag_id\": \"18/1234\"}, …]}``","operationId":"merkliste_bulk_import_api_me_merkliste_bulk_import_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_MerklisteBulkBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["meta"]}},"/api/subscriptions":{"get":{"summary":"Subscription List","description":"Liste aller Abos. Admins erhalten alle Abos inkl. user_id-Feld; normale\nUser sehen nur ihre eigenen Abos.","operationId":"subscription_list_api_subscriptions_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"tags":["meta"]},"post":{"summary":"Subscription Create","description":"Neues Abo für Benachrichtigungen anlegen.","operationId":"subscription_create_api_subscriptions_post","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_subscription_create_api_subscriptions_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["meta"]}},"/api/subscriptions/{sub_id}":{"delete":{"summary":"Subscription Delete","description":"Abo löschen (nur eigenes).","operationId":"subscription_delete_api_subscriptions__sub_id__delete","parameters":[{"name":"sub_id","in":"path","required":true,"schema":{"type":"integer","title":"Sub Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["meta"]}},"/unsubscribe/{sub_id}/{token}":{"get":{"summary":"Unsubscribe","description":"Unsubscribe-Link aus E-Mails — kein Login nötig (HMAC-Token verifiziert).","operationId":"unsubscribe_unsubscribe__sub_id___token__get","parameters":[{"name":"sub_id","in":"path","required":true,"schema":{"type":"integer","title":"Sub Id"}},{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["frontend"]}},"/api/comment":{"post":{"summary":"Comment Add","description":"Kommentar hinzufügen.","operationId":"comment_add_api_comment_post","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_comment_add_api_comment_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["assessments"]}},"/api/comments":{"get":{"summary":"Comments List","description":"Kommentare für einen Antrag.","operationId":"comments_list_api_comments_get","parameters":[{"name":"drucksache","in":"query","required":true,"schema":{"type":"string","title":"Drucksache"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["assessments"]}},"/api/comment/{comment_id}":{"delete":{"summary":"Comment Delete","description":"Eigenen Kommentar löschen.","operationId":"comment_delete_api_comment__comment_id__delete","parameters":[{"name":"comment_id","in":"path","required":true,"schema":{"type":"integer","title":"Comment Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["assessments"]}},"/api/assessment/history":{"get":{"summary":"Assessment History","description":"Versionshistorie eines Assessments.","operationId":"assessment_history_api_assessment_history_get","parameters":[{"name":"drucksache","in":"query","required":true,"schema":{"type":"string","title":"Drucksache"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["assessments"]}},"/api/vote":{"post":{"summary":"Vote Endpoint","description":"Bewertung als treffend/fragwürdig markieren. Toggle: gleicher Vote nochmal = entfernen.","operationId":"vote_endpoint_api_vote_post","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_vote_endpoint_api_vote_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["assessments"]}},"/api/votes":{"get":{"summary":"Votes Endpoint","description":"Aggregierte Votes + eigener Vote für eine Drucksache.","operationId":"votes_endpoint_api_votes_get","parameters":[{"name":"drucksache","in":"query","required":true,"schema":{"type":"string","title":"Drucksache"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["assessments"]}},"/api/auth/register":{"post":{"summary":"Auth Register","description":"Registrierung: erstellt User in Keycloak mit enabled=false.\nAdmin muss den Account manuell freischalten.\nKein Passwort nötig — nach Freischaltung sendet Keycloak eine\nE-Mail zum Passwort-Setzen.","operationId":"auth_register_api_auth_register_post","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_auth_register_api_auth_register_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["meta"]}},"/api/auth/pending-users":{"get":{"summary":"Auth Pending Users","description":"Liste nicht-freigeschalteter User (Admin-only).","operationId":"auth_pending_users_api_auth_pending_users_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"tags":["meta"]}},"/api/auth/approve-user":{"post":{"summary":"Auth Approve User","description":"User freischalten (Admin-only).\n\nAktiviert den User und triggert eine Keycloak-E-Mail zum Passwort setzen.\nVoraussetzung: Keycloak Realm hat SMTP konfiguriert (Realm Settings → Email).","operationId":"auth_approve_user_api_auth_approve_user_post","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_auth_approve_user_api_auth_approve_user_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["meta"]}},"/api/assessments":{"get":{"summary":"List Assessments","description":"Return assessments from database, optionally filtered by Bundesland.\n\n``bundesland=\"ALL\"`` and missing parameter both mean \"no filter\".","operationId":"list_assessments_api_assessments_get","parameters":[{"name":"bundesland","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bundesland"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["assessments"]}},"/api/assessment":{"get":{"summary":"Get Single Assessment","description":"Get a single assessment by drucksache ID.","operationId":"get_single_assessment_api_assessment_get","parameters":[{"name":"drucksache","in":"query","required":true,"schema":{"type":"string","title":"Drucksache"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["assessments"]}},"/api/assessment/delete":{"delete":{"summary":"Delete Assessment Endpoint","description":"Löscht ein Assessment, damit es neu analysiert werden kann.","operationId":"delete_assessment_endpoint_api_assessment_delete_delete","parameters":[{"name":"drucksache","in":"query","required":true,"schema":{"type":"string","title":"Drucksache"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["assessments"]}},"/api/assessment/pdf":{"get":{"summary":"Download Assessment Pdf","description":"Generate and download PDF for an assessment.","operationId":"download_assessment_pdf_api_assessment_pdf_get","parameters":[{"name":"drucksache","in":"query","required":true,"schema":{"type":"string","title":"Drucksache"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["assessments"]}},"/api/search":{"get":{"summary":"Search Internal","description":"Search internal assessments database only.","operationId":"search_internal_api_search_get","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","title":"Q"}},{"name":"bundesland","in":"query","required":false,"schema":{"type":"string","default":"NRW","title":"Bundesland"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["assessments"]}},"/api/search-landtag":{"get":{"summary":"Search Landtag","description":"Search external parliament portal (e.g., NRW OPAL).\nReturns results that can be analyzed with \"Jetzt prüfen\".\n\nRequires a concrete Bundesland — the special \"ALL\" / Bundesweit mode\ncannot pick a single Landtag adapter and is rejected with HTTP 400.","operationId":"search_landtag_api_search_landtag_get","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","title":"Q"}},{"name":"bundesland","in":"query","required":false,"schema":{"type":"string","default":"NRW","title":"Bundesland"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":20,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["assessments"]}},"/api/batch-analyze":{"post":{"summary":"Batch Analyze","description":"Sucht die neuesten Drucksachen im Landtag-Portal und enqueued\nalle, die noch nicht in der DB bewertet sind.\n\n`bundesland=\"ALL\"` iteriert ueber alle aktiven Bundeslaender und\nverteilt das Limit proportional. Adapter-Fehler pro BL werden\ngeloggt und uebersprungen.\n\nReturns: Liste der enqueued Drucksachen + Queue-Position.","operationId":"batch_analyze_api_batch_analyze_post","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_batch_analyze_api_batch_analyze_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["assessments"]}},"/api/analyze-drucksache":{"post":{"summary":"Analyze Drucksache","description":"Download a document from parliament portal and analyze it.","operationId":"analyze_drucksache_api_analyze_drucksache_post","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_analyze_drucksache_api_analyze_drucksache_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["assessments"]}},"/api/bundeslaender":{"get":{"summary":"List Bundeslaender","description":"List available bundesländer with their status.\n\nIncludes the synthetic \"ALL\" / Bundesweit entry as the first item so\nthat the frontend can render it directly. ``parlament_name`` is added\nso the detail view can show the source parliament without an extra\nbackend round-trip.","operationId":"list_bundeslaender_api_bundeslaender_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"tags":["meta"]}},"/impressum":{"get":{"summary":"Impressum Page","operationId":"impressum_page_impressum_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"tags":["frontend"]}},"/datenschutz":{"get":{"summary":"Datenschutz Page","operationId":"datenschutz_page_datenschutz_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"tags":["frontend"]}},"/best-practice":{"get":{"summary":"Best Practice Page","description":"Öffentliche Best-Practice-Bibliothek (#200).\n\nKuratierte Liste hoch bewerteter Anträge als Referenz für Fraktionen,\nJournalismus und Lobbyarbeit. Filter: Bundesland × GWÖ-Klasse ×\nMindest-Score × Thema (Substring im Themen-Tag).","operationId":"best_practice_page_best_practice_get","parameters":[{"name":"bundesland","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bundesland"}},{"name":"klasse","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Klasse"}},{"name":"min_score","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Min Score"}},{"name":"thema","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thema"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["frontend"]}},"/api/best-practice":{"get":{"summary":"Api Best Practice","description":"JSON-API für die Best-Practice-Bibliothek (#200).\n\nFilter analog zur Web-Route, plus expliziter ``limit`` (1-500).","operationId":"api_best_practice_api_best_practice_get","parameters":[{"name":"bundesland","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bundesland"}},{"name":"klasse","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Klasse"}},{"name":"min_score","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Min Score"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["assessments"]}},"/api/best-practice/{drucksache}":{"post":{"summary":"Api Best Practice Set","description":"Admin-Endpoint: Best-Practice-Flag setzen oder entfernen (#200).\n\nErwartet JSON-Body `{is_best_practice: bool, begruendung?: str, klasse?: str}`.\nKlasse muss bei `is_best_practice=true` einer der fünf GWÖ-Werte sein —\nbei `false` werden Begründung und Klasse ignoriert/zurückgesetzt.","operationId":"api_best_practice_set_api_best_practice__drucksache__post","parameters":[{"name":"drucksache","in":"path","required":true,"schema":{"type":"string","title":"Drucksache"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BestPracticeFlag"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["assessments"]}},"/methodik":{"get":{"summary":"Methodik Page","description":"Transparenz-/Methodik-Seite (#96, #203).","operationId":"methodik_page_methodik_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"tags":["frontend"]}},"/glossar":{"get":{"summary":"Glossar Page","description":"Öffentliche Glossar-Seite (#185): alle Fachbegriffe laienverständlich.","operationId":"glossar_page_glossar_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"tags":["frontend"]}},"/api/admin/bias-audit/run":{"post":{"summary":"Api Admin Bias Audit Run","description":"Trigger fuer den Bias-Audit (#203).\n\nAggregation laeuft synchron — die Datenmenge ist klein (eine\nDrucksache + Score pro Antragsteller-Fraktion). PDF-Rendering via\nWeasyPrint dauert auf prod-Maschinen ~1-2 s; falls WeasyPrint nicht\nverfuegbar ist, wird das PDF uebersprungen und JSON+MD trotzdem\ngeschrieben.\n\nReturns die Pfade der erzeugten Dateien (relativ zu data/).","operationId":"api_admin_bias_audit_run_api_admin_bias_audit_run_post","parameters":[{"name":"bundesland","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bundesland"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["admin"]}},"/api/admin/bias-audit/file":{"get":{"summary":"Api Admin Bias Audit File","description":"Download eines Audit-Files (#203).\n\n``date`` = ISO-Datum aus dem Dateinamen, ``kind`` in\n{json, md, pdf}. Keine Path-Traversal: wir bauen den Pfad selbst\naus den validierten Inputs und prüfen die Existenz.","operationId":"api_admin_bias_audit_file_api_admin_bias_audit_file_get","parameters":[{"name":"date","in":"query","required":true,"schema":{"type":"string","title":"Date"}},{"name":"kind","in":"query","required":true,"schema":{"type":"string","title":"Kind"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["admin"]}},"/methodik/bias-audit/{date}.{kind}":{"get":{"summary":"Methodik Bias Audit File","description":"Öffentlicher Download der Audit-Files.\n\nDie Audit-Berichte sind bewusst öffentlich — sie sind das\ntransparente Selbstprüfungs-Artefakt; ein Login-Zwang würde das\nZiel (Schutz vor Verzerrungs-Vorwürfen durch Offenheit)\nuntergraben. Der **Trigger** zum Erzeugen bleibt admin-only.","operationId":"methodik_bias_audit_file_methodik_bias_audit__date___kind__get","parameters":[{"name":"date","in":"path","required":true,"schema":{"type":"string","title":"Date"}},{"name":"kind","in":"path","required":true,"schema":{"type":"string","title":"Kind"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["frontend"]}},"/opendata":{"get":{"tags":["opendata"],"summary":"Opendata Index","description":"Open-Data-Übersichts-Seite mit Download-Links und Lizenz-Hinweis (#205).\n\nListet die jüngsten Wochen-Snapshots (eine ZIP pro ISO-Kalenderwoche).\nDer Cron-Wrapper ``scripts/opendata-snapshot-cron.sh`` hält max.\nKEEP_WEEKS=26 Snapshots vor.","operationId":"opendata_index_opendata_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/opendata/snapshot/{filename}":{"get":{"tags":["opendata"],"summary":"Opendata Snapshot Download","description":"Statisches Streaming einer Snapshot-ZIP (#205).\n\nValidiert den Dateinamen strikt gegen das Muster\n``snapshot-YYYY-WW.zip`` (ISO-Kalenderwoche), um Path-Traversal\nzu verhindern.","operationId":"opendata_snapshot_download_opendata_snapshot__filename__get","parameters":[{"name":"filename","in":"path","required":true,"schema":{"type":"string","title":"Filename"}}],"responses":{"200":{"description":"Snapshot-ZIP","content":{"application/json":{"schema":{}},"application/zip":{}}},"404":{"description":"Snapshot existiert nicht"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/was-ist-neu":{"get":{"summary":"Was Ist Neu Page","description":"Was-ist-neu-Seite zur 2.0-Ankuendigung.\n\nErklaert die acht groessten Veraenderungen seit 1.0 mit Intention und\ngrober Umsetzung pro Block.","operationId":"was_ist_neu_page_was_ist_neu_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"tags":["frontend"]}},"/quellen":{"get":{"summary":"Quellen Page","description":"Quellen-Seite mit allen Wahl- und Parteiprogrammen, nach BL gruppiert.","operationId":"quellen_page_quellen_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"tags":["frontend"]}},"/api/quellen/search":{"get":{"summary":"Quellen Search","description":"Semantische Volltextsuche über alle indizierten Wahlprogramme.\n\nNutzt die DashScope-Embeddings (text-embedding-v4): wortunscharf,\nfindet auch synonyme/verwandte Begriffe. Filter:\n- ``filter=current``: nur aktuelle Programme (gueltig_bis IS NULL)\n- ``filter=all``: auch historische Programme\n- ``bundesland`` / ``partei``: optionale Eingrenzung\n\nReturns: JSON mit Trefferliste {name, partei, bundesland, seite, text,\ngueltig_ab, gueltig_bis, similarity, pdf_url, programm_id}.","operationId":"quellen_search_api_quellen_search_get","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":2,"maxLength":200,"description":"Suchbegriff","title":"Q"},"description":"Suchbegriff"},{"name":"filter","in":"query","required":false,"schema":{"type":"string","pattern":"^(current|all)$","default":"current","title":"Filter"}},{"name":"bundesland","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bundesland"}},{"name":"partei","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Partei"}},{"name":"top_k","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"default":20,"title":"Top K"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["quellen"]}},"/targets":{"get":{"summary":"Targets Page","description":"Übersichtsseite aller Soll-Quellen (#213) — öffentlich.\n\nListet alle in ``app.targets.TARGETS`` registrierten Targets mit\nClient-side-Filter über Typ × Bundesland × Wahlperiode × aktuell-Flag.","operationId":"targets_page_targets_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"tags":["frontend"]}},"/api/targets":{"get":{"summary":"Api Targets","description":"JSON-Liste aller Targets mit optionalen Filtern (#213).\n\nFilter:\n- ``bundesland``: BL-Code (z.B. ``NRW``) oder ``__keins__`` für\n  überstaatliche/Bundes-Targets.\n- ``typ``: einer der TargetTyp-Strings (``koalitionsvertrag``,\n  ``staatsziel``, ``sdg``, …).\n- ``wahlperiode``: WP-Nummer; ``None``-Targets (ohne WP-Bindung)\n  werden nur gelistet, wenn der Filter weggelassen wird.\n- ``nur_aktuell``: nur Targets mit ``gueltig_bis IS NULL``.\n\nAntwort: ``{n: int, results: [Target-Dict mit typ_label]}``.","operationId":"api_targets_api_targets_get","parameters":[{"name":"bundesland","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":8},{"type":"null"}],"title":"Bundesland"}},{"name":"typ","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}],"title":"Typ"}},{"name":"wahlperiode","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":99,"minimum":1},{"type":"null"}],"title":"Wahlperiode"}},{"name":"nur_aktuell","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Nur Aktuell"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["meta"]}},"/api/tour/voice":{"get":{"summary":"Tour Voice","description":"Generiert (oder liefert aus Cache) eine MP3 für Tour-Erklär-Texte (#185).\n\nNutzt ElevenLabs-TTS, wenn ENV ``ELEVENLABS_API_KEY`` gesetzt ist —\nsonst 503, damit das Frontend auf ``speechSynthesis`` (browser-\neingebaute Stimme) zurückfällt.\n\nCaching: pro (text, voice_id, model_id) wird einmal generiert und in\n``data/tour_audio/<hash>.mp3`` gespeichert. Folgeabrufe gehen aus\ndem Cache und kosten kein API-Quota.","operationId":"tour_voice_api_tour_voice_get","parameters":[{"name":"text","in":"query","required":true,"schema":{"type":"string","minLength":2,"maxLength":2000,"title":"Text"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["meta"]}},"/api/wahlprogramm-cite":{"get":{"summary":"Wahlprogramm Cite","description":"Render eine Wahlprogramm-Seite mit gelb hervorgehobener Zitat-Stelle.\n\nIssue #47: Klick auf eine Zitat-Quelle im Report soll direkt zur\nStelle im Wahlprogramm-PDF springen, mit dem zitierten Snippet\nvisuell markiert. Statt das ganze PDF auszuliefern (Browser scrollt\nauf #page=N und Leser muss von Hand suchen), liefern wir hier ein\n1-Seiten-PDF mit ``add_highlight_annot``-Annotation auf den per\n``page.search_for`` gefundenen Bounding-Boxes.\n\nAkzeptiert ``pid`` (PROGRAMME-Key) ODER ``pdf`` (Dateiname wie\n``spd-grundsatzprogramm.pdf``). Letzterer ermöglicht die retroaktive\nNutzung von Pre-#47-URLs im Frontend, wo nur der statische Pfad\n``/static/referenzen/<pdf>#page=<N>`` gespeichert ist.\n\nSecurity: ``pid`` muss ein registrierter PROGRAMME-Key sein —\nverhindert Path-Traversal und arbiträren File-Read aus dem\nreferenzen-Verzeichnis. ``seite`` wird per Pydantic-Coercion\nauf int gezwungen. ``q`` ist auf 200 Zeichen begrenzt im Renderer.","operationId":"wahlprogramm_cite_api_wahlprogramm_cite_get","parameters":[{"name":"pid","in":"query","required":false,"schema":{"type":"string","default":"","title":"Pid"}},{"name":"pdf","in":"query","required":false,"schema":{"type":"string","default":"","title":"Pdf"}},{"name":"seite","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"Seite"}},{"name":"q","in":"query","required":false,"schema":{"type":"string","default":"","title":"Q"}},{"name":"ds","in":"query","required":false,"schema":{"type":"string","default":"","title":"Ds"}},{"name":"bl","in":"query","required":false,"schema":{"type":"string","default":"","title":"Bl"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["quellen"]}},"/api/programme/thumbnail/{programm_id}":{"get":{"summary":"Programme Thumbnail","description":"Thumbnail der ersten Seite eines Wahlprogramm-PDFs (PNG, 200px breit).\n\nWird auf der Quellen-Seite als Vorschau angezeigt. Cached 24h.","operationId":"programme_thumbnail_api_programme_thumbnail__programm_id__get","parameters":[{"name":"programm_id","in":"path","required":true,"schema":{"type":"string","title":"Programm Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["quellen"]}},"/api/programme":{"get":{"summary":"List Programme","description":"List all available programmes.","operationId":"list_programme_api_programme_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"tags":["quellen"]}},"/api/programme/status":{"get":{"summary":"Programme Status","description":"Get indexing status of all programmes.","operationId":"programme_status_api_programme_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"tags":["quellen"]}},"/api/programme/index":{"post":{"summary":"Index Programme","description":"Index programme(s) for semantic search.","operationId":"index_programme_api_programme_index_post","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_index_programme_api_programme_index_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["quellen"]}},"/auswertungen":{"get":{"summary":"Auswertungen Page","description":"Auswertungs-Dashboard in v2 (Phase 3 Migration aus Classic). Auth-only.\n\n``wahlkreis`` (#201) ist ein optionaler Query-Param, der das\nDefault-Wahlkreis-Filter-Dropdown vorbelegt und vom Client-JS\nan die ``/api/auswertungen/matrix``-Endpoint durchgereicht wird.","operationId":"auswertungen_page_auswertungen_get","parameters":[{"name":"wahlkreis","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Wahlkreis"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["frontend"]}},"/stimmverhalten":{"get":{"summary":"Stimmverhalten Page","description":"Eigene View für Stimmverhalten × GWÖ (#169). Rendert auswertungen.html\nmit default_tab=stimmverhalten und Active-Nav 'stimmverhalten'.","operationId":"stimmverhalten_page_stimmverhalten_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"tags":["frontend"]}},"/aktuelle-themen":{"get":{"summary":"Aktuelle Themen Page","description":"Aktuelle-Themen-Dashboard: News × Anträge × Pressemitteilungs-Drafts.","operationId":"aktuelle_themen_page_aktuelle_themen_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"tags":["frontend"]}},"/api/aktuelle-themen/top":{"get":{"summary":"Api Aktuelle Themen Top","description":"Top-K News der letzten N Tage mit Antrags-Match.\n\nMit `only_relevant=true` werden News mit Relevance-Level \"low\" oder\n\"none\" rausgefiltert.\n\nMit `date=YYYY-MM-DD` werden nur News dieses Tages angezeigt\n(overrides `days`).","operationId":"api_aktuelle_themen_top_api_aktuelle_themen_top_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","default":7,"title":"Days"}},{"name":"top_k","in":"query","required":false,"schema":{"type":"integer","default":10,"title":"Top K"}},{"name":"min_similarity","in":"query","required":false,"schema":{"type":"number","default":0.4,"title":"Min Similarity"}},{"name":"matches_per_news","in":"query","required":false,"schema":{"type":"integer","default":3,"title":"Matches Per News"}},{"name":"only_relevant","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Only Relevant"}},{"name":"date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Date"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["aktuelle-themen"]}},"/api/aktuelle-themen/cluster":{"get":{"summary":"Api Aktuelle Themen Cluster","description":"News-zu-News-Cluster ueber Embeddings — gleiches Thema, mehrere\nQuellen → ein Cluster, nicht 5 separate Cards.","operationId":"api_aktuelle_themen_cluster_api_aktuelle_themen_cluster_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","default":7,"title":"Days"}},{"name":"intra_threshold","in":"query","required":false,"schema":{"type":"number","default":0.55,"title":"Intra Threshold"}},{"name":"antrag_threshold","in":"query","required":false,"schema":{"type":"number","default":0.4,"title":"Antrag Threshold"}},{"name":"min_cluster_size","in":"query","required":false,"schema":{"type":"integer","default":2,"title":"Min Cluster Size"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["aktuelle-themen"]}},"/api/aktuelle-themen/top-antraege":{"get":{"summary":"Api Aktuelle Themen Top Antraege","description":"Reverse-Sicht: hoch GWÖ-bewertete Antraege mit aktueller Pressewirkung.","operationId":"api_aktuelle_themen_top_antraege_api_aktuelle_themen_top_antraege_get","parameters":[{"name":"min_gwoe_score","in":"query","required":false,"schema":{"type":"number","default":8.0,"title":"Min Gwoe Score"}},{"name":"days","in":"query","required":false,"schema":{"type":"integer","default":14,"title":"Days"}},{"name":"min_similarity","in":"query","required":false,"schema":{"type":"number","default":0.4,"title":"Min Similarity"}},{"name":"top_k_news","in":"query","required":false,"schema":{"type":"integer","default":5,"title":"Top K News"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["aktuelle-themen"]}},"/api/aktuelle-themen/zeitreihe":{"get":{"summary":"Api Aktuelle Themen Zeitreihe","description":"News-Volumen pro Tag × Source — Stacked-Area-Chart.","operationId":"api_aktuelle_themen_zeitreihe_api_aktuelle_themen_zeitreihe_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","default":30,"title":"Days"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["aktuelle-themen"]}},"/api/aktuelle-themen/news-fuer-antrag":{"get":{"summary":"Api News Fuer Antrag","description":"Top-K News, die zu einem gegebenen Antrag passen (für Detail-View).","operationId":"api_news_fuer_antrag_api_aktuelle_themen_news_fuer_antrag_get","parameters":[{"name":"drucksache","in":"query","required":true,"schema":{"type":"string","title":"Drucksache"}},{"name":"top_k","in":"query","required":false,"schema":{"type":"integer","default":5,"title":"Top K"}},{"name":"min_similarity","in":"query","required":false,"schema":{"type":"number","default":0.4,"title":"Min Similarity"}},{"name":"days","in":"query","required":false,"schema":{"type":"integer","default":90,"title":"Days"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["aktuelle-themen"]}},"/api/aktuelle-themen/anträge-fuer-news":{"get":{"summary":"Api Anträge Fuer News","description":"Top-K Anträge, die zu einem gegebenen News-Artikel passen.","operationId":"api_anträge_fuer_news_api_aktuelle_themen_anträge_fuer_news_get","parameters":[{"name":"url","in":"query","required":true,"schema":{"type":"string","title":"Url"}},{"name":"top_k","in":"query","required":false,"schema":{"type":"integer","default":5,"title":"Top K"}},{"name":"min_similarity","in":"query","required":false,"schema":{"type":"number","default":0.4,"title":"Min Similarity"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["aktuelle-themen"]}},"/api/aktuelle-themen/generate-presse":{"post":{"summary":"Api Generate Presse","description":"Generiert einen LLM-Pressemitteilungs-Vorschlag.\n\nAuth-only + rate-limited (5/min) wegen LLM-Kosten.\n\n``style='pm'`` (Default) → klassische PM mit ~320–380 Worten.\n``style='thread'`` → Mastodon/Twitter-Thread (3–5 Posts à ≤280 Zeichen).\n\n``force=True`` ueberschreibt den Idempotenz-Check und macht einen\nneuen LLM-Call, auch wenn fuer (drucksache, news_url, style) schon\nein Draft existiert.","operationId":"api_generate_presse_api_aktuelle_themen_generate_presse_post","parameters":[{"name":"drucksache","in":"query","required":true,"schema":{"type":"string","title":"Drucksache"}},{"name":"news_url","in":"query","required":true,"schema":{"type":"string","title":"News Url"}},{"name":"force","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Force"}},{"name":"style","in":"query","required":false,"schema":{"type":"string","default":"pm","title":"Style"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["aktuelle-themen"]}},"/api/aktuelle-themen/drafts":{"get":{"summary":"Api Drafts List","description":"Liste der zuletzt generierten Pressemitteilungs-Entwürfe.","operationId":"api_drafts_list_api_aktuelle_themen_drafts_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":20,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["aktuelle-themen"]}},"/api/aktuelle-themen/drafts/{draft_id}":{"get":{"summary":"Api Draft Detail","description":"Einen einzelnen Pressemitteilungs-Entwurf.","operationId":"api_draft_detail_api_aktuelle_themen_drafts__draft_id__get","parameters":[{"name":"draft_id","in":"path","required":true,"schema":{"type":"integer","title":"Draft Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["aktuelle-themen"]}},"/api/aktuelle-themen/drafts/pdf/{draft_id}":{"get":{"summary":"Api Draft Pdf","description":"PM-Entwurf als PDF (WeasyPrint, Phase 4.1).","operationId":"api_draft_pdf_api_aktuelle_themen_drafts_pdf__draft_id__get","parameters":[{"name":"draft_id","in":"path","required":true,"schema":{"type":"integer","title":"Draft Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["aktuelle-themen"]}},"/api/aktuelle-themen/drafts-versions":{"get":{"summary":"Api Draft Versions","description":"Alle Versions-Drafts fuer (drucksache, news_url) — neueste oben.","operationId":"api_draft_versions_api_aktuelle_themen_drafts_versions_get","parameters":[{"name":"drucksache","in":"query","required":true,"schema":{"type":"string","title":"Drucksache"}},{"name":"news_url","in":"query","required":true,"schema":{"type":"string","title":"News Url"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["aktuelle-themen"]}},"/api/briefe/generate":{"post":{"summary":"Api Brief Generate","description":"Generiert einen Brief-/Stellungnahme-Draft und persistiert ihn.\n\nAuth-only + rate-limited (5/min) wegen LLM-Kosten. ``typ`` ist\n``brief_mdl`` (Default) oder ``stellungnahme_ngo``. Idempotenz greift\npro (drucksache, typ, mdl_name, ton); ``force=True`` erzeugt eine\nneue Version.","operationId":"api_brief_generate_api_briefe_generate_post","parameters":[{"name":"drucksache","in":"query","required":true,"schema":{"type":"string","title":"Drucksache"}},{"name":"typ","in":"query","required":false,"schema":{"type":"string","default":"brief_mdl","title":"Typ"}},{"name":"mdl_name","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mdl Name"}},{"name":"ton","in":"query","required":false,"schema":{"type":"string","default":"sachlich-kritisch","title":"Ton"}},{"name":"force","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Force"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["assessments"]}},"/api/briefe":{"get":{"summary":"Api Brief List","description":"Liste der letzten Briefe / Stellungnahmen, optional nach typ.","operationId":"api_brief_list_api_briefe_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":20,"title":"Limit"}},{"name":"typ","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Typ"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["assessments"]}},"/api/briefe/{draft_id}":{"get":{"summary":"Api Brief Detail","description":"Einzelner Brief-Entwurf als JSON.","operationId":"api_brief_detail_api_briefe__draft_id__get","parameters":[{"name":"draft_id","in":"path","required":true,"schema":{"type":"integer","title":"Draft Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["assessments"]}},"/api/briefe/{draft_id}/mailto":{"get":{"summary":"Api Brief Mailto","description":"Liefert eine ``mailto:``-URL mit URL-encoded subject + body.","operationId":"api_brief_mailto_api_briefe__draft_id__mailto_get","parameters":[{"name":"draft_id","in":"path","required":true,"schema":{"type":"integer","title":"Draft Id"}},{"name":"to","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"To"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["assessments"]}},"/api/briefe/{draft_id}/pdf":{"get":{"summary":"Api Brief Pdf","description":"Rendert den Brief/die Stellungnahme als A4-PDF via WeasyPrint.","operationId":"api_brief_pdf_api_briefe__draft_id__pdf_get","parameters":[{"name":"draft_id","in":"path","required":true,"schema":{"type":"integer","title":"Draft Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["assessments"]}},"/api/auswertungen/score-histogram":{"get":{"summary":"Auswertungen Score Histogram","description":"GWÖ-Score-Verteilung (0–10) ueber alle Bewertungen.\n\nLiefert ein Bucket-Array fuer einen Histogramm-Chart. Filterbar\nueber Bundesland + Wahlperiode (gleicher Pattern wie /matrix).","operationId":"auswertungen_score_histogram_api_auswertungen_score_histogram_get","parameters":[{"name":"bundesland","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bundesland"}},{"name":"wahlperiode","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Wahlperiode"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["auswertungen"]}},"/api/auswertungen/matrix":{"get":{"summary":"Auswertungen Matrix","description":"2D-Matrix Bundesland × Partei mit Anzahl + Ø-GWÖ-Score.\n\n``wahlkreis`` (#201) leitet implizit das Bundesland aus der\n``mdls``-Tabelle ab und beschränkt zusätzlich auf die WPs der dort\neingetragenen Personen.","operationId":"auswertungen_matrix_api_auswertungen_matrix_get","parameters":[{"name":"wahlperiode","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Wahlperiode"}},{"name":"bundesland","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bundesland"}},{"name":"wahlkreis","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Wahlkreis"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["auswertungen"]}},"/api/auswertungen/zeitreihe":{"get":{"summary":"Auswertungen Zeitreihe","description":"Score-Verlauf einer (BL, Partei)-Kombination über alle WPs.","operationId":"auswertungen_zeitreihe_api_auswertungen_zeitreihe_get","parameters":[{"name":"bundesland","in":"query","required":true,"schema":{"type":"string","title":"Bundesland"}},{"name":"partei","in":"query","required":true,"schema":{"type":"string","title":"Partei"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["auswertungen"]}},"/api/auswertungen/themen-matrix":{"get":{"summary":"Auswertungen Themen Matrix","description":"Thema × Fraktion Heatmap (#105 Integration in Auswertungen).\n\nZeigt die Ø-GWÖ-Scores pro Thema und Fraktion. Nur Themen mit\nmindestens `min_count` Assessments werden angezeigt. Optional auf\nein Bundesland einschränken.","operationId":"auswertungen_themen_matrix_api_auswertungen_themen_matrix_get","parameters":[{"name":"min_count","in":"query","required":false,"schema":{"type":"integer","default":3,"title":"Min Count"}},{"name":"bundesland","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bundesland"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["auswertungen"]}},"/api/auswertungen/export.json":{"get":{"summary":"Auswertungen Export Json","description":"Open-Data-JSON-Export aller Assessments (#113).\n\nVollständiger Download aller Bewertungen als JSON mit Metadaten.\nLizenz: CC BY 4.0 (öffentliche parlamentarische Dokumente + KI-Analyse).","operationId":"auswertungen_export_json_api_auswertungen_export_json_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"tags":["auswertungen"]}},"/api/clusters":{"get":{"summary":"Clusters Api","description":"Antrag-Cluster (#105) per Cosine-Similarity über v4-Embeddings.\n\nWenn threshold nicht angegeben, nutze den Default aus clustering.py\n(0.55, empirisch kalibriert für die aktuelle Prod-DB).","operationId":"clusters_api_api_clusters_get","parameters":[{"name":"bundesland","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bundesland"}},{"name":"threshold","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Threshold"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["assessments"]}},"/api/assessment/similar":{"get":{"summary":"Assessment Similar","description":"Ähnliche Anträge zum gegebenen (#108 Teil B).","operationId":"assessment_similar_api_assessment_similar_get","parameters":[{"name":"drucksache","in":"query","required":true,"schema":{"type":"string","title":"Drucksache"}},{"name":"top_k","in":"query","required":false,"schema":{"type":"integer","default":5,"title":"Top K"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["assessments"]}},"/api/feed.xml":{"get":{"summary":"Feed Xml","description":"Atom 1.0 Feed der neuesten Bewertungen (Issue #125).\n\nQuery-Parameter:\n- bundesland: optionaler BL-Code (NRW, MV, BE, …)\n- partei: optionaler Partei-Filter (CDU, SPD, GRÜNE, …) — matcht gegen fraktionen-Liste\n- limit: Anzahl Einträge (default 50, max 200)","operationId":"feed_xml_api_feed_xml_get","parameters":[{"name":"bundesland","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bundesland"}},{"name":"partei","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Partei"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["meta"]}},"/api/auswertungen/export.csv":{"get":{"summary":"Auswertungen Export Csv","description":"Long-Format-CSV-Export aller Assessments. Deckt #45 mit ab.","operationId":"auswertungen_export_csv_api_auswertungen_export_csv_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"tags":["auswertungen"]}},"/api/auswertungen/stimm-index":{"get":{"summary":"Auswertungen Stimm Index","description":"Pro Fraktion Ø-GWÖ der JA-Anträge MINUS Ø-GWÖ der NEIN-Anträge.\n\nAntwort auf \"Welche Fraktionen stimmen häufiger gemeinwohl-\norientierten Anträgen zu?\". Antragsteller-Bias per Default raus.","operationId":"auswertungen_stimm_index_api_auswertungen_stimm_index_get","parameters":[{"name":"bundesland","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bundesland"}},{"name":"wahlperiode","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Wahlperiode"}},{"name":"exclude_antragsteller","in":"query","required":false,"schema":{"type":"boolean","default":true,"title":"Exclude Antragsteller"}},{"name":"min_n","in":"query","required":false,"schema":{"type":"integer","default":5,"title":"Min N"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["auswertungen"]}},"/api/auswertungen/heuchelei":{"get":{"summary":"Auswertungen Heuchelei","description":"Pro Fraktion: Anteil der Anträge mit wahlprogramm_score>=threshold,\nbei denen die Fraktion trotzdem NEIN gestimmt hat.\n\nMacht sichtbar, wer gegen die eigenen Wahlversprechen stimmt.","operationId":"auswertungen_heuchelei_api_auswertungen_heuchelei_get","parameters":[{"name":"bundesland","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bundesland"}},{"name":"wahlperiode","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Wahlperiode"}},{"name":"score_threshold","in":"query","required":false,"schema":{"type":"number","default":7.0,"title":"Score Threshold"}},{"name":"min_n","in":"query","required":false,"schema":{"type":"integer","default":5,"title":"Min N"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["auswertungen"]}},"/api/auswertungen/heuchelei-cases":{"get":{"summary":"Auswertungen Heuchelei Cases","description":"Drilldown-Liste: konkrete Anträge wo `partei` mit NEIN gestimmt hat,\nobwohl der Antrag inhaltlich zum eigenen Wahlprogramm passt.","operationId":"auswertungen_heuchelei_cases_api_auswertungen_heuchelei_cases_get","parameters":[{"name":"partei","in":"query","required":true,"schema":{"type":"string","title":"Partei"}},{"name":"bundesland","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bundesland"}},{"name":"wahlperiode","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Wahlperiode"}},{"name":"score_threshold","in":"query","required":false,"schema":{"type":"number","default":7.0,"title":"Score Threshold"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["auswertungen"]}},"/api/auswertungen/empfehlungs-konsistenz-cases":{"get":{"summary":"Auswertungen Empfehlungs Konsistenz Cases","description":"Drilldown: Anträge wo `partei` mit NEIN stimmte trotz GWÖ-Empfehlung\n'Unterstützen'. Quelle für Klick auf Empfehlungs-Konsistenz-Bar (#167).","operationId":"auswertungen_empfehlungs_konsistenz_cases_api_auswertungen_empfehlungs_konsistenz_cases_get","parameters":[{"name":"partei","in":"query","required":true,"schema":{"type":"string","title":"Partei"}},{"name":"bundesland","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bundesland"}},{"name":"wahlperiode","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Wahlperiode"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["auswertungen"]}},"/api/auswertungen/stimm-index-pro-wert":{"get":{"summary":"Auswertungen Stimm Index Pro Wert","description":"Stimm-Index aufgeschlüsselt pro GWÖ-Wert (5 Spalten:\nWürde/Solidarität/Nachhaltigkeit/Gerechtigkeit/Demokratie).","operationId":"auswertungen_stimm_index_pro_wert_api_auswertungen_stimm_index_pro_wert_get","parameters":[{"name":"bundesland","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bundesland"}},{"name":"wahlperiode","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Wahlperiode"}},{"name":"exclude_antragsteller","in":"query","required":false,"schema":{"type":"boolean","default":true,"title":"Exclude Antragsteller"}},{"name":"min_n","in":"query","required":false,"schema":{"type":"integer","default":5,"title":"Min N"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["auswertungen"]}},"/api/auswertungen/stimm-index-cross-bl":{"get":{"summary":"Auswertungen Stimm Index Cross Bl","description":"Stimm-Index pro (Fraktion, Bundesland) — regionale Drift sichtbar\nfuer bundesweit aktive Fraktionen.","operationId":"auswertungen_stimm_index_cross_bl_api_auswertungen_stimm_index_cross_bl_get","parameters":[{"name":"wahlperiode","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Wahlperiode"}},{"name":"exclude_antragsteller","in":"query","required":false,"schema":{"type":"boolean","default":true,"title":"Exclude Antragsteller"}},{"name":"min_n","in":"query","required":false,"schema":{"type":"integer","default":5,"title":"Min N"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["auswertungen"]}},"/api/auswertungen/stimm-index-zeitreihe":{"get":{"summary":"Auswertungen Stimm Index Zeitreihe","description":"Stimm-Index ueber Zeit (Quartal × Fraktion) — Drift im Stimmverhalten\nwaehrend der Wahlperiode (#168).","operationId":"auswertungen_stimm_index_zeitreihe_api_auswertungen_stimm_index_zeitreihe_get","parameters":[{"name":"bundesland","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bundesland"}},{"name":"wahlperiode","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Wahlperiode"}},{"name":"parteien","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parteien"}},{"name":"exclude_antragsteller","in":"query","required":false,"schema":{"type":"boolean","default":true,"title":"Exclude Antragsteller"}},{"name":"min_n_per_bucket","in":"query","required":false,"schema":{"type":"integer","default":3,"title":"Min N Per Bucket"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["auswertungen"]}},"/api/auswertungen/stimm-index-pro-gruppe":{"get":{"summary":"Auswertungen Stimm Index Pro Gruppe","description":"Stimm-Index pro Beruehrungsgruppe (A-E der GWÖ-Matrix-Zeilen) (#166).","operationId":"auswertungen_stimm_index_pro_gruppe_api_auswertungen_stimm_index_pro_gruppe_get","parameters":[{"name":"bundesland","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bundesland"}},{"name":"wahlperiode","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Wahlperiode"}},{"name":"exclude_antragsteller","in":"query","required":false,"schema":{"type":"boolean","default":true,"title":"Exclude Antragsteller"}},{"name":"min_n","in":"query","required":false,"schema":{"type":"integer","default":5,"title":"Min N"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["auswertungen"]}},"/api/auswertungen/vote-orphans":{"get":{"summary":"Api Vote Orphans","description":"Drucksachen mit Plenum-Vote aber ohne GWÖ-Bewertung (#172).","operationId":"api_vote_orphans_api_auswertungen_vote_orphans_get","parameters":[{"name":"bundesland","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bundesland"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":200,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["auswertungen"]}},"/api/auswertungen/vote-orphans/auto-rate":{"post":{"summary":"Api Auto Rate Vote Orphans","description":"Bulk-Auto-Bewerten der Top-N Vote-Orphans (#172).\n\nAdmin-only + rate-limited. Nimmt die neuesten Drucksachen aus\n`vote-orphans`, laedt den Antragstext per Adapter herunter und\nenqueued einen Job pro Drucksache. Konservatives Default-Limit 10.\n\n`source` = 'manual'|'cron'|'api' wird in auto_rate_runs persistiert.\n`daily_cap` = max. Tagessumme an Auto-Bewertungen (Default 200), wird\ngegen die Run-Historie geprueft.","operationId":"api_auto_rate_vote_orphans_api_auswertungen_vote_orphans_auto_rate_post","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_api_auto_rate_vote_orphans_api_auswertungen_vote_orphans_auto_rate_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["auswertungen"]}},"/api/auto-rate-runs":{"get":{"summary":"Api Auto Rate Runs","description":"Letzte N Runs der Vote-Orphans-Auto-Bewertung (admin-only).","operationId":"api_auto_rate_runs_api_auto_rate_runs_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":20,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["auswertungen"]}},"/api/auswertungen/empfehlungs-konsistenz":{"get":{"summary":"Auswertungen Empfehlungs Konsistenz","description":"Pro Fraktion: Anteil der Anträge mit GWÖ-Empfehlung \"Uneingeschränkt\nunterstützen\"/\"Unterstützen mit Änderungen\", bei denen die Fraktion\ntrotzdem NEIN gestimmt hat (#167).","operationId":"auswertungen_empfehlungs_konsistenz_api_auswertungen_empfehlungs_konsistenz_get","parameters":[{"name":"bundesland","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bundesland"}},{"name":"wahlperiode","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Wahlperiode"}},{"name":"min_n","in":"query","required":false,"schema":{"type":"integer","default":5,"title":"Min N"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["auswertungen"]}},"/api/auswertungen/stimmverhalten.csv":{"get":{"summary":"Auswertungen Stimmverhalten Csv","description":"Long-Format-CSV: eine Zeile pro (drucksache, partei, vote). Macht die\nStimmverhalten-Aussagen wissenschaftlich auswertbar (R/pandas/Excel).","operationId":"auswertungen_stimmverhalten_csv_api_auswertungen_stimmverhalten_csv_get","parameters":[{"name":"bundesland","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bundesland"}},{"name":"wahlperiode","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Wahlperiode"}},{"name":"exclude_antragsteller","in":"query","required":false,"schema":{"type":"boolean","default":true,"title":"Exclude Antragsteller"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["auswertungen"]}},"/v2":{"get":{"summary":"V2 Redirect","description":"Redirect /v2 → / (v2 ist jetzt Default unter /).","operationId":"v2_redirect_v2_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"tags":["frontend"]}},"/v2/merkliste":{"get":{"summary":"V2 Merkliste","description":"Merkliste (Bookmarks) — nur für eingeloggte User; lädt Daten via /api/bookmarks client-seitig.","operationId":"v2_merkliste_v2_merkliste_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"tags":["frontend"]}},"/v2/tags":{"get":{"summary":"V2 Tags","description":"Tag-Cloud-Seite — Themen-Filter über alle Assessments.","operationId":"v2_tags_v2_tags_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"tags":["frontend"]}},"/v2/abos":{"get":{"summary":"V2 Abos","description":"Eigene E-Mail-Abos verwalten — auth-only.","operationId":"v2_abos_v2_abos_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"tags":["frontend"]}},"/v2/feed":{"get":{"summary":"V2 Feed","description":"Atom-Feed-Konfigurations-Seite — auth-only.","operationId":"v2_feed_v2_feed_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"tags":["frontend"]}},"/v2/cluster":{"get":{"summary":"V2 Cluster","description":"Cluster-Liste — nur für Admins.","operationId":"v2_cluster_v2_cluster_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"tags":["frontend"]}},"/v2/neu":{"get":{"summary":"V2 Neu","description":"Neuer-Antrag-Form — nur für eingeloggte User; startet Analyse via /api/analyze-drucksache.","operationId":"v2_neu_v2_neu_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"tags":["frontend"]}},"/v2/landtag-suche":{"get":{"summary":"V2 Landtag Suche","description":"Landtag-Suche — nur für eingeloggte User; sucht Drucksachen live im Landtags-Portal.","operationId":"v2_landtag_suche_v2_landtag_suche_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"tags":["frontend"]}},"/v2/batch":{"get":{"summary":"V2 Batch","description":"Batch-Analyse-Form — nur für Admins; enqueued ungeprüfte Drucksachen eines BL.","operationId":"v2_batch_v2_batch_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"tags":["frontend"]}},"/v2/admin/freischaltungen":{"get":{"summary":"V2 Admin Freischaltungen","description":"Ausstehende User-Freischaltungen (Admin).","operationId":"v2_admin_freischaltungen_v2_admin_freischaltungen_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"tags":["admin"]}},"/v2/admin/queue":{"get":{"summary":"V2 Admin Queue","description":"Queue-Status-Übersicht (Admin).","operationId":"v2_admin_queue_v2_admin_queue_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"tags":["admin"]}},"/v2/admin/stand":{"get":{"summary":"V2 Admin Stand","description":"System-Stand-Dashboard — Ueberblick ueber alle Datenmengen.","operationId":"v2_admin_stand_v2_admin_stand_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"tags":["admin"]}},"/api/admin/stand":{"get":{"summary":"Api Admin Stand","description":"Datenstand-Aggregation für das Stand-Dashboard.\n\nLiefert Gesamt + Per-Quelle + Letzte-7-Tage in einem Roundtrip.","operationId":"api_admin_stand_api_admin_stand_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"tags":["admin"]}},"/v2/admin/abos":{"get":{"summary":"V2 Admin Abos","description":"Abo-Verwaltung — alle E-Mail-Abonnements (Admin).","operationId":"v2_admin_abos_v2_admin_abos_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"tags":["admin"]}},"/cockpit":{"get":{"summary":"Cockpit Page","description":"KPI-Cockpit mit Ampel-Logik (#196). Admin-only.\n\nRendert die Ampel-Kacheln pro (Bundesland, Fraktion) fuer die drei\nCockpit-Kennzahlen. Schwellen-Edit-UI ist unter ``/cockpit/thresholds``\nerreichbar; aktuelle Werte werden serverseitig vorberechnet.","operationId":"cockpit_page_cockpit_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"tags":["admin"]}},"/api/cockpit/status":{"get":{"summary":"Api Cockpit Status","description":"JSON-Endpoint fuer externe Konsumenten.\n\nOptionale Query-Param ``bundesland=`` (mehrfach erlaubt). Ohne Filter\nwerden alle aktiven Bundeslaender ausgewertet.","operationId":"api_cockpit_status_api_cockpit_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"tags":["admin"]}},"/api/cockpit/thresholds":{"get":{"summary":"Api Cockpit Thresholds","description":"Aktuelle Schwellen aller Kennzahlen (Admin-only).","operationId":"api_cockpit_thresholds_api_cockpit_thresholds_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"tags":["admin"]},"post":{"summary":"Api Cockpit Threshold Upsert","description":"Lege eine Schwelle an oder aktualisiere sie (Admin-only).","operationId":"api_cockpit_threshold_upsert_api_cockpit_thresholds_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_CockpitThresholdIn"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["admin"]}},"/alerts/subscribe":{"get":{"summary":"Alerts Subscribe Page","description":"Opt-in-Seite für Frühwarn-Abos (#198).\n\nAuth wird im Template selbst gepruft — anonyme User sehen einen\nLogin-Hinweis statt 401. So bleibt die Page als Landing-Seite\nverlinkbar.","operationId":"alerts_subscribe_page_alerts_subscribe_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"tags":["meta"]}},"/api/alerts/subscribe":{"post":{"summary":"Api Alerts Subscribe","description":"Neues Alert-Abo anlegen.\n\nErwartet Form-encoded oder URL-Encoded Body mit:\n* trigger_typen (mehrfach, mind. 1) — Kennzahl-Keys aus KENNZAHLEN\n* trigger_schwelle — 'gelb' (default) oder 'rot'\n* bundesland / partei / wahlkreis (optional)","operationId":"api_alerts_subscribe_api_alerts_subscribe_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"tags":["meta"]}},"/api/alerts/subscriptions":{"get":{"summary":"Api Alerts Subscriptions","description":"Liste der Alert-Abos des aktuellen Nutzers.","operationId":"api_alerts_subscriptions_api_alerts_subscriptions_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"tags":["meta"]}},"/cockpit/triggers":{"get":{"summary":"Cockpit Triggers Page","description":"Admin-UI für Alert-Triggers (#198, admin-only).","operationId":"cockpit_triggers_page_cockpit_triggers_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"tags":["admin"]}},"/api/alerts/triggers":{"get":{"summary":"Api Alerts Triggers List","description":"Liste aller Alert-Triggers (admin-only).","operationId":"api_alerts_triggers_list_api_alerts_triggers_get","parameters":[{"name":"only_active","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Only Active"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["meta"]},"post":{"summary":"Api Alerts Trigger Create","description":"Trigger anlegen (admin-only).","operationId":"api_alerts_trigger_create_api_alerts_triggers_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_AlertTriggerIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["meta"]}},"/api/alerts/triggers/{trigger_id}":{"patch":{"summary":"Api Alerts Trigger Update","description":"Trigger aktualisieren — nur ``aktiv`` und ``schwelle`` (admin-only).","operationId":"api_alerts_trigger_update_api_alerts_triggers__trigger_id__patch","parameters":[{"name":"trigger_id","in":"path","required":true,"schema":{"type":"integer","title":"Trigger Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_AlertTriggerPatch"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["meta"]},"delete":{"summary":"Api Alerts Trigger Delete","description":"Trigger löschen (admin-only). alert_log bleibt für Audit.","operationId":"api_alerts_trigger_delete_api_alerts_triggers__trigger_id__delete","parameters":[{"name":"trigger_id","in":"path","required":true,"schema":{"type":"integer","title":"Trigger Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["meta"]}},"/api/alerts/log":{"get":{"summary":"Api Alerts Log","description":"Letzte N Alert-Auslösungen (admin-only).","operationId":"api_alerts_log_api_alerts_log_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["meta"]}},"/newsletter":{"get":{"summary":"Newsletter Subscribe Page","description":"Öffentliche Opt-in-Seite für den Wochen-Newsletter (#206).","operationId":"newsletter_subscribe_page_newsletter_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"tags":["frontend"]}},"/api/newsletter/subscribe":{"post":{"summary":"Api Newsletter Subscribe","description":"Newsletter-Abo anlegen — sendet Confirm-Mail (Double-Opt-in).\n\nRate-Limited auf 5/min pro IP, um Mail-Bombing zu verhindern.\nAntwort ist absichtlich generisch (immer 200), damit Nutzer nicht\naus dem Response ableiten können, ob die Adresse schon im System ist\n(E-Mail-Enumeration-Schutz).","operationId":"api_newsletter_subscribe_api_newsletter_subscribe_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"tags":["meta"]}},"/api/newsletter/confirm":{"get":{"summary":"Api Newsletter Confirm","description":"Confirm-Endpoint für Double-Opt-in. Setzt ``consent_at`` und zeigt\neine simple Bestätigungs-Page.","operationId":"api_newsletter_confirm_api_newsletter_confirm_get","parameters":[{"name":"token","in":"query","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["meta"]}},"/newsletter/unsubscribe":{"get":{"summary":"Newsletter Unsubscribe","description":"1-Klick-Abmeldung (#209, DSGVO-Pflicht). Setzt ``consent_at`` auf\nNULL und markiert das Abo als abgemeldet — der Empfänger fällt damit\naus allen künftigen Versand-Runs.","operationId":"newsletter_unsubscribe_newsletter_unsubscribe_get","parameters":[{"name":"token","in":"query","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["frontend"]}},"/newsletter/archiv":{"get":{"summary":"Newsletter Archiv Index","description":"Liste aller vergangenen Newsletter-Issues (öffentlich).","operationId":"newsletter_archiv_index_newsletter_archiv_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"tags":["frontend"]}},"/newsletter/archiv/{kw}":{"get":{"summary":"Newsletter Archiv Show","description":"Render eines archivierten Newsletters per KW (öffentlich).","operationId":"newsletter_archiv_show_newsletter_archiv__kw__get","parameters":[{"name":"kw","in":"path","required":true,"schema":{"type":"string","title":"Kw"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["frontend"]}},"/v2/og-template":{"get":{"summary":"Og Template","description":"Internes Render-Template für Playwright (#141).\n\nWird von render_og_card() intern aufgerufen — nicht für Endnutzer.","operationId":"og_template_v2_og_template_get","parameters":[{"name":"drucksache","in":"query","required":false,"schema":{"type":"string","default":"","title":"Drucksache"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["frontend"]}},"/v2/scorecard-werkstatt":{"get":{"summary":"Scorecard Werkstatt","description":"Live-Sandbox für Scorecard-Design-Iteration.\n\nZeigt eine Vorschau-iframe der /v2/scorecard und einen CSS-Live-Editor.\nKein DB-Lookup nötig — der Editor passt nur Styles an, der Inhalt kommt\nvon der gewählten Drucksache. Plus Embed-Link-Generator für die\nfertige Ansicht in anderen Kontexten.","operationId":"scorecard_werkstatt_v2_scorecard_werkstatt_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"tags":["frontend"]}},"/v2/scorecard":{"get":{"summary":"Scorecard Template","description":"Internes Render-Template für Scorecards (#179).\n\n`format=portrait` → 1080×1350 (Instagram 4:5 Hochformat — DEFAULT)\n`format=square`   → 1080×1080 (Instagram quadratisch)\n`format=og`       → 1200×630  (LinkedIn/Twitter-OG)","operationId":"scorecard_template_v2_scorecard_get","parameters":[{"name":"drucksache","in":"query","required":true,"schema":{"type":"string","title":"Drucksache"}},{"name":"bundesland","in":"query","required":false,"schema":{"type":"string","default":"NRW","title":"Bundesland"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","default":"portrait","title":"Format"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["frontend"]}},"/api/assessment/scorecard.png":{"get":{"summary":"Api Scorecard Png","description":"Liefert die Scorecard als PNG via WeasyPrint→PyMuPDF.\n\n`scale=2.0` rendert in doppelter Auflösung (für Retina-Displays).","operationId":"api_scorecard_png_api_assessment_scorecard_png_get","parameters":[{"name":"drucksache","in":"query","required":true,"schema":{"type":"string","title":"Drucksache"}},{"name":"bundesland","in":"query","required":false,"schema":{"type":"string","default":"NRW","title":"Bundesland"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","default":"portrait","title":"Format"}},{"name":"scale","in":"query","required":false,"schema":{"type":"number","default":2.0,"title":"Scale"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["assessments"]}},"/api/assessment/scorecard.pdf":{"get":{"summary":"Api Scorecard Pdf","description":"Liefert die Scorecard als PDF via WeasyPrint (#179).\n\n`format=og` → 1200×630, `format=square` → 1080×1080.","operationId":"api_scorecard_pdf_api_assessment_scorecard_pdf_get","parameters":[{"name":"drucksache","in":"query","required":true,"schema":{"type":"string","title":"Drucksache"}},{"name":"bundesland","in":"query","required":false,"schema":{"type":"string","default":"NRW","title":"Bundesland"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","default":"portrait","title":"Format"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["assessments"]}},"/api/og/{drucksache_encoded}.png":{"get":{"summary":"Api Og Card","description":"Liefert die Open-Graph-PNG-Karte für einen Antrag (#141).\n\nCache-Hit → direkte Datei-Response.\nCache-Miss → Playwright-Render (synchron, blockiert kurz).","operationId":"api_og_card_api_og__drucksache_encoded__png_get","parameters":[{"name":"drucksache_encoded","in":"path","required":true,"schema":{"type":"string","title":"Drucksache Encoded"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["assessments"]}},"/v2/admin/wahlprogramme":{"get":{"summary":"V2 Admin Wahlprogramme","description":"Admin-Übersicht fehlender Wahlprogramme mit Kandidaten-URLs (#138).","operationId":"v2_admin_wahlprogramme_v2_admin_wahlprogramme_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}},"tags":["admin"]}},"/api/admin/wahlprogramm-fetch":{"post":{"summary":"Api Admin Wahlprogramm Fetch","description":"Lädt ein Wahlprogramm von einer angegebenen URL (#138).\n\nBody: JSON { \"bl\": \"NRW\", \"partei\": \"BSW\", \"url\": \"https://...\" }\nSHA-Gate: Wenn eine Datei bereits vorhanden ist und der SHA abweicht,\nwird sie nicht überschrieben — stattdessen wird ein 409-Fehler zurückgegeben.","operationId":"api_admin_wahlprogramm_fetch_api_admin_wahlprogramm_fetch_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"tags":["admin"]}},"/api/feedback":{"post":{"summary":"Submit Feedback","description":"Erstellt ein Gitea-Issue mit Label 'feedback'.\n\nAudit-Trail (Klicks, Errors, URL etc.) wird im Issue-Body als\nMarkdown-Code-Block angefügt. Screenshot wird als Issue-Asset\nhochgeladen, falls vorhanden.","operationId":"submit_feedback_api_feedback_post","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_submit_feedback_api_feedback_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["assessments"]}},"/mdls":{"get":{"summary":"Mdls List Page","description":"Übersichtsseite aller MdLs mit Filtern (#210).\n\nBewusst öffentlich (Bürger\\*innen-Sicht): „Wer sitzt im Landtag?\".\nFilter über Bundesland, Fraktion, Wahlperiode und Wahlkreis-Textsuche;\nSortierung nach Name oder Bundesland. Rendert robust mit 0 MdLs.","operationId":"mdls_list_page_mdls_get","parameters":[{"name":"bundesland","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bundesland"}},{"name":"fraktion","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Fraktion"}},{"name":"wp","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Wp"}},{"name":"wahlkreis","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Wahlkreis"}},{"name":"sort","in":"query","required":false,"schema":{"type":"string","default":"name","title":"Sort"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/mdls":{"get":{"summary":"Api Mdls List","description":"JSON-Liste der MdL-Übersicht mit Filtern + Facetten (#210).\n\nWahlkreis ist Teilstring-Suche (LIKE). Pendant zur HTML-Seite\n``/mdls``; ``/api/mdl`` (Singular, #201) bleibt für exakten\nWahlkreis-Match bestehen.","operationId":"api_mdls_list_api_mdls_get","parameters":[{"name":"bundesland","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bundesland"}},{"name":"fraktion","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Fraktion"}},{"name":"wp","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Wp"}},{"name":"wahlkreis","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Wahlkreis"}},{"name":"sort","in":"query","required":false,"schema":{"type":"string","default":"name","title":"Sort"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":2000,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/mdl/{slug}":{"get":{"summary":"Mdl Detail Page","description":"Profil-Seite einer MdL-Person mit GWÖ-Stimmverhalten + Programm-Treue.\n\nAggregat-Sicht: Stimmen werden über die Fraktion abgeleitet, sofern\nkeine namentliche Abstimmung vorliegt. Folge-Issue: Parser-Erweiterung\nje Bundesland.","operationId":"mdl_detail_page_mdl__slug__get","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["frontend"]}},"/api/mdl":{"get":{"summary":"Api Mdl List","description":"JSON-Liste aller MdLs mit optionalen Filtern.\n\nOhne Auth, da bewusst eine Bürger\\*innen-Sicht: „Wer vertritt mich\nim Landtag?\".","operationId":"api_mdl_list_api_mdl_get","parameters":[{"name":"bundesland","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bundesland"}},{"name":"fraktion","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Fraktion"}},{"name":"wahlkreis","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Wahlkreis"}},{"name":"wp","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Wp"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":500,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["assessments"]}},"/api/mdl/{slug}":{"get":{"summary":"Api Mdl Detail","description":"Einzelne MdL-Profil-Daten + aggregiertes Stimmverhalten als JSON.","operationId":"api_mdl_detail_api_mdl__slug__get","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["assessments"]}},"/api/mdl-wahlkreise":{"get":{"summary":"Api Mdl Wahlkreise","description":"Distinct Wahlkreis-Liste, optional nach Bundesland gefiltert.\n\nSpeist das Wahlkreis-Filter-Dropdown auf der ``/auswertungen``-Seite.","operationId":"api_mdl_wahlkreise_api_mdl_wahlkreise_get","parameters":[{"name":"bundesland","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bundesland"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["assessments"]}},"/wahlversprechen":{"get":{"summary":"Wahlversprechen Page","description":"Öffentliche Übersichtsseite des Wahlversprechen-Trackers.\n\nFilterung passiert serverseitig — robuste URLs, die ohne JS\nfunktionieren. Der Bilanz-Block (Erfüllungsquote pro Fraktion) wird\nparallel zur Liste berechnet.","operationId":"wahlversprechen_page_wahlversprechen_get","parameters":[{"name":"partei","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Partei"}},{"name":"bundesland","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bundesland"}},{"name":"wp","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Wp"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["frontend"]}},"/api/wahlversprechen":{"get":{"summary":"Api Wahlversprechen","description":"JSON-Liste mit denselben Filtern wie die HTML-Seite.","operationId":"api_wahlversprechen_api_wahlversprechen_get","parameters":[{"name":"partei","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Partei"}},{"name":"bundesland","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bundesland"}},{"name":"wp","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Wp"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"programm_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Programm Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":500,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["assessments"]}},"/api/wahlversprechen/bilanz":{"get":{"summary":"Api Wahlversprechen Bilanz","description":"Erfüllungsquote pro (Partei, Bundesland, WP) am WP-Ende.","operationId":"api_wahlversprechen_bilanz_api_wahlversprechen_bilanz_get","parameters":[{"name":"partei","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Partei"}},{"name":"bundesland","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bundesland"}},{"name":"wp","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Wp"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["assessments"]}},"/api/wahlversprechen/match":{"get":{"summary":"Api Wahlversprechen Match","description":"Schlägt Versprechen vor, die zu einer Drucksache passen.\n\nLiest den Antrag aus der Assessments-Tabelle, baut Such-Text aus\nTitel + Zusammenfassung + Themen, embeddet und matcht gegen die\nVersprechen-Embeddings. Ergebnis ist eine Vorschlagsliste für die\nmanuelle Pflege (Admin-UI).","operationId":"api_wahlversprechen_match_api_wahlversprechen_match_get","parameters":[{"name":"drucksache","in":"query","required":true,"schema":{"type":"string","title":"Drucksache"}},{"name":"top_k","in":"query","required":false,"schema":{"type":"integer","default":5,"title":"Top K"}},{"name":"min_similarity","in":"query","required":false,"schema":{"type":"number","default":0.4,"title":"Min Similarity"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["assessments"]}},"/api/wahlversprechen/{wv_id}":{"patch":{"summary":"Api Wahlversprechen Update","description":"Manuelles Status-Update durch Admins.\n\nErwartetes Payload-Schema (alle Felder optional):\n``{status, status_begruendung, evidenz_drucksachen (list[str]),\nmanuell_geprueft (bool)}``.","operationId":"api_wahlversprechen_update_api_wahlversprechen__wv_id__patch","parameters":[{"name":"wv_id","in":"path","required":true,"schema":{"type":"integer","title":"Wv Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Payload"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["assessments"]}},"/berichte":{"get":{"summary":"Berichte Page","description":"Öffentliche Listing-Seite aller generierten Quartal/Jahres/WP-Berichte.\n\nFilter: Typ (quartal/jahr/wp) und Bundesland. Download über\n``/berichte/{id}`` mit Content-Disposition.","operationId":"berichte_page_berichte_get","parameters":[{"name":"typ","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Typ"}},{"name":"bundesland","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bundesland"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["frontend"]}},"/api/berichte":{"get":{"summary":"Api Berichte List","description":"JSON-Liste aller Berichte mit denselben Filtern wie /berichte.","operationId":"api_berichte_list_api_berichte_get","parameters":[{"name":"typ","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Typ"}},{"name":"bundesland","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bundesland"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["assessments"]}},"/berichte/{bericht_id}":{"get":{"summary":"Berichte Download","description":"PDF-Download eines einzelnen Berichts.","operationId":"berichte_download_berichte__bericht_id__get","parameters":[{"name":"bericht_id","in":"path","required":true,"schema":{"type":"integer","title":"Bericht Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"tags":["frontend"]}},"/health":{"get":{"tags":["meta"],"summary":"Health","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}}},"components":{"schemas":{"BestPracticeFlag":{"properties":{"is_best_practice":{"type":"boolean","title":"Is Best Practice"},"begruendung":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Begruendung"},"klasse":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Klasse"}},"type":"object","required":["is_best_practice"],"title":"BestPracticeFlag"},"Body_analyze_drucksache_api_analyze_drucksache_post":{"properties":{"drucksache":{"type":"string","title":"Drucksache"},"bundesland":{"type":"string","title":"Bundesland","default":"NRW"},"model":{"type":"string","title":"Model","default":"qwen-plus"}},"type":"object","required":["drucksache"],"title":"Body_analyze_drucksache_api_analyze_drucksache_post"},"Body_api_auto_rate_vote_orphans_api_auswertungen_vote_orphans_auto_rate_post":{"properties":{"bundesland":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bundesland"},"limit":{"type":"integer","title":"Limit","default":10},"source":{"type":"string","title":"Source","default":"manual"},"daily_cap":{"type":"integer","title":"Daily Cap","default":200}},"type":"object","title":"Body_api_auto_rate_vote_orphans_api_auswertungen_vote_orphans_auto_rate_post"},"Body_auth_approve_user_api_auth_approve_user_post":{"properties":{"user_id":{"type":"string","title":"User Id"}},"type":"object","required":["user_id"],"title":"Body_auth_approve_user_api_auth_approve_user_post"},"Body_auth_direct_login_api_auth_login_post":{"properties":{"username":{"type":"string","title":"Username"},"password":{"type":"string","title":"Password"}},"type":"object","required":["username","password"],"title":"Body_auth_direct_login_api_auth_login_post"},"Body_auth_register_api_auth_register_post":{"properties":{"firstName":{"type":"string","title":"Firstname"},"lastName":{"type":"string","title":"Lastname"},"email":{"type":"string","title":"Email"},"username":{"type":"string","title":"Username"}},"type":"object","required":["firstName","lastName","email","username"],"title":"Body_auth_register_api_auth_register_post"},"Body_batch_analyze_api_batch_analyze_post":{"properties":{"bundesland":{"type":"string","title":"Bundesland"},"limit":{"type":"integer","title":"Limit","default":10}},"type":"object","required":["bundesland"],"title":"Body_batch_analyze_api_batch_analyze_post"},"Body_bookmark_toggle_api_bookmark_post":{"properties":{"drucksache":{"type":"string","title":"Drucksache"}},"type":"object","required":["drucksache"],"title":"Body_bookmark_toggle_api_bookmark_post"},"Body_comment_add_api_comment_post":{"properties":{"drucksache":{"type":"string","title":"Drucksache"},"text":{"type":"string","title":"Text"},"visibility":{"type":"string","title":"Visibility","default":"all"}},"type":"object","required":["drucksache","text"],"title":"Body_comment_add_api_comment_post"},"Body_index_programme_api_programme_index_post":{"properties":{"programm_id":{"type":"string","title":"Programm Id"},"all_programmes":{"type":"boolean","title":"All Programmes","default":false}},"type":"object","title":"Body_index_programme_api_programme_index_post"},"Body_start_analysis_analyze_post":{"properties":{"text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Text"},"file":{"anyOf":[{"type":"string","format":"binary"},{"type":"null"}],"title":"File"},"bundesland":{"type":"string","title":"Bundesland","default":"NRW"},"model":{"type":"string","title":"Model","default":"qwen-plus"}},"type":"object","title":"Body_start_analysis_analyze_post"},"Body_submit_feedback_api_feedback_post":{"properties":{"titel":{"type":"string","title":"Titel"},"beschreibung":{"type":"string","title":"Beschreibung"},"url":{"type":"string","title":"Url","default":""},"user_agent":{"type":"string","title":"User Agent","default":""},"viewport":{"type":"string","title":"Viewport","default":""},"drucksache":{"type":"string","title":"Drucksache","default":""},"klicks_json":{"type":"string","title":"Klicks Json","default":"[]"},"errors_json":{"type":"string","title":"Errors Json","default":"[]"},"screenshot":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Screenshot"},"screenshot_error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Screenshot Error"}},"type":"object","required":["titel","beschreibung"],"title":"Body_submit_feedback_api_feedback_post"},"Body_subscription_create_api_subscriptions_post":{"properties":{"bundesland":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bundesland"},"partei":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Partei"},"frequency":{"type":"string","title":"Frequency","default":"daily"}},"type":"object","title":"Body_subscription_create_api_subscriptions_post"},"Body_vote_endpoint_api_vote_post":{"properties":{"drucksache":{"type":"string","title":"Drucksache"},"target":{"type":"string","title":"Target","default":"overall"},"vote":{"type":"string","title":"Vote"}},"type":"object","required":["drucksache","vote"],"title":"Body_vote_endpoint_api_vote_post"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"_AlertTriggerIn":{"properties":{"kennzahl":{"type":"string","title":"Kennzahl"},"schwelle":{"type":"string","title":"Schwelle","default":"gelb"},"fraktion":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Fraktion"},"bundesland":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bundesland"},"aktiv":{"type":"boolean","title":"Aktiv","default":true}},"type":"object","required":["kennzahl"],"title":"_AlertTriggerIn"},"_AlertTriggerPatch":{"properties":{"aktiv":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Aktiv"},"schwelle":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Schwelle"}},"type":"object","title":"_AlertTriggerPatch"},"_CockpitThresholdIn":{"properties":{"kennzahl":{"type":"string","title":"Kennzahl"},"gelb_ab":{"type":"number","title":"Gelb Ab"},"rot_ab":{"type":"number","title":"Rot Ab"},"niedriger_ist_schlecht":{"type":"boolean","title":"Niedriger Ist Schlecht","default":false},"anwendung_auf":{"type":"string","title":"Anwendung Auf","default":"global"},"scope_wert":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Scope Wert"}},"type":"object","required":["kennzahl","gelb_ab","rot_ab"],"title":"_CockpitThresholdIn"},"_MerklisteAddBody":{"properties":{"antrag_id":{"type":"string","title":"Antrag Id"},"notiz":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notiz"}},"type":"object","required":["antrag_id"],"title":"_MerklisteAddBody"},"_MerklisteBulkBody":{"properties":{"entries":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Entries"}},"type":"object","required":["entries"],"title":"_MerklisteBulkBody"}}},"tags":[{"name":"assessments","description":"Einzel-Bewertungen pro Drucksache: GWÖ-Score, Matrix-Zuordnung, Wahlprogramm-Treue, Verbesserungsvorschläge."},{"name":"auswertungen","description":"Aggregationen über Bundesland × Partei × Wahlperiode, Stimmverhalten, Heuchelei-Quote, CSV-Exporte."},{"name":"aktuelle-themen","description":"News×Anträge-Verschränkung und LLM-generierte Pressemitteilungs-Entwürfe."},{"name":"quellen","description":"Wahl- und Grundsatzprogramme als zitierfähige Quellen mit semantischer Volltextsuche."},{"name":"opendata","description":"Wöchentlicher Open-Data-Snapshot mit CC-BY-SA-4.0-Lizenz."},{"name":"meta","description":"Bundesländer-Registry, Auth-Status, Versions-Info, Abos/Alerts/Newsletter und Merkliste."},{"name":"frontend","description":"Server-gerenderte HTML-Seiten der Web-UI (Index, Antrags-Detail, Auswertungen, Quellen, statische Seiten)."},{"name":"admin","description":"Admin- und Cockpit-Endpoints: Datenstand, Freischaltungen, Schwellwerte, Bias-Audit, Queue-Verwaltung. Auth-geschützt."}]}