Novedad: campañas, automatizaciones y correos del producto en la misma cuenta. Conoce Postal
Iniciar sesión Crear cuenta

Inbound

Recibe correos en tu app.

Cada mensaje que llega a una dirección tuya se convierte en un evento JSON en tu webhook, con remitente, asunto y adjuntos. Lee el texto, el HTML y los archivos por la API, sin montar un servidor de correo.

En el plan Gratis, recibe en una dirección de in.postal.so

POST firmado a tu webhook
email.received
{
  "type": "email.received",
  "data": {
    "email_id": "019a1c00-3e4f-7a5b-…",
    "from": "Bruno <[email protected]>",
    "to": ["[email protected]"],
    "subject": "Factura del pedido #10475",
    "attachments": [{
      "filename": "nota-fiscal-10475.pdf",
      "content_type": "application/pdf",
      "size": 48213
    }]
  }
}
200Tu sistema confirmó la recepción

El correo como interfaz

El correo se convierte en una entrada de tu sistema

Quien escribe usa el correo de siempre. Tu app recibe cada mensaje como datos y decide qué hacer: abrir un ticket, guardar un adjunto, responder.

Cómo funciona

Configúralo en tres pasos

avisa a tu sistema
webhook.js
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 cola.agregar(event.data.email_id); // procésalo fuera de la solicitud
  }

  res.sendStatus(200);
});

Ejemplos de código

Del aviso al contenido, en pocas líneas

Comprueba la firma con el SDK oficial, obtén el mensaje completo y descarga los adjuntos.

Webhook en Node.js

Con el paquete postal-so, verifyWebhook comprueba la firma y devuelve el evento. El cuerpo debe llegar sin procesar, sin pasar por el parser de JSON.

  • Rechaza avisos con más de 5 minutos de diferencia
  • El mensaje completo viene de GET /emails/receiving/{id}
  • Responde 2xx en hasta 15 segundos
SDK para Node.js
webhook.js
import express from 'express';
import { verifyWebhook } from 'postal-so';

const app = express();
const api = { Authorization: `Bearer ${process.env.POSTAL_API_KEY}` };

// El cuerpo debe llegar sin procesar para que la firma coincida
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 y email.attachments[].download_url
    await abrirTicket({ from, subject, texto: email.text, adjuntos: email.attachments });
  }

  res.sendStatus(200);
});

Webhook en PHP

Con el paquete postal-so/postal-php, Webhook::verify comprueba la firma y devuelve el evento como array. Después, el contenido y los adjuntos vienen de la API.

  • Funciona en PHP puro y en Laravel
  • Cada adjunto tiene un enlace de descarga firmado
  • El nombre del archivo puede venir vacío: usa el id como alternativa
SDK para PHP
webhook.php
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'] y los adjuntos, con el enlace de descarga
    foreach ($email['attachments'] as $adjunto) {
        $nombre = basename($adjunto['filename'] ?? $adjunto['id']);
        file_put_contents("/var/adjuntos/{$nombre}", file_get_contents($adjunto['download_url']));
    }
}

http_response_code(200);

Desde la línea de comandos

Para probar o para obtener mensajes sin webhook: el mensaje completo, un adjunto y el original, con todos los encabezados.

  • Exige una clave de API de acceso total
  • El enlace del adjunto vale 1 hora; vuelve a obtener el mensaje para otro
  • Lista con filtros: inbox_id, unread y search
Referencia de los recibidos
terminal
# El mensaje completo: texto, HTML, encabezados y adjuntos
curl https://api.postal.so/emails/receiving/019a1c00-3e4f-7a5b-9c6d-7e8f9a0b1c2d \
  -H "Authorization: Bearer $POSTAL_API_KEY"

# Un adjunto: el download_url está firmado y vale 1 hora (no necesita la clave)
curl -o nota-fiscal-10475.pdf "$DOWNLOAD_URL"

# El mensaje original, tal como llegó al servidor
curl https://api.postal.so/emails/receiving/019a1c00-3e4f-7a5b-9c6d-7e8f9a0b1c2d/raw \
  -H "Authorization: Bearer $POSTAL_API_KEY"

Formato

Lo que llega y lo que obtienes

El webhook trae el resumen. La API trae el contenido completo, con los enlaces de los adjuntos.

