POST /send-email
Encola un correo para envío inmediato o lo programa para una fecha futura.
API avanzada (
recipient/sender/html) — la única con envío programado, plantillas y dry_run. Para integraciones simples, la API v1 usa nombres REST y contrato estable.Autenticacion
Bearer token con una API key del proyecto:sk_proj_*/sk_live_* (Live) y sk_test_* (Test). El project_id se infiere de la key.
Ver más en Autenticación.
Request Body
Adjuntos
Cada objeto en el arrayattachments tiene la siguiente estructura:
Límites:
- Máximo 10 adjuntos por correo.
- Máximo 10 MB por adjunto individual.
- Máximo 10 MB en total por correo (límite de la infraestructura de envío).
Programacion de Envio
El camposcheduled_at soporta múltiples formatos:
Timestamp ISO 8601
Lenguaje natural (ingles)
Zona horaria (timezone)
El campo timezone se usa para interpretar correctamente scheduled_at. Soporta:
- Nombre IANA:
"America/Santiago","US/Eastern","Europe/Madrid" - Offset:
"+09:00","-05:00","UTC-3","GMT+9" - Numérico entero:
-3,9(sin fracciones — para zonas de media hora como India usa el formato"+05:30")
timezone, se usa la zona horaria por defecto del proyecto (default_timezone). Si el proyecto no tiene zona horaria configurada, se asume UTC.
Ver más en Programar Envíos.
Gestionar un envio programado
UnPOST /send-email con scheduled_at devuelve scheduled_send_id (ver la respuesta del envío programado). Con ese ID puedes consultar, reprogramar o cancelar el envío mientras siga en estado pending.
GET /v1/scheduled-sends/:id
Devuelve el estado del envío programado.- cURL
200 OK
Responde
404 NOT_FOUND si el ID no existe en el proyecto.
PATCH /v1/scheduled-sends/:id
Reprograma el envío a una nueva fecha. Solo mientras el estado seapending.
- cURL
200 OK — la fila actualizada, con las mismas columnas del GET.
DELETE /v1/scheduled-sends/:id
Cancela el envío si sigue enpending.
- cURL
200 OK
Dry Run
Con"dry_run": true el endpoint renderiza el correo sin enviarlo: no encola, no registra actividad ni consume cuota. Útil para validar payload y variables antes de un envío real.
html_preview se trunca a 8000 caracteres. Las variables sin valor en data se dejan como {{variable}} en el preview.
Headers
Ver más sobre
Idempotency-Key en API Keys.
Ejemplo de Solicitud
Envio inmediato
- cURL
- Node.js
- Python
200 OK
Envio programado con adjuntos
- cURL
- Node.js
- Python
200 OK
Ver más en SDK de Node.js.
Respuesta del envio inmediato
El envío es asíncrono: el endpoint encola el correo y responde de inmediato con200 (ver el ejemplo arriba). El envío real ocurre en segundo plano.
El resultado final del envío (delivered, bounced, failed) no viene en esta respuesta: se consulta vía la Activity API usando
email_id, o se recibe vía webhooks (email.send, email.delivery, email.bounce, etc.).
Tipo de envio
El campoemail_type declara la naturaleza del envío, y de eso depende qué supresiones se le aplican.
La razón de que el default sea
transactional: un rebote es señal del buzón (esa dirección no
existe) y debe frenar todo, pero una baja del newsletter es señal del usuario sobre tus
campañas — no puede impedir que reciba su código de verificación o el resultado que pidió.campaign y automation se tratan como marketing. Cualquier otro valor
(individual, welcome, …) se acepta por compatibilidad y cuenta como transaccional.
Destinatario Suprimido
Si el destinatario está en la lista de supresión del proyecto, el correo no se encola: la API responde200 de inmediato con suppressed: true y nada sale hacia el destinatario.
Qué supresiones aplican depende del tipo de envío: un envío transaccional solo se frena por rebote duro o queja; uno de marketing, además, por las bajas voluntarias.
Es un
200 intencional (no un error): reintentar el mismo envío devolverá lo mismo. Lo correcto es marcar la dirección en tu sistema y dejar de enviarle — también puedes escuchar el webhook email.suppressed para sincronizarlo automáticamente. La lista se gestiona en el dashboard (Audiencia → Suprimidos).
Reply-To Automatico (Inbound Email)
Todos los envíos vía API incluyen automáticamente un headerReply-To con el nombre del remitente:
email.inbound con adjuntos. Ver Webhooks → Inbound.
Verificacion de Remitente
Elsender debe estar verificado antes de poder enviar. Hay dos formas:
- Verificar el email individual vía magic link (
POST /domains/verify-email). - Verificar el dominio completo vía DNS (
POST /domains/register) — recomendado, mejora deliverability y permite enviar desde cualquier dirección del dominio.
200 con queued: true, y el rechazo ocurre en segundo plano. El fallo queda en el activity record (current_status: "failed", error_message), consultable vía Activity con el email_id.
Ver más en Domains API.
Codigos de Error
Como el envío es asíncrono, los únicos errores síncronos (en la respuesta HTTP) son de validación:
Los errores de envío (sender no verificado, adjunto inválido, rate limit) ocurren en segundo plano: el activity record pasa a
current_status: "failed" con el detalle en error_message.