Inbound
Receba e-mails no seu app.
Cada mensagem que chega a um endereço seu vira um evento JSON no seu webhook, com remetente, assunto e anexos. Leia o texto, o HTML e os arquivos pela API, sem montar um servidor de e-mail.
No plano Grátis, receba num endereço em in.postal.so
{
"type": "email.received",
"data": {
"email_id": "019a1c00-3e4f-7a5b-…",
"from": "Bruno <[email protected]>",
"to": ["[email protected]"],
"subject": "Nota fiscal do pedido #10475",
"attachments": [{
"filename": "nota-fiscal-10475.pdf",
"content_type": "application/pdf",
"size": 48213
}]
}
}E-mail como interface
O e-mail vira uma entrada do seu sistema
Quem escreve usa o e-mail de sempre. O seu app recebe cada mensagem como dados e decide o que fazer: abrir um chamado, guardar um anexo, responder.
Como funciona
Configure em três passos
app.post('/webhooks/postal', express.raw({ type: 'application/json' }), async (req, res) => {
const event = verifyWebhook(req.body, req.headers, process.env.POSTAL_WEBHOOK_SECRET);
if (event.type === 'email.received') {
await fila.adicionar(event.data.email_id); // processe fora da requisição
}
res.sendStatus(200);
});Exemplos de código
Do aviso ao conteúdo, em poucas linhas
Confira a assinatura com o SDK oficial, busque a mensagem completa e baixe os anexos.
Webhook em Node.js
Com o pacote postal-so, verifyWebhook confere a assinatura e devolve o evento. O corpo precisa chegar cru, sem passar pelo parser de JSON.
- Recusa avisos com mais de 5 minutos de diferença
- A mensagem completa vem de GET /emails/receiving/{id}
- Responda 2xx em até 15 segundos
import express from 'express';
import { verifyWebhook } from 'postal-so';
const app = express();
const api = { Authorization: `Bearer ${process.env.POSTAL_API_KEY}` };
// O corpo precisa chegar cru para a assinatura bater
app.post('/webhooks/postal', express.raw({ type: 'application/json' }), async (req, res) => {
let event;
try {
event = verifyWebhook(req.body, req.headers, process.env.POSTAL_WEBHOOK_SECRET);
} catch {
return res.sendStatus(400);
}
if (event.type === 'email.received') {
const { email_id, from, subject } = event.data;
const email = await fetch(`https://api.postal.so/emails/receiving/${email_id}`, { headers: api })
.then((response) => response.json());
// email.text, email.html e email.attachments[].download_url
await abrirChamado({ from, subject, texto: email.text, anexos: email.attachments });
}
res.sendStatus(200);
});Webhook em PHP
Com o pacote postal-so/postal-php, Webhook::verify confere a assinatura e devolve o evento como array. Depois, o conteúdo e os anexos vêm da API.
- Funciona em PHP puro e no Laravel
- Cada anexo tem um link de download assinado
- O nome do arquivo pode vir vazio: use o id como reserva
use Postal\Exceptions\WebhookVerificationException;
use Postal\Webhook;
try {
$event = Webhook::verify(file_get_contents('php://input'), getallheaders(), getenv('POSTAL_WEBHOOK_SECRET'));
} catch (WebhookVerificationException $e) {
http_response_code(400);
exit;
}
if ($event['type'] === 'email.received') {
$id = $event['data']['email_id'];
$api = stream_context_create(['http' => ['header' => 'Authorization: Bearer ' . getenv('POSTAL_API_KEY')]]);
$email = json_decode(file_get_contents("https://api.postal.so/emails/receiving/{$id}", false, $api), true);
// $email['text'], $email['html'] e os anexos, com o link de download
foreach ($email['attachments'] as $anexo) {
$nome = basename($anexo['filename'] ?? $anexo['id']);
file_put_contents("/var/anexos/{$nome}", file_get_contents($anexo['download_url']));
}
}
http_response_code(200);Pela linha de comando
Para testar ou para buscar mensagens sem webhook: a mensagem completa, um anexo e o original, com todos os cabeçalhos.
- Exige uma chave de API de acesso total
- O link do anexo vale 1 hora; busque a mensagem de novo para outro
- Liste com filtros: inbox_id, unread e search
# A mensagem completa: texto, HTML, cabeçalhos e anexos
curl https://api.postal.so/emails/receiving/019a1c00-3e4f-7a5b-9c6d-7e8f9a0b1c2d \
-H "Authorization: Bearer $POSTAL_API_KEY"
# Um anexo: o download_url é assinado e vale 1 hora (não precisa da chave)
curl -o nota-fiscal-10475.pdf "$DOWNLOAD_URL"
# A mensagem original, como chegou ao servidor
curl https://api.postal.so/emails/receiving/019a1c00-3e4f-7a5b-9c6d-7e8f9a0b1c2d/raw \
-H "Authorization: Bearer $POSTAL_API_KEY"Formato
O que chega e o que você busca
O webhook traz o resumo. A API traz o conteúdo completo, com os links dos anexos.
{
"type": "email.received",
"created_at": "2026-11-04T12:41:09.880Z",
"data": {
"email_id": "019a1c00-3e4f-7a5b-9c6d-7e8f9a0b1c2d",
"inbox_id": "0199f5c1-0a1b-7c2d-8e3f-4a5b6c7d8e9f",
"thread_id": "019a1c00-5a10-7d11-8e22-0f1a2b3c4d5e",
"created_at": "2026-11-04T12:41:09.000Z",
"from": "Bruno <[email protected]>",
"to": ["[email protected]"],
"cc": [],
"subject": "Nota fiscal do pedido #10475",
"message_id": "[email protected]",
"attachments": [
{
"id": "019a1c00-3e50-7b6c-8d7e-9f0a1b2c3d4e",
"filename": "nota-fiscal-10475.pdf",
"content_type": "application/pdf",
"size": 48213
}
]
}
}{
"object": "received_email",
"id": "019a1c00-3e4f-7a5b-9c6d-7e8f9a0b1c2d",
"inbox_id": "0199f5c1-0a1b-7c2d-8e3f-4a5b6c7d8e9f",
"from": "Bruno <[email protected]>",
"to": ["[email protected]"],
"subject": "Nota fiscal do pedido #10475",
"size": 66103,
"otp_token": null,
"text": "Pode reenviar a nota fiscal? Segue o pedido.",
"html": "<p>Pode reenviar a nota fiscal? Segue o pedido.</p>",
"headers": { "date": ["Wed, 4 Nov 2026 09:41:07 -0300"] },
"attachments": [
{
"filename": "nota-fiscal-10475.pdf",
"content_type": "application/pdf",
"size": 48213,
"download_url": "https://api.postal.so/received-attachments/…"
}
]
}- thread_id junta as respostas da mesma conversa, pelos cabeçalhos In-Reply-To e References
- otp_token traz o código e a origem quando o e-mail tem um cabeçalho OTP-Token válido; ele não vai no webhook
- O original, como chegou ao servidor, sai em GET /emails/receiving/{id}/raw
Casos de uso
O que dá para construir
Casos que funcionam hoje com o webhook, a API de recebidos e a API de envio.
Agente de IA com e-mail
O agente lê cada mensagem pelo webhook e pela API e responde com POST /emails, passando In-Reply-To e References para a resposta cair na mesma conversa.
Suporte e chamados
Cada e-mail para suporte@ abre ou atualiza um chamado no seu sistema. O thread_id agrupa as respostas da mesma conversa.
Responder por e-mail
Com um catch-all, cada pedido ou comentário ganha um endereço próprio, como [email protected]. A resposta chega com esse endereço em to.
Registro no CRM
Copie ou encaminhe as conversas com clientes para um endereço da Postal e registre cada mensagem no histórico do contato, pelo remetente.
Leitura de anexos
Notas fiscais, currículos e planilhas chegam com nome, tipo e tamanho. O seu código baixa o arquivo por um link assinado e processa.
Testes com códigos de acesso
Nos testes automatizados, o e-mail de login chega a uma inbox de teste e a API devolve o código do cabeçalho OTP-Token, pronto para digitar.
Segurança
Seguro de ponta a ponta
O que a Postal faz para que só chegue ao seu sistema o que veio dela.
Aviso assinado
Cada POST leva webhook-id, webhook-timestamp e webhook-signature (HMAC-SHA256, padrão Standard Webhooks). Os SDKs conferem e recusam avisos com mais de 5 minutos.
Só entra o que tem destino
O servidor de entrada só aceita mensagens para endereços que têm inbox; as outras são recusadas na hora, sem devoluções depois. Mensagens acima de 25 MB também.
Conteúdo atrás da sua chave
O webhook leva só o resumo. Texto, HTML, anexos e o original pedem uma chave de API de acesso total, e os links dos anexos expiram em 1 hora.
Comparação
Inbound ou Inboxes?
É a mesma inbox, usada de dois jeitos. Dá para usar os dois ao mesmo tempo.
| Inbound | Inboxes | |
|---|---|---|
| Quem trabalha | O seu código | As pessoas do time, no painel |
| Como chega | Webhook email.received e API | Conversas no painel, com pastas, etiquetas e responsável |
| Responder | Pelo seu sistema, com POST /emails | Na conversa, pelo painel ou pela API |
| Endereços | Exato, catch-all ou em in.postal.so | Os mesmos |
| Para quê | Processar o que chega: chamados, anexos, respostas, testes | Atender clientes e organizar a caixa do time |
Precisa que alguém do time leia e responda? Veja as Inboxes.
Escopo
Escopo e limites
O que vale hoje, sem letras miúdas.
| Item | Como funciona |
|---|---|
| Planos | No plano Grátis, até 3 inboxes com endereço em in.postal.so. Endereços no seu domínio, inclusive catch-all, são dos planos pagos. Veja os planos e preços. |
| Tamanho | Até 25 MB por mensagem, com os anexos. Acima disso, o servidor recusa na entrega. |
| Endereços | Só entram mensagens para endereços que têm inbox. Um e-mail para outro endereço do domínio é recusado, a não ser que exista um catch-all. |
| Ritmo | Cada servidor remetente entrega até 60 mensagens por minuto; acima disso, ele recebe um aviso temporário e tenta de novo. |
| Webhook | Responda 2xx em até 15 segundos. Sem isso, a Postal tenta de novo até 8 vezes, em cerca de 27 horas. |
| Guarda | Mensagens, anexos e o original ficam pelo prazo de retenção do plano, 30 dias por padrão, e depois são apagados. Guarde no seu sistema o que precisar manter. |
| Envios | Receber não usa a cota de envios. Respostas e encaminhamentos saem como envios normais, de um domínio verificado. |
| O que não faz | A Postal não filtra spam nem vírus e não registra SPF, DKIM ou DMARC das mensagens recebidas. O original, com todos os cabeçalhos, fica disponível para o seu código conferir. |
Perguntas frequentes
Preciso de domínio próprio?
Não para começar. A Postal gera um endereço em in.postal.so, que recebe na hora, inclusive no plano Grátis. Para receber em endereços do seu domínio, inclusive com catch-all, use um plano pago, ative o recebimento no domínio e aponte o MX para mx.postal.so.
Como sei quando chega um e-mail?
Cadastre um webhook com o evento Recebido (email.received): a Postal envia um POST assinado assim que guarda a mensagem. Se preferir consultar, liste as mensagens com GET /emails/receiving, filtrando por inbox ou só as não lidas.
Posso responder pela API?
Pode. Envie a resposta com POST /emails, de um domínio verificado, com os cabeçalhos In-Reply-To e References apontando para o message_id recebido, para ela cair na mesma conversa. Numa inbox de um domínio seu verificado, também dá para responder na própria conversa, pela API das inboxes.
Como acesso os anexos?
O webhook lista os anexos com nome, tipo e tamanho. GET /emails/receiving/{id} devolve cada um com download_url, um link assinado que vale 1 hora e não precisa da chave. A mensagem original sai em GET /emails/receiving/{id}/raw.
Que verificações de segurança são feitas?
Cada aviso do webhook é assinado, e o servidor de entrada só aceita mensagens de até 25 MB para endereços que têm inbox. A Postal não filtra spam ou vírus e não registra SPF, DKIM ou DMARC das mensagens recebidas: se o seu fluxo depende disso, confira no seu código a partir da mensagem original.
Qual a diferença entre Inbound e Inboxes?
É a mesma inbox, usada de dois jeitos. No Inbound, o seu código processa cada mensagem pelo webhook e pela API. Nas Inboxes, o time lê e responde pelo painel, com conversas, etiquetas e responsável.
Comece a receber e-mails no seu app
Crie a sua conta grátis e um endereço em in.postal.so em poucos minutos.