MailLandDocs
Email entrante

Rutas de Entrada

Configure reglas de enrutamiento para dirigir los correos entrantes a almacenamiento, webhooks u otras acciones

Las rutas definen cómo MailLand gestiona los correos entrantes de un dominio. Cada ruta coincide con la parte local del destinatario (la parte de la dirección antes de @) y ejecuta una o más acciones: almacenar, entregar a un webhook, reenviar, rechazar en SMTP o descartar. Las rutas se evalúan en orden de prioridad (el número más bajo primero) y la primera coincidencia gana.

Las rutas solo coinciden con la parte local de la dirección del destinatario. No hay coincidencia por remitente, asunto ni otros encabezados: una ruta no puede filtrar por from o subject.

Tipos de coincidencia

Tipo de coincidenciaDescripción
exactLa parte local coincide exactamente con el patrón
prefixLa parte local comienza con el patrón
suffixLa parte local termina con el patrón
containsLa parte local contiene el patrón
plusaddressingLa parte local es el patrón seguido de +cualquier cosa (support coincide con support+ticket123)
catchallCoincide con todos los destinatarios; no requiere patrón
regexLa parte local coincide con el patrón como expresión regular (máx. 200 caracteres, tiempo de espera de 1 segundo)

La coincidencia no distingue mayúsculas de minúsculas y siempre se evalúa contra la parte local, [email protected] y [email protected] coinciden ambos con una ruta con patrón support limitada al mismo dominio.

El tipo de coincidencia regex requiere un plan con enrutamiento entrante por expresión regular (hoy Pro y Max, no Free). Crear una ruta con matchType: "regex", o actualizar una ruta existente para que su tipo de coincidencia pase a ser regex, en un plan sin esa función devuelve 400 PLAN_LIMIT_REACHED. Una ruta que ya usa regex sigue coincidiendo aunque el espacio de trabajo baje de plan después, y editarla sin cambiar su tipo de coincidencia no se ve afectado.

Acciones de ruta

El campo actions de una ruta es una lista de uno o más de los siguientes valores de cadena:

AcciónDescripción
storeAlmacenar el correo procesado para recuperarlo mediante la API y el panel
webhookEntregar el correo procesado a un webhook (requiere webhookId)
forwardEnviar una copia del correo a forwardToEmail, a través de la vía normal de envío
rejectRechazar el mensaje a nivel SMTP con rejectStatus/rejectMessage
dropAceptar el mensaje por SMTP y luego descartarlo silenciosamente, sin almacenamiento, sin webhook
unsubscribeTratar la dirección como un buzón de List-Unsubscribe; terminal, ver abajo

store y webhook pueden combinarse entre sí y con forward. reject, drop y unsubscribe son terminales: cada una debe ser la única acción de la ruta; la API rechaza una solicitud que combine una de ellas con cualquier otra acción.

Una copia reenviada no se envía por retransmisión SMTP en bruto: pasa por la misma canalización de envío que cualquier otro correo transaccional, por eso necesita el consentimiento del destino (ver abajo), cuenta contra su cuota de envío y aparece en su registro de mensajes como cualquier otro envío.

Destinos de reenvío

Antes de reenviar cualquier correo a una dirección, el propietario de esa dirección debe confirmarlo: excepto si la dirección está en uno de sus propios dominios totalmente verificados para envío. Para una dirección externa no hay forma de evitarlo: protege al propietario del destino de recibir correo que nunca aceptó, y protege su reputación de envío de una dirección que rebota o se queja.

Al crear o actualizar una ruta con forward en actions, MailLand automáticamente:

  1. Crea (o reutiliza) un registro de destino de reenvío para forwardToEmail, con alcance a su tenant: la misma dirección se recuerda en todas las rutas que reenvían a ella.
  2. Si la dirección necesita confirmación y nunca se le ha preguntado, envía un correo de confirmación con un enlace.

