Saltar al contenido principal

Crear una plantilla de email

POST/v1/mail-templates

Para desarrolladores

Descripción​

Crea una plantilla de email. La plantilla nace siempre como borrador (draft); publicarla, despublicarla y eliminarla se hace desde el panel.

El diseño se entrega de una de dos formas, excluyentes entre sí:

  • config: el documento completo. Un campo que el documento omite se guarda con su valor por defecto, si lo tiene. Un campo que hereda queda ausente y sigue heredando. Es también la forma de crear una plantilla en modo HTML crudo.
  • catalog_slug: una plantilla de la biblioteca, que se copia como punto de partida.

Sin ninguna de las dos, la plantilla se crea solo con su nombre, y el diseño se agrega después con PATCH /v1/mail-templates/{template_id}. El recorrido completo, desde crear una plantilla hasta editar su diseño, está en Plantillas por API, y la estructura del documento en Formato de plantillas.

Guía relacionada​

Autenticación​

Authorizationbearer tokenheaderobligatorio
API key con scope templates:write. Formato: Bearer <API_KEY>.
X-Instance-Slugstringheaderobligatorio
Identificador de su instancia. Ver Autenticación.

Request​

Body:

{
"name": "Black Friday 2026",
"subject": "Ofertas de fin de semana",
"preheader": "Hasta 40% de descuento este fin de semana",
"catalog_slug": "holidays/black-friday"
}
namestringobligatorio
Nombre de la plantilla, 1–255 caracteres. Los espacios al inicio y al final se eliminan, y un nombre que queda vacío se rechaza. Es único en la instancia: no puede repetir el de otra plantilla, sin importar mayúsculas ni tildes.
subjectstring | null
Asunto del correo, hasta 254 caracteres. Puede llevar etiquetas de Campos.
preheaderstring | null
Texto que la bandeja de entrada muestra junto al asunto, hasta 255 caracteres. Se incluye en el HTML como un bloque oculto al comienzo del cuerpo.
descriptionstring | null
Descripción libre, hasta 5.000 caracteres.
configobject | null
Documento completo, hasta 256 KB, como lo devuelve GET /v1/mail-templates/{template_id}. Un campo omitido se guarda con su valor por defecto, si lo tiene; uno que hereda sigue heredando. Para el modo HTML crudo: {"mode": "html", "rawHtml": "<html>…</html>", "page": {"rows": []}}. Excluye a catalog_slug.
catalog_slugstring | null
Identificador de una plantilla de la biblioteca, por ejemplo holidays/black-friday, tal como lo devuelve GET /v1/template-catalog. Excluye a config.

Response​

201 CreatedDevuelve el objeto creado. El header Location trae su URL (ver Headers).
idintegersiempre presente
Identificador de la plantilla creada.
namestringsiempre presente
Nombre de la plantilla.
subjectstring | nullsiempre presente
Asunto del email.
preheaderstring | nullsiempre presente
Texto que la bandeja de entrada muestra junto al asunto.
statusstring, enum: `draft`siempre presente
Una plantilla nueva es siempre un borrador.
descriptionstring | nullsiempre presente
Descripción libre.
providerstring, enum: `fidelizador`siempre presente
Editor de contenido de la plantilla.
htmlstring | nullsiempre presente
HTML que la plataforma genera a partir del diseño. null si la plantilla se creó sin diseño.
configobject | nullsiempre presente
Documento completo tal como quedó guardado. Con catalog_slug, es la copia de la plantilla de la biblioteca.
created_atstring (date-time)siempre presente
Fecha y hora de creación.
updated_atstring (date-time)siempre presente
Fecha y hora de la última modificación.
findingsobject[]siempre presente
Advertencias (warning) sobre el documento guardado. Vacío si no hay ninguna o si la plantilla no tiene diseño.
levelstring, enum: `warning`siempre presente
Gravedad. Un documento con errores no se guarda, así que esta respuesta nunca trae error.
codestringsiempre presente
Regla que se señala, por ejemplo placeholder_link.
messagestringsiempre presente
Descripción en inglés.
pathstringsiempre presente
Puntero JSON al valor señalado dentro del documento.
fixstringsiempre presente
Cómo corregirlo, en inglés.
uuidstring | nullsiempre presente
uuid de la fila, columna o módulo afectado, cuando lo hay.
lineinteger | nullsiempre presente
Línea del HTML, solo en una advertencia del modo HTML crudo.
columninteger | nullsiempre presente
Columna del HTML, solo en una advertencia del modo HTML crudo.

