Respostas e webhooks
Tudo que os destinatários enviam de volta — votos de enquete, envios de formulário, avaliações, giros — é coletado por projeto. Isso retorna para você de duas formas: uma visualização de respostas por destinatário no painel, e um webhook opcional que envia cada interação para o seu próprio endpoint no instante em que ela chega.
Respostas por destinatário no painel
Abra Painel → seu e-mail → Respostas. Cada interação que o e-mail coletou é agrupada por destinatário e unida à fonte de dados do projeto. Cada grupo mostra quem respondeu — o endereço de e-mail e os outros campos da linha dele — junto com o que fez: qual bloco, qual ação, os valores enviados e quando.
A atribuição funciona por meio dos mesmos tokens assinados que protegem os links de visualização ao vivo. Quando um e-mail é personalizado a partir de uma fonte de dados, os links de cada destinatário carregam um token vinculado à linha dele, e as interações que chegam com um token válido são atribuídas a essa linha. Interações que chegam sem token (por exemplo, um voto de enquete de um e-mail enviado sem personalização) ainda contam — elas são listadas em um grupo separado de Anônimos.
A lista de eventos brutos é paginada (mais recentes primeiro): depois de carregar a página mais recente, uma ação Carregar mais busca eventos mais antigos. Tudo abaixo — resumos, histogramas, o funil e a tendência — não é afetado por essa paginação; é pré-computado e sempre cobre o histórico completo do projeto.
Pedidos, fulfillment e reembolsos
Qualquer projeto com um bloco de produto recebe uma tabela de Pedidos em sua página de Respostas — uma linha por checkout, com comprador, valor, status e horário do pedido.
- No instante em que um pagamento é aprovado, o comprador recebe um e-mail automaticamente: o conteúdo de entrega de um produto digital, ou uma confirmação de que um pedido físico está a caminho do fulfillment.
- Para pedidos físicos, clique em Marcar como atendido depois de enviá-lo — o MailInApp não cuida do envio em si, mas envia ao comprador um aviso de envio no instante em que você aciona o botão.
- Clique em Reembolsar em qualquer pedido pago para reverter a cobrança por meio da sua conta Stripe conectada; o comprador recebe um e-mail de confirmação do reembolso. O mesmo e-mail é enviado automaticamente se uma venda for concluída exatamente quando a última unidade se esgota — o MailInApp reembolsa o comprador em vez de vender silenciosamente além do estoque.
- Contatar comprador abre um ticket de suporte pré-preenchido com o contexto daquele pedido — a forma mais rápida de perguntar algo diretamente a um comprador.
Métrica principal guiada pelo propósito
Se um projeto tiver um propósito definido (pesquisa, promoção, newsletter ou evento), a página de Respostas lidera com o único número que esse propósito mais valoriza: taxa de resposta para pesquisas, destinatários engajados para promoções, e aberturas rastreadas para newsletters e eventos. Projetos transacionais e projetos sem propósito definido vão direto para o funil e os resumos abaixo. Altere ou limpe o propósito quando quiser no menu ao lado do título da página; isso só afeta qual número é destacado, nunca o que é registrado.
Resumos de CSAT, CES e NPS
Todo bloco de avaliação recebe um resumo acima da lista de destinatários: contagem de respostas, média, e um histograma (a distribuição por trás da média — uma média de 4,1 esconde se é tudo notas 4 ou uma mistura de 5 e 1). Blocos no estilo NPS mostram contagens de promotores/neutros/detratores e a pontuação de −100…100 em vez de uma média simples. Uma divisão de distribuição de respostas faz o mesmo para blocos de enquete, por opção.
Um funil de engajamento (Enviado → Aberto (aprox.) → Respondido) fica acima dos resumos. Um gráfico de tendência de respostas por bloco (em blocos de dia ou semana) mostra a média ao longo do tempo — o valor de uma pesquisa recorrente está na linha de tendência, não em um único instantâneo. Ele só é renderizado quando um bloco tem pelo menos dois blocos de dados.
Resumos de perguntas da pesquisa
Todo bloco de formulário recebe um resumo por pergunta, da mesma forma que os blocos de avaliação e enquete. Perguntas de múltipla escolha, caixas de seleção, escala linear e avaliação por estrelas recebem um gráfico de barras com a contagem de opções; perguntas de texto livre (texto curto, texto longo, e-mail, número, telefone, data) recebem uma contagem de respostas mais algumas respostas de amostra. Pesquisas de múltiplas páginas são resumidas da mesma forma que as de página única — um envio só conta quando todas as páginas foram concluídas, então uma pesquisa abandonada nunca aparece como uma resposta parcial.
Esses resultados de enquete, avaliação e pergunta de pesquisa não são um beco sem saída — qualquer um deles pode ser plotado diretamente dentro de um e-mail futuro vinculando um bloco de gráfico a "resposta de campanha", sem necessidade de reentrada manual. Veja Vinculando gráficos a dados reais.
Lição de casa e diário de notas
Todo bloco de tarefa com pelo menos uma conclusão ou envio recebe um cartão de estatísticas (conclusões, conclusões atrasadas, envios) acima de uma tabela de Diário de notas. A tabela tem uma linha por aluno e uma coluna por tarefa, mostrando "Concluído" ou a resposta enviada em verde, ou em vermelho se ela chegou depois da data de entrega do bloco. Tarefas sem respostas ainda não sobrecarregam a tabela. Como todo outro resumo, ele é pré-computado e cobre o histórico completo de um projeto, e ambas as exportações de CSV incluem uma coluna de tarefa por bloco.
Mapa de calor de cliques
Abaixo dos resumos, um Mapa de calor de cliques classifica todo bloco portador de link simples — botões, imagens com link, ícones sociais — por contagem de cliques, com o comprimento e a intensidade da barra proporcionais ao volume relativo. Veja como os cliques são rastreados para saber o que conta e o que não conta.
Funil de profundidade de rolagem
Um funil de profundidade de rolagem mostra qual fração dos visitantes da visualização ao vivo alcançou cada marco de 25/50/75/100% da página, para que você saiba se as pessoas estão desistindo no início ou lendo até o fim. Ele só reflete visitas à visualização ao vivo hospedada, não ao e-mail enviado em si — veja Profundidade de rolagem para entender por quê.
Teste A/B e vencedores automáticos
Enviar com mais de uma variante (veja Enviar) adiciona uma comparação de variantes à página de Respostas: taxa de abertura, taxa de clique e taxa de resposta lado a lado para cada variante, com o líder atual sinalizado pela métrica que o teste usou. Cada destinatário recebe uma variante de forma determinística com base no próprio endereço de e-mail, então reenvios e novas tentativas nunca embaralham quem viu qual variante. Os resultados são cumulativos para o projeto, cobrindo todo envio A/B que ele já executou, não apenas o mais recente.
Uma variante não se limita à redação da linha de assunto; ela também pode trocar a identidade de remetente, ou todo o conteúdo do projeto. As próprias respostas de enquete/quiz/RSVP e aberturas de uma variante que varia conteúdo são rastreadas na própria página de Respostas daquele projeto, em vez de entrarem nessa comparação, já que a validação de interação vincula um envio ao projeto exato a partir do qual ele foi renderizado. O painel de comparação linka para lá em vez de mostrar um zero enganoso.
Escolher um vencedor automaticamente transforma um teste A/B manual em um processo autônomo. Escolha uma fração de teste (por exemplo, enviar para 20% da lista dividida entre variantes), quanto tempo esperar antes de decidir, e qual métrica usar na decisão: abertura, clique, resposta dentro do e-mail, ou receita. Resposta dentro do e-mail (conclusão de enquete/quiz/RSVP) é o padrão recomendado, já que não é afetada pela Proteção de Privacidade de E-mail da Apple da forma como o rastreamento de aberturas é.
Quando a espera termina, o MailInApp escolhe a variante com a melhor taxa por destinatário. Isso nunca é um total bruto, então uma variante que simplesmente foi enviada para mais pessoas no teste não pode parecer vencedora só pelo volume. O vencedor é enviado para todos que ficaram retidos do teste inicial. Se o resultado for um empate ou a amostra for pequena demais, o MailInApp recorre à variante 1 e a identifica claramente como tal, em vez de declarar um falso vencedor. O aviso de status na página de Respostas mostra exatamente em que estado um teste está: ainda decidindo, decidido, empatado, ou amostra pequena demais.
Otimização de horário de envio
Disponível a partir do plano Pro. Em vez de todo mundo em um envio saindo de uma vez, Enviar no melhor horário de cada destinatário analisa o próprio histórico de abertura de cada contato — em qual hora do dia, em UTC, ele de fato mais abriu e-mails seus. O envio da mensagem dele é retido até essa hora. Qualquer pessoa sem histórico de abertura suficiente para um sinal confiável passa direto para um envio imediato comum.
Isso se aplica da mesma forma a um envio manual, a um agendamento recorrente e à própria etapa de envio de uma jornada; um agendamento ainda envia para todos sem sinal no próprio horário configurado, igual ao comportamento anterior à otimização. Não pode, atualmente, ser combinado com um teste de vencedor automático no mesmo envio, já que um destinatário postergado não seria contado a tempo de um vencedor ser decidido.
Detalhando por um campo
Use Detalhar por para agrupar os mesmos resumos por qualquer campo da sua fonte de dados — CSAT médio por agente, NPS por plano, e assim por diante. Destinatários cuja linha foi excluída ou reduzida desde o envio são agrupados em (desconhecido); se um campo de texto livre gerar mais de 20 valores distintos, os grupos menores se dobram em um grupo final de Outros, para que a visualização não exploda.
Exportação de CSV
Baixar CSV na página de Respostas exporta um arquivo amplo, com uma linha por destinatário: todo campo da fonte de dados, horário da primeira abertura, e uma coluna por bloco interativo (com o cabeçalho da respectiva pergunta). Respostas de acompanhamento recebem sua própria coluna <pergunta> — follow-up. Uma segunda exportação de eventos brutos fornece uma linha por evento (destinatário, bloco, ação, valor, data/hora) para analistas que preferem o formato longo.
Ciclo de vida da pesquisa
Um projeto pode ter uma data de encerramento e/ou um limite de respostas (maxResponses). Assim que qualquer um dos dois é atingido, novos eventos de interação são rejeitados — a visualização ao vivo mostra um aviso de encerramento em vez dos blocos interativos, embora o conteúdo estático continue sendo exibido — e a página de Respostas mostra se a pesquisa está atualmente encerrada. Nada é filtrado retroativamente: as respostas já registradas permanecem nos seus dados.
Alertas de nota baixa no app
Além da flag lowScore do webhook (abaixo), um projeto pode listar até alguns poucos endereços de e-mail para notificar diretamente — sem precisar de uma etapa no Zapier/Make. Sempre que uma resposta de avaliação cruza o limite configurado do bloco, o MailInApp envia um e-mail para esses endereços (através das suas próprias configurações de SMTP) com a pergunta, a nota, a identidade do destinatário quando conhecida, e um link direto para a página de Respostas. Se nenhum relay de SMTP estiver configurado, o alerta é ignorado silenciosamente — o webhook ainda dispara. Os alertas são limitados por projeto por hora, para que uma explosão de notas baixas não sobrecarregue seu relay.
Reconstruindo agregados
Resumos, o funil e a tendência são servidos a partir de um agregado pré-computado por projeto, atualizado conforme os eventos chegam — para que permaneçam rápidos independentemente do histórico que um projeto acumulou. Se um projeto mostrar totais inesperadamente baixos ou zerados, é provável que tenha coletado respostas antes de esse agregado existir para ele; clique em Reconstruir agregados em sua página de Respostas uma vez para reprocessar todo o histórico de eventos no agregado. Projetos novos nunca precisam disso.
Webhooks
Se preferir que os dados cheguem aos seus próprios sistemas — um CRM, uma planilha, uma ferramenta de automação — configure um webhook na mesma página de Respostas: informe uma URL HTTPS e clique em Ativar.
Duas coisas acontecem:
- Você vê um segredo de assinatura (
whsec_…) — copie-o imediatamente, ele é exibido apenas uma vez. Ele é armazenado no servidor e mascarado em todo lugar depois disso, como todas as credenciais no MailInApp. - A partir daí, cada interação é enviada via POST para a sua URL como JSON, imediatamente após ser registrada.
Você pode rotacionar o segredo (um novo é gerado e exibido uma vez) ou remover o webhook a qualquer momento.
Payload
{
"type": "interaction.received",
"projectId": "abc123",
"event": {
"campaignId": "abc123",
"blockId": "poll-1",
"blockType": "poll",
"action": "vote",
"value": { "option": "Blue" },
"recipient": "row:3",
"projectId": "abc123",
"receivedAt": 1752480000000
},
"recipient": {
"key": "row:3",
"row": { "email": "[email protected]", "first_name": "Ada" }
},
"lowScore": false
}
event.valueé o próprio dado coletado — a opção de enquete escolhida, os valores dos campos do formulário, a quantidade de estrelas.recipienténullpara interações anônimas. Para as atribuídas,keyé o índice da linha do destinatário na sua fonte de dados ("row:3"= quarta linha).recipient.row— a linha completa de dados do destinatário — é incluído para fontes de dados hospedadas. Para fontes do tipo API, não chamamos seu endpoint em cada interação; faça a junção pelo índice da linha do seu lado.lowScoreétruequando o evento é uma açãorateem um bloco de avaliação cujo valor está em ou abaixo do limite de alerta configurado para esse bloco — o sinal que uma automação no Zapier/Make (ou seu próprio alerta dentro do app) filtra para notificar um gestor de suporte. Ele é omitido inteiramente em eventos que não são de avaliação, ou quando o bloco não tem limite configurado.
Verificando assinaturas
Toda entrega é assinada para que seu endpoint possa confirmar que ela realmente veio do MailInApp. Dois cabeçalhos são enviados:
| Cabeçalho | Conteúdo |
| --- | --- |
| X-MailInApp-Timestamp | Quando a entrega foi assinada, em milissegundos desde a época Unix |
| X-MailInApp-Signature | v1= seguido do HMAC-SHA256(secret, timestamp + "." + rawBody) em hexadecimal |
Calcule a assinatura esperada a partir do corpo bruto da requisição (antes de qualquer análise de JSON) e compare com uma comparação de tempo constante. Rejeitar registros de data/hora antigos bloqueia entregas repetidas (replay):
import { createHmac, timingSafeEqual } from "node:crypto";
function isValidDelivery(headers, rawBody, secret) {
const timestamp = headers["x-mailinapp-timestamp"];
const given = Buffer.from(headers["x-mailinapp-signature"] ?? "");
const expected = Buffer.from(
"v1=" +
createHmac("sha256", secret)
.update(`${timestamp}.${rawBody}`)
.digest("hex"),
);
if (given.length !== expected.length || !timingSafeEqual(given, expected)) {
return false;
}
// Reject deliveries signed more than 5 minutes ago (replay protection).
return Math.abs(Date.now() - Number(timestamp)) < 5 * 60 * 1000;
}
Semântica de entrega
- A primeira tentativa é imediata, depois há novas tentativas automáticas. As entregas expiram após 5 segundos; qualquer coisa que não seja uma resposta
2xx(um tempo esgotado, uma falha de conexão, ou um status de erro) é tratada como falha. O evento é sempre armazenado primeiro no MailInApp, então uma entrega perdida não perde nada — trate o webhook como um sinal em tempo real e a visualização de Respostas como a fonte da verdade. - Novas tentativas automáticas com backoff. Uma entrega com falha é reenviada em intervalos crescentes — aproximadamente 1 minuto, 5 minutos, 30 minutos, 2 horas, depois 6 horas — usando a URL e o segredo atuais do seu webhook, então um segredo rotacionado ou uma URL atualizada são adotados automaticamente. Se todas as tentativas falharem, a entrega para de tentar por conta própria, mas nunca é descartada.
- Reenvio manual. Qualquer entrega que ainda esteja falhando (em nova tentativa ou esgotada) aparece em Entregas com falha na página de Respostas, com o motivo da última falha e um botão Reenviar — útil logo depois que você corrigir o que estava quebrado do seu lado, em vez de esperar a próxima tentativa agendada.
- Nunca no caminho do destinatário. As entregas acontecem depois que a interação do destinatário é confirmada; um endpoint lento ou quebrado não pode atrasar ou falhar o voto ou envio dele.
- Responda rápido. Retorne qualquer
2xxrapidamente e faça o processamento pesado de forma assíncrona.
Aviso sobre confiança: os endpoints de interação são públicos por necessidade (uma caixa de entrada não tem como se autenticar), então eventos anônimos não são autenticados por design. Eventos atribuídos são protegidos por tokens de destinatário assinados. Verifique a assinatura da entrega e trate
event.valuecomo entrada de usuário.