El guardado de la ruta en sí siempre tiene éxito; un correo de confirmación fallido no hace fallar la ruta: el destino simplemente queda pending (no se reenvía nada) hasta que reenvíe la confirmación.

Enlace de confirmación

El enlace del correo de confirmación es válido durante 7 días y es de un solo uso: una vez que el destinatario confirma o rechaza, visitar el enlace de nuevo solo muestra la misma decisión, no se puede revertir volviendo a visitarlo. Un enlace expirado que nunca se decidió devuelve 410 Gone si se abre de nuevo.

  • Confirmar: el correo reenviado a este tenant ahora se enviará a la dirección.
  • Rechazar: definitivo. Nunca se vuelve a reenviar nada a la dirección para este tenant, y el tenant no puede volver a solicitar confirmación para ella.

Obtener un destino de reenvío

GET https://api.mail.land/v1/transactional/inbound/forward-destinations/{destinationId}
Respuesta de destino de reenvío
{
  "id": "f2k9m3q7p4w8x1",
  "email": "[email protected]",
  "status": "pending",
  "confirmedVia": null,
  "lastSentAt": "2026-09-26T10:00:00Z",
  "confirmedAt": null,
  "declinedAt": null
}

status es uno de pending, confirmed o declined. confirmedVia es link cuando el propietario confirmó por correo, verified_domain cuando la dirección está en uno de sus propios dominios verificados para envío y no necesitó confirmación, o null en otro caso. La respuesta de una ruta también incluye este mismo objeto bajo forwardDestination (ver la respuesta de ruta más abajo).

Reenviar una confirmación

POST https://api.mail.land/v1/transactional/inbound/forward-destinations/{destinationId}/resend

Solo para un destino que sigue pending y realmente necesita un enlace (una dirección en uno de sus propios dominios de envío verificados devuelve 409 FORWARD_DESTINATION_NO_CONFIRMATION_NEEDED, ya que no hay nada que reenviar). Con límite de frecuencia: como máximo una vez cada 5 minutos y 5 veces al día por destino, y 50 veces al día para todo el tenant. Superar cualquiera de los límites devuelve 429 FORWARD_CONFIRMATION_RATE_LIMITED.

No hay forma de deshacer el rechazo de un destino a través de la API una vez que ha rechazado: una dirección rechazada queda bloqueada para ese tenant.

Crear una ruta

Las rutas pertenecen a un dominio y se crean bajo ese dominio.

POST https://api.mail.land/v1/transactional/inbound/domains/{domainId}/routes
Create route request
{
  "name": "Support Inbox",
  "matchType": "exact",
  "matchPattern": "support",
  "actions": ["store", "webhook"],
  "webhookId": "w4k8m2q7p9x3z1",
  "priority": 10
}
CampoTipoRequeridoDescripción
namestringSíNombre de la ruta
matchTypestringSíUno de los tipos de coincidencia anteriores
matchPatternstringSíPatrón para coincidir con la parte local (se ignora en catchall, máx. 64 caracteres, máx. 200 en regex)
actionsstring[]SíUno o más de store, webhook, forward, reject, drop, unsubscribe
webhookIdstringCond.ID público de un webhook existente; requerido cuando actions incluye webhook. Las rutas nunca crean un webhook en línea: créelo primero en la página de Webhooks
forwardToEmailstringCond.Destino para forward; requerido cuando actions incluye forward. Debe ser una dirección simple (sin nombre de visualización, sin corchetes angulares). El propio dominio de la ruta debe estar totalmente verificado para envío, la copia reenviada se envía desde él, o la solicitud se rechaza con 400 FORWARD_DOMAIN_NOT_VERIFIED. El destino mismo debe confirmar por separado, salvo que esté en uno de sus propios dominios verificados para envío (ver Destinos de reenvío)
rejectStatusstringNoEstado SMTP para reject, p. ej. 550 o 550 5.1.1 (por defecto 550 5.1.1)
rejectMessagestringNoTexto de rechazo SMTP para reject
priorityintNoNúmero más bajo = se evalúa primero. Por defecto es uno más que la prioridad más alta actual del dominio. Debe ser único por dominio
Create an inbound route
curl -X POST https://api.mail.land/v1/transactional/inbound/domains/k3v9x2m8q1w7z4/routes \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Support Inbox",
    "matchType": "exact",
    "matchPattern": "support",
    "actions": ["store", "webhook"],
    "webhookId": "w4k8m2q7p9x3z1",
    "priority": 10
  }'

