API de Plantillas de Correo Electrónico
La API de Plantillas de Correo permite a los administradores personalizar los correos transaccionales enviados por Auris. Cada uno de los trece tipos de plantilla corresponde a un evento específico (verificación, restablecimiento de contraseña, magic link, alertas de seguridad, …) y puede personalizarse con HTML y variables dinámicas, de forma independiente por idioma.
Auris incluye plantillas predeterminadas para todos los tipos en cinco idiomas (en, it, fr, de, es). Cuando existe una plantilla personalizada para un tipo y un idioma, se usa para todos los correos futuros de ese tipo; en caso contrario se usa la predeterminada con la marca del tenant. Orden de resolución en el envío: personalizada (idioma solicitado) -> personalizada (en) -> predeterminada (idioma solicitado) -> predeterminada (en).
Todos los endpoints requieren un token Bearer con el permiso manage:security y seleccionan el tenant mediante la cabecera x-tenant (el identificador de realm del tenant).
Estos endpoints devuelven objetos JSON simples — no usan el envoltorio { ok, data } presente en
otras partes de la API de Auris.
Listar Plantillas
/api/email-templatesRequires: manage:securityLista los trece tipos de plantilla con su estado de personalización para el tenant. Los cuerpos HTML completos no se incluyen — usa la lectura de una plantilla individual.
Respuesta de éxito (200)
{
"templates": [
{
"type": "verification",
"label": "Email Verification",
"description": "Sent when a new user registers to verify their email address.",
"variables": ["email", "link", "expiresIn", "year", "month", "day", "date"],
"hasCustomTemplate": true,
"active": true,
"updatedAt": "2026-07-20T10:00:00.000Z",
"customLocales": ["en", "es"]
}
],
"availableLocales": ["en", "it", "fr", "de", "es"],
"wellKnownLocales": { "en": "English", "es": "Español", "pt-BR": "Português (Brasil)" }
}| Campo | Tipo | Descripción |
|---|---|---|
type | string | Identificador del tipo de plantilla (mira Tipos de Plantilla más abajo) |
label | string | Nombre legible de la plantilla |
description | string | Cuándo se envía el correo |
variables | string[] | Variables disponibles para este tipo, incluidas las variables de fecha globales auto-inyectadas (year, month, day, date) |
hasCustomTemplate | boolean | true si existe al menos una versión personalizada (en cualquier idioma) |
active | boolean | Si hay una versión personalizada activa (true cuando no existe plantilla personalizada — la predeterminada siempre está activa) |
updatedAt | string | null | Marca temporal ISO 8601 de la última personalización, o null |
customLocales | string[] | Idiomas para los que existe una versión personalizada |
availableLocales | string[] | Idiomas con plantillas predeterminadas integradas |
wellKnownLocales | object | Mapa código de idioma -> etiqueta usado por la Consola |
Obtener una Plantilla
/api/email-templates/{type}?locale={locale}Requires: manage:securityObtiene una plantilla para un idioma: el contenido personalizado (si existe) más la base predeterminada con la marca del tenant. El parámetro locale es en por defecto.
Respuesta de éxito (200)
{
"type": "verification",
"locale": "es",
"label": "Email Verification",
"description": "Sent when a new user registers to verify their email address.",
"variables": ["email", "link", "expiresIn", "year", "month", "day", "date"],
"hasCustomTemplate": false,
"subject": null,
"htmlBody": null,
"metadata": null,
"active": true,
"updatedAt": null,
"defaultSubject": "Verifica tu dirección de correo",
"defaultHtmlBody": "<!DOCTYPE html>...",
"availableLocales": ["en", "it", "fr", "de", "es"],
"customLocales": ["en"],
"hasDefaultTemplate": true,
"wellKnownLocales": { "en": "English", "es": "Español" }
}subject, htmlBody y metadata son null cuando no existe plantilla personalizada para el idioma solicitado. defaultSubject y defaultHtmlBody contienen siempre la plantilla integrada, renderizada con la marca del tenant (logo, color, pie white-label) exactamente igual que en un envío real. hasDefaultTemplate indica si el idioma solicitado tiene una predeterminada integrada (en, it, fr, de, es); los demás idiomas recurren al inglés.
Respuestas de error
| HTTP | Descripción |
|---|---|
400 | Tipo de plantilla o código de idioma no válido |
401 / 403 | Autenticación ausente o permisos insuficientes |
404 | Tenant no encontrado |
Actualizar una Plantilla
/api/email-templates/{type}Requires: manage:securityCrea o actualiza la plantilla personalizada para un idioma. El idioma puede pasarse en el body o como parámetro query; por defecto en. La plantilla guardada está activa de inmediato.
Body de la petición
{
"subject": "Verifica tu correo — {{email}}",
"htmlBody": "<!DOCTYPE html><html><body><h1>Verifica tu correo</h1><p>Hola {{email}},</p><p><a href=\"{{link}}\">Confirma tu dirección</a></p><p>El enlace caduca en {{expiresIn}}.</p></body></html>",
"locale": "es",
"metadata": { "source": "code" }
}| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
subject | string | Sí | Asunto del correo. Puede incluir placeholders {{variable}} |
htmlBody | string | Sí | Cuerpo HTML completo. Tamaño máximo 500 KB |
locale | string | No | Código de idioma (estilo BCP-47, p. ej. en, pt-BR). Por defecto en |
metadata | object | No | Estado del editor usado por la Consola (tema, layout del builder, modo). Validado contra un esquema cerrado — los campos no reconocidos se rechazan, no se descartan en silencio. Tamaño máximo 256.000 caracteres |
El cuerpo HTML se sanea en el servidor antes de guardarse: se eliminan las etiquetas <script>, los atributos de manejadores de eventos (onclick, …), los URI javascript:/data:, las etiquetas <iframe>/<embed>/<object>/<form>/<base> y las construcciones CSS peligrosas.
Respuesta de éxito (200) — el registro de la plantilla guardada:
{
"id": "cltpl123",
"tenantId": "tnt_ScUtrVKUKGxtu7WY",
"type": "verification",
"locale": "es",
"subject": "Verifica tu correo — {{email}}",
"htmlBody": "<!DOCTYPE html>...",
"metadata": { "source": "code" },
"active": true,
"createdAt": "2026-07-23T09:00:00.000Z",
"updatedAt": "2026-07-23T09:00:00.000Z"
}Respuestas de error
| HTTP | Descripción |
|---|---|
400 | Tipo no válido, idioma no válido, o faltan subject/htmlBody |
413 | htmlBody supera el límite de 500 KB, o metadata supera los 256.000 caracteres |
422 | metadata no coincide con el esquema esperado (forma o campo no reconocido) |
Los cambios tienen efecto inmediato para todos los correos futuros de ese tipo y ese idioma. No hay mecanismo de borradores — previsualiza y prueba la plantilla antes de guardar.
Eliminar una Plantilla
/api/email-templates/{type}?locale={locale}Requires: manage:securityElimina la plantilla personalizada y vuelve a la predeterminada integrada. Con el parámetro locale solo se elimina ese idioma; sin él, se eliminan TODOS los idiomas del tipo.
Respuesta de éxito (200)
{ "success": true }Previsualizar una Plantilla
/api/email-templates/{type}/previewRequires: manage:securityRenderiza un asunto y un cuerpo HTML con variables de ejemplo realistas para el tipo de plantilla. No se envía ni se guarda nada.
Body de la petición
{
"subject": "Verifica tu correo — {{email}}",
"htmlBody": "<!DOCTYPE html>..."
}Respuesta de éxito (200)
{
"subject": "Verifica tu correo — [email protected]",
"html": "<!DOCTYPE html>...",
"variables": {
"email": "[email protected]",
"link": "https://console.auris.dev/verify-email?token=abc123",
"expiresIn": "24 hours",
"year": "2026",
"month": "07",
"day": "23",
"date": "2026-07-23"
}
}El campo variables devuelve los valores de ejemplo sustituidos. El cuerpo HTML se sanea antes del renderizado; el asunto se renderiza como texto plano (sin escape HTML de los valores).
Correo de Prueba
/api/email-templates/{type}/testRequires: manage:securityRenderiza el asunto y el cuerpo HTML con datos de ejemplo y los envía como un correo real. Por defecto el correo va a la dirección del administrador autenticado.
Body de la petición
{
"subject": "Verifica tu correo — {{email}}",
"htmlBody": "<!DOCTYPE html>...",
"recipientEmail": "[email protected]"
}| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
subject | string | Sí | Asunto (con placeholders) |
htmlBody | string | Sí | Cuerpo HTML (con placeholders) |
recipientEmail | string | No | Destinatario alternativo opcional. Si se omite (o está vacío), la prueba se envía al buzón del administrador autenticado. Debe ser una dirección de correo válida |
Respuesta de éxito (200)
{ "success": true, "sentTo": "[email protected]" }Respuestas de error
| HTTP | Descripción |
|---|---|
400 | Tipo no válido, faltan subject/htmlBody, recipientEmail no válido, o no se pudo determinar el correo del llamante |
500 | Fallo en el envío del correo |
El asunto renderizado lleva el prefijo [TEST] para que los correos de prueba sean fáciles de
distinguir de los transaccionales reales. La entrega usa la configuración SMTP del tenant cuando está
presente y activa; si no, el remitente predeterminado de la plataforma.
Tipos de Plantilla
Auris soporta trece tipos de plantilla de correo transaccional:
| Tipo | Cuándo se envía | Variables |
|---|---|---|
verification | Un nuevo usuario se registra y debe verificar su correo | email, link, expiresIn |
password_reset | Un usuario solicita restablecer su contraseña | email, link, expiresIn |
invitation | Un usuario es invitado a un tenant | email, orgName, role, inviterEmail, link, expiresIn |
mfa_code | Autenticación de dos factores por correo | email, code, expiresIn |
magic_link | Inicio de sesión sin contraseña vía magic link | email, link, approveLink, expiresIn, tenantName |
login_alert | Nuevo inicio de sesión detectado en la cuenta | email, device, ipAddress, location, time |
welcome | El usuario verifica con éxito su correo | email, name, orgName, dashboardLink |
password_changed | Confirmación de un cambio de contraseña | email, name, time, ipAddress |
account_locked | Cuenta bloqueada tras intentos fallidos | email, name, lockDuration, attempts, ipAddress, time |
suspicious_login | Inicio de sesión inusual detectado | email, name, device, ipAddress, location, time, reason |
email_changed | Cambio del correo principal (enviado a la dirección antigua) | email, name, newEmail, time |
license_issued | Emisión de una clave de licencia | key, jwtToken, product, expiresAt, features |
ciba | Aprobación de inicio de sesión solicitada vía flujo CIBA | email, appName, bindingMessage, approveUrl, denyUrl |
Las variables de fecha globales year, month, day y date (formato YYYY-MM-DD) se inyectan automáticamente en cada renderizado, además de las variables por tipo listadas arriba.
Sintaxis de las Plantillas
{{variable}}— se sustituye por el valor. En el cuerpo HTML los valores llevan escape HTML automático para prevenir inyección; en el asunto se insertan como texto plano.{{{variable}}}— interpolación raw sin escape. Solo para fragmentos HTML de confianza construidos en el servidor.{{#if variable}}...{{/if}}— el bloque se conserva solo cuando la variable tiene un valor no vacío; en caso contrario se elimina por completo (markup incluido). Ejemplo: la plantilla predeterminada demagic_linkmuestra el botón secundario de aprobación solo cuandoapproveLinktiene valor.
Los placeholders desconocidos permanecen tal cual en la salida. La notación con punto y los bucles no están soportados.
<h1>Inicia sesión en {{tenantName}}</h1>
<p><a href="{{link}}">Iniciar sesión en este dispositivo</a></p>
{{#if approveLink}}
<p><a href="{{approveLink}}">Aprobar en el dispositivo de origen</a></p>
{{/if}}
<p>El enlace caduca en {{expiresIn}}.</p>Referencia de Permisos
| Permiso | Descripción |
|---|---|
manage:security | Listar, ver, actualizar, eliminar, previsualizar y probar todas las plantillas de correo del tenant |
Relacionado
- Personalizar Plantillas de Correo — Guía paso a paso de personalización
- Plantillas de Correo — Editar plantillas visualmente desde la Consola