Migration depuis la v1
Ce guide fait correspondre chaque champ hérité de /create*Message à son équivalent dans l’API de Messagerie v2. Utilisez-le comme référence lors de la migration de vos intégrations existantes.
Différences de haut niveau
Anchor link to| Aspect | v1 | v2 |
|---|---|---|
| Point de terminaison par canal | méthode distincte par canal (/createMessage, /createEmailMessage, /createSMSMessage, /createKakaoMessage, …) | point de terminaison unique — POST /messaging/v2/notify |
| Authentification | champ auth dans le corps de la requête | en-tête Authorization: Token <API_TOKEN> |
| Ciblage | mixte : filter + conditions + devices + users dans la même requête | séparation explicite : NotifySegment vs NotifyTransactional |
| Contenu | content plat + blocs de plateforme frères | payload.content.localized_content.{locale}.{platform} imbriqué |
| Réponse | MessageCode[] | message_code + unknown_identifiers optionnel |
Depuis /createMessage
Anchor link toLes entrées v1 notifications[*] deviennent des requêtes Notify individuelles (un message chacune). Si un appel v1 a plusieurs entrées, émettez une requête Notify par entrée.
Décision de ciblage. Si l’entrée v1 utilise devices ou users (listes explicites), faites-la correspondre à transactional. Sinon, faites-la correspondre à segment.
Champs au niveau de la requête
Anchor link toapplication→segment.applicationoutransactional.application(même format de code d’application).applications_group: non pris en charge en v2. Utilisez plusieurs requêtes par application.auth: déplacé vers l’en-têteAuthorization, n’est plus dans le corps.transactionId→transaction_id, un champ au niveau de la requête à côté desegment/transactional. Même comportement de déduplication que la v1 : un appel répété avec la même valeur dans les 5 minutes renvoie lemessage_coded’origine au lieu de le renvoyer, la correspondance se faisant sur la clé seule, et non sur le payload. Voirtransaction_id.
Planification
Anchor link tosend_date("YYYY-MM-DD HH:mm"ou"now") →schedule.at(horodatage UTC RFC 3339). Pour reproduire le"now"de la v1, définissezschedule.atsur l’heure actuelle. Un horodatage dans le passé est envoyé immédiatement lorsquefollow_user_timezonen’est pas défini ou vautfalse. Avecfollow_user_timezone: true, consultez plutôt l’avertissement sur unatpassé.ignore_user_timezone→schedule.follow_user_timezone. Inversé :ignore_user_timezone: truedevientfollow_user_timezone: false.timezone: non pris en charge. La v2 utilise toujours l’UTC pourat. Convertissez côté client.
Ciblage
Anchor link tofilter(nom du segment) →segment.code.conditions([[tag, op, value], ...]) →segment.expression. Réécrivez en une expression seglang. En seglang,*est un ET logique et les tags spécifiques à l’application sont référencés commeTag("<application-code>", "<tag>", <op>, <value>). Exemple :[["Country","EQ","BR"],["Language","EQ","pt"]]avecconditions_operator: AND→Tag("XXXXX-XXXXX", "Country", EQ, "br") * Tag("XXXXX-XXXXX", "Language", EQ, "pt").conditions_operator(AND/OR) : intégré danssegment.expression.devices(hwids ou push tokens) →transactional.hwids.listoutransactional.push_tokens.list. La v2 sépare les deux : les hwids vont danshwids, les push tokens bruts danspush_tokens.users→transactional.users.list.platforms(codes numériques[1, 3, …]) →segment.platformsoutransactional.platforms(énumérations de chaînes["IOS", "ANDROID", …]). Voir Énumération de plateforme.
Contenu
Anchor link tocontent(chaîne) →payload.content.localized_content.default.{platform}.body. En v2, le contenu est toujours par locale et par plateforme. Placez une chaîne v1 simple sous la clé spéciale"default"(traduction fourre-tout, voir Sélection de la locale).content({locale: text}) →payload.content.localized_content.{locale}.{platform}.body. Dupliquez le corps dans chaque bloc de plateforme ciblé.preset→payload.preset.data→payload.custom_data.rich_media→payload.open_action.rich_media.code.link→payload.open_action.link.url.minimize_link(0ou2) →payload.open_action.link.shortener(NONEouBITLY).inbox_image→payload.content.localized_content.{locale}.{platform}.inbox.image_url(chaque bloc de plateforme a son propreinbox).inbox_date→payload.content.localized_content.{locale}.{platform}.inbox.expiration_date.inbox_days→payload.content.localized_content.{locale}.{platform}.inbox.expires_in, sous forme de durée en secondes (par exemple, 7 jours correspondent à"604800s").
Contrôles de livraison
Anchor link todynamic_content/dynamic_content_placeholders→dynamic_content_placeholderssursegmentoutransactional.campaign→campaignsursegmentoutransactional.campaign_name→campaign_namesursegmentoutransactional, inchangé.capping_days→frequency_capping.days.capping_count→frequency_capping.count.send_rate(entier) →send_rate.valueavecsend_rate.bucket: "1s".message_type("marketing"/"transactional") →message_type(MESSAGE_TYPE_MARKETING/MESSAGE_TYPE_TRANSACTIONAL).
Non pris en charge en v2
Anchor link totemplate_bindings: les liaisons de modèles Liquid ne sont pas disponibles en v2. Continuez à utiliser la v1 si vous en dépendez.
Blocs spécifiques à la plateforme
Anchor link toLa v1 accepte les paramètres spécifiques à la plateforme au niveau supérieur de chaque entrée notifications[*] (ios, android, safari, chrome, …). En v2, ils se déplacent à l’intérieur de la locale :
// 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" } } } }}Les noms de champs dans les blocs de plateforme diffèrent par endroits. Consultez la Référence du payload pour les noms exacts de la v2.
Exemple : Avant et après
Anchor link tov1 /createMessage (push vers un 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" }}Depuis /createTargetedMessage
Anchor link to/createTargetedMessage correspond à transactional dans la plupart des cas ou à segment si vous l’utilisiez uniquement comme un devices_filter inter-applications sans identifiants explicites.
devices_filter→segment.expression(seglang) ousegment.filter_expression(structuré).content→payload.content.localized_content.{locale}.{platform}.body.- Tous les autres champs, comme pour
/createMessageci-dessus.
Depuis /createEmailMessage
Anchor link toPassez à Notify avec platforms: ["EMAIL"] et un bloc email_payload. Référence complète : Référence du payload d’e-mail.
subject→email_payload.subject(map indexée par locale. Encadrez les valeurs à locale unique dans{"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>" }]).devices(adresses e-mail) →transactional.hwids.list. Pour l’e-mail, le hwid est l’adresse.use_auto_registration: true→transactional.registration_type: "REGISTRATION_TYPE_FORCE". Il enregistre les adresses nouvelles pour Pushwoosh et leur envoie le message dans la même requête. Il ne fonctionne qu’avechwids. Sans lui, les nouvelles adresses sont ignorées. Avecreturn_unknown_identifiers: true, une requête dans laquelle aucune des adresses n’est enregistrée échoue avecNo recipients found.- Ciblage, planification, campagne, etc., comme pour
/createMessage.
Depuis /createSMSMessage
Anchor link toPassez à Notify avec platforms: ["SMS"]. Le corps du SMS est livré via le fournisseur SMS configuré de l’application. Placez le contenu dans payload.content.localized_content.{locale}.{platform}.body sur n’importe quel bloc de plateforme rempli.
Les options spécifiques au fournisseur SMS (ID de l’expéditeur, etc.) continuent de provenir de la configuration SMS de l’application plutôt que du corps de la requête.
devices(numéros de téléphone au format international, par ex.+14155552671) →transactional.hwids.list.use_auto_registration: true→transactional.registration_type: "REGISTRATION_TYPE_FORCE", qui enregistre les nouveaux numéros de téléphone avant l’envoi.
/createSMSMessage n’a pas d’équivalent MMS. Pour envoyer des MMS (sujet + pièces jointes d’images), utilisez sms.subject et sms.file_urls — voir MMS.
Depuis /createKakaoMessage
Anchor link toPassez à Notify avec platforms: ["KAKAO"], en utilisant payload.content.localized_content.{locale}.kakao :
template_id→kakao.template.content→kakao.content.variables→kakao.content_variables(chaîne JSON).
Depuis /createWhatsAppMessage
Anchor link toPassez à Notify avec platforms: ["WHATS_APP"], en utilisant payload.content.localized_content.{locale}.whatsapp :
content(texte libre) →whatsapp.content. Livré par Meta uniquement dans la fenêtre de service client de 24 heures.content_id→whatsapp.content_id. Nom d’un modèle Meta pré-approuvé.language→whatsapp.language. Locale du modèle Meta (par ex."en_US"). Indépendant de la clé de locale externeLocalizedContent.content_variables(objet en v1) →whatsapp.content_variables(objet en chaîne JSON). Exemple v1{"1": "John"}devient v2"{\"1\":\"John\"}".button_url_variables(objet) →whatsapp.button_url_variables(chaîne JSON).header_variables(objet) →whatsapp.header_variables(chaîne JSON).preset→payload.preset(preset générique au niveau du payload).- Ciblage : le numéro de téléphone WhatsApp qui, en v1, allait dans
devices(par ex."whatsapp:+1234567890") va danstransactional.hwids.list. Si vous l’avez enregistré via/registerDevicepour un utilisateur, vous pouvez plutôt cibler cet utilisateur avectransactional.users.list. use_auto_registration: true→transactional.registration_type: "REGISTRATION_TYPE_FORCE". Placez le numéro danstransactional.hwids.listavec le préfixewhatsapp:, comme en v1, et Pushwoosh l’enregistre avant l’envoi : vous pouvez donc ignorer l’appel à/registerDevice. Consultez Envoyer à de nouvelles adresses e-mail et de nouveaux numéros de téléphone pour le format du hwid de chaque canal et la limite de la fenêtre de 24 heures.
Depuis /createLineMessage
Anchor link toPassez à Notify avec platforms: ["LINE"], en utilisant payload.content.localized_content.{locale}.line :
content(texte brut) →line.content.preset(code de preset LINE) →line.template. Le champ v2 stocke un code qui référence un modèle LINE configuré dans le Panneau de Contrôle Pushwoosh.templateen ligne (structures de message v1 image, carrousel ou flex) : non pris en charge directement en v2. Pré-configurez le message riche comme un preset LINE dans le Panneau de Contrôle et référencez-le vialine.template.- Ciblage : la liste
devicesv1 (ID utilisateur LINE enregistrés via le SDK //registerDevice) devienttransactional.users.list(ou le hwid viatransactional.hwids.list) en v2.
Différences de réponse
Anchor link toLa v1 /createMessage renvoie :
{ "status_code": 200, "status_message": "OK", "response": { "Messages": ["XXXXX-XXXXX-AAAAA"] }}La v2 Notify renvoie :
{ "result": { "message_code": "XXXXX-XXXXX-AAAAA", "unknown_identifiers": [] }}Les réponses autres que 200 suivent l’enveloppe d’erreur standard gRPC-Gateway ({ "code": ..., "message": ..., "details": [...] }) au lieu de la paire v1 status_code / status_message.