Respuesta

Route response
{
  "id": "r7k3m9q2p4w8x1",
  "name": "Support Inbox",
  "domainId": "k3v9x2m8q1w7z4",
  "domainName": "yourdomain.com",
  "priority": 10,
  "isEnabled": true,
  "matchType": "Exact",
  "matchPattern": "support",
  "actions": ["store", "webhook"],
  "webhookId": "w4k8m2q7p9x3z1",
  "webhookName": "Support Webhook",
  "webhookUrl": "https://yourapp.com/webhooks/support",
  "forwardToEmail": null,
  "forwardDestination": null,
  "rejectStatus": null,
  "rejectMessage": null,
  "createdAt": "2026-02-17T12:00:00Z",
  "updatedAt": "2026-02-17T12:00:00Z"
}

Las solicitudes aceptan matchType en cualquier combinación de mayúsculas/minúsculas; las respuestas siempre devuelven el nombre del enum capitalizado: Exact, Prefix, Suffix, Contains, PlusAddressing, CatchAll, Regex. No compare el matchType de una respuesta con una cadena en minúsculas.

forwardDestination solo se completa cuando actions incluye forward; incluye el mismo objeto descrito en Obtener un destino de reenvío:

Respuesta de ruta con un reenvío pendiente
{
  "...": "...",
  "actions": ["store", "forward"],
  "forwardToEmail": "[email protected]",
  "forwardDestination": {
    "id": "f2k9m3q7p4w8x1",
    "email": "[email protected]",
    "status": "pending",
    "confirmedVia": null,
    "lastSentAt": "2026-09-26T10:00:00Z",
    "confirmedAt": null,
    "declinedAt": null
  }
}

Listar rutas de un dominio

GET https://api.mail.land/v1/transactional/inbound/domains/{domainId}/routes

Devuelve todas las rutas del dominio, ordenadas por prioridad (la más baja primero).

List routes for a domain
curl https://api.mail.land/v1/transactional/inbound/domains/k3v9x2m8q1w7z4/routes \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
Route list response
{
  "items": [
    { "id": "r7k3m9q2p4w8x1", "name": "Support Inbox", "priority": 10, "isEnabled": true, "..." : "..." }
  ],
  "totalCount": 1
}

Listar todas las rutas

Para listar rutas de todos los dominios del tenant, use en su lugar el endpoint paginado por cursor:

GET https://api.mail.land/v1/transactional/inbound/routes
ParámetroTipoPor defectoDescripción
cursorstring-Cursor opaco de nextCursor de la página anterior. Omitir en la primera página
limitint50Elementos por página

Obtener detalles de una ruta

GET https://api.mail.land/v1/transactional/inbound/routes/{routeId}
Get route details
curl https://api.mail.land/v1/transactional/inbound/routes/r7k3m9q2p4w8x1 \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."

Actualizar una ruta

PUT https://api.mail.land/v1/transactional/inbound/routes/{routeId}

El cuerpo de la solicitud coincide con el de creación, pero todos los campos son opcionales: solo se actualizan los campos que envíe.

Update an inbound route
curl -X PUT https://api.mail.land/v1/transactional/inbound/routes/r7k3m9q2p4w8x1 \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
  -H "Content-Type: application/json" \
  -d '{
    "matchPattern": "help",
    "priority": 5
  }'

Activar o desactivar una ruta

