POST /api/v1/render
Renderiza un email con datos de ejemplo y devuelve el resultado. No envía nada, no guarda nada y no cambia nada: es el único endpoint de aquí sin efectos secundarios, así que llámalo tantas veces como quieras, antes y después de cada edición.
unsubscribeUrl, today, currentYear y poweredBy no son valores de ejemplo: el servidor los calcula y sobrescribe lo que envíes para ellos. La fecha y el año vienen de la zona horaria y el idioma configurados en la organización de la clave de API, no del llamante ni del reloj del servidor, así que un renderizado responde con la misma fecha que leerá el destinatario.
Se exige templateId o content: no enviar ninguno responde 400. Enviar ambos renderiza tu content con el asunto de la plantilla, que es como pruebas una edición antes de guardarla.
json
{
"success": true,
"data": {
"html": "<html>…<p>Hi Camille</p>…</html>",
"text": "Hi Camille …",
"subject": "What shipped in August",
"unknownVariables": ["company"]
}
}unknownVariables enumera los marcadores {{…}} que no forman parte del vocabulario. Se resuelven como una cadena vacía en el momento del envío: no se rompe nada, pero tampoco se muestra nada. Corrígelos aquí.
Un HTML sin enlace de baja se rechaza, aquí y en el momento del envío. La respuesta es un
400 que nombra el problema: añade {{unsubscribeUrl}} dentro de un enlace en tu HTML. Nunca se añade nada a tu marcado en tu nombre, así que una plantilla que se renderiza es una plantilla que se puede enviar.Autorización
| Rol en la organización | Este endpoint |
|---|---|
OWNER | Permitido |
ADMIN | Permitido |
MEMBER | Permitido |
Cuerpo de la solicitud
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
templateId | string | no | Renderiza una plantilla de tu organización |
content | string | no | Renderiza HTML en bruto: prevalece sobre el contenido propio de la plantilla |
subject | string | no | Por defecto, el defaultSubject de la plantilla |
previewText | string | null | no | Hasta 200 caracteres tras eliminar espacios. Se renderiza en {{previewText}} o {{preheader}}; ausente, vacío o null se renderiza vacío |
preheader | string | null | no | Alias compatible de previewText; valores normalizados distintos devuelven 400 |
variables | object | no | Valores de ejemplo: firstName, lastName, email |
json
{
"previewText": "Timely m’a bloqué mes paiements Stripe pendant 5 jours.",
"content": "<div data-skip-in-text=\"true\" style=\"display:none;font-size:1px;line-height:1px;max-height:0;max-width:0;opacity:0;overflow:hidden;mso-hide:all;\">{{previewText}}</div><p>Hello</p><a href=\"{{unsubscribeUrl}}\">Unsubscribe</a>"
}Ejemplo
bash
curl -X POST -H "x-api-key: $AGENTMAIL_API_KEY" -H "content-type: application/json" \
-d '{"templateId":"'$TEMPLATE_ID'","variables":{"firstName":"Camille"}}' \
"https://www.agentsmail.io/api/v1/render"Respuesta
200 OK: el email renderizado.400 Bad Request: campos no válidos, alias de vista previa en conflicto, o falta el HTML requerido.401 Unauthorized: clave ausente o no válida, o su propietario salió de la organización.429 Too Many Requests: más de 120 solicitudes en un minuto para esta clave.
Campos de la respuesta
| Campo | Tipo | Descripción |
|---|---|---|
success | boolean | Indica si la operación se realizó correctamente |
data.html | string | El documento renderizado, con las etiquetas de combinación resueltas |
data.text | string | Su equivalente en texto plano |
data.subject | string | El asunto tras la resolución |
data.unknownVariables | string[] | Etiquetas que el producto no conoce: se dejan visibles en el resultado |
data.warnings | string[] | missing_postal_address, dark_mode_contrast_corrected, dark_mode_contrast_unverified, dark_mode_declaration_removed, missing_preheader_shortcode |
Ejemplo de respuesta
json
{
"success": true,
"data": {
"html": "<html>…</html>",
"text": "August news…",
"subject": "August news",
"unknownVariables": [],
"warnings": []
}
}Receta para agentes
Render es la única llamada sin efectos secundarios: itera sobre ella hasta que el documento esté limpio y después crea la campaña. Un agente que se salta este paso envía{{fistName}} a bandejas de entrada reales.
js
const render = async (content) =>
(
await fetch(`${base}/render`, {
method: 'POST',
headers: {...headers, 'content-type': 'application/json'},
body: JSON.stringify({content}),
})
).json()
let html = draft
for (let attempt = 0; attempt < 3; attempt++) {
const {data} = await render(html)
if (data.unknownVariables.length === 0) break
html = fixTypos(html, data.unknownVariables) // your own correction pass
}Notas
previewText y preheader nombran el mismo valor. Si se envían ambos, deben coincidir tras eliminar espacios (incluido null). Un valor no vacío sin ninguno de los dos shortcodes fuera de los comentarios HTML devuelve missing_preheader_shortcode. No se inserta nada en el HTML.