Errores​

CódigoCuándo
404catalog_slug no corresponde a ninguna plantilla de la biblioteca (catalog_template_not_found).
409La creación de plantillas no está disponible en este entorno (template_editor_unavailable). También cuando ya existe otra plantilla con ese nombre (template_name_taken): elija otro nombre.
413El body supera el tamaño máximo de una petición, o el documento, una vez completado con sus valores por defecto, supera los 256 KB (request_too_large).
422El body no es válido, o el documento tiene errores. En errors[]:

Valores de errors[].code propios de este endpoint:

  • invalid_document: el documento no cumple el formato. Hay un ítem por cada error. pointer señala el valor dentro del body (/config/page/rows/0/columns/0/modules/3/type). params.rule trae la regla incumplida (unknown_module_type, unsafe_link, unsafe_html, …) y params.uuid, el nodo afectado, cuando lo hay. El message incluye cómo corregirlo.
  • catalog_slug_is_exclusive: se combinó catalog_slug con config.
  • essential_not_supported: el body trae el campo essential. Esta API recibe el diseño completo en config.
  • template_html_too_large: en modo HTML crudo, rawHtml supera los 100 KB.
  • template_syntax_error: el subject o el preheader no es una plantilla Liquid válida: un bloque sin cerrar, un filtro que no existe o un respaldo escrito {{CLAVE|respaldo}} en vez de con default. En el diseño, el mismo error llega como invalid_document con params.rule template_syntax_error, en el texto que lo tiene. Ver Campos.
  • value_error: config supera los 256 KB, o name queda vacío.

Detalle en Errores genéricos: Errores por campo (422), request-too-large, not-found y conflict.

Notas
  • Antes de crear, valide. POST /v1/mail-templates/validate y POST /v1/mail-templates/preview revisan y renderizan un documento sin guardar nada.
  • Un documento con errores no se guarda. La respuesta 422 los trae todos a la vez, cada uno con su puntero, para corregirlos en una sola pasada.
  • config se guarda con sus valores por defecto escritos. Un campo que el documento omite se guarda con el default que declara el schema de GET /v1/mail-templates/format, que es el mismo valor con que se dibuja: el correo no cambia, pero el config que devuelve la respuesta trae el campo. Un campo sin default que hereda (un color de texto, por ejemplo) no se escribe: queda ausente y toma el valor de la fila o de la página. Lo único que nunca se completa es el contenido de un módulo, que es obligatorio.
  • El modo HTML crudo guarda el HTML sin cambios, salvo el preheader, que se inserta o reemplaza. Sus advertencias de sintaxis (tag-pair, tagname-lowercase, attr-no-duplication) llegan en findings y nunca impiden guardar.
  • El campo html no se acepta como entrada: la plataforma lo genera a partir del diseño, y un html en el body se ignora.
Request
curl -X POST "https://$API_HOST/v1/mail-templates" \
-H "Authorization: Bearer $API_KEY" \
-H "X-Instance-Slug: $SLUG" \
-H "Content-Type: application/json" \
-d '{
"name": "Black Friday 2026",
"subject": "Ofertas de fin de semana",
"preheader": "Hasta 40% de descuento este fin de semana",
"catalog_slug": "holidays/black-friday"
}'
Response
{
"id": 41,
"name": "Black Friday 2026",
"subject": "Ofertas de fin de semana",
"preheader": "Hasta 40% de descuento este fin de semana",
"status": "draft",
"description": null,
"provider": "fidelizador",
"html": "<!DOCTYPE html><html>…</html>",
"config": {
"page": {
"title": "Black Friday",
"body": {
"…": "…"
},
"rows": [
"…"
]
}
},
"created_at": "2026-10-12T14:22:31Z",
"updated_at": "2026-10-12T14:22:31Z",
"findings": []
}