diff --git a/brevo-communi-pipeline.md b/brevo-communi-pipeline.md
new file mode 100644
index 0000000..1bcae48
--- /dev/null
+++ b/brevo-communi-pipeline.md
@@ -0,0 +1,43 @@
+# Brevo Newsletter → Communi App
+
+Automatische Übernahme der CK-Newsletter aus Brevo in den Communi-News-Feed.
+
+## Ablauf (Webhook-Pipeline)
+
+```mermaid
+flowchart TD
+ Brevo[Brevo Newsletter-Versand]
+ WH["brevo-webhook · VPS
(Container, Port 8055)"]
+ Seen{"camp_id schon
in seen_campaigns.json?"}
+ Fetch["Kampagne via
/emailCampaigns/{camp_id} holen"]
+ Conv["HTML → Markdown
Format: 📰 {Typ} · {Betreff}"]
+ Communi["Communi API · /recommendation
Gruppe 88531 · isOfficial"]
+
+ Brevo -->|"Webhook: Event 'Zugestellt'
(liefert camp_id)"| WH
+ WH --> Seen
+ Seen -->|ja| Skip["200 skipped
kein API-Call"]
+ Seen -->|nein| Fetch
+ Fetch --> Conv
+ Conv --> Communi
+ WH -.antwortet IMMER 200.-> Brevo
+```
+
+## Verteiler (Brevo-Listen-IDs)
+
+| Newsletter | Brevo-Liste | Communi-Gruppe |
+|---|---|---|
+| GemeindeNewsletter | 198 (Gemeinderundmail) | 88531 |
+| Regionalnewsletter | 89 (Regional-NL SCK) | 88531 |
+
+## Schutzmechanik
+
+```mermaid
+flowchart LR
+ A["'Zugestellt' feuert
pro Empfänger (~150x)"] --> B{Idempotenz
pro camp_id}
+ B -->|1. Mal| C[verarbeiten + posten]
+ B -->|"2..n"| D[verwerfen]
+ C --> E["Fehler? → ntfy-Alert
(nie HTTP 500)"]
+```
+
+> Hinweis: Idempotenz keyt auf `camp_id` (nicht Event-`id`) — sonst 1 Post pro Empfänger.
+> Webhook antwortet immer 200, damit Brevo keinen Retry-Sturm auslöst.