Zum Hauptinhalt springen

Dispatch API

Base URL: https://api.fwv-raura.ch

Die Dispatch API verwaltet E-Mail-Versand, Briefversand (Pingen), Newsletter, Kontaktformular, Mailcow-Integration, PDF-Vorlagen und Organisations-Einstellungen.

E-Mail-Vorlagen

Vorlagen abrufen

GET /templates
Authorization: Bearer <token>

Vorlage erstellen

POST /templates
Authorization: Bearer <token>
Content-Type: application/json

{
"name": "Einladung GV",
"subject": "Einladung zur Generalversammlung",
"html": "<p>Liebe Mitglieder...</p>",
"text": "Liebe Mitglieder..."
}

Vorlage bearbeiten

PUT /templates/:id
Authorization: Bearer <token>

Vorlage löschen

DELETE /templates/:id
Authorization: Bearer <token>

E-Mail-Versand

Einzelne E-Mail versenden

POST /email/send
Authorization: Bearer <token>
Content-Type: application/json

{
"to": "empfaenger@example.com",
"subject": "Betreff",
"html": "<p>Nachricht</p>",
"text": "Nachricht als Plain-Text"
}

Massen-E-Mail versenden

POST /email/bulk
Authorization: Bearer <token>
Content-Type: application/json

{
"member_ids": ["<uuid>", "<uuid>"],
"subject": "Rundschreiben",
"html": "<p>Liebe Mitglieder...</p>",
"template_id": 1
}

Intelligenter Versand

POST /dispatch/smart
Authorization: Bearer <token>
Content-Type: application/json

{
"member_ids": ["<uuid>"],
"subject": "Einladung",
"html": "<p>...</p>"
}

Versendet automatisch per E-Mail oder Brief, je nach Zustellungspräferenz des Mitglieds.

Kontaktformular

Kontaktformular absenden

POST /contact
Content-Type: application/json

{
"name": "Max Muster",
"email": "max@example.com",
"message": "Nachricht..."
}

Sendet eine Bestätigungs-E-Mail an den Absender.

Kontaktanfrage bestätigen

GET /contact/confirm/:token

Bestätigt die Kontaktanfrage per Token (Double-Opt-In).

Newsletter

Newsletter abonnieren

POST /newsletter/subscribe
Content-Type: application/json

{
"email": "max@example.com"
}

Abo bestätigen

GET /newsletter/confirm?token=xxx

Newsletter abbestellen

POST /newsletter/unsubscribe
Content-Type: application/json

{
"email": "max@example.com"
}

Mailcow-Integration

Verwaltung von E-Mail-Postfächern und Aliases über die Mailcow-API.

Postfächer abrufen

GET /mailcow/mailboxes
Authorization: Bearer <token>

Einzelnes Postfach

GET /mailcow/mailboxes/:email
Authorization: Bearer <token>

Postfach erstellen

POST /mailcow/mailboxes
Authorization: Bearer <token>
Content-Type: application/json

{
"local_part": "neues-postfach",
"name": "Neues Postfach",
"password": "xxx",
"quota": 1024
}

Postfach bearbeiten

PUT /mailcow/mailboxes/:email
Authorization: Bearer <token>

Postfach löschen

DELETE /mailcow/mailboxes/:email
Authorization: Bearer <token>

Aliases abrufen

GET /mailcow/aliases
Authorization: Bearer <token>

Alias erstellen

POST /mailcow/aliases
Authorization: Bearer <token>
Content-Type: application/json

{
"address": "alias@fwv-raura.ch",
"goto": "ziel@fwv-raura.ch"
}

Alias bearbeiten/löschen

PUT /mailcow/aliases/:id
DELETE /mailcow/aliases/:id
Authorization: Bearer <token>

Domain-Info

GET /mailcow/domain
Authorization: Bearer <token>

Speicherplatz-Status

GET /mailcow/quota
Authorization: Bearer <token>

Post-Versand (Pingen)

Konto-Informationen

GET /pingen/account?staging=false
Authorization: Bearer <token>

Response:

{
"name": "Feuerwehrverein Raura",
"balance": 5000,
"currency": "CHF",
"isStaging": false
}

Statistiken

GET /pingen/stats
Authorization: Bearer <token>

Response:

{
"total": 50,
"sent": 45,
"pending": 3,
"failed": 2,
"last_30_days": 15,
"last_7_days": 5
}

Alle Briefe abrufen

GET /pingen/letters?event_id=<uuid>&member_id=<uuid>&limit=50
Authorization: Bearer <token>

Brief-Status

GET /pingen/letters/:letterId/status?staging=false
Authorization: Bearer <token>

Response:

{
"letterId": "abc123",
"status": "sent",
"price": 125,
"pages": 2,
"sentAt": "2026-01-21T10:00:00Z"
}

Brief versenden

POST /pingen/send
Authorization: Bearer <token>
Content-Type: application/json

{
"member_id": "<uuid>",
"pdf_base64": "<base64-encoded-pdf>",
"staging": false
}

Einzelbrief manuell senden

POST /pingen/send-manual
Authorization: Bearer <token>
Content-Type: application/json