Cambia isEnabled sin tocar ningún otro campo. Sin cuerpo de solicitud.

POST https://api.mail.land/v1/transactional/inbound/routes/{routeId}/toggle
Toggle a route
curl -X POST https://api.mail.land/v1/transactional/inbound/routes/r7k3m9q2p4w8x1/toggle \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."

Reordenar rutas

Actualiza la prioridad de todas las rutas de un dominio a la vez, pasando los IDs de ruta en el orden deseado: el primer ID pasa a prioridad 1, el segundo a prioridad 2, y así sucesivamente.

POST https://api.mail.land/v1/transactional/inbound/domains/{domainId}/routes/reorder
Reorder routes request
{
  "routeIds": ["r7k3m9q2p4w8x1", "m2p8w4x1k7q3z9", "x4k1p7m3q9w2z8"]
}
Reorder routes
curl -X POST https://api.mail.land/v1/transactional/inbound/domains/k3v9x2m8q1w7z4/routes/reorder \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
  -H "Content-Type: application/json" \
  -d '{
    "routeIds": ["r7k3m9q2p4w8x1", "m2p8w4x1k7q3z9", "x4k1p7m3q9w2z8"]
  }'

Probar una ruta

Compruebe qué ruta coincidiría con una dirección de destinatario dada sin procesar un correo.

POST https://api.mail.land/v1/transactional/inbound/domains/{domainId}/routes/test
Test route request
{
  "emailAddress": "[email protected]"
}
Test a route
curl -X POST https://api.mail.land/v1/transactional/inbound/domains/k3v9x2m8q1w7z4/routes/test \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
  -H "Content-Type: application/json" \
  -d '{
    "emailAddress": "[email protected]"
  }'
Test route response: match found
{
  "matched": true,
  "matchedRouteId": "r7k3m9q2p4w8x1",
  "matchedRouteName": "Support Inbox",
  "actions": ["store", "webhook"]
}

Si ninguna ruta coincide, la respuesta es 200 con matched: false, y matchedRouteId/matchedRouteName/actions son todos null. 404 significa que el dominio no se encontró, o que la dirección probada no es válida (sin @).

Eliminar una ruta

DELETE https://api.mail.land/v1/transactional/inbound/routes/{routeId}
Delete a route
curl -X DELETE https://api.mail.land/v1/transactional/inbound/routes/r7k3m9q2p4w8x1 \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."

Ejemplos de rutas

Ruta catch-all: almacenar todo destinatario no reconocido:

Catch-all route
{
  "name": "Catch All",
  "matchType": "catchall",
  "matchPattern": "*",
  "actions": ["store"],
  "priority": 999
}

Direccionamiento plus: enrutar todas las variantes de support+*@yourdomain.com a un webhook:

Plus-addressing route
{
  "name": "Support Tickets",
  "matchType": "plusaddressing",
  "matchPattern": "support",
  "actions": ["store", "webhook"],
  "webhookId": "w4k8m2q7p9x3z1",
  "priority": 5
}

Rechazo en SMTP: rechazar correo a un buzón retirado antes de que sea aceptado:

Reject route
{
  "name": "Retired Mailbox",
  "matchType": "exact",
  "matchPattern": "old-team",
  "actions": ["reject"],
  "rejectStatus": "550 5.1.1",
  "rejectMessage": "Mailbox does not exist",
  "priority": 1
}

Las rutas se evalúan en orden de prioridad (el número más bajo primero). Coloque las rutas específicas en números de prioridad más bajos y las rutas catch-all en el número más alto para que se ejecuten al final.

Cómo es una copia reenviada

