API Reference

REST API v1 — Envío de emails programático

v1
Introducción

La API de EasyEmails te permite enviar emails de forma programática desde cualquier aplicación. Todas las peticiones se realizan sobre HTTPS y las respuestas se devuelven en formato JSON.

Base URL
https://easyemails.dev/api/v1
Formato
application/json
Autenticación
Bearer token
Fechas y horas
ISO 8601 · UTC
Todos los campos de fecha y hora (queued_at, sent_at, scheduled_at, created_at, etc.) se expresan en UTC con formato ISO 8601 (2026-06-01T10:00:00+00:00). Envía scheduled_at también en UTC.
Autenticación

Todas las peticiones deben incluir tu API key en el header Authorization usando el esquema Bearer. Puedes generar claves desde Cuentas SMTP.

# Header requerido en todas las peticiones Authorization: Bearer ee_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Cada API key está vinculada a una cuenta SMTP específica. Guarda tus claves de forma segura — no las incluyas en código público.
POST /api/v1/emails Encola un email para envío

Acepta tanto application/json como multipart/form-data (para adjuntos).

Parámetros del cuerpo
CampoTipoDescripción
to requeridoarrayLista de destinatarios. Ej: ["user@example.com"]
subject requeridostringAsunto del email
html opcionalstringCuerpo en HTML. Se requiere al menos html, text o easyrender
text opcionalstringCuerpo en texto plano
cc opcionalarrayDestinatarios en copia
bcc opcionalarrayDestinatarios en copia oculta
reply_to opcionalstringDirección de respuesta
from_name opcionalstringNombre del remitente (sobreescribe el de la cuenta SMTP)
attachments opcionalarray / file[]Archivos adjuntos. En JSON: array de objetos (ver tabla inferior). Con multipart/form-data: campos attachments[]
headers opcionalobjectHeaders adicionales. Ej: {"X-Custom": "value"}
priority opcionalintegerPrioridad de la cola: 1 (alta) – 5 (baja). Por defecto: 3
scheduled_at opcionalstringEnvío programado en ISO 8601 UTC. Ej: 2026-06-01T10:00:00Z
track_opens opcionalbooleanActivar tracking de aperturas
track_clicks opcionalbooleanActivar tracking de clics
tags opcionalarrayEtiquetas para categorizar. Ej: ["newsletter", "promo"]
metadata opcionalobjectDatos personalizados adjuntos al job
template_id opcionalstring (UUID)ID de una plantilla guardada en tu cuenta. Rellena subject, html y from_name como valores por defecto; cualquier campo explícito en el payload tiene prioridad
Objeto attachments[] (en JSON)

Cuando usas application/json, cada adjunto es un objeto con las siguientes propiedades. Puedes mezclar adjuntos regulares e imágenes incrustadas (CID) en el mismo envío.

CampoTipoDescripción
content requerido* string Contenido del archivo en Base64. Usa este campo o url, no ambos.
url requerido* string URL pública del archivo. El servidor lo descargará. Usa este campo o content, no ambos.
filename opcional string Nombre del archivo. Ej: "logo.png". Por defecto se toma del nombre de la URL o "attachment".
mime_type opcional string MIME type. Ej: "image/png", "application/pdf". Por defecto: "application/octet-stream".
cid opcional string Identificador CID para imagen incrustada. Cuando se especifica, la imagen se adjunta como inline y el HTML puede referenciarla con <img src="cid:tu-cid">.
Sin este campo, el archivo se adjunta como descarga normal.

* Se requiere exactamente uno de los dos: content o url.

Ejemplo — JSON
curl -X POST https://easyemails.dev/api/v1/emails \ -H "Authorization: Bearer ee_xxxxx" \ -H "Content-Type: application/json" \ -d '{ "to": ["destinatario@ejemplo.com"], "subject": "Bienvenido", "html": "<h1>Hola!</h1><p>Gracias por registrarte.</p>", "text": "Hola! Gracias por registrarte.", "tags": ["welcome"], "priority": 1 }'
Respuesta 202 Accepted
{ "email_id": "019e5f4e-6a62-73bb-a718-3a1e21be3588", "status": "pending", "priority": 1, "queued_at": "2026-05-25T10:00:00+00:00" }
Ejemplo — adjunto regular (Base64)
curl -X POST https://easyemails.dev/api/v1/emails \ -H "Authorization: Bearer ee_xxxxx" \ -H "Content-Type: application/json" \ -d '{ "to": ["cliente@ejemplo.com"], "subject": "Informe mensual", "html": "<p>Adjunto el informe.</p>", "attachments": [ { "content": "<base64 del PDF>", "filename": "informe-junio.pdf", "mime_type": "application/pdf" } ] }'
Ejemplo — imagen incrustada con CID

El campo cid incrusta la imagen directamente en el email (no como descarga). Referencia la imagen en el HTML con <img src="cid:tu-cid">.

curl -X POST https://easyemails.dev/api/v1/emails \ -H "Authorization: Bearer ee_xxxxx" \ -H "Content-Type: application/json" \ -d '{ "to": ["cliente@ejemplo.com"], "subject": "Bienvenido a EasyEmails", "html": "<img src=\"cid:logo\" alt=\"Logo\"><p>Gracias por registrarte.</p>", "attachments": [ { "content": "<base64 de la imagen>", "filename": "logo.png", "mime_type": "image/png", "cid": "logo" } ] }'
El valor de cid puede ser cualquier cadena sin espacios. El sistema genera internamente el Content-ID MIME y reescribe las referencias cid: del HTML automáticamente. Puedes combinar imágenes incrustadas y adjuntos regulares en el mismo envío.
Ejemplo con adjuntos — multipart/form-data
curl -X POST https://easyemails.dev/api/v1/emails \ -H "Authorization: Bearer ee_xxxxx" \ -F 'to=["destinatario@ejemplo.com"]' \ -F "subject=Informe mensual" \ -F "html=<p>Adjunto el informe.</p>" \ -F "attachments=@/ruta/al/informe.pdf"
Ejemplo con plantilla guardada