{
"member_id": "<uuid>",
"event_id": "<uuid>",
"subject": "Einladung GV",
"body": "Brieftext hier...",
"staging": false
}

Der Brief wird automatisch formatiert mit Absender, Adresse und Datum.

Arbeitsplan per Post senden

POST /pingen/send-arbeitsplan
Authorization: Bearer <token>
Content-Type: application/json

{
"event_id": "<uuid>",
"member_id": "<uuid>",
"pdf_base64": "<base64-encoded-pdf>",
"staging": false
}

Mitglieder mit Post-Zustellung

GET /pingen/post-members
Authorization: Bearer <token>

Response:

{
"count": 12,
"members": [
{
"id": "<uuid>",
"name": "Max Muster",
"address": "Musterstrasse 1, 4303 Kaiseraugst",
"strasse": "Musterstrasse 1",
"plz": "4303",
"ort": "Kaiseraugst"
}
]
}

Massen-PDF versenden

POST /pingen/send-bulk-pdf
Authorization: Bearer <token>
Content-Type: application/json

{
"pdf_base64": "<base64-encoded-pdf>",
"subject": "Einladung GV 2026",
"member_ids": ["<uuid>", "<uuid>"],
"staging": false
}

Wenn member_ids nicht angegeben wird, wird das PDF an alle Mitglieder mit zustellung_post = true gesendet.

Response:

{
"totalRecipients": 12,
"successCount": 11,
"failedCount": 1,
"success": [
{ "name": "Max Muster", "letterId": "abc123" }
],
"failed": [
{ "name": "Hans Mueller", "error": "Invalid address" }
],
"staging": false
}

Webhooks (Pingen)

Registrierte Webhooks abrufen

GET /pingen/webhooks?staging=false
Authorization: Bearer <token>

Webhook registrieren

POST /pingen/webhooks/register
Authorization: Bearer <token>
Content-Type: application/json

{
"webhook_url": "https://api.fwv-raura.ch/pingen/webhook",
"staging": false
}

Webhook löschen

DELETE /pingen/webhooks/:id?staging=false
Authorization: Bearer <token>

Webhook-Empfang (von Pingen)

POST /pingen/webhook
Content-Type: application/json

{
"data": { "id": "letterId", "attributes": { "status": "sent" } },
"meta": { "event": "letter.status_changed" }
}

Empfängt automatische Status-Updates von Pingen und aktualisiert den Status in der Datenbank.

PDF-Vorlagen

Verwaltung von PDF-Vorlagen für Briefe, Rechnungen und andere Dokumente. Die Vorlagen werden im PDF-Designer visuell bearbeitet.

Alle Vorlagen

GET /pdf-templates
Authorization: Bearer <token>

Vorlage abrufen

GET /pdf-templates/:id
Authorization: Bearer <token>

Vorlage erstellen

POST /pdf-templates
Authorization: Bearer <token>
Content-Type: application/json

{
"name": "Rechnung Standard",
"category": "rechnung",
"layout": { ... }
}

Vorlage bearbeiten

PUT /pdf-templates/:id
Authorization: Bearer <token>

Vorlage löschen

DELETE /pdf-templates/:id
Authorization: Bearer <token>

Aktives PDF-Layout

GET /pdf-templates/layout/active
Authorization: Bearer <token>

Gibt das aktuell aktive Layout (z.B. Briefkopf) zurück.

Rechnungen

Rechnung mit QR-Code generieren

POST /invoices/generate-qr
Authorization: Bearer <token>
Content-Type: application/json

{
"member_id": "<uuid>",
"amount": 50.00,
"description": "Jahresbeitrag 2026"
}

Generiert eine Swiss QR-Bill (Einzahlungsschein) als PDF.

Massen-Rechnungen generieren

POST /invoices/generate-bulk
Authorization: Bearer <token>
Content-Type: application/json

{
"member_ids": ["<uuid>", "<uuid>"],
"amount": 50.00,
"description": "Jahresbeitrag 2026"
}

Organisations-Einstellungen

Einstellungen abrufen

GET /organisation-settings
Authorization: Bearer <token>

Einstellung aktualisieren

PUT /organisation-settings/:key
Authorization: Bearer <token>
Content-Type: application/json

{
"value": "Neuer Wert"
}

Versand-Protokoll

Versand-Historie

GET /dispatch-log?type=email&status=sent&limit=100
Authorization: Bearer <token>

Query Parameter:

  • type - Filter nach Typ (email, pingen)
  • status - Filter nach Status (sent, pending, failed)
  • member_id - Filter nach Mitglied
  • event_id - Filter nach Event
  • limit - Anzahl Ergebnisse (Standard: 100)

Staging-Modus

Alle Pingen-Endpoints unterstützen einen staging Parameter:

  • staging=false (Standard): Briefe werden tatsächlich versendet und Kosten entstehen
  • staging=true: Briefe werden nur in der Testumgebung verarbeitet, keine echten Kosten

Im Vorstand-Dashboard kann der Staging-Modus über einen Toggle aktiviert werden. Die Umgebungsvariable PINGEN_STAGING setzt den Standard-Wert.