Una copia reenviada es un correo transaccional nuevo y normal, no una retransmisión en bruto de los bytes originales, enviado desde su dominio verificado para que pueda pasar DKIM y DMARC en el buzón del destino:

  • From: "<nombre del remitente original> via <dirección coincidente>@<su dominio>", p. ej. "Jane Doe via [email protected]". Un nombre de visualización que parece una dirección (contiene @, < o >) se reemplaza por la dirección original simple, para que una copia nunca pueda suplantar una marca bajo su DKIM.
  • Reply-To: el Reply-To del mensaje original si lo tenía, si no la dirección del remitente original, para que las respuestas lleguen al autor real, no a usted.
  • Sin seguimiento: el seguimiento de apertura y clics siempre está desactivado en una copia reenviada, sean cuales sean los ajustes de seguimiento de su workspace.
  • Sin pie de marca: el pie de página del plan gratuito que pueden llevar otros envíos nunca se añade.
  • Adjuntos: filtrados con las mismas reglas que un envío saliente por API (tipo, cantidad, tamaño total). Lo que se omite se indica con una nota al principio de la copia: "Forwarded without N attachment(s) that exceed the outbound attachment limits: ...", la copia igual llega, solo sin esas partes.
  • Etiqueta: cada copia reenviada lleva la etiqueta inbound-forward, para que pueda encontrarlas en su registro de mensajes habitual; su estado de entrega (queued, sent, delivered, bounced, etc.) es el mismo estado que recibe cualquier otro envío transaccional, porque pasa por la misma canalización de entrega.
  • Uso: cada copia reenviada cuenta como un envío contra la cuota y facturación de su plan, y se muestra como su propia línea "Inbound forward" en el uso, separada de los envíos por API, SMTP, campañas y automatizaciones.

Lo que nunca se reenvía

Un mensaje que coincide con una ruta forward no se reenvía, y nunca se factura, cuando:

  • Se marcó como spam, o el remitente está bloqueado como spam.
  • Falló DMARC según la política efectiva del dominio remitente, que es quarantine o reject, resuelta subiendo desde el dominio del remitente hasta encontrar el registro aplicable más cercano, de modo que el sp= propio de un subdominio prevalece sobre el p= de su dominio organizacional, y un registro t=y (de prueba) o pct=0 se trata un nivel de política por debajo, reenviarlo volvería a firmar un mensaje que el remitente pidió explícitamente a los receptores rechazar.
  • Él, o su cuerpo HTML/texto, supera los límites de tamaño de salida de la plataforma.
  • Reenviarlo crearía un bucle: el destino es uno de los propios destinatarios del mensaje, o ya lleva demasiados saltos o cabeceras Received.

Una copia que es elegible pero no se puede enviar temporalmente (una pausa de política, una ventana de cuota, una interrupción) se reintenta con espera creciente hasta 24 horas, y luego expira sin enviarse. Una ruta que se deshabilita, se elimina o cambia su destino después de recibir un mensaje también detiene cualquier copia que aún esperaba: la configuración actual de la ruta siempre es la autoridad.

Comprobar el resultado de un reenvío

Todo correo entrante que coincidió con una ruta forward lleva un array forwards en su respuesta de detalle (GET /v1/transactional/inbound/emails/{id}): una entrada por cada destino al que el mensaje se puso en cola para reenviar, para que veas lo que realmente ocurrió, no solo a dónde se configuró.

forwards en un correo entrante
"forwards": [
  {
    "destination": "[email protected]",
    "status": "Admitted",
    "reason": null,
    "omittedAttachmentCount": 0,
    "messageId": "m_01hz3k...",
    "createdAt": "2026-09-26T10:00:00Z",
    "updatedAt": "2026-09-26T10:00:02Z"
  }
]
CampoTipoDescripción
destinationstringLa dirección de destino del reenvío
statusstringUno de los estados de abajo
reasonstring | nullCódigo de detalle legible por máquina (por ejemplo hop_limit), o null
omittedAttachmentCountnúmeroAdjuntos excluidos de la copia por superar los límites de adjuntos salientes
messageIdstring | nullEl id del mensaje de la copia reenviada una vez admitida, si no null
createdAt / updatedAtstringMarcas de tiempo ISO-8601 del registro de reenvío

