# Eventwerk Eventwerk ist die ruhige Plattform für Anmeldung und Verwaltung von Veranstaltungen. ## Einstieg - [Dokumentation](https://eventwerk.eu/docs): Alle Funktionen und die öffentliche API im Überblick. - [Kurze Fassung](https://eventwerk.eu/llms.txt): Einstieg und Funktionsübersicht. - [OpenAPI](https://api.eventwerk.eu/openapi.json): Maschinenlesbare Beschreibung der API als OpenAPI 3.1. ## Funktionen - [Events und Serien](https://eventwerk.eu/docs/event-anlegen): Events anlegen, veröffentlichen, bearbeiten und als Serie wiederholen. - [Tickets und Promo-Codes](https://eventwerk.eu/docs/tickets): Ticketarten, Kontingente, Preise und Promo-Codes. - [Anmeldung und Warteliste](https://eventwerk.eu/docs/anmeldung-und-warteliste): Anmeldung ohne Konto, Freigabe, Zugangscode und Warteliste. - [Gästeliste und Check-in](https://eventwerk.eu/docs/gaesteliste-und-check-in): Gästeliste, CSV-Export, Check-in per QR-Code und Berechtigungen. - [Gäste-Import und Empfehlungen](https://eventwerk.eu/docs/gaeste-import-und-empfehlungen): CSV-Import und Empfehlungscodes über die Sitzungs-API. - [Erinnerungen und Rückfrage](https://eventwerk.eu/docs/erinnerungen-und-rueckfrage): Automatische Erinnerungen und die Rückfrage, ob Gäste kommen. - [Nachrichten](https://eventwerk.eu/docs/nachrichten): E-Mails an Empfängergruppen entwerfen, planen und senden. - [Umfragen](https://eventwerk.eu/docs/umfragen): Umfragen anlegen, öffnen, beantworten und auswerten. - [Programm und Speaker](https://eventwerk.eu/docs/programm-und-speaker): Programmpunkte, Sprecher und persönliche Agenda. - [Entdecken und Kalender](https://eventwerk.eu/docs/entdecken-und-kalender): Öffentliche Events finden, filtern, als Kalender abonnieren und Veranstalterseiten lesen. - [Team und Rollen](https://eventwerk.eu/docs/team-und-rollen): Rollen, Sitze, Einladungen und Rechte. - [Benachrichtigungen](https://eventwerk.eu/docs/benachrichtigungen): Meldungen der Organisation und Webhooks. - [API-Referenz](https://eventwerk.eu/docs/api): Öffentliche API unter /api/v1, OpenAPI-Beschreibung, Webhooks und Betrieb. ## Seiten - [Erste Schritte](https://eventwerk.eu/docs/erste-schritte) - [Pläne und Grenzen](https://eventwerk.eu/docs/plaene-und-grenzen) - [Event anlegen](https://eventwerk.eu/docs/event-anlegen) - [Tickets](https://eventwerk.eu/docs/tickets) - [Anmeldung und Warteliste](https://eventwerk.eu/docs/anmeldung-und-warteliste) - [Gästeliste und Check-in](https://eventwerk.eu/docs/gaesteliste-und-check-in) - [Gäste-Import und Empfehlungen](https://eventwerk.eu/docs/gaeste-import-und-empfehlungen) - [Nachrichten](https://eventwerk.eu/docs/nachrichten) - [Erinnerungen und Rückfrage](https://eventwerk.eu/docs/erinnerungen-und-rueckfrage) - [Umfragen](https://eventwerk.eu/docs/umfragen) - [Programm und Speaker](https://eventwerk.eu/docs/programm-und-speaker) - [Entdecken und Kalender](https://eventwerk.eu/docs/entdecken-und-kalender) - [Team und Rollen](https://eventwerk.eu/docs/team-und-rollen) - [Benachrichtigungen](https://eventwerk.eu/docs/benachrichtigungen) - [API-Referenz](https://eventwerk.eu/docs/api) - [API-Grundlagen](https://eventwerk.eu/docs/api-grundlagen) - [API: Events und Anmeldungen](https://eventwerk.eu/docs/api-ereignisse) - [API: Webhooks](https://eventwerk.eu/docs/api-webhooks) - [API: Fehler](https://eventwerk.eu/docs/api-fehler) ## Hinweise für KI-Agenten - API-Basisadresse: `https://api.eventwerk.eu/api/v1` - OpenAPI 3.1: `https://api.eventwerk.eu/openapi.json` und `/api/v1/openapi.json`. Daraus lassen sich Clients und Typprüfungen generieren. - Anmeldung: `Authorization: Bearer ew_...` - Schlüssel: Einstellungen unter `/dashboard/einstellungen`, nur mit Eventwerk Plus und nur für Eigentümer. Der volle Schlüssel wird nur einmal angezeigt. Name und Zeitpunkt der letzten Nutzung werden geführt und ausgegeben. - Zeiten: Alle Zeitpunkte kommen in UTC mit Suffix `Z`. Die Zeitzone des Events steht getrennt in `timezone` als IANA-Name, Standard `Europe/Vienna`. Clients rechnen selbst um. - Paginierung: Die Event- und Anmeldelisten liefern `{items, has_more, next_cursor}` mit `limit` (Standard 50, höchstens 200), `cursor` und `updated_since`. - Grenzen: 200 Anfragen pro Minute je Schlüssel. Der Zähler liegt im Speicher je Instanz, ist hinter mehreren Instanzen ein Vielfaches und beginnt nach einem Deploy neu. Bei Überschreitung antwortet die API mit 429, `rate_limited` und `Retry-After`. - Gastgrenzen: Anmelde-Link 20 je Stunde je IP-Adresse, Anmeldung 60 je Stunde je IP-Adresse und 3 je Stunde je E-Mail-Adresse und Event. - Fehler: JSON mit `code` und `message`, optional mit `details`. # Erste Schritte Konto, erstes Event und der Einstieg in die Arbeit mit einem KI-Agenten. Eventwerk bündelt Anmeldung, Gästeliste, Nachrichten und den Überblick über Ihre Veranstaltungen. Die Oberfläche ist auf Deutsch, die Daten liegen in der Europäischen Union. ## Konto und Anmeldung Die Anmeldung funktioniert ohne Passwort. Sie geben auf `/login` Ihre E-Mail-Adresse ein und erhalten einen Anmelde-Link. Der Link ist 15 Minuten gültig und kann nur einmal verwendet werden. - Beim ersten bestätigten Link entsteht automatisch eine Organisation. - Sie werden Eigentümer dieser Organisation und können später weitere Personen einladen. - Die Sitzung bleibt über ein Refresh-Token erhalten. Das Access-Token gilt 15 Minuten. - Das Anfordern eines Anmelde-Links ist auf 20 Anfragen pro Stunde je IP-Adresse begrenzt. ## Event anlegen Ein Event lässt sich ohne Konto unter `/erstellen` anlegen. Alternativ legen Sie es nach der Anmeldung im Dashboard unter `/dashboard/events/new` an. - Ohne Anmeldung entsteht zunächst ein Entwurf. Erst nach der Bestätigung des Anmelde-Links wird das Event veröffentlicht. - Im Dashboard wählen Sie den Status selbst: Entwurf oder veröffentlicht. - Jedes neue Event erhält automatisch eine freie Ticketart mit dem Namen Standard. ## Das Dashboard - Übersicht: Kennzahlen, kommende Events und offene Aufgaben. - Events: anlegen, bearbeiten, duplizieren und löschen. - Gäste und Einlass: Anmeldungen lesen, filtern, exportieren und einchecken. - Nachrichten: E-Mails an Empfängergruppen entwerfen, planen und versenden. - Team: Rollen und Einladungen verwalten. - Einstellungen: Organisation, Plan und API-Schlüssel. - Benachrichtigungen: Meldungen der Organisation mit Ungelesen-Zähler. ## Mit einem KI-Agenten arbeiten Für Automatisierung gibt es die öffentliche API unter `/api/v1`. Sie gehört zu Eventwerk Plus und wird mit einem API-Schlüssel angesprochen. Ein Schlüssel handelt mit den Rechten des Eigentümers. 1. Stellen Sie den Plan in den Einstellungen auf Eventwerk Plus. Der Wechsel ist derzeit kostenlos. 2. Legen Sie unter Einstellungen, API-Schlüssel einen Schlüssel an. Der volle Schlüssel wird nur einmal angezeigt. 3. Prüfen Sie den Schlüssel mit `GET https://api.eventwerk.eu/api/v1/me`. Die Antwort enthält Organisation und Rolle. 4. Lesen Sie Events mit `GET https://api.eventwerk.eu/api/v1/events` und legen Sie Events mit `POST https://api.eventwerk.eu/api/v1/events` an. 5. Lesen Sie Anmeldungen mit `GET https://api.eventwerk.eu/api/v1/events/{eventID}/registrations`. ```bash curl -s https://api.eventwerk.eu/api/v1/me \ -H "Authorization: Bearer ew_..." ``` Anmeldungen lassen sich über die öffentliche API lesen. Das Anlegen und Stornieren läuft über die öffentliche Eventseite und das Ticket. > **Warnung:** Der Schlüssel handelt mit den Rechten des Eigentümers. Bewahren Sie ihn sicher auf und schreiben Sie ihn nicht in Protokolle, Repositorys oder öffentliche Konfigurationen. Es gelten 200 Anfragen pro Minute je Schlüssel, gezählt im Speicher jeder Instanz. Fehler kommen als JSON mit `code` und `message`. Die vollständige Referenz steht unter `/docs/api-grundlagen`, `/docs/api-ereignisse` und `/docs/api-fehler`. # Pläne und Grenzen Was der kostenlose Plan enthält, was Eventwerk Plus ergänzt und welche Grenzen gelten. Eventwerk ist in zwei Plänen verfügbar. Der kostenlose Plan ist der Standard. Eventwerk Plus ergänzt mehr Empfänger, mehr Verwalterplätze, API-Zugang und Webhooks. Eine Plattformgebühr gibt es nicht. ## Grenzen im Vergleich | Grenze | Eventwerk | Eventwerk Plus | | --- | --- | --- | | Verwalter (Eigentümer und Verwaltung) | 3 | 5 | | Empfänger pro Woche | 500 | 5.000 | | Aktive API-Schlüssel | keine | 25 | | Neue API-Schlüssel pro Tag | keine | 10 | | Webhooks | nicht enthalten | enthalten | | Rolle Einlass | unbegrenzt | unbegrenzt | | Events und Gäste | unbegrenzt | unbegrenzt | Das Empfängerkontingent zählt Empfänger, nicht Nachrichten. Gezählt werden alle Empfänger von Nachrichten, die in den letzten sieben Tagen versendet wurden. Die Grenze gilt für die gesamte Organisation. ## Eventwerk Plus - Bis zu 5.000 Empfänger pro Woche. - Bis zu 25 aktive API-Schlüssel, höchstens 10 neue pro Tag. - API-Zugang mit Schlüsseln und die öffentliche API unter `/api/v1`. - Webhooks für Benachrichtigungen. - Bis zu fünf Verwalterplätze. - Vorrang beim Support und früher Zugang zu neuen Funktionen. Eventwerk Plus kostet 49 Euro pro Monat. Die Bezahlung ist noch nicht angebunden. Der Plan lässt sich deshalb derzeit in den Einstellungen ohne Zahlung umschalten. > **Warnung:** Die Bezahlung ist noch nicht eingerichtet. Der Planwechsel erfolgt ohne Zahlung. Eine Abrechnung folgt, sobald die Bezahlung angebunden ist. ## Plan wechseln Nur Eigentümer können den Plan ändern. Der Wechsel ist jederzeit umkehrbar. Wechselt eine Organisation zurück auf Eventwerk, werden vorhandene API-Schlüssel nicht gelöscht, aber nicht mehr angenommen. ## Zusatzpakete Größere Empfängerkontingente sind als Zusatzpakete angekündigt. Die Staffeln gelten als Aufpreis pro Monat und sind noch nicht buchbar. | Empfänger pro Woche | Aufpreis pro Monat | | --- | --- | | 10.000 | 49 Euro | | 25.000 | 199 Euro | | 50.000 | 399 Euro | | 75.000 | 599 Euro | | 100.000 | 799 Euro | > **Hinweis:** Die Zusatzpakete sind nicht buchbar, solange die Bezahlung fehlt. ## Gemeinnützige Organisationen Gemeinnützige Organisationen erhalten 50 Prozent Rabatt auf Eventwerk Plus. Schreiben Sie formlos an info@aim-austria.org. Eine automatische Prüfung der Gemeinnützigkeit ist nicht gebaut. # Event anlegen Titel, Zeit, Ort, Sichtbarkeit und Serien richtig setzen. Ein Event braucht einen Titel, einen Beginn und eine Zeitzone. Alle weiteren Angaben sind optional, beeinflussen aber die öffentliche Darstellung und die Entdeckung. ## Wege zum Event - Ohne Anmeldung: `/erstellen` legt ein Event samt Organisation an und sendet einen Anmelde-Link. - Im Dashboard: `/dashboard/events/new` legt ein Event in der bestehenden Organisation an. - Über die API: `POST https://api.eventwerk.eu/api/v1/events` mit einem API-Schlüssel. ## Felder | Feld | Pflicht | Bedeutung | | --- | --- | --- | | title | ja | Titel, höchstens 200 Zeichen. | | start_at | ja | Beginn als RFC-3339-Zeitpunkt, zum Beispiel 2026-11-12T18:00:00+01:00. | | timezone | ja | IANA-Zeitzone, Standard Europe/Vienna. | | location_type | nein | offline, online oder hybrid. Standard offline. | | visibility | nein | public oder private. Standard private. | | status | nein | draft oder published. Standard draft. | | end_at | nein | Ende als RFC-3339-Zeitpunkt. Darf nicht vor dem Beginn liegen. | | description | nein | Freitext, Zeilenumbrüche bleiben erhalten. | | location_name | nein | Name des Ortes. | | location_address | nein | Adresse. Daraus werden Koordinaten für die Karte ermittelt. | | online_url | nein | Adresse für Online- oder Hybrid-Veranstaltungen. | | capacity | nein | Gesamtkapazität des Events, null bedeutet unbegrenzt. | | category | nein | konferenz, workshop, meetup, webinar, networking oder sonstiges. | | tags | nein | Höchstens 10 Schlagworte mit je höchstens 40 Zeichen. | ## Sichtbarkeit und Status - `draft`: Das Event ist nicht öffentlich erreichbar. - `published` und `private`: Das Event ist über den direkten Link `/e/` erreichbar, erscheint aber nicht in Entdeckung und Kalender. - `published` und `public`: Das Event erscheint zusätzlich in `/entdecken`, im Kalender und auf der Veranstalterseite. ## Veröffentlichen über Oberfläche und API - Über die Oberfläche ohne Konto: `/erstellen` legt einen Entwurf an. Veröffentlicht wird das Event erst nach der Bestätigung des Anmelde-Links. - Im Dashboard: Beim Anlegen und Bearbeiten wählen Sie den Status selbst. `published` ist sofort wirksam. - Über die API: `POST https://api.eventwerk.eu/api/v1/events` mit `status: published` veröffentlicht das Event sofort. Eine Bestätigung per E-Mail ist nicht nötig. > **Hinweis:** Der Unterschied ist beabsichtigt. Die Bestätigung per E-Mail schützt nur die Anlage ohne Konto, ein API-Schlüssel handelt im Namen der Organisation. ## Ohne Anmeldung anlegen 1. Formular unter `/erstellen` ausfüllen und eine E-Mail-Adresse angeben. 2. Eventwerk legt Nutzer, Organisation und Event als Entwurf an und sendet einen Anmelde-Link. 3. Nach der Bestätigung des Links wird das Event veröffentlicht. 4. Die Anlage ist auf fünf Versuche pro Stunde und Absender-IP begrenzt. ## Serien Ein Event kann zu einer Serie werden. Die Regel wiederholt den Ausgangstermin wöchentlich, alle zwei Wochen oder monatlich mit vier Wochen Abstand. - Die Serie endet nach einer Anzahl zwischen 2 und 52 Terminen oder an einem Enddatum. - Der Ausgangstermin zählt mit. - Weitere Termine entstehen als eigene Events mit eigenem Slug. - Die öffentliche Eventseite verweist auf die übrigen Termine der Serie. ## Bearbeiten und duplizieren Im Dashboard bearbeiten Sie alle Felder über die Eventseite. Ein Event lässt sich duplizieren; die Kopie erhält einen eigenen Slug. Beim Löschen werden auch die Anmeldungen des Events entfernt. Ein veröffentlichtes Event mit Anmeldungen lässt sich nicht löschen. Die API antwortet mit `event_has_registrations` und nennt in `details.count` die Zahl der Anmeldungen. > **Warnung:** Kostenpflichtige Tickets sind noch nicht buchbar. Ein Event mit einem Preis größer als null kann zwar angelegt werden, Anmeldungen werden aber mit `payment_not_available` abgelehnt. # Tickets Ticketarten, Kontingente, Preise und Promo-Codes. Jedes Event erhält beim Anlegen automatisch eine freie Ticketart mit dem Namen Standard. Sie hat kein Kontingent, ist aktiv und nicht verborgen. Weitere Ticketarten legen Sie im Dashboard unter dem Event an. ## Felder einer Ticketart | Feld | Bedeutung | | --- | --- | | name | Name der Ticketart, höchstens 200 Zeichen. | | description | Beschreibung für die öffentliche Seite. | | price_cents | Preis in Cent, nie negativ. 0 bedeutet kostenlos. | | currency | Dreistelliger Währungscode, Standard EUR. | | quantity | Kontingent. null bedeutet unbegrenzt. | | min_per_order | Mindestanzahl pro Bestellung, Standard 1. | | max_per_order | Höchstanzahl pro Bestellung, Standard 10. | | hidden | Verbirgt die Ticketart auf der öffentlichen Seite. | | is_donation | Kennzeichnet eine Spenden-Ticketart. | | active | Nur aktive Ticketarten sind öffentlich sichtbar. | | sort_order | Reihenfolge in der Anzeige. | ## Öffentliche Anzeige Öffentlich erscheinen nur aktive Ticketarten, die nicht verborgen sind. Das verbleibende Kontingent ergibt sich aus dem Kontingent minus der Anmeldungen mit Status pending oder confirmed. Zusätzlich kann die Kapazität des Events die Anmeldung begrenzen. ## Preise und Bezahlung Kostenlose Tickets führen zu einer bestätigten Anmeldung, solange ein Platz frei ist. Ist ein Preis größer als null und kein rabattierender Promo-Code gesetzt, antwortet die Anmeldung mit `payment_not_available`. Kartenzahlung und regionale Zahlungsmethoden sind geplant, aber noch nicht gebaut. > **Warnung:** Kostenpflichtige Tickets sind derzeit nicht buchbar. Bewerben Sie deshalb nur kostenlose Ticketarten. ## Promo-Codes Promo-Codes reduzieren den Preis einer Ticketart. Ein Code gilt immer für ein Event. Er wird bei der Anmeldung zusammen mit dem Ticket angegeben. | Feld | Bedeutung | | --- | --- | | code | Code, höchstens 64 Zeichen. Wird in Großbuchstaben gespeichert. | | discount_type | percent, fixed oder free. | | amount | Bei percent zwischen 1 und 100, bei fixed der Rabatt in Cent, bei free wird 0 gespeichert. | | max_redemptions | Maximale Einlösungen. null bedeutet unbegrenzt. | | expires_at | Ablaufzeitpunkt als RFC-3339-Zeitpunkt. | - Der berechnete Preis ist nie negativ. - Ein Prozentrabatt wird abgerundet. - Ein Code mit dem Typ free macht ein kostenpflichtiges Ticket kostenlos und damit buchbar. - Die maximale Einlöseanzahl darf nicht unter die bereits erreichten Einlösungen gesetzt werden. ## Löschen und pausieren Eine Ticketart mit Anmeldungen kann nicht gelöscht werden. Stattdessen setzen Sie sie auf inaktiv oder verborgen. Eine ungenutzte Ticketart lässt sich löschen. # Anmeldung und Warteliste Wie Gäste sich anmelden, wann Freigabe oder Zugangscode nötig sind und wie die Warteliste greift. Gäste brauchen kein Konto. Die Anmeldung läuft über die öffentliche Eventseite `/e/`. Dort wählen sie eine Ticketart, tragen Name und E-Mail-Adresse ein, beantworten die Fragen und bestätigen die Datenschutzhinweise. ## Pflichtangaben - Name und E-Mail-Adresse. - Eine aktive, nicht verborgene Ticketart. Ohne Auswahl wird die erste sichtbare Ticketart verwendet. - Die Zustimmung zu den Datenschutzhinweisen. - Antworten auf alle Pflichtfragen. - Bei Anmeldungen mit Zugangscode zusätzlich der Zugangscode. ## Bestätigung und Ticket Nach der Anmeldung sendet Eventwerk eine Bestätigungsmail. Der Link `/ticket/` enthält das Ticket mit QR-Code. Der Token ist ein Geheimnis und darf nicht weitergegeben werden. Bei Freigabe nötig entfällt das Ticket zunächst: Die Anmeldung wartet auf die Entscheidung des Veranstalters, erst danach entsteht ein Ticket. Erinnerungen vor dem Event enthalten eine Rückfrage, ob der Gast kommt. Die Antworten und ihre Folgen für die Warteliste stehen unter Erinnerungen und Rückfrage. - Gäste können ihr Ticket aufrufen, ihre Anmeldung stornieren oder ihre Daten endgültig löschen. - Stornieren ist nur solange möglich, wie die Anmeldung nicht eingecheckt ist. - Nach dem Löschen sind die Anmeldung, ihre Antworten und ihre Favoriten entfernt. ## Grenzen Öffentliche Anmeldeversuche sind je IP-Adresse begrenzt. Darüber antwortet der Dienst mit Status 429. - Anmeldung zu einem Event: 60 Anfragen pro Stunde je IP-Adresse. - Zusätzlich höchstens 3 Anmeldungen pro Stunde je E-Mail-Adresse und Event. ## Warteliste Ist das Kontingent einer Ticketart oder die Kapazität des Events erreicht, entsteht eine Anmeldung mit Status waitlisted. Ein fester Platz ist damit nicht reserviert. - Wird eine bestätigte Anmeldung storniert, rückt die älteste wartende Anmeldung derselben Ticketart nach. - Nachgerückte Anmeldungen werden bestätigt. Die erste nachgerückte Person erhält zusätzlich eine Nachricht mit ihrem Ticket. - Ein Platz wird nur frei, wenn eine bestätigte Anmeldung storniert wird. Die Stornierung einer wartenden Anmeldung löst kein Nachrücken aus. - Wartende Anmeldungen können nicht eingecheckt werden. ## Status | Status | Bedeutung | | --- | --- | | pending | Wartet auf Freigabe. Entsteht, wenn der Anmeldemodus Freigabe nötig ist. | | confirmed | Bestätigt, ein Platz ist reserviert. | | waitlisted | Warteliste, kein fester Platz. | | cancelled | Storniert. | | declined | Vom Veranstalter abgelehnt. | Pro Event lässt sich der Anmeldemodus wählen: Sofort bestätigen, Freigabe nötig oder Nur mit Zugangscode. Bei Freigabe nötig entscheidet das Team in der Gästeliste über jede offene Anmeldung. Bei Nur mit Zugangscode verlangt die öffentliche Anmeldung den gespeicherten Code; der Code selbst erscheint nicht in der öffentlichen Eventantwort. ## Eigene Fragen Pro Event lassen sich Fragen anlegen, wahlweise für alle Ticketarten oder für eine bestimmte Ticketart. Unterstützt werden Text, mehrzeiliger Text, Auswahl mit mindestens zwei Optionen, Ja/Nein, Telefonnummer und Webadresse. - Pflichtfragen müssen beantwortet werden, sonst antwortet die API mit `question_required`. - Antworten erscheinen in den Gastdetails und als zusätzliche Spalten im CSV-Export. - Die Reihenfolge steuert die Anzeige im Formular. ## Stornieren durch das Team Eigentümer und Verwaltung können Anmeldungen in der Gästeliste stornieren. Eine eingecheckte Anmeldung lässt sich nur mit einer ausdrücklichen Bestätigung stornieren. Beim Stornieren wird die Warteliste automatisch nachgezogen. > **Warnung:** Bezahlte Tickets sind noch nicht freigeschaltet. Eine Anmeldung mit einem Preis größer als null wird mit `payment_not_available` abgelehnt. # Gästeliste und Check-in Anmeldungen filtern, exportieren, importieren und am Einlass einchecken. Die Gästeliste zeigt alle Anmeldungen eines Events. Eigentümer, Verwaltung und die Rolle Einlass können sie lesen. Die Rolle Einlass kann Gäste lesen und einchecken, aber nicht verwalten. ## Gästeliste - Filter nach Status: Wartet auf Freigabe, Bestätigt, Warteliste, Storniert oder Abgelehnt. - Offene Anmeldungen lassen sich einzeln oder gesammelt annehmen und ablehnen. - Suche nach Name oder E-Mail-Adresse, ohne Beachtung der Großschreibung. - Anzeige von Ticketart, Preis, Anmeldezeitpunkt und Check-in-Zeitpunkt. - Die Reihenfolge ist nach Anmeldezeitpunkt aufsteigend. ## Gastdetails Die Detailseite zeigt E-Mail-Adresse, Ticketart, Preis, Promo-Code, Einwilligung und alle Antworten. Das Team kann die Anmeldung stornieren oder endgültig löschen. Das Löschen entfernt auch Antworten und Favoriten. ## CSV-Export Der Export enthält alle Anmeldungen des Events. Die Datei ist UTF-8 mit Byte Order Mark, trennt Spalten mit Semikolon und verwendet Zeiten in der Zeitzone des Events. - Spalten: name, email, status, ticket, preis_cent, waehrung, promo_code, angemeldet_am, eingecheckt_am, einwilligung_am, einwilligung_version. - Danach folgt je Frage eine eigene Spalte mit der Bezeichnung der Frage. - Feldinhalte mit Semikolon, Anführungszeichen oder Zeilenumbruch werden korrekt maskiert. Der umgekehrte Weg über eine CSV-Datei steht unter Gäste-Import und Empfehlungen. ## Check-in 1. Öffnen Sie das Event und wählen Sie Einlass. 2. Scannen Sie den QR-Code oder geben Sie den Code ein. 3. Eventwerk antwortet mit `checked_in` oder `already_checked_in`. - Einchecken ist für Anmeldungen mit Status pending oder confirmed möglich. - Warteliste, Storniert und Abgelehnt können nicht eingecheckt werden. - Der Check-in-Zeitpunkt wird nur einmal gesetzt. Ein zweiter Versuch meldet bereits eingecheckt. - Unbekannte Codes ergeben `registration_not_found`. > **Hinweis:** Der Einlass funktioniert auch auf dem Smartphone. Der QR-Code steckt im Ticket unter `/ticket/` und ist für den Gast bestimmt. ## Berechtigungen | Rolle | Gästeliste lesen | Check-in | Anmeldung löschen | | --- | --- | --- | --- | | Eigentümer | ja | ja | ja | | Verwaltung | ja | ja | ja | | Einlass | ja | ja | nein | # Gäste-Import und Empfehlungen Anmeldungen per CSV importieren und Empfehlungscodes für Gäste nutzen. Neben der Gästeliste und dem CSV-Export gibt es den CSV-Import und Empfehlungscodes. Beide laufen über die Sitzungs-API und sind nicht Teil der öffentlichen API unter `/api/v1`. ## CSV-Import Die Vorlage liegt unter `GET /api/events/{eventID}/registrations/import/template.csv`. Sie enthält ein Byte Order Mark und die Spalten name, email, ticket, promo_code und referral_code. - `POST /api/events/{eventID}/registrations/import/preview` prüft die Datei, ohne etwas zu speichern. - `POST /api/events/{eventID}/registrations/import` legt die gültigen Zeilen an. - Die Datei wird als Multipart-Feld file gesendet. - Erlaubt sind höchstens 2 MB und 5000 Datenzeilen. - Pflicht sind die Spalten name und email. Weitere Spalten sind optional. - Doppelte E-Mail-Adressen in der Datei und bereits vorhandene Anmeldungen werden übersprungen. - Unbekannte oder leere Ticketnamen verwenden die Ticketart Standard. Fehlt diese, schlägt die Zeile mit `ticket_not_found` fehl. - Ungültige Namen oder E-Mail-Adressen erscheinen als Fehler mit Zeilennummer. - Bei Events mit Zugangscode wird jede Zeile mit `access_code_required` abgelehnt. - Importierte Gäste erhalten keine E-Mail. Die Antwort des Imports enthält `created`, `skipped`, `failed`, `errors` und `note`. Die Vorschau liefert `columns`, die ersten 10 `rows`, `errors` und `total_rows`. > **Hinweis:** Die Vorschau speichert nichts. Eine eigene Oberfläche für den Import ist noch nicht gebaut; die Verwaltung läuft über die API. ## Empfehlungscodes Jede Anmeldung kann einen Empfehlungscode erhalten. Der Code gilt nur für das Event und ist acht Zeichen lang. Ein erneuter Aufruf liefert denselben Code. Die Antwort enthält `referral_code` und `share_url`. | Methode | Pfad | Zweck | | --- | --- | --- | | POST | /api/events/{eventID}/registrations/{registrationID}/referral | Empfehlungscode erzeugen oder lesen. | | GET | /api/events/{eventID}/referrals | Empfehlungen mit eingeladenen und angemeldeten Personen lesen. | Die geteilte Adresse lautet `/e/?ref=`. Bei der öffentlichen Anmeldung wird der Code als `referral_code` mitgeschickt. Ein unbekannter Code bricht die Anmeldung nicht ab; die Zuordnung fehlt dann. - Der Empfehlungscode steht in der Gästeliste bei der eingeladenen Anmeldung. - Die Auswertung enthält `referrer_name`, `referrer_email`, `code`, `invited_count` und `registered_count`. - `invited_count` zählt offene, bestätigte und wartende Anmeldungen, `registered_count` nur bestätigte. - Alle Endpunkte dieser Seite brauchen ein Sitzungs-Token und die Rolle Eigentümer oder Verwaltung. > **Hinweis:** Die öffentliche Anmeldung im Frontend sendet derzeit keinen Empfehlungscode mit. Die Zuordnung ist über die API möglich. Eine Oberfläche für Empfehlungen ist noch nicht gebaut. # Nachrichten E-Mails an Gäste entwerfen, planen, senden und Kontingente beachten. Nachrichten gehen per E-Mail an eine Gruppe von Anmeldungen eines Events. Sie können sofort versendet oder für einen Zeitpunkt in der Zukunft geplant werden. ## Empfängerkreise | Zielgruppe | Empfänger | | --- | --- | | all | Offene und bestätigte Anmeldungen. Die Warteliste ist nicht enthalten. | | confirmed | Nur bestätigte Anmeldungen. | | waitlisted | Nur Anmeldungen auf der Warteliste. | | checked_in | Nur bestätigte Anmeldungen, die bereits eingecheckt sind. | Stornierte und abgelehnte Anmeldungen erhalten nie eine Nachricht. Doppelte E-Mail-Adressen werden entfernt. ## Inhalt - Betreff mit höchstens 200 Zeichen. - Text mit höchstens 20.000 Zeichen. - Zielgruppe, standardmäßig all. - Optional ein Versandzeitpunkt als RFC-3339-Zeitpunkt in der Zukunft. ## Entwurf, Planung und Versand 1. Nachricht als Entwurf anlegen und prüfen. 2. Entweder sofort senden oder einen Versandzeitpunkt setzen. 3. Eine geplante Nachricht lässt sich abbrechen, solange sie noch nicht versendet wird. 4. Nach dem Versand sind Änderungen und Löschen nicht mehr möglich. Der Versand läuft im Hintergrund. Die API antwortet auf einen Sofortversand mit Status 202, `status: sending` und der Zahl der Empfänger. Der Status wechselt danach auf sent. Gesendete Nachrichten zeigen zusätzlich die Zahl der fehlgeschlagenen Zustellungen. > **Hinweis:** Eine Nachricht mit gesetztem Versandzeitpunkt bleibt technisch ein Entwurf. In der Oberfläche erscheint sie als Geplant. ## Versandkontingent Das Kontingent zählt Empfänger, nicht Nachrichten. Es umfasst alle Empfänger von Nachrichten der Organisation in den letzten sieben Tagen. Eventwerk erlaubt 500 Empfänger pro Woche, Eventwerk Plus 5.000. Ist das Kontingent erreicht, antwortet der Versand mit Status 403 und dem Code `weekly_send_limit`. Die Antwort enthält unter `details` die Werte `limit`, `used` und `plan`. ## Zustellung über Werkmail Eventwerk versendet alle E-Mails über die Premium-Infrastruktur von Werkmail (werkmail.eu). Mehr zur Infrastruktur steht unter [werkmail.eu](https://werkmail.eu). > **Warnung:** Automatische Erinnerungen vor dem Event sind gebaut und stehen unter Erinnerungen bereit. SMS, Push und WhatsApp sind als weitere Kanäle geplant, aber noch nicht gebaut. Nachrichten werden derzeit nur manuell oder zu einem festen Zeitpunkt versendet. # Erinnerungen und Rückfrage Automatische E-Mails vor dem Event und die Rückfrage, ob Gäste kommen. Erinnerungen verschicken vor einem Event automatisch E-Mails an bestätigte Gäste. Die Rückfrage fragt dieselben Gäste, ob sie kommen. Beides gehört zu einem Event. ## Erinnerungen Neue Events starten mit zwei Erinnerungen: 24 Stunden und 1 Stunde vor Beginn. Beide sind normale Einträge und lassen sich ändern oder deaktivieren. Die Oberfläche bietet für sie kein Löschen an. - Je Event sind höchstens 10 Erinnerungen erlaubt. Mehr ergeben Status 409 und `reminder_limit`. - Der Vorlauf liegt zwischen 5 und 100000 Minuten. - Der Betreff ist Pflicht und höchstens 200 Zeichen lang. - Der Text ist Pflicht und höchstens 20000 Zeichen lang. - Empfänger sind bestätigte Anmeldungen ohne Check-in. - Nur aktive Erinnerungen werden versendet. - Versendet wird nur, solange das Event veröffentlicht und noch nicht vorbei ist. - Der Versand zählt zum wöchentlichen Empfängerkontingent. - Jede Anmeldung erhält jede Erinnerung höchstens einmal. Im Betreff und im Text ersetzen Platzhalter die Angaben des Events und des Gasts: `{{titel}}`, `{{name}}`, `{{start}}`, `{{ort}}`, `{{rsvp}}`, `{{ticket}}` und `{{link}}`. ## Rückfrage Die Erinnerung enthält Links auf `/rsvp?token=` mit `answer=yes` oder `answer=no`, solange die Antwort noch offen ist. Der Token gehört zu einer Anmeldung und ist ein Geheimnis. Die Seite trägt `noindex` und wird nicht zwischengespeichert. - Die Antwort `yes` speichert die Zusage. Der Anmeldestatus bleibt unverändert. - Die Antwort `no` storniert eine offene, bestätigte oder wartende Anmeldung. Bei einer offenen oder bestätigten Anmeldung wird der Platz für die Warteliste frei. - Eine bereits stornierte oder abgelehnte Anmeldung bleibt unverändert. ## Endpunkte | Methode | Pfad | Zweck | | --- | --- | --- | | GET | /api/events/{eventID}/reminders | Erinnerungen eines Events lesen. | | POST | /api/events/{eventID}/reminders | Erinnerung anlegen. | | PATCH | /api/events/{eventID}/reminders/{reminderID} | Erinnerung ändern. | | DELETE | /api/events/{eventID}/reminders/{reminderID} | Erinnerung löschen. | | GET | /api/public/rsvp?token= | Rückfrage lesen. | | POST | /api/public/rsvp | Antwort speichern, Rumpf mit token und answer. | Die POST-Antwort auf eine Rückfrage enthält `answer`, `released` und `message`. > **Hinweis:** Die Erinnerungsendpunkte brauchen ein Sitzungs-Token und die Rolle Eigentümer oder Verwaltung. Die Rückfrage ist öffentlich und braucht nur den Token. > **Warnung:** Die Erinnerungen und die Rückfrage sind gebaut. SMS, Push und WhatsApp sind als weitere Kanäle geplant, aber noch nicht gebaut. # Umfragen Umfragen anlegen, öffnen, beantworten und auswerten. Umfragen gehören zu einem Event. Sie können im Entwurf vorbereitet, geöffnet und später geschlossen werden. Antworten sind anonym, solange kein Ticket-Token mitgeschickt wird. ## Status | Status | Bedeutung | | --- | --- | | draft | Entwurf. Fragen lassen sich bearbeiten. | | open | Offen. Die Umfrage ist öffentlich erreichbar und nimmt Antworten an. | | closed | Geschlossen. Es werden keine Antworten mehr angenommen. | Fragen lassen sich nur im Entwurf ändern. Eine offene Umfrage zeigt ihre Fragen unverändert an. Öffentlich erreichbar ist eine Umfrage nur, wenn sie offen ist und das Event veröffentlicht wurde. ## Fragetypen | Typ | Antwort | | --- | --- | | single | Genau eine Option. | | multi | Mehrere Optionen, ohne Doppelte. | | text | Freitext. | | scale | Ganze Zahl zwischen zwei Grenzen. Die Grenzen stehen als zwei Optionen mit numerischen Schlüsseln in der Frage. | ## Teilnahme Der öffentliche Link lautet `/e//umfrage/`. Auf der Ticketseite verlinkt Eventwerk offene Umfragen mit dem Ticket-Token als Parameter `t`. - Mit gültigem Ticket-Token wird die Antwort mit der Anmeldung verknüpft. - Pro Anmeldung ist eine Teilnahme möglich. Eine zweite Antwort ergibt `already_responded`. - Ohne Token oder mit unbekanntem Token wird die Antwort gespeichert, aber nicht mit einer Anmeldung verknüpft. - Pflichtfragen müssen beantwortet werden, sonst antwortet die API mit `question_required`. - Optionen müssen zur Frage gehören, sonst antwortet die API mit `invalid_option`. ## Auswertung Die Ergebnisse zeigen die Zahl der Teilnahmen und je Frage die Verteilung. Einfach- und Mehrfachauswahl liefern Anzahl und Prozent je Option. Textfragen liefern die Texte. Skalen liefern Minimum, Maximum, Durchschnitt und die Verteilung der Werte. > **Hinweis:** Eine Umfrage ist kein Pflichtformular. Gäste können sie auch ohne Anmeldung beantworten, wenn der Link geteilt wird. Mit Ticket-Token bleibt die Teilnahme dagegen eindeutig. # Programm und Speaker Programmpunkte, Sprecher, öffentliche Programmseite und persönliche Agenda. Das Programm besteht aus Programmpunkten und Sprechern. Beide gehören zu einem Event und erscheinen auf der öffentlichen Programmseite, sobald das Event veröffentlicht ist. ## Programmpunkte | Feld | Bedeutung | | --- | --- | | title | Titel, höchstens 200 Zeichen. | | description | Beschreibung, höchstens 20.000 Zeichen. | | start_at | Beginn als RFC-3339-Zeitpunkt. | | end_at | Optionales Ende. Muss nach dem Beginn liegen. | | location_name | Raum oder Ort, höchstens 200 Zeichen. | | track | Track oder Strang, höchstens 200 Zeichen. | | capacity | Optionale Kapazität, nicht negativ. | | sort_order | Reihenfolge bei gleichem Beginn. | Programmpunkte werden nach Beginn, dann nach Reihenfolge sortiert. Einem Programmpunkt lassen sich mehrere Sprecher zuordnen. ## Sprecher | Feld | Bedeutung | | --- | --- | | name | Name, höchstens 200 Zeichen. Pflichtfeld. | | title | Funktion, höchstens 200 Zeichen. | | company | Unternehmen, höchstens 200 Zeichen. | | bio | Biografie, höchstens 20.000 Zeichen. | | photo_url | Bildadresse, höchstens 2.000 Zeichen. | | website_url | Webadresse, höchstens 2.000 Zeichen. | | sort_order | Reihenfolge in der Sprecherliste. | Auf der öffentlichen Programmseite erscheinen nur Sprecher, die mindestens einem Programmpunkt zugeordnet sind. Die Zuordnung ersetzen Sie über die Sitzungsansicht im Dashboard. ## Öffentliche Programmseite Die Seite `/e//programm` zeigt alle Programmpunkte mit Zeit, Ort, Track und Sprechern. Bei mehrtägigen Events werden Tagesüberschriften ergänzt. Nicht veröffentlichte Events liefern `event_not_found`. ## Persönliche Agenda Angemeldete Gäste öffnen ihre Agenda über `/agenda/`. Dort können sie Programmpunkte als Favoriten markieren und die Auswahl getrennt von der vollständigen Liste sehen. - Favoriten werden zur Anmeldung gespeichert. - Stornierte und abgelehnte Anmeldungen können keine Favoriten ändern. - Ein unbekannter oder fehlender Programmpunkt ergibt `session_not_found`. > **Warnung:** Eine Zoom-Anbindung ist angekündigt, aber noch nicht gebaut. Programmpunkte haben derzeit kein eigenes Online-Ziel. # Entdecken und Kalender Öffentliche Events finden, filtern und als Kalender abonnieren. Die Entdeckung zeigt veröffentlichte Events mit Sichtbarkeit public. Private Events erscheinen dort nicht, bleiben aber über den direkten Link erreichbar. ## Entdecken Unter `/entdecken` suchen Gäste nach Titel und Beschreibung und filtern nach Kategorie, Format, Preis und Zeitraum. Die Ansicht wechselt zwischen Liste und Karte. | Filter | Werte | | --- | --- | | q | Suchbegriff, höchstens 200 Zeichen. | | category | konferenz, workshop, meetup, webinar, networking oder sonstiges. | | mode | offline, online oder hybrid. | | price | free oder paid. | | from, to | Zeitpunkt als RFC 3339. | | page, per_page | Seite ab 1, Seitengröße 1 bis 50, Standard 12. | | sort | date oder distance. distance benötigt Koordinaten. | Ein Event erscheint nur, wenn es veröffentlicht ist, die Sichtbarkeit public hat und der Beginn nicht mehr als einen Tag zurückliegt. Der angezeigte Preis stammt aus der günstigsten aktiven Ticketart. > **Hinweis:** Für die Kartenansicht ermittelt Eventwerk Koordinaten aus der Adresse. Ohne Adresse erscheint das Event nur in der Liste. ## Kalender Die Kalenderseite `/kalender` zeigt öffentliche Termine im Monatsüberblick. Der Monat lässt sich über `?monat=YYYY-MM` wählen. - Das Kalender-Abo für alle öffentlichen Events liegt unter `/api/public/discover/calendar.ics`. - Das Kalender-Abo einer Organisation liegt unter `/api/public/organizers//calendar.ics`. - Das Kalender-Abo der Entdeckung unterstützt dieselben Filter wie die Entdeckung. - Beide Abos brauchen keine Anmeldung. ## Veranstalterseite Jede Organisation hat eine öffentliche Seite unter `/veranstalter/`. Sie zeigt die kommenden öffentlichen Events und einen Kalender-Link. Den Slug ändern Sie in den Einstellungen; er muss eindeutig sein. > **Warnung:** Eine eigene Domain für Eventseiten ist angekündigt, aber noch nicht gebaut. Veranstalterseiten laufen derzeit unter der Eventwerk-Adresse. # Team und Rollen Rollen, Sitze, Einladungen und die Rechte im Dashboard. Eine Organisation hat Mitglieder mit einer von drei Rollen. Die Rolle bestimmt, welche Bereiche im Dashboard sichtbar sind und welche Aktionen die API erlaubt. ## Rollen | Rolle | Rechte | | --- | --- | | Eigentümer | Darf alles, einschließlich Rollen, Team, Einladungen, Plan, API-Schlüssel und Webhooks. | | Verwaltung | Darf alles außer Rollen ändern. Dazu gehören Events, Gäste, Nachrichten, Umfragen, Programm und Einladungen. | | Einlass | Darf Gäste lesen und einchecken. Keine Verwaltung, keine Gästeliste-Änderung. | Nur Eigentümer können die Rolle owner vergeben. Der letzte Eigentümer kann weder entfernt noch herabgestuft werden. ## Sitze Eigentümer und Verwaltung belegen einen Sitz. Die Rolle Einlass belegt keinen Sitz. Offene Einladungen zählen als belegt. | Plan | Sitze für Eigentümer und Verwaltung | | --- | --- | | Eventwerk | 3 | | Eventwerk Plus | 5 | Ist die Sitzgrenze erreicht, antwortet eine Einladung mit Status 403 und `plan_required`. ## Einladungen 1. Im Dashboard unter Team eine E-Mail-Adresse und eine Rolle wählen. 2. Eventwerk sendet einen Einladungslink an `/einladung/`. 3. Die eingeladene Person bestätigt die Einladung mit ihrem Namen. 4. Die Einladung ist 14 Tage gültig. - Eine bereits Mitglied gewordene Adresse ergibt `already_member`. - Eine offene Einladung für dieselbe Adresse ergibt `invitation_pending`. - Der Beitritt mit einem bereits bestehenden Konto ist noch nicht umgesetzt. - Offene Einladungen lassen sich zurückziehen. ## Organisation Name und Slug der Organisation ändern Sie in den Einstellungen. Der Slug bestimmt die öffentliche Adresse `/veranstalter/` und muss eindeutig sein. Ein belegter Slug ergibt `slug_taken`. # Benachrichtigungen Meldungen der Organisation, Ungelesen-Zähler und Webhooks. Benachrichtigungen gehören der Organisation, nicht einem einzelnen Mitglied. Alle Mitglieder sehen dieselben Meldungen. Die Glocke im Dashboard zeigt die Zahl der ungelesenen Einträge. ## Arten | Art | Auslöser | | --- | --- | | registration_created | Eine neue öffentliche Anmeldung. | | registration_cancelled | Eine Anmeldung wurde storniert. | | registration_promoted | Eine Anmeldung ist von der Warteliste nachgerückt. | | registration_checked_in | Eine Anmeldung wurde eingecheckt. | | survey_response | Eine neue Antwort auf eine Umfrage. | | message_sent | Eine Nachricht wurde versandt. | ## Lesen und als gelesen markieren Die Benachrichtigungsseite lädt die neuesten Meldungen. Standard sind 20 Einträge, höchstens 100. Ein Filter `unread_only` zeigt nur ungelesene Meldungen. - `GET /api/notifications?limit=20&unread_only=false` liefert Meldungen und die Zahl der ungelesenen Einträge. - `POST /api/notifications/read` mit einer Liste von IDs markiert genau diese Meldungen. - Ohne IDs markiert derselbe Aufruf alle ungelesenen Meldungen der Organisation. - Die Antwort enthält die verbleibende Zahl der ungelesenen Meldungen. > **Hinweis:** Diese Endpunkte brauchen ein Sitzungs-Token, keinen API-Schlüssel. Sie stehen nicht unter `/api/v1`. ## Webhooks Jede neue Benachrichtigung kann zusätzlich an aktive Webhooks der Organisation gesendet werden. Webhooks gehören zu Eventwerk Plus. Die Zustellung läuft im Hintergrund und hat keine dauerhafte Warteschlange. > **Warnung:** SMS, Push und WhatsApp sind als Benachrichtigungskanäle geplant, aber noch nicht gebaut. Die Benachrichtigungen sind derzeit nur in der Oberfläche und über die API abrufbar. # API-Referenz Alle Endpunkte der öffentlichen API, die OpenAPI-Beschreibung und die Webhook-Verwaltung im Überblick. Die öffentliche API liegt unter `/api/v1` und wird mit einem API-Schlüssel angesprochen. Sie gehört zu Eventwerk Plus. Die Webhook-Verwaltung liegt unter `/api/webhooks` und braucht ein Sitzungs-Token. ## OpenAPI Die vollständige Beschreibung der API liegt als OpenAPI 3.1 unter [https://api.eventwerk.eu/openapi.json](https://api.eventwerk.eu/openapi.json) und unter `/api/v1/openapi.json` bereit. Die Datei beschreibt Endpunkte, Felder, Statuscodes und Fehlercodes. - Aus der Beschreibung lassen sich Clients, Typprüfungen und Sammlungen für Testwerkzeuge generieren. - Beide Adressen liefern dieselbe Fassung der Beschreibung. ```bash curl -s https://api.eventwerk.eu/openapi.json ``` ## Einstieg - Grundlagen, Schlüssel und Grenzen: `/docs/api-grundlagen`. - Events, Tickets, Anmeldungen, CSV und Kennzahlen: `/docs/api-ereignisse`. - Webhooks, Signatur und Ereignisse: `/docs/api-webhooks`. - Fehlerform und Codes: `/docs/api-fehler`. ## Endpunkte mit API-Schlüssel | Methode | Pfad | Zweck | | --- | --- | --- | | GET | /me | Organisation und Rolle des Schlüssels. | | GET | /events | Alle Events der Organisation, seitenweise und nach Beginn sortiert. | | POST | /events | Event anlegen, optional mit `Idempotency-Key`. | | GET | /events/{eventID} | Ein Event lesen. | | PATCH | /events/{eventID} | Ein Event teilweise ändern. | | DELETE | /events/{eventID} | Ein Event löschen. Ein veröffentlichtes Event mit Anmeldungen wird abgelehnt. | | GET | /events/{eventID}/tickets | Ticketarten eines Events lesen. | | GET | /events/{eventID}/registrations | Anmeldungen seitenweise lesen, mit Statusfilter und Suche. | | GET | /events/{eventID}/registrations.csv | Anmeldungen als CSV exportieren. | | GET | /events/{eventID}/stats | Kennzahlen eines Events lesen. | > **Hinweis:** Alle Pfade dieser Tabelle sind relativ zur Basisadresse https://api.eventwerk.eu/api/v1. ## Webhooks mit Sitzungs-Token | Methode | Pfad | Zweck | | --- | --- | --- | | GET | /api/webhooks | Aktive Webhooks lesen. | | POST | /api/webhooks | Webhook mit URL anlegen. | | DELETE | /api/webhooks/{webhookID} | Webhook widerrufen. | Diese Endpunkte erwarten `Authorization: Bearer ` aus der E-Mail-Anmeldung. Sie sind nur für Eigentümer im Plus-Plan freigegeben. ## Betrieb Diese Pfade liegen direkt an der Wurzel der Serveradresse, nicht unter `/api/v1`. | Methode | Pfad | Zweck | | --- | --- | --- | | GET | /healthz | Prozess läuft. Antwort: status ok. | | GET | /readyz | Datenbank ist erreichbar. Sonst 503 mit database_unavailable. | ## Nicht Teil der öffentlichen API - Ticketarten anlegen, ändern oder löschen. - Anmeldungen anlegen oder stornieren. - Nachrichten, Umfragen und Programm lesen oder schreiben. - Team und Einladungen verwalten. - Webhooks mit einem API-Schlüssel verwalten. - Serien anlegen und Events duplizieren. - Erinnerungen, CSV-Import und Empfehlungscodes verwalten. > **Warnung:** Zapier-Workflows und eine eigene Domain für Eventseiten sind angekündigt, aber noch nicht gebaut. Erinnerungen, CSV-Import und Empfehlungscodes laufen über die Sitzungs-API. # API-Grundlagen Basisadresse, Anmeldung mit API-Schlüssel, Grenzen und Antwortformat. Die öffentliche API ist eine JSON-API über HTTP. Sie ist versioniert und liegt unter `/api/v1`. Alle Endpunkte der öffentlichen API erfordern Eventwerk Plus. ## Basisadresse Die Basisadresse lautet `https://api.eventwerk.eu/api/v1`. Ein Aufruf von `/me` wird damit zu `GET https://api.eventwerk.eu/api/v1/me`. ## Anmeldung Jede Anfrage trägt einen API-Schlüssel im Header `Authorization`. Das Format ist `Bearer ew_...`. Ein Schlüssel beginnt mit `ew_`, gefolgt von 40 Zeichen. Er handelt immer als Eigentümer der Organisation. ```bash curl -s https://api.eventwerk.eu/api/v1/me \ -H "Authorization: Bearer ew_..." ``` ## Schlüssel anlegen und zurückziehen 1. Plan in den Einstellungen auf Eventwerk Plus stellen. 2. Als Eigentümer unter Einstellungen, API-Schlüssel einen Namen angeben und den Schlüssel anlegen. 3. Den vollen Schlüssel jetzt kopieren. Er wird nur einmal angezeigt. 4. Nicht benötigte Schlüssel in den Einstellungen zurückziehen. - Höchstens 25 aktive Schlüssel pro Organisation. - Höchstens 10 neue Schlüssel in einem rollierenden Zeitfenster von 24 Stunden. - Ein zurückgezogener Schlüssel wird sofort abgelehnt und ergibt `invalid_api_key`. - Der angezeigte Prefix besteht aus den ersten acht Zeichen. - Zu jedem Schlüssel werden der Name und der Zeitpunkt der letzten Nutzung geführt. Die Einstellungen zeigen beides an. Der Zeitpunkt steht als `last_used_at` in der Antwort der Schlüssel-Endpunkte. Vor der ersten Nutzung ist er null. > **Warnung:** Der volle Schlüssel ist ein Geheimnis. Speichern Sie ihn nur an einem sicheren Ort und niemals in einem Repository oder in einer öffentlichen Variable. ## Antwortformat - JSON mit UTF-8 und `Content-Type: application/json; charset=utf-8`. - Zeitpunkte kommen als RFC-3339-Strings in UTC, immer mit dem Suffix `Z`. - Die Zeitzone des Events steht getrennt im Feld `timezone`. Sie ist ein IANA-Name, Standard `Europe/Vienna`. - Clients müssen Zeitpunkte selbst in die gewünschte Zeitzone umrechnen. Die API liefert keine lokale Zeit. - Geldbeträge als ganze Zahl in Cent. - Unbekannte Felder im Rumpf werden abgelehnt. Die Anfrage ergibt `unknown_field`, `details.field` nennt den Feldnamen. - Der Rumpf darf höchstens 1 MiB groß sein. Sonst ergibt sich `request_too_large`. ## Paginierung Die Listen unter `/events` und `/events/{eventID}/registrations` liefern seitenweise Ergebnisse. Die Antwort hat immer dieselbe Form. ```json { "items": [], "has_more": false, "next_cursor": null } ``` - `limit` legt die Seitengröße fest. Erlaubt sind 1 bis 200, Standard 50. Ein anderer Wert ergibt `invalid_limit`. - `cursor` setzt die Liste an der Stelle fort, die `next_cursor` nennt. Ohne Cursor beginnt die Liste vorn. - `updated_since` liefert nur Datensätze, die nach dem angegebenen RFC-3339-Zeitpunkt geändert wurden. - `has_more` sagt, ob weitere Datensätze folgen. Ist er false, ist `next_cursor` null. - Der Cursor ist undurchsichtig. Übernehmen Sie ihn unverändert und verwenden Sie ihn nur für dieselbe Liste. ## Idempotenz `POST /events` akzeptiert den optionalen Header `Idempotency-Key`. Damit lässt sich eine Anfrage wiederholen, etwa nach einer Zeitüberschreitung, ohne ein zweites Event anzulegen. - Gleicher Schlüssel und gleicher Rumpf: Die API liefert dieselbe Antwort erneut. - Gleicher Schlüssel und anderer Rumpf: Die API antwortet mit Status 409 und dem Code `idempotency_conflict`. - Ohne Header legt jeder Aufruf ein neues Event an. - Verwenden Sie je beabsichtigter Anlage einen eigenen, zufälligen Schlüssel. ## Grenzen Es gelten 200 Anfragen pro Minute je API-Schlüssel. Der Zähler liegt im Arbeitsspeicher jeder Instanz und wird nicht über Instanzen geteilt. - Hinter mehreren Instanzen liegt das wirksame Limit deshalb faktisch bei einem Vielfachen von 200 pro Minute. - Nach einem Neustart oder Deploy beginnt die Zählung neu. - Ist das Limit erreicht, antwortet die API mit Status 429, dem Code `rate_limited` und dem Header `Retry-After` in Sekunden. ### Grenzen der Gastrouten Öffentliche Routen ohne API-Schlüssel haben eigene Grenzen je IP-Adresse. - Anmelde-Link (Magic-Link) anfordern: 20 Anfragen pro Stunde je IP-Adresse. - Anmeldung zu einem Event: 60 Anfragen pro Stunde je IP-Adresse. - Zusätzlich höchstens 3 Anmeldungen pro Stunde je E-Mail-Adresse und Event. ## Fehler Fehler haben immer die Form `{ "code": "...", "message": "..." }`. Das Feld `details` kann zusätzliche Angaben enthalten, etwa `field` bei `unknown_field`, `count` bei `event_has_registrations` oder `limit`, `used` und `plan` beim Versandkontingent. `code` ist stabil, `message` ist für Menschen gedacht. > **Warnung:** Werten Sie nicht den deutschen Text von `message` aus. Prüfen Sie stattdessen `code` und den HTTP-Status. ## Nicht verfügbar - Schreiben von Ticketarten, Nachrichten, Umfragen, Programm oder Team über einen API-Schlüssel. - CSV-Import, Empfehlungscodes und Erinnerungen über einen API-Schlüssel. - Zapier-Workflows und Zoom-Anbindung. # API: Events und Anmeldungen Events lesen, anlegen und ändern, Tickets und Anmeldungen lesen, CSV und Kennzahlen. Die Endpunkte unter `/events` bilden die Verwaltung für einen API-Schlüssel ab. Ein Schlüssel sieht und ändert nur Events seiner eigenen Organisation. Alle Zeitpunkte kommen in UTC mit Suffix `Z`; die Zeitzone des Events steht getrennt in `timezone`. ## Event-Objekt | Feld | Typ | Bedeutung | | --- | --- | --- | | id | string | Kennung des Events. | | org_id | string | Kennung der Organisation. | | slug | string | Teil der öffentlichen Adresse `/e/`. | | title | string | Titel. | | description | string | Beschreibung. | | cover_url | string | Bildadresse. | | start_at | string | Beginn als RFC-3339-Zeitpunkt in UTC mit Suffix Z. | | end_at | string oder null | Ende als RFC-3339-Zeitpunkt in UTC mit Suffix Z. | | timezone | string | IANA-Zeitzone des Events, Standard Europe/Vienna. Gilt für die Darstellung, nicht für die übertragenen Zeitpunkte. | | location_type | string | offline, online oder hybrid. | | location_name | string | Name des Ortes. | | location_address | string | Adresse. | | online_url | string | Adresse für Online- oder Hybrid-Veranstaltungen. | | visibility | string | public oder private. | | status | string | draft oder published. | | capacity | number oder null | Gesamtkapazität. | | category | string | Kategorie oder leer. | | tags | string[] | Schlagworte. | | latitude | number oder null | Breitengrad. | | longitude | number oder null | Längengrad. | | series_id | string oder null | Kennung der Serie. | | series_index | number | Position in der Serie. | | created_at | string | Anlagezeitpunkt in UTC mit Suffix Z. | | updated_at | string | Änderungszeitpunkt in UTC mit Suffix Z. | Die Eventliste ergänzt `registration_count` mit der Zahl aller Anmeldungen. Ein einzelnes Event enthält dieses Feld nicht. ## Events lesen ```bash curl -s https://api.eventwerk.eu/api/v1/events \ -H "Authorization: Bearer ew_..." curl -s https://api.eventwerk.eu/api/v1/events/ \ -H "Authorization: Bearer ew_..." ``` Die Liste antwortet mit `{ "items": [...], "has_more": false, "next_cursor": null }` und ist nach Beginn aufsteigend sortiert. Ein einzelnes Event antwortet direkt mit dem Event-Objekt. | Parameter | Bedeutung | | --- | --- | | limit | Optional. Seitengröße zwischen 1 und 200. Standard 50. | | cursor | Optional. Cursor aus `next_cursor` der vorherigen Antwort. | | updated_since | Optional. RFC-3339-Zeitpunkt. Liefert nur Events, die danach geändert wurden. | `has_more` sagt, ob weitere Datensätze folgen. `next_cursor` enthält den Cursor der nächsten Seite oder null. Der Cursor ist undurchsichtig und gehört immer zu derselben Liste. ## Event anlegen Pflicht sind `title`, `start_at` und `timezone`. Ohne `location_type` gilt offline, ohne `visibility` private, ohne `status` draft. Die Zeit muss als RFC-3339-String mit Zeitzone vorliegen. `status: published` veröffentlicht das Event sofort, anders als die Anlage ohne Konto, die auf die Bestätigung der E-Mail-Adresse wartet. ```json { "title": "Herbstkonferenz", "description": "Ein Tag für Austausch und Workshops.", "start_at": "2026-11-12T09:00:00+01:00", "end_at": "2026-11-12T17:00:00+01:00", "timezone": "Europe/Vienna", "location_type": "offline", "location_name": "Kulturhaus", "location_address": "Hauptplatz 1, 8010 Graz", "visibility": "public", "status": "published", "category": "konferenz", "tags": ["austausch", "workshops"] } ``` ```bash curl -s -X POST https://api.eventwerk.eu/api/v1/events \ -H "Authorization: Bearer ew_..." \ -H "Content-Type: application/json" \ -H "Idempotency-Key: 7f2c1a9e-4b3d-4c8a-9f10-2e6d5b7a1c30" \ -d @event.json ``` Die Antwort ist das angelegte Event mit Status 201. Der Header `Location` nennt den Pfad zum Event. Jedes Event erhält automatisch eine freie Ticketart Standard, wenn keine Ticketart angegeben wurde. Mit dem optionalen Header `Idempotency-Key` lässt sich die Anlage wiederholen. Gleicher Schlüssel und gleicher Rumpf liefern dieselbe Antwort erneut. Ein anderer Rumpf mit demselben Schlüssel ergibt Status 409 und den Code `idempotency_conflict`. Ohne Header legt jeder Aufruf ein neues Event an. - Der Titel darf höchstens 200 Zeichen lang sein. - Das Ende darf nicht vor dem Beginn liegen. - Die Zeitzone muss eine gültige IANA-Zeitzone sein. - Die Kapazität darf nicht negativ sein. - Es sind höchstens 10 Schlagworte mit je höchstens 40 Zeichen erlaubt. - Ein unbekanntes Feld im Rumpf ergibt `unknown_field`; `details.field` nennt den Namen. ## Event ändern `PATCH /events/{eventID}` ändert nur die übergebenen Felder. Mindestens ein Feld muss gesetzt sein, sonst antwortet die API mit `no_changes`. Ein `end_at` von null entfernt das Ende. ```bash curl -s -X PATCH https://api.eventwerk.eu/api/v1/events/ \ -H "Authorization: Bearer ew_..." \ -H "Content-Type: application/json" \ -d '{"title":"Herbstkonferenz 2026"}' ``` ## Event löschen `DELETE /events/{eventID}` löscht das Event und alle zugehörigen Anmeldungen. Die Antwort hat Status 200 und enthält eine Meldung. Ein unbekanntes Event ergibt `event_not_found`. Ein veröffentlichtes Event mit Anmeldungen lässt sich nicht löschen; die API antwortet mit Status 409, dem Code `event_has_registrations` und `details.count`. ## Ticketarten lesen `GET /events/{eventID}/tickets` liefert `{ "tickets": [...] }`. Jede Ticketart enthält `id`, `event_id`, `name`, `description`, `price_cents`, `currency`, `quantity`, `min_per_order`, `max_per_order`, `hidden`, `is_donation`, `active`, `sort_order` und `created_at`. > **Hinweis:** Die öffentliche API kann Ticketarten nur lesen. Anlegen und Ändern erfolgt im Dashboard. ## Anmeldungen lesen `GET /events/{eventID}/registrations` liefert `{ "items": [...], "has_more": false, "next_cursor": null }`. Die Liste ist nach Anmeldung aufsteigend sortiert. | Parameter | Bedeutung | | --- | --- | | status | Optional. pending, confirmed, waitlisted, cancelled oder declined. | | query | Optional. Sucht ohne Beachtung der Großschreibung in Name und E-Mail-Adresse. | | limit | Optional. Seitengröße zwischen 1 und 200. Standard 50. | | cursor | Optional. Cursor aus `next_cursor` der vorherigen Antwort. | | updated_since | Optional. RFC-3339-Zeitpunkt. Liefert nur Anmeldungen, die danach geändert wurden. | `has_more` sagt, ob weitere Datensätze folgen. `next_cursor` enthält den Cursor der nächsten Seite oder null. Der Cursor ist undurchsichtig und gehört immer zu derselben Liste. Jede Anmeldung enthält `id`, `name`, `email`, `status`, `ticket_type_id`, `price_paid_cents`, `checked_in_at` und `created_at`. Zeitpunkte kommen in UTC mit Suffix `Z`. Der QR-Token ist nicht in der Liste enthalten. ```bash curl -s "https://api.eventwerk.eu/api/v1/events//registrations?status=confirmed&query=Anna" \ -H "Authorization: Bearer ew_..." ``` ## CSV-Export `GET /events/{eventID}/registrations.csv` liefert eine CSV-Datei mit Semikolon als Trennzeichen und einem Byte Order Mark am Anfang. Die Spalten entsprechen dem Export im Dashboard, einschließlich der Antworten auf eigene Fragen. ## Kennzahlen `GET /events/{eventID}/stats?days=30` liefert Kennzahlen. `days` liegt zwischen 1 und 365, Standard 30. Aufrufe gelten für den Zeitraum, die Anmeldezahlen für das gesamte Event. | Feld | Bedeutung | | --- | --- | | views_total | Aufrufe der öffentlichen Seite im Zeitraum. | | views_by_day | Aufrufe je Tag. | | registrations | Alle Anmeldungen. | | confirmed | Bestätigte Anmeldungen. | | pending | Anmeldungen, die auf Freigabe warten. | | waitlisted | Anmeldungen auf der Warteliste. | | cancelled | Stornierte Anmeldungen. | | checked_in | Eingecheckte Anmeldungen. | | conversion_rate | Anmeldungen geteilt durch Aufrufe, zwischen 0 und 1. | | checkin_rate | Eingecheckte geteilt durch bestätigte Anmeldungen, zwischen 0 und 1. | > **Hinweis:** Serien, Duplizieren, Nachrichten, Umfragen, Programm, Erinnerungen, CSV-Import und Empfehlungscodes sind nicht Teil der öffentlichen API. # API: Webhooks Webhooks anlegen, Ereignisse empfangen und Signaturen prüfen. Ein Webhook ist eine URL, an die Eventwerk bei einer neuen Benachrichtigung einen HTTP-POST sendet. Webhooks gehören zu Eventwerk Plus. Sie werden pro Organisation verwaltet. ## Webhooks verwalten > **Warnung:** Die Webhook-Endpunkte erwarten ein Sitzungs-Token aus der E-Mail-Anmeldung, keinen API-Schlüssel. Sie sind nur für Eigentümer im Plus-Plan freigegeben. | Methode | Pfad | Antwort | | --- | --- | --- | | GET | /api/webhooks | Liste der aktiven Webhooks. | | POST | /api/webhooks | 201 mit dem angelegten Webhook. | | DELETE | /api/webhooks/{webhookID} | 204 ohne Rumpf. | Ein Webhook enthält `id`, `url`, `secret`, `created_at` und `revoked_at`. Die Liste zeigt nur nicht widerrufene Webhooks. Das Geheimnis steht in der Antwort und dient der Signaturprüfung. ```bash curl -s -X POST /api/webhooks \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{"url":"https://example.test/eventwerk-hook"}' ``` - Die URL muss mit http oder https beginnen und höchstens 2.048 Zeichen lang sein. - Lokale Adressen sind erlaubt, damit sich die Zustellung testen lässt. - Eine ungültige URL ergibt `invalid_webhook_url`. - Ein unbekannter oder fremder Webhook ergibt `webhook_not_found`. - Ohne Plus antwortet die Verwaltung mit `plan_required`. ## Zustellung Eventwerk sendet einen POST mit JSON-Rumpf. Der Rumpf enthält die Art, den Titel, den Text, den internen Link und den Zeitpunkt der Benachrichtigung. ```json { "kind": "registration_created", "title": "Neue Anmeldung", "body": "Anna hat sich für Herbstkonferenz angemeldet.", "link_path": "/dashboard/events//registrations", "created_at": "2026-10-25T12:00:00Z" } ``` | Header | Wert | | --- | --- | | Content-Type | application/json | | User-Agent | Eventwerk-Webhook/1.0 | | X-Eventwerk-Signature | `sha256=` | - Ein Zustellversuch hat ein Zeitlimit von 5 Sekunden. - Jeder Webhook erhält höchstens zwei Versuche im Abstand von 500 Millisekunden. - Eine Antwort mit Status 2xx gilt als erfolgreich. - Es gibt keine dauerhafte Warteschlange. Nach einem Neustart gehen nicht zugestellte Aufrufe verloren. - Fehler werden nur protokolliert. Der auslösende Vorgang, etwa eine Anmeldung, bleibt gültig. - Die Reihenfolge der Zustellungen ist nicht garantiert. ## Signatur prüfen Berechnen Sie die HMAC-SHA256-Signatur über den rohen Rumpf, nicht über das neu serialisierte JSON. Vergleichen Sie die Signatur in konstanter Zeit mit dem Header. ```javascript import crypto from "node:crypto"; const expected = "sha256=" + crypto.createHmac("sha256", secret).update(rawBody).digest("hex"); const received = request.headers["x-eventwerk-signature"]; if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(received))) { return response.status(401).end(); } ``` ## Ereignisse | kind | Auslöser | | --- | --- | | registration_created | Neue öffentliche Anmeldung. | | registration_cancelled | Anmeldung storniert. | | registration_promoted | Anmeldung von der Warteliste nachgerückt. | | registration_checked_in | Anmeldung eingecheckt. | | survey_response | Neue Umfrageantwort. | | message_sent | Nachricht versandt. | > **Warnung:** Eine eigene Oberfläche für Webhooks gibt es noch nicht. Die Verwaltung läuft über die API. Zustellungen werden nicht gespeichert und nicht nachträglich nachgeholt. # API: Fehler Fehlerform, Statuscodes und stabile Codes der öffentlichen API. Jeder Fehler kommt als JSON. Das Feld `code` ist stabil und für Programme gedacht. Das Feld `message` ist deutsch und für Menschen formuliert. `details` ist optional. ```json { "code": "invalid_title", "message": "Ein Titel ist erforderlich." } ``` ## Statuscodes | Status | Bedeutung | | --- | --- | | 400 | Die Anfrage ist ungültig. Meist ein Feld oder ein JSON-Problem. | | 401 | Kein gültiger API-Schlüssel. | | 403 | Der Plan erlaubt die Aktion nicht oder die Rolle fehlt. | | 404 | Die Ressource wurde nicht gefunden. | | 405 | Diese Methode ist für die Ressource nicht erlaubt. | | 409 | Die Aktion passt nicht zum aktuellen Zustand. | | 413 | Der Rumpf ist größer als 1 MiB. | | 429 | Zu viele Anfragen. `Retry-After` beachten. | | 500 | Interner Fehler. | | 503 | Der Dienst ist vorübergehend nicht verfügbar. | ## Codes | Code | Status | Bedeutung | | --- | --- | --- | | invalid_json | 400 | Kein gültiges JSON. | | unknown_field | 400 | Ein Feld im Rumpf ist unbekannt. `details.field` nennt den Namen. | | request_too_large | 413 | Der Rumpf ist größer als 1 MiB. | | invalid_title | 400 | Titel fehlt oder ist zu lang. | | invalid_start_at | 400 | Beginn fehlt oder ist kein RFC-3339-Zeitpunkt. | | invalid_end_at | 400 | Ende ist ungültig oder liegt vor dem Beginn. | | invalid_timezone | 400 | Zeitzone fehlt oder ist keine IANA-Zeitzone. | | invalid_location_type | 400 | Ortstyp ist nicht offline, online oder hybrid. | | invalid_visibility | 400 | Sichtbarkeit ist nicht public oder private. | | invalid_status | 400 | Status ist nicht draft oder published, oder der Statusfilter ist ungültig. | | invalid_capacity | 400 | Kapazität ist negativ. | | invalid_category | 400 | Kategorie ist unbekannt. | | invalid_tags | 400 | Zu viele Schlagworte oder ein Schlagwort ist zu lang. | | no_changes | 400 | Die Änderung enthält kein Feld. | | invalid_days | 400 | Der Zeitraum liegt nicht zwischen 1 und 365 Tagen. | | invalid_limit | 400 | Ein `limit` ist ungültig, etwa keine ganze Zahl oder außerhalb des erlaubten Bereichs. | | idempotency_conflict | 409 | Derselbe Idempotency-Key wurde mit einem anderen Rumpf verwendet. | | event_has_registrations | 409 | Ein veröffentlichtes Event mit Anmeldungen lässt sich nicht löschen. `details.count` nennt die Zahl der Anmeldungen. | | invalid_api_key | 401 | Der Schlüssel fehlt, ist unbekannt oder wurde zurückgezogen. | | auth_unavailable | 503 | Der Schlüssel konnte nicht geprüft werden. | | plan_required | 403 | Die Aktion erfordert Eventwerk Plus. | | forbidden | 403 | Die Rolle erlaubt die Aktion nicht. | | event_not_found | 404 | Das Event wurde nicht gefunden. | | ticket_not_found | 404 | Die Ticketart wurde nicht gefunden. | | registration_not_found | 404 | Die Anmeldung wurde nicht gefunden. | | not_found | 404 | Die Route existiert nicht. | | method_not_allowed | 405 | Die Methode ist für diese Route nicht erlaubt. | | rate_limited | 429 | Mehr als 200 Anfragen pro Minute je Schlüssel und Instanz. | | internal_error | 500 | Interner Fehler. | | service_unavailable | 503 | Der Dienst ist vorübergehend nicht verfügbar. | ## Weitere Codes | Code | Status | Bedeutung | | --- | --- | --- | | invalid_webhook_url | 400 | Die Webhook-Adresse ist keine gültige http- oder https-Adresse. | | webhook_not_found | 404 | Der Webhook wurde nicht gefunden. | | invalid_name | 400 | Der Name des API-Schlüssels ist leer oder zu lang. | | key_limit_reached | 400 | Es sind bereits 25 aktive API-Schlüssel vorhanden. | | key_daily_limit | 400 | Es wurden heute bereits 10 API-Schlüssel angelegt. | | weekly_send_limit | 403 | Das wöchentliche Versandkontingent ist erreicht. Details enthält limit, used und plan. | | invalid_unread_only | 400 | unread_only ist nicht true oder false. | | invalid_notification_id | 400 | Die Kennung einer Benachrichtigung ist ungültig. | ## Fehler behandeln 1. Bei 400 die Anfrage anhand von code, message und details korrigieren. Nicht automatisch wiederholen. 2. Bei 401 den Schlüssel prüfen. Ein zurückgezogener Schlüssel wird nie wieder gültig. 3. Bei 403 den Plan und die Rolle prüfen. Ein Planwechsel hilft sofort. 4. Bei 404 die Kennung prüfen. Die Ressource kann gelöscht worden sein. 5. Bei 409 den Zustand prüfen. `idempotency_conflict` bedeutet einen anderen Rumpf beim selben Schlüssel, `event_has_registrations` ein veröffentlichtes Event mit Anmeldungen. 6. Bei 429 den Wert von Retry-After abwarten. 7. Bei 500 und 503 mit wachsender Pause erneut versuchen. > **Hinweis:** `POST /events` akzeptiert einen `Idempotency-Key`. Gleicher Schlüssel und gleicher Rumpf liefern dieselbe Antwort, ein anderer Rumpf ergibt 409 `idempotency_conflict`. Ohne Schlüssel legt ein wiederholter POST ein neues Event an.