Migración desde v1
Esta guía mapea cada campo del antiguo /create*Message a su equivalente en la API de Mensajería v2. Úsela como referencia mientras migra las integraciones existentes.
Diferencias de alto nivel
Anchor link to| Aspecto | v1 | v2 |
|---|---|---|
| Endpoint por canal | método separado por canal (/createMessage, /createEmailMessage, /createSMSMessage, /createKakaoMessage, …) | único endpoint — POST /messaging/v2/notify |
| Autenticación | campo auth en el cuerpo de la solicitud | encabezado Authorization: Token <API_TOKEN> |
| Segmentación | mixto: filter + conditions + devices + users en la misma solicitud | división explícita: NotifySegment vs NotifyTransactional |
| Contenido | content plano + bloques de plataforma hermanos | payload.content.localized_content.{locale}.{platform} anidado |
| Respuesta | MessageCode[] | message_code + unknown_identifiers opcional |
Desde /createMessage
Anchor link toLas entradas notifications[*] de la v1 se convierten en solicitudes Notify individuales (un mensaje cada una). Si una llamada v1 tiene múltiples entradas, emita una solicitud Notify por cada entrada.
Decisión de segmentación. Si la entrada v1 utiliza devices o users (listas explícitas), mapéela a transactional. De lo contrario, mapéela a segment.
Campos a nivel de solicitud
Anchor link toapplication→segment.applicationotransactional.application(mismo formato de app-code).applications_group: no soportado en v2. Use múltiples solicitudes por aplicación.auth: movido al encabezadoAuthorization, ya no está en el cuerpo.
Programación
Anchor link tosend_date("YYYY-MM-DD HH:mm"o"now") →schedule.at(marca de tiempo RFC 3339 UTC). Para reproducir el"now"de la v1, establezcaschedule.ata la hora actual. Cualquier marca de tiempo en el pasado se envía inmediatamente.ignore_user_timezone→schedule.follow_user_timezone. Invertido:ignore_user_timezone: truese convierte enfollow_user_timezone: false.timezone: no soportado. v2 siempre usa UTC paraat. Convierta del lado del cliente.
Segmentación
Anchor link tofilter(nombre del segmento) →segment.code.conditions([[tag, op, value], ...]) →segment.expression. Reescriba a una expresión de seglang. En seglang,*es un Y lógico y las etiquetas específicas de la aplicación se referencian comoTag("<application-code>", "<tag>", <op>, <value>). Ejemplo:[["Country","EQ","BR"],["Language","EQ","pt"]]conconditions_operator: AND→Tag("XXXXX-XXXXX", "Country", EQ, "br") * Tag("XXXXX-XXXXX", "Language", EQ, "pt").conditions_operator(AND/OR): integrado ensegment.expression.devices(hwids o push tokens) →transactional.hwids.listotransactional.push_tokens.list. v2 separa los dos: los hwids van enhwids, los push tokens sin procesar van enpush_tokens.users→transactional.users.list.platforms(códigos numéricos[1, 3, …]) →segment.platformsotransactional.platforms(enums de cadena["IOS", "ANDROID", …]). Consulte el Platform enum.
Contenido
Anchor link tocontent(cadena) →payload.content.localized_content.default.{platform}.body. En v2, el contenido es siempre por configuración regional y por plataforma. Coloque una cadena simple de v1 bajo la clave especial"default"(traducción general, consulte Selección de configuración regional).content({locale: text}) →payload.content.localized_content.{locale}.{platform}.body. Duplique el cuerpo en cada bloque de plataforma segmentado.preset→payload.preset.data→payload.custom_data.rich_media→payload.open_action.rich_media.code.link→payload.open_action.link.url.minimize_link(0o2) →payload.open_action.link.shortener(NONEoBITLY).inbox_image→payload.content.localized_content.{locale}.{platform}.inbox.image_url(cada bloque de plataforma tiene su propioinbox).inbox_date→payload.content.localized_content.{locale}.{platform}.inbox.expiration_date.inbox_days: no soportado. Convierta a unaexpiration_dateabsoluta del lado del cliente.
Controles de entrega
Anchor link todynamic_content/dynamic_content_placeholders→dynamic_content_placeholdersensegmentotransactional.campaign→campaignensegmentotransactional.capping_days→frequency_capping.days.capping_count→frequency_capping.count.send_rate(int) →send_rate.valueconsend_rate.bucket: "1s".message_type("marketing"/"transactional") →message_type(MESSAGE_TYPE_MARKETING/MESSAGE_TYPE_TRANSACTIONAL).
No soportado en v2
Anchor link totransactionId: sin equivalente directo. Realice el seguimiento de la correlación de su lado.template_bindings: Las vinculaciones de plantillas Liquid no están disponibles en v2. Siga usando v1 si depende de ellas.
Bloques específicos de la plataforma
Anchor link tov1 acepta parámetros específicos de la plataforma en el nivel superior de cada entrada notifications[*] (ios, android, safari, chrome, …). En v2 se mueven dentro de la configuración regional:
// 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" } } } }}Los nombres de los campos dentro de los bloques de plataforma difieren en algunos lugares. Consulte la Referencia de payload para los nombres exactos de v2.
Ejemplo: Antes y después
Anchor link tov1 /createMessage (push a un segmento):
{ "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" }}Desde /createTargetedMessage
Anchor link to/createTargetedMessage se mapea a transactional en la mayoría de los casos o a segment si lo estaba usando puramente como un devices_filter entre aplicaciones sin identificadores explícitos.
devices_filter→segment.expression(seglang) osegment.filter_expression(estructurado).content→payload.content.localized_content.{locale}.{platform}.body.- Todos los demás campos, igual que en
/createMessagearriba.
Desde /createEmailMessage
Anchor link toPase a Notify con platforms: ["EMAIL"] y un bloque email_payload. Referencia completa: Referencia de payload de correo electrónico.
subject→email_payload.subject(mapa con clave por configuración regional. Envuelva los valores de una sola configuración regional en{"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>" }]).- Segmentación, programación, campaña, etc., igual que en
/createMessage.
Desde /createSMSMessage
Anchor link toPase a Notify con platforms: ["SMS"]. El cuerpo del SMS se entrega a través del proveedor de SMS configurado en la aplicación. Coloque el contenido en payload.content.localized_content.{locale}.{platform}.body en cualquier bloque de plataforma rellenado.
Las opciones específicas del proveedor de SMS (ID del remitente, etc.) continúan proviniendo de la configuración de SMS de la aplicación en lugar del cuerpo de la solicitud.
Desde /createKakaoMessage
Anchor link toPase a Notify con platforms: ["KAKAO"], usando payload.content.localized_content.{locale}.kakao:
template_id→kakao.template.content→kakao.content.variables→kakao.content_variables(en formato de cadena JSON).
Desde /createWhatsAppMessage
Anchor link toPase a Notify con platforms: ["WHATS_APP"], usando payload.content.localized_content.{locale}.whatsapp:
content(texto de formato libre) →whatsapp.content. Entregado por Meta solo dentro de la ventana de servicio al cliente de 24 horas.content_id→whatsapp.content_id. Nombre de una plantilla de Meta preaprobada.language→whatsapp.language. Configuración regional de la plantilla de Meta (p. ej.,"en_US"). Independiente de la clave de configuración regional deLocalizedContentexterna.content_variables(objeto en v1) →whatsapp.content_variables(objeto en formato de cadena JSON). Ejemplo v1{"1": "John"}se convierte en v2"{\"1\":\"John\"}".button_url_variables(objeto) →whatsapp.button_url_variables(en formato de cadena JSON).header_variables(objeto) →whatsapp.header_variables(en formato de cadena JSON).preset→payload.preset(preset genérico a nivel de payload).- Segmentación: el número de teléfono de WhatsApp que en v1 iba en
devices(p. ej.,"whatsapp:+1234567890") debe registrarse a través de/registerDevicecontra un usuario. En v2, segmente al usuario resultante contransactional.users.list(o el hwid a través detransactional.hwids.list). use_auto_registration: no soportado. Registre el número de WhatsApp antes de enviar.
Desde /createLineMessage
Anchor link toPase a Notify con platforms: ["LINE"], usando payload.content.localized_content.{locale}.line:
content(texto plano) →line.content.preset(código de preset de LINE) →line.template. El campo v2 almacena un código que hace referencia a una plantilla de LINE configurada en el Panel de Control de Pushwoosh.- Plantilla en línea (estructuras de mensajes de imagen, carrusel o flex de v1): no soportado directamente en v2. Preconfigure el mensaje enriquecido como un preset de LINE en el Panel de Control y haga referencia a él a través de
line.template. - Segmentación: la lista de
devicesde v1 (IDs de usuario de LINE registrados a través del SDK //registerDevice) se convierte entransactional.users.list(o el hwid a través detransactional.hwids.list) en v2.
Diferencias en la respuesta
Anchor link tov1 /createMessage devuelve:
{ "status_code": 200, "status_message": "OK", "response": { "Messages": ["XXXXX-XXXXX-AAAAA"] }}v2 Notify devuelve:
{ "result": { "message_code": "XXXXX-XXXXX-AAAAA", "unknown_identifiers": [] }}Las respuestas que no son 200 siguen el sobre de error estándar de gRPC-Gateway ({ "code": ..., "message": ..., "details": [...] }) en lugar del par status_code / status_message de v1.