Newsletter Management: Shop API
Shop API des Newsletter-Plugins für Sylius - Anmeldung, Bestätigung, Abmeldung, Einstellungen und Kategorien headless nutzen, mit curl-Beispielen, Parametern und Fehlerformat
Newsletter Management: Shop API
Diese Dokumentation bezieht sich immer auf die aktuellste veröffentlichte Version.
Das Plugin läuft zweigleisig: Anmeldung, Bestätigung, Abmeldung und Verwalten des Abonnements funktionieren im Twig-Storefront und headless über die Shop API, und beide Wege laufen durch denselben Domain-Service (NewsletterSubscriptionManager). Es gibt keine zweite Geschäftslogik im API-Code.
graph LR
A["Storefront Formular"] --> C["NewsletterSubscriptionManager"]
B["Shop API Request"] --> C
C --> D{"Newsletter im Channel aktiv?"}
D -->|"Nein"| E["404"]
D -->|"Ja"| F["PRE_SUBSCRIBE Event"]
F -->|"abgelehnt"| G["422"]
F -->|"akzeptiert"| H["Abonnement + Bestätigungs-Mail"]
Endpunkte
Alle Pfade liegen unter dem Shop-API-Präfix deines Sylius-Projekts (Standard: /api/v2), also zum Beispiel /api/v2/shop/newsletter-subscriptions. Anfragen mit Body (POST, PUT) senden Content-Type: application/json.
| Method | Path | Beschreibung |
|---|---|---|
POST |
/shop/newsletter-subscriptions |
Anmeldung. Antwortet mit 202 und ohne Body, egal ob die Adresse neu, noch unbestätigt oder schon bestätigt ist |
POST |
/shop/newsletter-subscriptions/confirm |
Bestätigt per Token (Double Opt-in). 204 bei Erfolg, 404 bei unbekanntem oder bereits abgemeldetem Token |
POST |
/shop/newsletter-subscriptions/unsubscribe |
Meldet per Token ab. 204 bei Erfolg (auch wenn schon abgemeldet), 404 bei unbekanntem Token |
GET |
/shop/newsletter-preferences/{token} |
Liest Name, Kategorien und Tracking-Einwilligung eines bestätigten Abonnements |
PUT |
/shop/newsletter-preferences/{token} |
Ändert Name, Kategorien und Tracking-Einwilligung. Die E-Mail-Adresse lässt sich nie ändern |
GET |
/shop/newsletter-categories |
Liste der Kategorien, die der aktuelle Channel anbietet, nach Position sortiert |
GET |
/shop/newsletter-categories/{id} |
Eine einzelne Kategorie (404, wenn deaktiviert oder für einen anderen Channel beschränkt) |
Der Token in
/confirmund/unsubscribeist der 64 Zeichen lange Token aus dem Link der jeweiligen Mail. Bei/shop/newsletter-preferences/{token}ist es der Abmelde-Token, den jede Newsletter-Mail im Footer trägt. Ein Token anderer Länge im Body von/confirmund/unsubscribeergibt422, ein unbekannter Token in der URL von/shop/newsletter-preferences/{token}404.
Channel
Die Endpunkte arbeiten immer für den Channel, den Sylius für die Anfrage ermittelt (in der Regel über den Hostnamen). Ist der Newsletter für diesen Channel nicht aktiviert, antwortet die Anmeldung mit 404, und die Kategorien-Liste ist unabhängig davon auf die Kategorien dieses Channels begrenzt. Die Einstellung findest du unter Konfiguration.
Anmeldung
Body
| Feld | Typ | Pflicht | Beschreibung |
|---|---|---|---|
email |
string | ja | Gültige E-Mail-Adresse, maximal 255 Zeichen. Wird klein geschrieben gespeichert |
consent |
boolean | ja | Muss true sein, sonst 422 |
firstName |
string | nein | Maximal 100 Zeichen |
lastName |
string | nein | Maximal 100 Zeichen |
categories |
string | nein | Kategorie-Codes. Leer bedeutet: der allgemeine Newsletter, also alles. Unbekannte, deaktivierte oder für den Channel nicht angebotene Codes werden verworfen |
trackingConsent |
boolean | nein | Einwilligung in persönliches Tracking, Standard false. Zählt nur, wenn der Channel den Tracking-Modus Personenbezogen hat |
Beispiel
curl -X POST https://shop.example.com/api/v2/shop/newsletter-subscriptions \
-H "Content-Type: application/json" \
-d '{
"email": "anna.beispiel@example.com",
"firstName": "Anna",
"lastName": "Beispiel",
"categories": ["neuheiten", "tutorials"],
"consent": true
}'
Antwort: 202 Accepted ohne Body. Bei aktiviertem Double Opt-in (Standard) bekommt die Adresse jetzt die Bestätigungs-Mail. Ist die Adresse schon bestätigt, ändert die Anfrage nichts am Abonnement, und die Adresse erhält stattdessen die Mail "bereits angemeldet". So lässt sich über die API nicht herausfinden, wer auf der Liste steht.
Mails, die ein öffentliches Formular auslöst, werden pro Adresse gedrosselt: Innerhalb von 10 Minuten geht höchstens eine solche Mail an dieselbe Adresse. Die Antwort bleibt trotzdem
202.
Bestätigen und Abmelden
Die Mail verlinkt auf die Storefront-Seite. Ein Headless-Shop liest den Token aus diesem Link (Pfad /newsletter/confirm/{token} beziehungsweise /newsletter/unsubscribe/{token}) und sendet ihn an die API:
curl -X POST https://shop.example.com/api/v2/shop/newsletter-subscriptions/confirm \
-H "Content-Type: application/json" \
-d '{"token": "3f9a1c0e5b7d42a8c6e1f0b9d8a7c6e5f4b3a29180716253443526170809a0b1"}'
Antwort: 204 No Content. Für die Abmeldung gilt derselbe Aufruf an /shop/newsletter-subscriptions/unsubscribe.
Einstellungen des Abonnenten
curl https://shop.example.com/api/v2/shop/newsletter-preferences/TOKEN \
-H "Accept: application/json"
Die Antwort enthält email (nur lesbar), firstName, lastName, trackingConsent und categories (Liste der Codes). Der Token selbst steht nie in der Antwort. Für unbekannte Token und für noch unbestätigte Abonnements antwortet die API mit 404.
curl -X PUT https://shop.example.com/api/v2/shop/newsletter-preferences/TOKEN \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"firstName": "Anna",
"lastName": "Beispiel",
"categories": ["tutorials"],
"trackingConsent": false
}'
Die Antwort zeigt, was tatsächlich gespeichert wurde: unbekannte oder deaktivierte Kategorie-Codes fehlen dort. Ein mitgesendetes email-Feld wird ignoriert.
| Feld | Verhalten bei PUT |
|---|---|
firstName, lastName |
Werden ersetzt (maximal 100 Zeichen). Fehlt ein Feld, wird der Name geleert |
categories |
Ersetzt die bisherige Auswahl. Eine leere Liste bedeutet den allgemeinen Newsletter |
trackingConsent |
Weggelassen (null) lässt die Einwilligung unverändert. false widerruft sie und löscht die persönlichen Tracking-Daten. true erteilt sie, aber nur wenn der Channel den Modus Personenbezogen hat |
Kategorien
curl https://shop.example.com/api/v2/shop/newsletter-categories \
-H "Accept: application/json"
Jede Kategorie enthält id, code, position, name und description; name und description kommen in der Sprache der Anfrage. Es erscheinen nur aktivierte Kategorien, die entweder für alle Channels oder für den aktuellen Channel angeboten werden.
Fehlerformat
| Status | Wann |
|---|---|
202 |
Anmeldung angenommen (sagt nichts über den Zustand der Adresse aus) |
204 |
Bestätigung oder Abmeldung erfolgreich |
404 |
Newsletter für den Channel nicht aktiviert, unbekannter Token oder Kategorie nicht verfügbar |
422 |
Validierungsfehler (ungültige E-Mail-Adresse, consent nicht true, Token nicht 64 Zeichen lang, Felder zu lang) oder Ablehnung durch ein PRE_SUBSCRIBE-Listener |
Eine Ablehnung durch ein Spam-Schutz-Plugin liefert ebenfalls 422; als Meldung steht der Grund, den der Listener übergeben hat (ein Übersetzungsschlüssel oder der Standardtext "Signup rejected."). Wie du so einen Listener schreibst, steht unter Erweiterbarkeit.
Das ALTCHA-Plugin schützt die Anmeldung auch über die API. Der Proof gehört dann in den Header
X-Altcha-Payload, siehe ALTCHA: Shop API.
Nicht über die API verfügbar
Die Shop API deckt nur das ab, was ein Kunde selbst tut. Folgendes gibt es ausschließlich im Admin (Twig):
- Newsletter anlegen, bearbeiten, versenden, planen und duplizieren
- Versandprotokoll (Deliveries) und Statistiken
- Abonnenten-Verwaltung und CSV-Export
Die Bestätigungs-Mail linkt auf die Storefront-Seite. Ein reiner Headless-Shop muss diesen Link in der Mail-Vorlage auf sein eigenes Frontend umschreiben und den Token von dort an die API senden.