Docs / Módulo / Mail
Módulo de Mail
Correo transaccional por evento: registros, confirmaciones de compra, recuperación de contraseña, notificaciones. Un correo por request, con tu propio HTML y variables de personalización.
¿Buscas newsletters o campañas masivas a listas segmentadas? Ese es un producto distinto — ver Marketing.
Introducción
La API de Mail te permite enviar correos transaccionales directamente desde tu backend, sin configurar SMTP ni gestionar infraestructura de entrega. Envías tu HTML/texto y las variables de personalización; Webability se encarga de la cola, reintentos y entregabilidad.
¿Para qué sirve?
- • Correos de bienvenida y confirmación de cuenta
- • Comprobantes de compra y facturas
- • Recuperación de contraseña con enlaces de un solo uso
- • Notificaciones de estado (envíos, pagos, alertas)
Características
- • Envío síncrono o asíncrono (wait_send)
- • Consulta de estatus por correo (GET /status)
- • Variables de personalización {{variable}}
- • Envío a múltiples destinatarios en un solo request
Quickstart
Un correo, un request.
CLIENTID="tu-client-id"
TOKEN="tu-token-secreto"
TS=$(date +%s)
PATH="/v1/mail/send"
MSG="POST|${PATH}|${TS}|${CLIENTID}"
DIG=$(echo -n "$MSG" | openssl dgst -sha256 -hmac "$TOKEN" | awk '{print $2}')
curl -s -X POST https://api.webability.info${PATH} \
-H "X-WA-Client: $CLIENTID" \
-H "X-WA-Timestamp: $TS" \
-H "X-WA-Digest: $DIG" \
-H "Content-Type: application/json" \
-d '{
"from": { "email": "no-reply@tuempresa.com", "name": "Tu Empresa" },
"to": { "email": "cliente@ejemplo.com", "name": "Ana", "vars": { "nombre": "Ana" } },
"subject": "Confirma tu compra",
"html": "<p>Hola {{nombre}}, tu compra fue confirmada.</p>"
}'
{ "status": "ok", "queue_key": 42, "queue_status": "pending", "to": "cliente@ejemplo.com" }
El correo se encola y se envía en segundo plano. Consulta GET /v1/mail/status/{queue_key} para saber si ya se entregó, o usa wait_send para esperar el resultado en el mismo request.
Autenticación
Mismo esquema que el resto de la API: ClientID (público) + Token (secreto), firma HMAC-SHA256. Ver el detalle completo en la documentación de DNS — el mecanismo es idéntico en todos los módulos.
| Header | Descripción |
|---|---|
| X-WA-Client | Tu Client ID (público) |
| X-WA-Timestamp | Unix timestamp actual. La petición expira en ±300 s. |
| X-WA-Digest | HMAC-SHA256 del mensaje canónico, en hexadecimal. |
POST /v1/mail/send
Envía un correo a un solo destinatario.
Body JSON
| Campo | Tipo | Req. | Descripción |
|---|---|---|---|
| from.email | string | ✓ | Correo remitente |
| from.name | string | Nombre del remitente | |
| to.email | string | ✓ | Correo destinatario |
| to.name | string | Nombre del destinatario | |
| to.vars | object | Variables de personalización: cada clave sustituye {{clave}} en subject/html/text | |
| subject | string | ✓ | Asunto |
| html | string | Cuerpo HTML (al menos uno de html/text) | |
| text | string | Cuerpo en texto plano | |
| tags | string[] | Etiquetas libres para tus propios reportes | |
| track_opens | bool | Pixel de apertura | |
| track_clicks | bool | Link wrapping para clics | |
| wait_send | bool | Ver wait_send abajo |
Respuesta (200)
{
"status": "ok",
"queue_key": 42,
"queue_status": "pending",
"to": "cliente@ejemplo.com"
}
queue_status viene "pending" salvo que uses wait_send (ver abajo). El envío real ocurre en segundo plano.
wait_send — envío síncrono
Por defecto /v1/mail/send responde de inmediato con el correo encolado (queue_status: "pending") — el envío real (conexión SMTP, entrega) sucede después, de forma asíncrona. Si necesitas saber el resultado real en el mismo request (por ejemplo, para decidir si reintentar con otro proveedor o marcar algo en tu base de datos), manda "wait_send": true.
Con wait_send: true, el servidor espera hasta 20 segundos el resultado real antes de responder. Si el envío se resuelve a tiempo, queue_status viene "sent" o "error" (con error_detail). Si no se resuelve a tiempo, la respuesta degrada a "pending" igual que sin la bandera — el queue_key sigue siendo válido para consultar después con GET /status.
curl -s -X POST https://api.webability.info/v1/mail/send \
-H "X-WA-Client: $CLIENTID" -H "X-WA-Timestamp: $TS" -H "X-WA-Digest: $DIG" \
-H "Content-Type: application/json" \
-d '{ "from": {...}, "to": {...}, "subject": "...", "html": "...", "wait_send": true }'
{ "status": "ok", "queue_key": 42, "queue_status": "sent", "to": "cliente@ejemplo.com" }
{ "status": "ok", "queue_key": 43, "queue_status": "error",
"error_detail": "550 5.1.1 The email account does not exist", "to": "no-existe@dominio.com" }
GET /v1/mail/status/{queue_key}
Consulta el estatus real de un envío hecho con POST /v1/mail/send. Solo el cliente dueño de la cuenta que lo encoló puede consultarlo — cualquier otro queue_key responde 404, sin distinguir "no existe" de "no es tuyo".
PATH="/v1/mail/status/42"
MSG="GET|${PATH}|$(date +%s)|${CLIENTID}"
DIG=$(echo -n "$MSG" | openssl dgst -sha256 -hmac "$TOKEN" | awk '{print $2}')
curl -s https://api.webability.info${PATH} \
-H "X-WA-Client: $CLIENTID" \
-H "X-WA-Timestamp: $(date +%s)" \
-H "X-WA-Digest: $DIG"
{ "status": "ok", "queue_key": 42, "queue_status": "sent" }
Valores de queue_status
| Valor | Significado |
|---|---|
| pending | Encolado, aún no se procesa. |
| processing | El mailer lo tomó de la cola y está enviándolo. |
| sent | Entregado al servidor destino sin errores. |
| error | Falló — revisa error_detail para el motivo (SMTP rechazado, dominio inexistente, buzón lleno, etc.). |
POST /v1/mail/send-bulk
Envía el mismo correo (con variables por destinatario) a varios destinatarios en un solo request. Cada destinatario se encola por separado — no soporta wait_send.
{
"from": { "email": "newsletter@tuempresa.com", "name": "Tu Empresa" },
"subject": "Novedades de la semana",
"html": "<p>Hola {{nombre}}!</p>",
"recipients": [
{ "email": "ana@ejemplo.com", "vars": { "nombre": "Ana" } },
{ "email": "luis@ejemplo.com", "vars": { "nombre": "Luis" } }
]
}
{
"status": "ok", "total": 2, "queued": 2, "failed": 0,
"results": [
{ "email": "ana@ejemplo.com", "queue_key": 10, "status": "queued" },
{ "email": "luis@ejemplo.com", "queue_key": 11, "status": "queued" }
]
}
Cada queue_key se puede consultar individualmente con GET /v1/mail/status/{queue_key}.
Errores
| Código | HTTP | Descripción |
|---|---|---|
| 3001 | 401 | Faltan headers de autenticación |
| 3002 | 401 | Firma inválida o timestamp expirado |
| 3003 | 401 | Cliente no encontrado |
| 3010 | 404 | Servicio desconocido (usa send / send-bulk / status) |
| 3011 | 405 | Método HTTP no soportado |
| 3020 | 400 | Body JSON inválido o vacío |
| 3021 | 400 | Campo requerido faltante (from.email, to.email o recipients) |
| 3022 | 500 | Error al encolar el correo |
| 3023 | 400 | Clave de cola inválida (GET status) |
| 3024 | 404 | Cola no encontrada, o no pertenece a este cliente (GET status) |