status es uno de:

EstadoSignificado
PendingEscrito junto con el correo entrante; aún no reclamado por el worker de reenvío
ProcessingReclamado por el worker de reenvío; en curso
DeferredUn rechazo transitorio (retraso de política, tasa, ventana de cuota, interrupción); se reintenta con backoff hasta 24 horas
AdmittedEnviado a través del pipeline de envío normal: messageId identifica la copia, cuyo propio estado de entrega (en cola/enviado/entregado/rebotado) es el autoritativo
SkippedLoopProtección contra bucles: límite de saltos, demasiados encabezados Received, o el destino es uno de los propios destinatarios del mensaje
SkippedSpamEl mensaje fue marcado como spam, o el remitente está en la lista de bloqueo como spam
SkippedAuthFailFalló DMARC según la política efectiva del dominio remitente (quarantine o reject, con el sp= del subdominio respetado)
SkippedTooLargeEl mensaje supera el límite de tamaño de reenvío saliente
RefusedSuppressedEl destino está suprimido, o rechazado por la protección de destinatarios
RefusedDomainNotVerifiedEl dominio de la ruta no está (o ya no está) verificado para envío
RefusedPolicyUn rechazo terminal por política o cuenta
RefusedRouteInactiveLa ruta fue deshabilitada, eliminada, perdió su acción forward, o cambió de destino después de recibir el mensaje
RefusedInvalidEl mensaje almacenado no pudo convertirse en una copia enviable
ExpiredSeguía en Deferred cuando se cerró la ventana de reintento de 24 horas
RefusedDestinationUnconfirmedEl destino aún no ha confirmado (ver Destinos de reenvío)
RefusedDestinationDeclinedEl propietario del destino declinó; nunca se reenvía nada a esa dirección

Pending, Processing y Deferred son los únicos estados no finales, cualquier otro valor es terminal.

Respuestas de error de reenvío

EstadoCódigoDescripción
400VALIDATION_FAILED (campo forwardToEmail)Al crear: actions incluye forward pero forwardToEmail está vacío
400FORWARD_DESTINATION_REQUIREDAl actualizar (PUT): la ruta efectiva resultante reenvía pero no tiene forwardToEmail
400FORWARD_DOMAIN_NOT_VERIFIEDEl dominio de la ruta no está totalmente verificado para envío, así que nunca podría enviarse desde él una copia reenviada
404RESOURCE_NOT_FOUNDDestino de reenvío no encontrado
409FORWARD_DESTINATION_NOT_PENDINGSe solicitó reenviar para un destino que ya confirmó o rechazó
409FORWARD_DESTINATION_NO_CONFIRMATION_NEEDEDSe solicitó reenviar para un destino en uno de sus propios dominios de envío verificados
410FORWARD_CONFIRMATION_EXPIREDEl enlace de confirmación expiró (7 días) sin decidirse
409FORWARD_CONFIRMATION_ALREADY_DECIDEDEl enlace se usó para la otra decisión
429FORWARD_CONFIRMATION_RATE_LIMITEDSe solicitó reenviar demasiado pronto, o se alcanzó el límite diario de reenvíos

Respuestas de error

EstadoCódigoDescripción
400VALIDATION_FAILEDFaltan campos requeridos, matchType/actions inválidos, o una acción terminal combinada con otra
400INVALID_REQUESTYa existe una ruta con esta priority para el dominio, o no se encontró el webhookId referenciado
400PLAN_LIMIT_REACHEDCrear una ruta con matchType: "regex", o actualizar una ruta para que su tipo de coincidencia pase a ser regex, en un plan sin soporte de rutas regex (Free hoy)
403FORBIDDENPermisos insuficientes
404RESOURCE_NOT_FOUNDDominio o ruta no encontrados (endpoint de prueba: también una dirección no válida sin @; sin coincidencia es 200 con matched: false, no un 404)

Próximos pasos

En esta página