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.
Canal e-mail
Seção intitulada “Canal e-mail”| 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 |
Canal SMS
Seção intitulada “Canal SMS”| Evento | Quando acontece |
|---|---|
msg_deliverability_yes_delivery |
o SMS foi aceito pela operadora |
msg_deliverability_not_accepted |
o SMS não foi aceito |
Todo evento da tela é enviado
Seção intitulada “Todo evento da tela é enviado”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.
Os corpos
Seção intitulada “Os corpos”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.
Mensagem processada — entrega, falha e descarte
Seção intitulada “Mensagem processada — entrega, falha e descarte”{ "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, "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.
Aceite pela API
Seção intitulada “Aceite pela API”{ "event": "msg_deliverability_yes_queue", "about": { "status": "msg:yes:queue" }, "param": { "message_tracking_code": "<o seu código de rastreio>", "http_request_params": { "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.
Engajamento — abertura e clique
Seção intitulada “Engajamento — abertura e clique”{ "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, "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.
Canal SMS
Seção intitulada “Canal SMS”{ "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 bloco param.details
Seção intitulada “O bloco param.details”É 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 |
message
Seção intitulada “message”| 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 |
delivery
Seção intitulada “delivery”| 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 |
engagement
Seção intitulada “engagement”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 |
As etiquetas
Seção intitulada “As etiquetas”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.
O formato não muda, e você não fica para trás
Seção intitulada “O formato não muda, e você não fica para trás”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 |