Usa el UUID de una plantilla creada en Plantillas. El asunto y el cuerpo HTML se toman de la plantilla; puedes sobreescribir cualquier campo en el payload. Si la plantilla tiene from_name, también se aplica como default.

curl -X POST https://easyemails.dev/api/v1/emails \ -H "Authorization: Bearer ee_xxxxx" \ -H "Content-Type: application/json" \ -d '{ "to": ["cliente@ejemplo.com"], "template_id": "019e5f4e-6a62-73bb-a718-3a1e21be3588" }' # Sobreescribir el asunto manteniendo el HTML de la plantilla: curl -X POST https://easyemails.dev/api/v1/emails \ -H "Authorization: Bearer ee_xxxxx" \ -H "Content-Type: application/json" \ -d '{ "to": ["cliente@ejemplo.com"], "template_id": "019e5f4e-6a62-73bb-a718-3a1e21be3588", "subject": "Asunto personalizado para este envío" }'
Prioridad de campos: payload > plantilla. Si envías html, text o easyrender, el cuerpo de la plantilla se ignora y solo se aplican subject y from_name como defaults.
GET /api/v1/emails/{id} Consulta el estado de un email
Ejemplo
curl https://easyemails.dev/api/v1/emails/019e5f4e-... \ -H "Authorization: Bearer ee_xxxxx"
Respuesta 200 OK
{ "email_id": "019e5f4e-...", "status": "sent", "priority": 3, "subject": "Bienvenido", "to": ["dest@ejemplo.com"], "attempt_count": 1, "sent_at": "2026-05-25T10:00:05+00:00", "created_at": "2026-05-25T10:00:00+00:00", "last_error": null, "attempts": [{ "attempt": 1, "status": "success", "smtp_response": "250 OK", "error": null, "attempted_at": "2026-05-25T10:00:05+00:00" }] }
Estados posibles
pending — en cola, esperando envío processing — enviándose ahora sent — entregado correctamente failed — falló tras todos los intentos cancelled — cancelado manualmente
PATCH /api/v1/emails/{id} Actualiza y reencola un email fallido

Permite modificar los datos de un email en estado failed y volver a encolarlo. Se registra un historial de todos los cambios. Si el email lleva más de 3 días fallando y el usuario ya fue notificado, pasa a estado errored y no puede modificarse.

Campos editables
CampoTipoDescripción
toarrayDestinatarios
subjectstringAsunto
htmlstringCuerpo HTML
textstringCuerpo texto plano
reply_tostringDirección reply-to
ccarrayCopia
bccarrayCopia oculta
headersobjectCabeceras personalizadas
tagsarrayEtiquetas
metadataobjectMetadatos arbitrarios
Ejemplo
curl -X PATCH https://easyemails.dev/api/v1/emails/019e5f4e-... \ -H "Authorization: Bearer ee_xxxxx" \ -H "Content-Type: application/json" \ -d '{ "to": ["nuevo@ejemplo.com"], "subject": "Asunto corregido" }'
Respuesta 200 OK
{ "email_id": "019e5f4e-...", "status": "pending", "fields_updated": ["to", "subject"], "edit_count": 1, "first_failed_at": "2026-05-24T10:00:00+00:00", "queued_at": "2026-05-26T08:30:00+00:00" }
Errores posibles
CódigoMotivo
404Email no encontrado
409El email no está en estado failed
422El email está en estado errored (permanente)
422Validación del payload fallida
Historial de cambios: cada actualización queda registrada. Consúltalo en GET /api/v1/emails/{id} bajo el campo edits[].
DELETE /api/v1/emails/{id} Cancela un email pendiente

Solo se pueden cancelar emails en estado pending. Si ya está siendo procesado o enviado, devuelve 409 Conflict.

Ejemplo
curl -X DELETE https://easyemails.dev/api/v1/emails/019e5f4e-... \ -H "Authorization: Bearer ee_xxxxx"
Respuesta 200 OK
{ "cancelled": true }
Códigos de error
CódigoDescripción
400 Bad RequestPetición malformada o CSRF inválido
401 UnauthorizedAPI key ausente o inválida
403 ForbiddenSin cuota disponible o cuenta suspendida
404 Not FoundEmail no encontrado o no pertenece a esta API key
409 ConflictEl email no está en estado pending y no se puede cancelar
422 Unprocessable EntityValidación fallida. El body incluye array errors
429 Too Many RequestsRate limit alcanzado
500 Internal Server ErrorError del servidor
Formato de error estándar
{ "errors": [ "\"to\" must be a non-empty array of email addresses.", "\"subject\" is required." ] } // O para error único: { "error": "Only pending emails can be cancelled." }
Rate limits y cola

EasyEmails encola los emails y los envía secuencialmente respetando el rate limit configurado en cada cuenta SMTP. Esto evita que tu servidor SMTP bloquee tu IP por exceso de peticiones.

Asíncrono
Los emails se procesan en segundo plano
Reintentos
Reintentos automáticos con backoff exponencial
Prioridad
Cola con 5 niveles de prioridad (1 = máxima)
Quick start en 3 pasos
1
Añade una cuenta SMTP
Ve a Cuentas SMTP y configura tu servidor
2
Genera una API key
Desde la gestión de la cuenta SMTP, genera y copia tu clave
3
Envía tu primer email
Usa el endpoint POST /api/v1/emails con tu Bearer token