Pular para o conteúdo

Os eventos de webhook e seus corpos

Cada evento marcado na tela do endpoint gera um POST para o seu endereço. Esta página lista os eventos de cada canal e o corpo que chega em cada um.

O nome do evento vem no campo event do corpo e também no cabeçalho X-iPORTO-Event.

Evento Como aparece na tela Quando acontece
msg_deliverability_yes_queue Mensagem recebida a mensagem foi aceita — somente no envio pela API; o envio por SMTP não gera este evento
msg_deliverability_yes_delivery Mensagem entregue ao destinatário a mensagem foi entregue ao servidor do destinatário
msg_deliverability_not_delivery_soft_bounce Falha temporária na entrega recusa temporária do provedor; a entrega ainda pode acontecer
msg_deliverability_not_delivery_hard_bounce Falha permanente na entrega recusa definitiva, normalmente endereço inexistente
msg_deliverability_not_accepted Mensagem rejeitada (total ou parcial) a mensagem foi descartada por filtro do destino
msg_engagement_open E-mail foi aberto pelo destinatário o destinatário abriu a mensagem
msg_engagement_click Link do e-mail foi clicado o destinatário clicou em um link
msg_engagement_compliance_spam E-mail foi marcado como spam o destinatário marcou a mensagem como spam e o provedor nos avisou
Evento Quando acontece
msg_deliverability_yes_delivery o SMS foi aceito pela operadora
msg_deliverability_not_accepted o SMS não foi aceito

Não há, hoje, nenhuma caixa que você possa marcar e que não gere envio. Tudo o que a tela oferece chega ao seu endereço.

Se você integrou o SMS antes de outubro de 2026, a tela antiga oferecia quatro caixas que nunca enviaram nada — resposta, descadastro, reclamação de spam e o aceite pela operadora. Elas saíram. Se o seu sistema esperava por algum desses eventos, ele nunca os recebeu, e não é defeito da sua integração.

A Prospecção não tem eventos próprios: as mensagens dela saem por e-mail e geram os eventos do canal e-mail, listados acima. Para separá-las das transacionais, olhe param.tags — elas chegam com application_prospect_email, prospect e approach.

São três formas, pela origem do evento. Os campos não listados aqui podem aparecer e não devem ser usados: o que esta página descreve é o que tem contrato.

Em todas as formas, param traz também o details — o registro inteiro da mensagem, com assunto, remetente, destinatários, desfecho da entrega e o motivo da falha. Ele está descrito em O bloco param.details e aparece inteiro nos dois primeiros exemplos abaixo.

{
"email": [
],
"event": "msg_deliverability_yes_delivery",
"about": {
"status": "msg:yes:finished",
"sum_hard_bounce": 0,
"sum_soft_bounce": 0,
"sum_discarded": 0
},
"param": {
"message_id": "1s9KpQ-0004Zx-2H",
"message_id_relay": "1s9KpR-0007Bd-9K",
"message_tracking_code": "<o seu código de rastreio>",
"tags": [
"transacional",
"pedido-1234"
],
"details": {
"object": "message",
"event": {
"type": "email.delivered",
"occurred_at": "2026-10-15T09:12:04-03:00",
"emitted_at": "2026-10-15T09:14:31-03:00",
"id": "01M4YQV7RC6VKAVJM5E6B4TCY8"
},
"channel": "email",
"message": {
"tracking_code": "<o seu código de rastreio>",
"message_id": "1s9KpQ-0004Zx-2H",
"message_id_relay": "1s9KpR-0007Bd-9K",
"subject": "Seu pedido 1234",
"body": null,
"from": "[email protected]",
"from_visible": "Loja <[email protected]>",
"recipients": [
],
"tags": [
"transacional",
"pedido-1234"
],
"smtp_domain_id": 4180,
"smtp_account_id": 9271,
"plan_type": "smtp",
"sent_at": "2026-10-15T09:11:58-03:00",
"id": "<identificador do registro>"
},
"delivery": {
"status": "msg:yes:finished",
"hard_bounce": 0,
"soft_bounce": 0,
"discarded": 0,
"trap": 0,
"bounce": null
},
"engagement": null
},
"id": "<identificador do registro>"
}
}

about.status e os contadores dizem o desfecho: sum_hard_bounce em 1 na falha permanente, sum_soft_bounce na temporária, sum_discarded no descarte por filtro.

{
"email": "[email protected]",
"event": "msg_deliverability_yes_queue",
"about": {
"status": "msg:yes:queue"
},
"param": {
"message_tracking_code": "<o seu código de rastreio>",
"http_request_params": {
"address_to": "[email protected]",
"subject": "Seu pedido 1234",
"html_body": "<html>corpo</html>"
},
"id": "<identificador do registro>"
}
}

O param.details vem aqui também — foi omitido acima para não repetir o bloco. Neste evento a mensagem acabou de ser aceita e ainda não saiu, então details.message.message_id, subject, from, tags e sent_at vêm vazios: o que você enviou está em param.http_request_params, no mesmo corpo.

