Migração da v1
Este guia mapeia cada campo legado do /create*Message para seu equivalente na Messaging API v2. Use-o como referência ao portar integrações existentes.
Diferenças de alto nível
Anchor link to| Aspecto | v1 | v2 |
|---|---|---|
| Endpoint por canal | método separado por canal (/createMessage, /createEmailMessage, /createSMSMessage, /createKakaoMessage, …) | endpoint único — POST /messaging/v2/notify |
| Autenticação | campo auth no corpo da requisição | cabeçalho Authorization: Token <API_TOKEN> |
| Direcionamento | misto: filter + conditions + devices + users na mesma requisição | divisão explícita: NotifySegment vs NotifyTransactional |
| Conteúdo | content plano + blocos de plataforma irmãos | payload.content.localized_content.{locale}.{platform} aninhado |
| Resposta | MessageCode[] | message_code + unknown_identifiers opcional |
A partir de /createMessage
Anchor link toAs entradas notifications[*] da v1 tornam-se requisições Notify individuais (uma mensagem cada). Se uma chamada v1 tiver múltiplas entradas, emita uma Notify por entrada.
Decisão de direcionamento. Se a entrada v1 usa devices ou users (listas explícitas), mapeie-a para transactional. Caso contrário, mapeie-a para segment.
Campos a nível de requisição
Anchor link toapplication→segment.applicationoutransactional.application(mesmo formato de app-code).applications_group: não suportado na v2. Use múltiplas requisições por aplicativo.auth: movido para o cabeçalhoAuthorization, não está mais no corpo.
Agendamento
Anchor link tosend_date("YYYY-MM-DD HH:mm"ou"now") →schedule.at(timestamp RFC 3339 UTC). Para reproduzir o"now"da v1, definaschedule.atpara o horário atual. Qualquer timestamp no passado é enviado imediatamente.ignore_user_timezone→schedule.follow_user_timezone. Invertido:ignore_user_timezone: truetorna-sefollow_user_timezone: false.timezone: não suportado. A v2 sempre usa UTC paraat. Converta no lado do cliente.
Direcionamento
Anchor link tofilter(nome do segmento) →segment.code.conditions([[tag, op, value], ...]) →segment.expression. Reescreva para uma expressão seglang. Em seglang,*é o E lógico e as tags específicas do aplicativo são referenciadas comoTag("<application-code>", "<tag>", <op>, <value>). Exemplo:[["Country","EQ","BR"],["Language","EQ","pt"]]comconditions_operator: AND→Tag("XXXXX-XXXXX", "Country", EQ, "br") * Tag("XXXXX-XXXXX", "Language", EQ, "pt").conditions_operator(AND/OR): incorporado emsegment.expression.devices(hwids ou push tokens) →transactional.hwids.listoutransactional.push_tokens.list. A v2 separa os dois: hwids vão parahwids, push tokens brutos parapush_tokens.users→transactional.users.list.platforms(códigos numéricos[1, 3, …]) →segment.platformsoutransactional.platforms(enums de string["IOS", "ANDROID", …]). Veja Enum de Plataforma.
Conteúdo
Anchor link tocontent(string) →payload.content.localized_content.default.{platform}.body. Na v2, o conteúdo é sempre por localidade e por plataforma. Coloque uma string simples da v1 sob a chave especial"default"(tradução genérica, veja Seleção de Localidade).content({locale: text}) →payload.content.localized_content.{locale}.{platform}.body. Duplique o corpo em cada bloco de plataforma direcionado.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(cada bloco de plataforma tem seu próprioinbox).inbox_date→payload.content.localized_content.{locale}.{platform}.inbox.expiration_date.inbox_days: não suportado. Converta para umaexpiration_dateabsoluta no lado do cliente.
Controles de entrega
Anchor link todynamic_content/dynamic_content_placeholders→dynamic_content_placeholdersemsegmentoutransactional.campaign→campaignemsegmentoutransactional.capping_days→frequency_capping.days.capping_count→frequency_capping.count.send_rate(int) →send_rate.valuecomsend_rate.bucket: "1s".message_type("marketing"/"transactional") →message_type(MESSAGE_TYPE_MARKETING/MESSAGE_TYPE_TRANSACTIONAL).
Não suportado na v2
Anchor link totransactionId: sem equivalente direto. Rastreie a correlação do seu lado.template_bindings: Vinculações de template Liquid não estão disponíveis na v2. Continue usando a v1 se você depende delas.
Blocos específicos da plataforma
Anchor link toA v1 aceita parâmetros específicos da plataforma no nível superior de cada entrada notifications[*] (ios, android, safari, chrome, …). Na v2, eles se movem para dentro da localidade:
// 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" } } } }}Os nomes dos campos dentro dos blocos de plataforma diferem em alguns lugares. Consulte a Referência de Payload para os nomes exatos da v2.
Exemplo: Antes e depois
Anchor link tov1 /createMessage (push para um 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" }}A partir de /createTargetedMessage
Anchor link to/createTargetedMessage mapeia para transactional na maioria dos casos ou para segment se você o estivesse usando puramente como um devices_filter entre aplicativos sem identificadores explícitos.
devices_filter→segment.expression(seglang) ousegment.filter_expression(estruturado).content→payload.content.localized_content.{locale}.{platform}.body.- Todos os outros campos, o mesmo que
/createMessageacima.
A partir de /createEmailMessage
Anchor link toMude para Notify com platforms: ["EMAIL"] e um bloco email_payload. Referência completa: Referência de payload de e-mail.
subject→email_payload.subject(mapa chaveado por localidade. Envolva valores de localidade única em{"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>" }]).- Direcionamento, agendamento, campanha, etc., o mesmo que
/createMessage.
A partir de /createSMSMessage
Anchor link toMude para Notify com platforms: ["SMS"]. O corpo do SMS é entregue através do provedor de SMS configurado do aplicativo. Coloque o conteúdo em payload.content.localized_content.{locale}.{platform}.body em qualquer bloco de plataforma preenchido.
Opções específicas do provedor de SMS (ID do remetente, etc.) continuam a vir da configuração de SMS do aplicativo em vez do corpo da requisição.
A partir de /createKakaoMessage
Anchor link toMude para Notify com platforms: ["KAKAO"], usando payload.content.localized_content.{locale}.kakao:
template_id→kakao.template.content→kakao.content.variables→kakao.content_variables(string JSON).
A partir de /createWhatsAppMessage
Anchor link toMude para Notify com platforms: ["WHATS_APP"], usando payload.content.localized_content.{locale}.whatsapp:
content(texto de forma livre) →whatsapp.content. Entregue pela Meta apenas dentro da janela de 24 horas de atendimento ao cliente.content_id→whatsapp.content_id. Nome de um template da Meta pré-aprovado.language→whatsapp.language. Localidade do template da Meta (ex:"en_US"). Independente da chave de localidade externaLocalizedContent.content_variables(objeto na v1) →whatsapp.content_variables(objeto em string JSON). Exemplo v1{"1": "John"}torna-se v2"{\"1\":\"John\"}".button_url_variables(objeto) →whatsapp.button_url_variables(string JSON).header_variables(objeto) →whatsapp.header_variables(string JSON).preset→payload.preset(preset genérico no nível do payload).- Direcionamento: o número de telefone do WhatsApp que na v1 ia em
devices(ex:"whatsapp:+1234567890") deve ser registrado via/registerDeviceem um usuário. Na v2, direcione o usuário resultante comtransactional.users.list(ou o hwid viatransactional.hwids.list). use_auto_registration: não suportado. Registre o número do WhatsApp antes de enviar.
A partir de /createLineMessage
Anchor link toMude para Notify com platforms: ["LINE"], usando payload.content.localized_content.{locale}.line:
content(texto simples) →line.content.preset(código de preset LINE) →line.template. O campo v2 armazena um código que referencia um template LINE configurado no Painel de Controle da Pushwoosh.templateem linha (estruturas de mensagem de imagem, carrossel ou flex da v1): não suportado diretamente na v2. Pré-configure a mensagem rica como um preset LINE no Painel de Controle e referencie-a através deline.template.- Direcionamento: a lista
devicesda v1 (IDs de usuário LINE registrados através do SDK //registerDevice) torna-setransactional.users.list(ou o hwid viatransactional.hwids.list) na v2.
Diferenças na resposta
Anchor link tov1 /createMessage retorna:
{ "status_code": 200, "status_message": "OK", "response": { "Messages": ["XXXXX-XXXXX-AAAAA"] }}v2 Notify retorna:
{ "result": { "message_code": "XXXXX-XXXXX-AAAAA", "unknown_identifiers": [] }}Respostas diferentes de 200 seguem o envelope de erro padrão do gRPC-Gateway ({ "code": ..., "message": ..., "details": [...] }) em vez do par status_code / status_message da v1.