Migration von v1
Dieser Leitfaden ordnet jedes veraltete /create*Message-Feld seinem Äquivalent in der Messaging API v2 zu. Verwenden Sie ihn als Referenz beim Portieren bestehender Integrationen.
Allgemeine Unterschiede
Anchor link to| Aspekt | v1 | v2 |
|---|---|---|
| Endpunkt pro Kanal | separate Methode pro Kanal (/createMessage, /createEmailMessage, /createSMSMessage, /createKakaoMessage, …) | einzelner Endpunkt — POST /messaging/v2/notify |
| Auth | auth-Feld im Anfrage-Body | Authorization: Token <API_TOKEN>-Header |
| Targeting | gemischt: filter + conditions + devices + users in derselben Anfrage | explizite Trennung: NotifySegment vs NotifyTransactional |
| Inhalt | flaches content + nebengeordnete Plattformblöcke | verschachteltes payload.content.localized_content.{locale}.{platform} |
| Antwort | MessageCode[] | message_code + optional unknown_identifiers |
Von /createMessage
Anchor link tov1 notifications[*]-Einträge werden zu einzelnen Notify-Anfragen (jeweils eine Nachricht). Wenn ein v1-Aufruf mehrere Einträge hat, führen Sie eine Notify-Anfrage pro Eintrag aus.
Targeting-Entscheidung. Wenn der v1-Eintrag devices oder users (explizite Listen) verwendet, ordnen Sie ihn transactional zu. Andernfalls ordnen Sie ihn segment zu.
Felder auf Anfrageebene
Anchor link toapplication→segment.applicationodertransactional.application(gleiches App-Code-Format).applications_group: wird in v2 nicht unterstützt. Verwenden Sie mehrere Anfragen pro App.auth: in denAuthorization-Header verschoben, nicht mehr im Body.
Zeitplanung
Anchor link tosend_date("YYYY-MM-DD HH:mm"oder"now") →schedule.at(RFC 3339 UTC-Zeitstempel). Um v1"now"zu reproduzieren, setzen Sieschedule.atauf die aktuelle Zeit. Jeder Zeitstempel in der Vergangenheit wird sofort gesendet.ignore_user_timezone→schedule.follow_user_timezone. Invertiert:ignore_user_timezone: truewird zufollow_user_timezone: false.timezone: nicht unterstützt. v2 verwendet immer UTC fürat. Konvertieren Sie clientseitig.
Targeting
Anchor link tofilter(Segmentname) →segment.code.conditions([[tag, op, value], ...]) →segment.expression. Schreiben Sie dies in einen seglang-Ausdruck um. In seglang ist*ein logisches UND und app-spezifische Tags werden alsTag("<application-code>", "<tag>", <op>, <value>)referenziert. Beispiel:[["Country","EQ","BR"],["Language","EQ","pt"]]mitconditions_operator: AND→Tag("XXXXX-XXXXX", "Country", EQ, "br") * Tag("XXXXX-XXXXX", "Language", EQ, "pt").conditions_operator(AND/OR): insegment.expressionintegriert.devices(HWIDs oder Push-Tokens) →transactional.hwids.listodertransactional.push_tokens.list. v2 trennt die beiden: HWIDs gehen inhwids, rohe Push-Tokens inpush_tokens.users→transactional.users.list.platforms(numerische Codes[1, 3, …]) →segment.platformsodertransactional.platforms(String-Enums["IOS", "ANDROID", …]). Siehe Platform enum.
Inhalt
Anchor link tocontent(String) →payload.content.localized_content.default.{platform}.body. In v2 ist der Inhalt immer pro Locale und pro Plattform. Setzen Sie einen einfachen v1-String unter den speziellen Schlüssel"default"(Catch-all-Übersetzung, siehe Locale-Auswahl).content({locale: text}) →payload.content.localized_content.{locale}.{platform}.body. Duplizieren Sie den Body in jeden anvisierten Plattformblock.preset→payload.preset.data→payload.custom_data.rich_media→payload.open_action.rich_media.code.link→payload.open_action.link.url.minimize_link(0oder2) →payload.open_action.link.shortener(NONEoderBITLY).inbox_image→payload.content.localized_content.{locale}.{platform}.inbox.image_url(jeder Plattformblock hat seinen eigeneninbox).inbox_date→payload.content.localized_content.{locale}.{platform}.inbox.expiration_date.inbox_days: nicht unterstützt. Konvertieren Sie clientseitig in ein absolutesexpiration_date.
Zustellungssteuerung
Anchor link todynamic_content/dynamic_content_placeholders→dynamic_content_placeholdersaufsegmentodertransactional.campaign→campaignaufsegmentodertransactional.capping_days→frequency_capping.days.capping_count→frequency_capping.count.send_rate(int) →send_rate.valuemitsend_rate.bucket: "1s".message_type("marketing"/"transactional") →message_type(MESSAGE_TYPE_MARKETING/MESSAGE_TYPE_TRANSACTIONAL).
In v2 nicht unterstützt
Anchor link totransactionId: kein direktes Äquivalent. Verfolgen Sie die Korrelation auf Ihrer Seite.template_bindings: Liquid-Template-Bindungen sind in v2 nicht verfügbar. Verwenden Sie weiterhin v1, wenn Sie darauf angewiesen sind.
Plattformspezifische Blöcke
Anchor link tov1 akzeptiert plattformspezifische Parameter auf der obersten Ebene jedes notifications[*]-Eintrags (ios, android, safari, chrome, …). In v2 werden sie in die locale verschoben:
// v1"notifications": [{ "content": "Hello", "ios": { "title": "Hi", "sound": "default.caf" }, "android": { "header": "Hi", "led": "#ff0000" }}]
// v2"payload": { "content": { "localized_content": { "en": { "ios": { "title": "Hi", "body": "Hello", "sound": "default.caf" }, "android": { "title": "Hi", "body": "Hello", "led_color": "#ff0000" } } } }}Feldnamen innerhalb von Plattformblöcken unterscheiden sich an einigen Stellen. Die genauen v2-Namen finden Sie in der Payload-Referenz.
Beispiel: Vorher und nachher
Anchor link tov1 /createMessage (Push an ein Segment):
{ "request": { "application": "XXXXX-XXXXX", "auth": "YOUR_API_TOKEN", "notifications": [{ "send_date": "2026-05-01 12:00", "content": "Hello!", "platforms": [1, 3], "filter": "active_users", "campaign": "YYYYY-YYYYY", "capping_days": 7, "capping_count": 3, "message_type": "marketing" }] }}v2 /messaging/v2/notify:
{ "segment": { "application": "XXXXX-XXXXX", "platforms": ["IOS", "ANDROID"], "code": "active_users", "payload": { "content": { "localized_content": { "en": { "ios": { "body": "Hello!" }, "android": { "body": "Hello!" } } } } }, "schedule": { "at": "2026-05-01T12:00:00Z" }, "frequency_capping": { "days": 7, "count": 3 }, "campaign": "YYYYY-YYYYY", "message_type": "MESSAGE_TYPE_MARKETING" }}Von /createTargetedMessage
Anchor link to/createTargetedMessage wird in den meisten Fällen transactional zugeordnet oder segment, wenn Sie es ausschließlich als app-übergreifenden devices_filter ohne explizite Identifikatoren verwendet haben.
devices_filter→segment.expression(seglang) odersegment.filter_expression(strukturiert).content→payload.content.localized_content.{locale}.{platform}.body.- Alle anderen Felder, wie bei
/createMessageoben.
Von /createEmailMessage
Anchor link toWechseln Sie zu Notify mit platforms: ["EMAIL"] und einem email_payload-Block. Vollständige Referenz: E-Mail-Payload-Referenz.
subject→email_payload.subject(Map mit Locale als Schlüssel. Umschließen Sie Werte für eine einzelne Locale mit{"en": "..."}).content(HTML) →email_payload.body.email_template→email_payload.email_template.from/from_name→email_payload.from({ "name": "...", "email": "..." }).reply_to/reply_to_name→email_payload.reply_to.list_unsubscribe→email_payload.list_unsubscribe.attachments→email_payload.attachments([{ "name": "...", "content": "<base64>" }]).- Targeting, Zeitplan, Kampagne usw., wie bei
/createMessage.
Von /createSMSMessage
Anchor link toWechseln Sie zu Notify mit platforms: ["SMS"]. Der SMS-Body wird über den konfigurierten SMS-Anbieter der App zugestellt. Fügen Sie den Inhalt in payload.content.localized_content.{locale}.{platform}.body in einem beliebigen ausgefüllten Plattformblock ein.
SMS-spezifische Anbieteroptionen (Absender-ID usw.) stammen weiterhin aus der SMS-Konfiguration der App und nicht aus dem Anfrage-Body.
Von /createKakaoMessage
Anchor link toWechseln Sie zu Notify mit platforms: ["KAKAO"] und verwenden Sie payload.content.localized_content.{locale}.kakao:
template_id→kakao.template.content→kakao.content.variables→kakao.content_variables(JSON-stringifiziert).
Von /createWhatsAppMessage
Anchor link toWechseln Sie zu Notify mit platforms: ["WHATS_APP"] und verwenden Sie payload.content.localized_content.{locale}.whatsapp:
content(Freitext) →whatsapp.content. Wird von Meta nur innerhalb des 24-Stunden-Kundenservice-Fensters zugestellt.content_id→whatsapp.content_id. Name einer vorab genehmigten Meta-Vorlage.language→whatsapp.language. Meta-Vorlagen-Locale (z.B."en_US"). Unabhängig vom äußerenLocalizedContent-Locale-Schlüssel.content_variables(Objekt in v1) →whatsapp.content_variables(JSON-stringifiziertes Objekt). Beispiel v1{"1": "John"}wird zu v2"{\"1\":\"John\"}".button_url_variables(Objekt) →whatsapp.button_url_variables(JSON-stringifiziert).header_variables(Objekt) →whatsapp.header_variables(JSON-stringifiziert).preset→payload.preset(generisches Preset auf Payload-Ebene).- Targeting: Die WhatsApp-Telefonnummer, die in v1 in
devicesging (z.B."whatsapp:+1234567890"), muss über/registerDevicefür einen Benutzer registriert werden. In v2 zielen Sie auf den resultierenden Benutzer mittransactional.users.list(oder die HWID übertransactional.hwids.list). use_auto_registration: nicht unterstützt. Registrieren Sie die WhatsApp-Nummer vor dem Senden.
Von /createLineMessage
Anchor link toWechseln Sie zu Notify mit platforms: ["LINE"] und verwenden Sie payload.content.localized_content.{locale}.line:
content(Klartext) →line.content.preset(LINE-Preset-Code) →line.template. Das v2-Feld speichert einen Code, der auf eine im Pushwoosh Control Panel konfigurierte LINE-Vorlage verweist.- Inline-
template(v1-Bild-, Karussell- oder Flex-Nachrichtenstrukturen): in v2 nicht direkt unterstützt. Konfigurieren Sie die Rich Message als LINE-Preset im Control Panel vor und verweisen Sie darauf überline.template. - Targeting: Die v1-
devices-Liste (LINE-Benutzer-IDs, die über das SDK //registerDeviceregistriert wurden) wird in v2 zutransactional.users.list(oder die HWID übertransactional.hwids.list).
Unterschiede bei der Antwort
Anchor link tov1 /createMessage gibt zurück:
{ "status_code": 200, "status_message": "OK", "response": { "Messages": ["XXXXX-XXXXX-AAAAA"] }}v2 Notify gibt zurück:
{ "result": { "message_code": "XXXXX-XXXXX-AAAAA", "unknown_identifiers": [] }}Antworten, die nicht den Status 200 haben, folgen dem Standard-gRPC-Gateway-Fehlerformat ({ "code": ..., "message": ..., "details": [...] }) anstelle des v1-Paares status_code / status_message.