{
"email": null,
"event": "msg_engagement_click",
"about": {
"status": "msg:yes:finished",
"sum_hard_bounce": null,
"sum_soft_bounce": null,
"sum_discarded": null
},
"param": {
"message_id": "1s9KpQ-0004Zx-2H",
"message_id_relay": "1s9KpR-0007Bd-9K",
"message_tracking_code": "<o seu código de rastreio>",
"tags": [
"transacional",
"pedido-1234"
],
"link": "https://cliente.com.br/pedido/1234",
"details": {
"object": "message",
"event": {
"type": "email.clicked",
"occurred_at": "2026-10-15T14:02:17-03:00",
"emitted_at": "2026-10-15T14:02:17-03:00",
"id": "01M4Z8F3QW1ABCDEF2GHJK3MNP"
},
"channel": "email",
"message": {
"tracking_code": "<o seu código de rastreio>",
"message_id": "1s9KpQ-0004Zx-2H",
"message_id_relay": "1s9KpR-0007Bd-9K",
"subject": "Seu pedido 1234",
"body": null,
"from": "[email protected]",
"from_visible": "Loja <[email protected]>",
"recipients": [
],
"tags": [
"transacional",
"pedido-1234"
],
"smtp_domain_id": 4180,
"smtp_account_id": 9271,
"plan_type": "smtp",
"sent_at": "2026-10-15T09:11:58-03:00",
"id": "<identificador do registro>"
},
"delivery": {
"status": "msg:yes:finished",
"hard_bounce": 0,
"soft_bounce": 0,
"discarded": 0,
"trap": 0,
"bounce": null
},
"engagement": {
"link": "https://cliente.com.br/pedido/1234",
"ip": "203.0.113.7",
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)",
"device": "desktop",
"platform": "macOS",
"referer": null
}
},
"id": "<identificador do registro>"
}
}

No clique, param.link traz o endereço clicado. Na abertura, o campo não existe.

É só aqui que details.engagement deixa de ser nulo: ele descreve o acesso do destinatário, e nos eventos de entrega ninguém acessou nada.

{
"phone": "5511999998888",
"event": "msg_deliverability_yes_delivery",
"about": "",
"param": {
"id": "<identificador do registro>"
}
}

O param.details vem aqui também, com channel: "sms". O que o canal não tem fica nulo: subject, message_id_relay, tags e o bloco engagement. Em from e to vão os telefones.

É o registro inteiro da mensagem, o mesmo que você vê no painel — assunto, remetente, destinatários, desfecho da entrega e, quando houve falha, a resposta do servidor de destino. Ele existe para você não precisar consultar a API depois de cada evento.

Está em todo evento, nos dois canais, nas três formas de corpo.

Bloco O que traz
object sempre "message"
event o fato: tipo, quando ocorreu, quando saiu, e o identificador
channel email ou sms
message a mensagem: assunto, remetente, destinatários, etiquetas
delivery o desfecho da entrega, com o motivo da falha
engagement o acesso do destinatário — nulo fora de abertura e clique
Campo O que é
type o nome do evento no formato novo — email.delivered, email.clicked, sms.accepted
occurred_at quando o fato aconteceu
emitted_at quando nós o emitimos
id identificador do fato; é o mesmo valor do cabeçalho X-iPORTO-Event-Id
Campo O que é
tracking_code o localizador da mensagem — o mesmo de param.message_tracking_code
message_id identificador do servidor de envio
message_id_relay identificador do relay
subject o assunto
body o texto da mensagem — só em SMS recebido; em e-mail é sempre nulo
from o endereço remetente
from_visible o remetente como o destinatário o vê, com nome
to o destinatário principal
recipients todos os destinatários, como lista
tags as suas etiquetas, as mesmas de param.tags
smtp_domain_id o domínio de envio
smtp_account_id a conta de autenticação usada
plan_type de onde a mensagem saiu — smtp, email_marketing, marketing ou prospect
sent_at quando a mensagem saiu
id identificador do registro de histórico; o mesmo de param.id
Campo O que é
status o status final, na forma msg:yes:finished com sufixo quando houve falha
hard_bounce quantos destinatários deram falha permanente
soft_bounce quantos deram falha temporária
discarded quantos o destino descartou ou filtrou
trap quantos caíram em armadilha de spam
bounce o motivo, quando houve

delivery.bounce é o campo que mais muda o seu atendimento: ele diz qual foi a resposta do servidor de destino, e não só que houve uma falha.

{
"kind": "hard",
"code": "550",
"answer": "550 5.1.1 The email account does not exist",
"domain": "exemplo.com.br"
}
Campo O que é
kind hard, soft, discarded ou trap
code o código SMTP extraído da resposta
answer a resposta do servidor de destino, como ela veio
domain o domínio que respondeu

Só em abertura e clique. Nos outros eventos é null.

Campo O que é
link o endereço clicado; nulo na abertura
ip o IP do acesso
user_agent o User-Agent recebido
device o tipo de dispositivo
platform o sistema operacional
referer a origem do clique, quando o navegador a informa

O campo param.tags traz as etiquetas que você enviou na requisição de envio, no campo tags. Elas viajam com a mensagem e voltam em todo evento dela — é o caminho para carregar a sua própria classificação (campanha, tipo de mensagem, identificador de pedido) sem depender de uma consulta do seu lado.

A iPORTO também acrescenta as suas. Mensagem enviada pela Prospecção chega com application_prospect_email, prospect e approach, e é assim que você separa o que é prospecção do que é transacional sem precisar de outro endereço de webhook.

Nenhum campo descrito aqui vai desaparecer, mudar de nome ou mudar de posição. É o compromisso desta versão do formato, e ele vale sem prazo: não há data de fim de vida.

Um formato novo, quando houver, será opcional e escolhido por endereço — e você não precisa fazer nada para continuar funcionando.

E o formato atual continua recebendo melhoria de dado:

campo novo dentro de param.details você recebe, sem mexer em nada
tipo de evento novo só no formato novo — o atual nomeia os eventos pelos nomes desta página, e um evento novo não tem nome aqui
mudança no significado de um evento que já existe nunca nesta versão: seria quebrar quem já conta em cima dele