POST a tu webhook
{
  "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": "Factura del pedido #10475",
    "message_id": "[email protected]",
    "attachments": [
      {
        "id": "019a1c00-3e50-7b6c-8d7e-9f0a1b2c3d4e",
        "filename": "nota-fiscal-10475.pdf",
        "content_type": "application/pdf",
        "size": 48213
      }
    ]
  }
}
GET /emails/receiving/{id}
{
  "object": "received_email",
  "id": "019a1c00-3e4f-7a5b-9c6d-7e8f9a0b1c2d",
  "inbox_id": "0199f5c1-0a1b-7c2d-8e3f-4a5b6c7d8e9f",
  "from": "Bruno <[email protected]>",
  "to": ["[email protected]"],
  "subject": "Factura del pedido #10475",
  "size": 66103,
  "otp_token": null,
  "text": "¿Puedes reenviar la factura? Adjunto el pedido.",
  "html": "<p>¿Puedes reenviar la factura? Adjunto el 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 agrupa las respuestas de la misma conversación, por los encabezados In-Reply-To y References
  • otp_token trae el código y el origen cuando el correo tiene un encabezado OTP-Token válido; no va en el webhook
  • El original, tal como llegó al servidor, sale de GET /emails/receiving/{id}/raw

Casos de uso

Lo que puedes construir

Casos que funcionan hoy con el webhook, la API de recibidos y la API de envío.

Agente de IA con correo

El agente lee cada mensaje por el webhook y la API y responde con POST /emails, pasando In-Reply-To y References para que la respuesta quede en la misma conversación.

Soporte y tickets

Cada correo a suporte@ abre o actualiza un ticket en tu sistema. El thread_id agrupa las respuestas de la misma conversación.

Responder por correo

Con un catch-all, cada pedido o comentario tiene su propia dirección, como [email protected]. La respuesta llega con esa dirección en to.

Registro en el CRM

Copia o reenvía las conversaciones con clientes a una dirección de Postal y registra cada mensaje en el historial del contacto, por remitente.

Lectura de adjuntos

Facturas, currículos y hojas de cálculo llegan con nombre, tipo y tamaño. Tu código descarga el archivo por un enlace firmado y lo procesa.

Pruebas con códigos de acceso

En las pruebas automatizadas, el correo de inicio de sesión llega a un buzón de prueba y la API devuelve el código del encabezado OTP-Token, listo para escribir.

Seguridad

Seguro de punta a punta

Lo que hace Postal para que a tu sistema solo llegue lo que vino de ella.

Aviso firmado

Cada POST lleva webhook-id, webhook-timestamp y webhook-signature (HMAC-SHA256, estándar Standard Webhooks). Los SDK lo comprueban y rechazan avisos con más de 5 minutos.

Solo entra lo que tiene destino

El servidor de entrada solo acepta mensajes para direcciones que tienen buzón; los demás se rechazan en el momento, sin rebotes después. Los mensajes de más de 25 MB, también.

Contenido detrás de tu clave

El webhook lleva solo el resumen. El texto, el HTML, los adjuntos y el original piden una clave de API de acceso total, y los enlaces de los adjuntos caducan en 1 hora.

Comparación

¿Inbound o buzones de entrada?

Es el mismo buzón, usado de dos maneras. Puedes usar las dos a la vez.

InboundBuzones de entrada
Quién trabajaTu códigoLas personas del equipo, en el panel
Cómo llegaWebhook email.received y APIConversaciones en el panel, con carpetas, etiquetas y responsable
ResponderDesde tu sistema, con POST /emailsEn la conversación, desde el panel o por la API
DireccionesExacta, catch-all o en in.postal.soLas mismas
Para qué sirveProcesar lo que llega: tickets, adjuntos, respuestas, pruebasAtender a clientes y organizar la bandeja del equipo

¿Necesitas que alguien del equipo lea y responda? Mira los buzones de entrada.

Alcance

Alcance y límites

Lo que vale hoy, sin letra pequeña.

ElementoCómo funciona
PlanesEn el plan Gratis, hasta 3 buzones de entrada con dirección en in.postal.so. Las direcciones en tu dominio, catch-all incluido, son de los planes de pago. Consulta los planes y precios.
TamañoHasta 25 MB por mensaje, con los adjuntos. Por encima, el servidor lo rechaza en la entrega.
DireccionesSolo entran mensajes para direcciones que tienen buzón. Un correo a otra dirección del dominio se rechaza, salvo que exista un catch-all.
RitmoCada servidor remitente entrega hasta 60 mensajes por minuto; por encima, recibe un aviso temporal y vuelve a intentarlo.
WebhookResponde 2xx en hasta 15 segundos. Si no, Postal vuelve a intentarlo hasta 8 veces, en unas 27 horas.
AlmacenamientoLos mensajes, los adjuntos y el original se guardan durante el plazo de retención del plan, 30 días por defecto, y después se borran. Guarda en tu sistema lo que necesites conservar.
EnvíoRecibir no usa la cuota de envíos. Las respuestas y los reenvíos salen como envíos normales, desde un dominio verificado.
Lo que no hacePostal no filtra spam ni virus y no registra SPF, DKIM ni DMARC de los mensajes recibidos. El original, con todos los encabezados, queda disponible para que tu código lo compruebe.

Preguntas frecuentes

¿Necesito un dominio propio?

No para empezar. Postal genera una dirección en in.postal.so que recibe al instante, también en el plan Gratis. Para recibir en direcciones de tu dominio, catch-all incluido, usa un plan de pago, activa la recepción en el dominio y apunta el MX a mx.postal.so.

¿Cómo sé cuándo llega un correo?

Registra un webhook con el evento Recibido (email.received): Postal envía un POST firmado en cuanto guarda el mensaje. Si prefieres consultar, lista los mensajes con GET /emails/receiving, filtrando por buzón o solo los no leídos.

¿Puedo responder por la API?

Sí. Envía la respuesta con POST /emails, desde un dominio verificado, con los encabezados In-Reply-To y References apuntando al message_id recibido, para que quede en la misma conversación. En un buzón de un dominio tuyo verificado, también puedes responder en la propia conversación, por la API de buzones.

¿Cómo accedo a los adjuntos?

El webhook lista los adjuntos con nombre, tipo y tamaño. GET /emails/receiving/{id} devuelve cada uno con download_url, un enlace firmado que vale 1 hora y no necesita la clave. El mensaje original sale de GET /emails/receiving/{id}/raw.

¿Qué comprobaciones de seguridad se hacen?

Cada aviso del webhook va firmado, y el servidor de entrada solo acepta mensajes de hasta 25 MB para direcciones que tienen buzón. Postal no filtra spam ni virus y no registra SPF, DKIM ni DMARC de los mensajes recibidos: si tu flujo depende de eso, compruébalo en tu código a partir del mensaje original.

¿Cuál es la diferencia entre Inbound y los buzones de entrada?

Es el mismo buzón, usado de dos maneras. Con Inbound, tu código procesa cada mensaje por el webhook y la API. Con los buzones de entrada, el equipo lee y responde en el panel, con conversaciones, etiquetas y responsable.

Empieza a recibir correos en tu app

Crea tu cuenta gratis y una dirección en in.postal.so en pocos minutos.