Emails
Envía emails, consulta los mensajes y su contenido, y prográmalos, cancélalos, reinténtalos o reenvíalos.
Enviar un email
Envía un email desde un dominio de envío verificado. Cada destinatario recibe una copia independiente con su propio ID de email, y cada destinatario cuesta un crédito.
/emailsFunciona con claves de API sending y full. Los envíos cuentan para los límites de envío del espacio de trabajo, y una respuesta correcta significa que el email se ha aceptado y puesto en cola, no que se haya entregado. Sigue la entrega con webhooks o con Obtener un email. Los espacios de trabajo sin verificar solo pueden enviar a las direcciones de email de las cuentas de sus miembros.
Cabeceras
Idempotency-KeystringUna clave única de hasta 256 letras, dígitos, - y _. Un reintento con la misma clave en un plazo de 24 horas devuelve la primera respuesta en lugar de volver a enviar el email. Consulta Idempotencia.
Parámetros del cuerpo
fromstringobligatorioEl remitente, como hello@acme.com o Acme <hello@acme.com>. La dirección debe pertenecer a un dominio de envío verificado del espacio de trabajo, y al dominio de la clave si la clave está limitada a un dominio.
tostring | string[]obligatorioLos destinatarios, como array o como cadena separada por comas. Cada entrada puede ser ada@example.com o Ada Lovelace <ada@example.com>. Hasta 50.
ccstring | string[]bccstring | string[]reply_tostring | string[]subjectstringtemplate.htmlstringhtml, text o ambos, salvo que template aporte el contenido.textstringhtml y text, los destinatarios reciben un mensaje multiparte.templatestringUna plantilla que enviar. Pasa un ID de plantilla (tem_…) para usar exactamente esa versión, o un alias para usar su versión publicada. subject, html y text en la petición sustituyen a los de la plantilla. Consulta Plantillas.
variablesobjectLos valores de los marcadores de Temple, como {{first_name}}, que se renderizan en el asunto, el HTML y el texto. Funciona con plantillas y con contenido en línea.
attachmentsobject[]headersobjectCabeceras MIME adicionales como pares nombre–valor, por ejemplo {"List-Unsubscribe": "<https://acme.com/unsubscribe>"}. Emailit asigna Message-ID por su cuenta.
metaobjectTus propios datos clave–valor, por ejemplo {"order_id": "1042"}. Los valores deben ser cadenas. Se guardan con el email y se incluyen en las lecturas y en los payloads de los webhooks.
scheduled_atstringCuándo enviar, como fecha y hora ISO 8601, por ejemplo 2026-10-02T09:00:00Z, o en inglés, como tomorrow at 9am. Incluye una zona horaria en los valores ISO 8601. Una hora en el pasado, o un valor que no se puede interpretar (incluida una marca de tiempo Unix), envía el email de inmediato. Los emails programados tienen el estado scheduled hasta que se envían.
trackingboolean | objectActiva o desactiva el seguimiento de aperturas y de clics de este email: true, false o {"loads": true, "clicks": false}. Por defecto, se usa la configuración del dominio de envío. El seguimiento solo funciona si el CNAME de seguimiento del dominio está verificado; si no, está desactivado y la respuesta muestra false.
Objeto de adjunto
filenamestringobligatoriocontentstringcontent o url, no ambos.urlstringUna URL pública http o https desde la que descargar el archivo. Emailit la descarga al enviar: la descarga debe terminar en 30 segundos, ocupar como máximo 25 MB y no puede redirigir.
content_typestringapplication/pdf. Obligatorio con content. Con url, por defecto se usa el tipo que devuelve el servidor.content_idstringConvierte el adjunto en un adjunto en línea. Haz referencia a él en el HTML como <img src="cid:logo"> cuando content_id es logo.
encodingstringpor defecto: base64content, como base64 o hex.El mensaje completo, adjuntos incluidos, puede ocupar hasta 40 MB. Se permiten estos tipos de archivo:
| Categoría | Extensiones |
|---|---|
| Texto | .txt, .csv, .log, .css, .ics, .xml |
| Imágenes | .jpg, .jpe, .jpeg, .gif, .png, .bmp, .psd, .tif, .tiff, .svg, .indd, .ai, .eps |
| Documentos | .doc, .docx, .rtf, .odt, .ott, .pdf, .pub, .pages, .mobi, .epub |
| Audio | .mp3, .m4a, .m4v, .wma, .ogg, .flac, .wav, .aif, .aifc, .aiff |
| Vídeo | .mp4, .mov, .avi, .mkv, .mpeg, .mpg, .wmv |
| Hojas de cálculo | .xls, .xlsx, .ods, .numbers |
| Presentaciones | .odp, .ppt, .pptx, .pps, .key |
| Archivos comprimidos | .zip, .vcf |
.eml |
|
| Criptografía | .p7c, .p7m, .p7s, .pgp, .asc, .sig |
Devuelve
Devuelve 200 con el objeto de email del primer destinatario. Si el mensaje tiene más de un destinatario entre to, cc y bcc, ids relaciona cada destinatario con el ID de su copia. Cada copia dispara un evento email.accepted o email.scheduled.
objectstringemail.idstringidsobjecttokenstringmessage_idstringMessage-ID del primer email, como <token@acme.com>.fromstringtostring[]to, sin nombres visibles ni duplicados.ccstring[]cc. Solo aparece si los enviaste.bccstring[]bcc. Solo aparece si los enviaste.subjectstringstatusstringaccepted, o scheduled si scheduled_at es una fecha futura.scheduled_atstring | nullnull.created_atstringtrackingobjectloads y clicks.curl -X POST https://api.emailit.com/v2/emails \
-H "Authorization: Bearer $EMAILIT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "Acme <hello@acme.com>",
"to": "ada@example.com",
"template": "welcome",
"variables": {
"first_name": "Ada",
"activation_url": "https://acme.com/activate?token=8f2c1e"
}
}'const email = await emailit.emails.send({
from: 'Acme <hello@acme.com>',
to: 'ada@example.com',
template: 'welcome',
variables: {
first_name: 'Ada',
activation_url: 'https://acme.com/activate?token=8f2c1e',
},
});email = client.emails.send({
"from": "Acme <hello@acme.com>",
"to": "ada@example.com",
"template": "welcome",
"variables": {
"first_name": "Ada",
"activation_url": "https://acme.com/activate?token=8f2c1e"
}
})curl -X POST https://api.emailit.com/v2/emails \
-H "Authorization: Bearer $EMAILIT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "Acme Billing <billing@acme.com>",
"to": "ada@example.com",
"subject": "Your invoice INV-1042",
"html": "<img src=\"cid:logo\"><p>Your invoice is attached.</p>",
"attachments": [
{
"filename": "INV-1042.pdf",
"content": "JVBERi0xLjQKJcOkw7zDqc...",
"content_type": "application/pdf"
},
{
"filename": "logo.png",
"url": "https://acme.com/assets/logo.png",
"content_id": "logo"
}
]
}'import { readFile } from 'node:fs/promises';
const pdf = await readFile('INV-1042.pdf');
const email = await emailit.emails.send({
from: 'Acme Billing <billing@acme.com>',
to: 'ada@example.com',
subject: 'Your invoice INV-1042',
html: '<img src="cid:logo"><p>Your invoice is attached.</p>',
attachments: [
{
filename: 'INV-1042.pdf',
content: pdf.toString('base64'),
content_type: 'application/pdf',
},
{
filename: 'logo.png',
url: 'https://acme.com/assets/logo.png',
content_id: 'logo',
},
],
});import base64
with open("INV-1042.pdf", "rb") as f:
pdf = base64.b64encode(f.read()).decode()
email = client.emails.send({
"from": "Acme Billing <billing@acme.com>",
"to": "ada@example.com",
"subject": "Your invoice INV-1042",
"html": '<img src="cid:logo"><p>Your invoice is attached.</p>',
"attachments": [
{"filename": "INV-1042.pdf", "content": pdf, "content_type": "application/pdf"},
{"filename": "logo.png", "url": "https://acme.com/assets/logo.png", "content_id": "logo"}
]
})curl -X POST https://api.emailit.com/v2/emails \
-H "Authorization: Bearer $EMAILIT_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: reminder-appt-5531" \
-d '{
"from": "Acme <reminders@acme.com>",
"to": "ada@example.com",
"subject": "Your appointment tomorrow",
"text": "See you tomorrow at 2 PM.",
"scheduled_at": "2026-10-02T09:00:00Z",
"meta": { "appointment_id": "5531" }
}'const email = await emailit.emails.send({
from: 'Acme <reminders@acme.com>',
to: 'ada@example.com',
subject: 'Your appointment tomorrow',
text: 'See you tomorrow at 2 PM.',
scheduled_at: '2026-10-02T09:00:00Z',
meta: { appointment_id: '5531' },
});email = client.emails.send({
"from": "Acme <reminders@acme.com>",
"to": "ada@example.com",
"subject": "Your appointment tomorrow",
"text": "See you tomorrow at 2 PM.",
"scheduled_at": "2026-10-02T09:00:00Z",
"meta": {"appointment_id": "5531"}
}){
"object": "email",
"id": "em_4KYof1ZzXndZE2VPi0DgULiekG8",
"ids": {
"ada@example.com": "em_4KYof1ZzXndZE2VPi0DgULiekG8",
"grace@example.com": "em_4KfIXZSV8v8L1k0Mg2YDR3rytvj"
},
"token": "4KDY1iIpQSSW5pAoiz3JEfqcsO0",
"message_id": "<4KDY1iIpQSSW5pAoiz3JEfqcsO0@acme.com>",
"from": "Acme <hello@acme.com>",
"to": ["ada@example.com", "grace@example.com"],
"subject": "Welcome to Acme",
"status": "accepted",
"scheduled_at": null,
"created_at": "2026-10-01T09:30:12.482913Z",
"tracking": {
"loads": true,
"clicks": true
}
}{
"object": "email",
"id": "em_4K76IA5sFNIsLXW9QC2ro8cDbOj",
"token": "4KWzEED2cnej6UMjF4v508VqQIp",
"message_id": "<4KWzEED2cnej6UMjF4v508VqQIp@acme.com>",
"from": "Acme <reminders@acme.com>",
"to": ["ada@example.com"],
"subject": "Your appointment tomorrow",
"status": "scheduled",
"scheduled_at": "2026-10-02T09:00:00.000Z",
"created_at": "2026-10-01T09:30:12.482913Z",
"tracking": {
"loads": false,
"clicks": false
}
}{
"error": "Validation failed",
"validation_errors": [
"Missing required field: subject",
"Invalid to email address at index 1: grace@example"
]
}{
"error": "Insufficient credits",
"message": "Insufficient credits to send this email. Required: 2, available: 0."
}{
"code": "unverified_workspace_recipient",
"error": "Workspace not verified",
"message": "Unverified workspaces can only send to workspace members' account emails. Blocked recipient: grace@example.com.",
"blocked_recipients": ["grace@example.com"]
}{
"error": "Domain not authorized",
"message": "API key is not authorized to send from this domain"
}{
"error": "Template not found",
"message": "Template 'welcome' not found or not published"
}{
"error": "Message too large",
"message": "Message size (41.27MB) exceeds maximum allowed size of 40MB"
}{
"error": "Domain not verified"
}{
"error": "Rate limit exceeded",
"message": "Too many requests. Maximum 2 messages per second allowed.",
"limit": 2,
"current": 2,
"retry_after": 1
}Listar emails
Devuelve una página de emails, del más reciente al más antiguo. Por defecto, la lista muestra los emails salientes de los últimos 14 días.
/emailsRequiere una clave de API full. Cada destinatario de un envío es un email independiente en esta lista.
Parámetros de consulta
pageintegerpor defecto: 1limitintegerpor defecto: 25typestringpor defecto: outbounddate_fromstringSolo los emails creados en esta fecha o después, como 2026-08-01 (desde las 00:00 UTC). Sin este parámetro, la lista empieza hace 14 días. Los filtros created_at no cambian esta ventana.
date_tostringsearchstringmatchstringpor defecto: allall u or. Cómo se combinan los filtros que se indican abajo.orderstringdirectionstringasc o desc.Filtros
Añade filtros con el formato key.condition=value, por ejemplo status.exact=bounced o created_at.after=2026-09-01. Para conocer las condiciones de cada tipo, consulta Filtrado.
| Clave | Tipo | Valores y notas |
|---|---|---|
to |
cadena | Dirección del destinatario. |
from |
cadena | Remitente tal como se envió, incluido el nombre visible, si lo hay. |
subject |
cadena | |
status |
enumeración | accepted, scheduled, delivered, loaded, clicked, attempted, bounced, failed, rejected, suppressed, received, complained, canceled, held |
tag |
cadena | La etiqueta del email. Por ahora, los envíos por la API o por SMTP no asignan ninguna etiqueta. |
spam_score |
número | |
created_at |
fecha | |
updated_at |
fecha | |
api_key_id |
cadena | El ID de la clave de API que envió el email (key_…). |
sending_domain_id |
cadena | El ID del dominio de envío (dom_…). |
Todas las claves de filtro son también claves de ordenación. Los parámetros de consulta antiguos status, rcpt_to, mail_from, subject, api_key_id y sending_domain_id siguen funcionando: status busca coincidencias exactas, y los parámetros de dirección y de asunto, coincidencias parciales.
Devuelve
Devuelve un array data de objetos de email con next_page_url y previous_page_url. Consulta Paginación. Las URL de página no incluyen tus filtros, así que pide la página siguiente con tus propios parámetros y page aumentado en uno.
objectstringemail.idstringtypestringoutbound o inbound.fromstringtostringsubjectstringstatusstringsizeintegerscheduled_atstring | nullnull.created_atstringupdated_atstringmetaobject | nullmeta que enviaste.curl -G https://api.emailit.com/v2/emails \
-H "Authorization: Bearer $EMAILIT_API_KEY" \
-d status.exact=bounced \
-d status.exact=failed \
-d match=or \
-d date_from=2026-09-01 \
-d order=created_at \
-d direction=desc{
"data": [
{
"object": "email",
"id": "em_4KYof1ZzXndZE2VPi0DgULiekG8",
"type": "outbound",
"from": "Acme <hello@acme.com>",
"to": "ada@example.com",
"subject": "Welcome to Acme",
"status": "delivered",
"size": 4523,
"scheduled_at": null,
"created_at": "2026-10-01T09:30:12.482913Z",
"updated_at": "2026-10-01T09:30:14.118204Z",
"meta": null
},
{
"object": "email",
"id": "em_4KfIXZSV8v8L1k0Mg2YDR3rytvj",
"type": "outbound",
"from": "Acme <hello@acme.com>",
"to": "grace@example.com",
"subject": "Welcome to Acme",
"status": "loaded",
"size": 4527,
"scheduled_at": null,
"created_at": "2026-10-01T09:30:12.482913Z",
"updated_at": "2026-10-01T09:41:03.770521Z",
"meta": null
}
],
"next_page_url": "/app/v2/emails?page=2&limit=25",
"previous_page_url": null
}{
"statusCode": 400,
"error": "Bad Request",
"message": "Validation error",
"details": [
{
"instancePath": "/limit",
"schemaPath": "#/properties/limit/maximum",
"keyword": "maximum",
"params": { "comparison": "<=", "limit": 100 },
"message": "must be <= 100"
}
]
}Obtener un email
Obtiene un email con su estado, las cabeceras analizadas, el cuerpo HTML y de texto, y los adjuntos.
/emails/{id}Requiere una clave de API full. El contenido del mensaje se conserva durante el periodo de retención de contenido de tu plan. Después, headers, body y attachments quedan vacíos, y se conservan el estado y los metadatos. Para obtener solo una parte de un email, usa Obtener el cuerpo, Obtener los metadatos, Listar adjuntos u Obtener el MIME en bruto.
Parámetros de ruta
idstringobligatorioem_4KYof1ZzXndZE2VPi0DgULiekG8.Devuelve
Devuelve el objeto de email.
objectstringemail.idstringtypestringoutbound para los emails que enviaste, inbound para los emails que recibiste.tokenstringmessage_idstringMessage-ID.fromstringAcme <hello@acme.com>.tostringsubjectstringstatusstringEl estado actual: accepted, scheduled, delivered, loaded, clicked, attempted, bounced, failed, rejected, suppressed, received, complained, canceled o held. Consulta Estados de los emails.
sizeintegerscheduled_atstring | nullnull.created_atstringupdated_atstringtrackingobjectloads) y de clics (clicks) está activado.metaobject | nullmeta que enviaste, o null.headersobject | nullnull una vez purgado el contenido.bodyobjecttext y html, cada uno una cadena o null.attachmentsobject[]Los adjuntos, cada uno con filename, content_type, size en bytes, content_id (en los archivos en línea), content_disposition (attachment o inline) y content (Base64).
{
"object": "email",
"id": "em_4KYof1ZzXndZE2VPi0DgULiekG8",
"type": "outbound",
"token": "4KDY1iIpQSSW5pAoiz3JEfqcsO0",
"message_id": "<4KDY1iIpQSSW5pAoiz3JEfqcsO0@acme.com>",
"from": "Acme Billing <billing@acme.com>",
"to": "ada@example.com",
"subject": "Your invoice INV-1042",
"status": "delivered",
"size": 48213,
"scheduled_at": null,
"created_at": "2026-10-01T09:30:12.482913Z",
"updated_at": "2026-10-01T09:30:14.118204Z",
"tracking": {
"loads": true,
"clicks": true
},
"meta": {
"invoice_id": "INV-1042"
},
"headers": {
"From": "Acme Billing <billing@acme.com>",
"To": "ada@example.com",
"Subject": "Your invoice INV-1042",
"Message-ID": "<4KDY1iIpQSSW5pAoiz3JEfqcsO0@acme.com>",
"MIME-Version": "1.0",
"Content-Type": "multipart/mixed; boundary=\"--_NmP-4f1c2a9e7b3d0e5f-Part_1\""
},
"body": {
"text": "Your invoice is attached.",
"html": "<p>Your invoice is attached.</p>"
},
"attachments": [
{
"filename": "INV-1042.pdf",
"content_type": "application/pdf",
"size": 40960,
"content_id": null,
"content_disposition": "attachment",
"content": "JVBERi0xLjQKJcOkw7zDqc..."
}
]
}{
"object": "email",
"id": "em_4KbeG9poqTmjvQZeN8pMoJkCVNd",
"type": "inbound",
"token": "4KTnDU5PzzqDqp8UWb9qVhPVFOT",
"message_id": "<CAH7x2k9@mail.example.com>",
"from": "Ada Lovelace <ada@example.com>",
"to": "support@inbound.acme.com",
"subject": "Re: Your invoice INV-1042",
"status": "received",
"size": 8234,
"scheduled_at": null,
"created_at": "2026-10-01T11:02:45.031877Z",
"updated_at": "2026-10-01T11:02:45.031877Z",
"meta": null,
"headers": {
"From": "Ada Lovelace <ada@example.com>",
"To": "support@inbound.acme.com",
"Subject": "Re: Your invoice INV-1042",
"Content-Type": "text/plain; charset=utf-8"
},
"body": {
"text": "Thanks, received.",
"html": null
},
"attachments": []
}{
"error": "Email not found",
"message": "Email with ID 'em_4KYof1ZzXndZE2VPi0DgULiekG8' not found in your workspace"
}Obtener el MIME en bruto
Obtiene el código fuente MIME completo de un email tal como lo almacena Emailit, junto con sus metadatos.
/emails/{id}/rawRequiere una clave de API full. Úsalo para archivar un mensaje, depurar su estructura o analizarlo con tu propia biblioteca MIME. Cuando termina el periodo de retención del contenido, raw y headers son null.
Parámetros de ruta
idstringobligatorioDevuelve
Devuelve los metadatos del email, como en Obtener los metadatos pero sin attachments, además del mensaje en bruto.
rawstring | nullnull una vez purgado el contenido.headersobject | nullLos demás campos (object, id, type, token, message_id, from, to, subject, status, size, scheduled_at, created_at, updated_at, tracking y meta) son los mismos que en Obtener un email.
{
"object": "email",
"id": "em_4KYof1ZzXndZE2VPi0DgULiekG8",
"type": "outbound",
"token": "4KDY1iIpQSSW5pAoiz3JEfqcsO0",
"message_id": "<4KDY1iIpQSSW5pAoiz3JEfqcsO0@acme.com>",
"from": "Acme <hello@acme.com>",
"to": "ada@example.com",
"subject": "Welcome to Acme",
"status": "delivered",
"size": 1342,
"scheduled_at": null,
"created_at": "2026-10-01T09:30:12.482913Z",
"updated_at": "2026-10-01T09:30:14.118204Z",
"tracking": {
"loads": false,
"clicks": false
},
"meta": null,
"headers": {
"From": "Acme <hello@acme.com>",
"To": "ada@example.com",
"Subject": "Welcome to Acme",
"Message-ID": "<4KDY1iIpQSSW5pAoiz3JEfqcsO0@acme.com>",
"MIME-Version": "1.0",
"Content-Type": "text/html; charset=utf-8"
},
"raw": "From: Acme <hello@acme.com>\r\nTo: ada@example.com\r\nSubject: Welcome to Acme\r\nMessage-ID: <4KDY1iIpQSSW5pAoiz3JEfqcsO0@acme.com>\r\nMIME-Version: 1.0\r\nContent-Type: text/html; charset=utf-8\r\nContent-Transfer-Encoding: quoted-printable\r\n\r\n<h1>Welcome!</h1><p>Thanks for signing up.</p>"
}{
"error": "Email not found",
"message": "Email with ID 'em_4KYof1ZzXndZE2VPi0DgULiekG8' not found in your workspace"
}Listar adjuntos
Devuelve los adjuntos de un email, incluido su contenido.
/emails/{id}/attachmentsRequiere una clave de API full. Funciona con emails salientes y entrantes. Incluye las imágenes en línea (partes con un Content-ID). Para obtener la lista sin el contenido de los archivos, usa Obtener los metadatos. Cuando termina el periodo de retención del contenido, la lista está vacía.
Parámetros de ruta
idstringobligatorioDevuelve
Devuelve un objeto de lista con todos los adjuntos. La lista no está paginada.
objectstringlist.dataobject[]data[].filenamestringdata[].content_typestringapplication/pdf.data[].sizeintegerdata[].content_idstring | nullContent-ID de un adjunto en línea, o null.data[].content_dispositionstring | nullattachment o inline.data[].contentstring{
"object": "list",
"data": [
{
"filename": "INV-1042.pdf",
"content_type": "application/pdf",
"size": 40960,
"content_id": null,
"content_disposition": "attachment",
"content": "JVBERi0xLjQKJcOkw7zDqc..."
},
{
"filename": "logo.png",
"content_type": "image/png",
"size": 5120,
"content_id": "logo",
"content_disposition": "inline",
"content": "iVBORw0KGgoAAAANSUhEUgAA..."
}
]
}{
"error": "Email not found",
"message": "Email with ID 'em_4KYof1ZzXndZE2VPi0DgULiekG8' not found in your workspace"
}Obtener el cuerpo
Devuelve el cuerpo HTML y de texto plano de un email, decodificado a partir de sus partes MIME.
/emails/{id}/bodyRequiere una clave de API full. Funciona con emails salientes y entrantes. En los emails salientes, el cuerpo es lo que se envió, después de renderizar la plantilla y las variables. Cuando termina el periodo de retención del contenido, los dos campos son null.
Parámetros de ruta
idstringobligatorioDevuelve
textstring | nullnull si el email no tiene.htmlstring | nullnull si el email no tiene.{
"text": "Welcome!\n\nThanks for signing up.",
"html": "<h1>Welcome!</h1><p>Thanks for signing up.</p>"
}{
"error": "Email not found",
"message": "Email with ID 'em_4KYof1ZzXndZE2VPi0DgULiekG8' not found in your workspace"
}Obtener los metadatos
Obtiene un email sin su cuerpo: el estado, las cabeceras, tus datos meta y la lista de adjuntos sin su contenido.
/emails/{id}/metaRequiere una clave de API full. Es la forma más ligera de consultar los detalles de un email cuando no necesitas el contenido.
Parámetros de ruta
idstringobligatorioDevuelve
Devuelve los mismos campos que Obtener un email, sin body, y con attachments descritos pero sin su contenido:
attachmentsobject[]filename, content_type, size, content_id y content_disposition de cada adjunto. Sin content.headersobject | nullnull una vez purgado el contenido.metaobject | nullmeta que enviaste con el email.{
"object": "email",
"id": "em_4KYof1ZzXndZE2VPi0DgULiekG8",
"type": "outbound",
"token": "4KDY1iIpQSSW5pAoiz3JEfqcsO0",
"message_id": "<4KDY1iIpQSSW5pAoiz3JEfqcsO0@acme.com>",
"from": "Acme Billing <billing@acme.com>",
"to": "ada@example.com",
"subject": "Your invoice INV-1042",
"status": "delivered",
"size": 48213,
"scheduled_at": null,
"created_at": "2026-10-01T09:30:12.482913Z",
"updated_at": "2026-10-01T09:30:14.118204Z",
"tracking": {
"loads": true,
"clicks": true
},
"meta": {
"invoice_id": "INV-1042"
},
"headers": {
"From": "Acme Billing <billing@acme.com>",
"To": "ada@example.com",
"Subject": "Your invoice INV-1042",
"Message-ID": "<4KDY1iIpQSSW5pAoiz3JEfqcsO0@acme.com>",
"MIME-Version": "1.0",
"Content-Type": "multipart/mixed; boundary=\"--_NmP-4f1c2a9e7b3d0e5f-Part_1\""
},
"attachments": [
{
"filename": "INV-1042.pdf",
"content_type": "application/pdf",
"size": 40960,
"content_id": null,
"content_disposition": "attachment"
}
]
}{
"error": "Email not found",
"message": "Email with ID 'em_4KYof1ZzXndZE2VPi0DgULiekG8' not found in your workspace"
}Actualizar un email programado
Traslada un email programado a una nueva hora de envío.
/emails/{id}Funciona con claves de API sending y full. Solo puedes reprogramar un email cuyo estado sea scheduled y cuya hora de envío actual quede a más de 3 minutos. Solo se puede cambiar la hora de envío; para cambiar el contenido, cancela el email y envía uno nuevo.
Un envío programado a varios destinatarios crea un email por destinatario. Reprograma cada ID del mapa ids de la respuesta del envío.
Parámetros de ruta
idstringobligatorioParámetros del cuerpo
scheduled_atstringobligatorioLa nueva hora de envío, como fecha y hora ISO 8601, por ejemplo 2026-10-03T09:00:00Z, o en inglés, como tomorrow at 3pm. Debe quedar a más de 3 minutos en el futuro.
Devuelve
objectstringemail.idstringstatusstringscheduled.scheduled_atstringupdated_atstringmessagestringDevuelve 422 si el email no está programado, si faltan menos de 3 minutos para su envío, o si la hora nueva no se puede interpretar o está demasiado próxima.
curl -X POST https://api.emailit.com/v2/emails/em_4K76IA5sFNIsLXW9QC2ro8cDbOj \
-H "Authorization: Bearer $EMAILIT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"scheduled_at": "tomorrow at 3pm"}'{
"object": "email",
"id": "em_4K76IA5sFNIsLXW9QC2ro8cDbOj",
"status": "scheduled",
"scheduled_at": "2026-10-03T09:00:00.000Z",
"updated_at": "2026-10-01T10:15:40.207316Z",
"message": "Email schedule has been updated successfully"
}{
"error": "Email not found",
"message": "Email with ID 'em_4K76IA5sFNIsLXW9QC2ro8cDbOj' not found in your workspace"
}{
"error": "Cannot update email",
"message": "Email cannot be updated. Current status: 'delivered'. Only 'scheduled' emails can be updated."
}{
"error": "Cannot update email",
"message": "Scheduled emails can only be updated at least 3 minutes before the scheduled time. This email is scheduled to send in 2 minute(s)."
}{
"error": "Invalid scheduled_at",
"message": "The new scheduled time must be at least 3 minutes in the future."
}Cancelar un email
Quita un email de la cola de envío y cambia su estado a canceled.
/emails/{id}/cancelFunciona con claves de API sending y full. La cancelación se hace sin garantía: saca el email de la cola, pero si ya ha empezado un intento de entrega, ese intento puede completarse y solo se detienen los reintentos restantes. La respuesta indica en in_flight cuál es el caso. Al cancelar se dispara un evento email.canceled, y el crédito no se reembolsa. La acción Cancel delivery del panel hace lo mismo.
| Estado | Se puede cancelar | Notas |
|---|---|---|
scheduled |
Sí | Hasta 3 minutos antes de la hora programada. |
accepted |
Sí | En cola y aún sin entregar. |
attempted |
Sí | Detiene los reintentos restantes tras un fallo temporal. |
| Cualquier otro | No | El email ya se entregó, falló o se canceló. |
Para cancelar un envío con varios destinatarios, cancela cada ID del mapa ids de la respuesta del envío.
Parámetros de ruta
idstringobligatorioDevuelve
objectstringemail.idstringstatusstringcanceled.in_flightbooleantrue si puede que ya haya un intento de entrega en marcha y que aún se complete. false si el email se quitó de la cola antes de cualquier intento.messagestring{
"object": "email",
"id": "em_4K76IA5sFNIsLXW9QC2ro8cDbOj",
"status": "canceled",
"in_flight": false,
"message": "Email has been canceled and removed from the send queue."
}{
"object": "email",
"id": "em_4K76IA5sFNIsLXW9QC2ro8cDbOj",
"status": "canceled",
"in_flight": true,
"message": "Email was canceled. The current delivery attempt may still complete; remaining retries were stopped."
}{
"error": "Email not found",
"message": "Email with ID 'em_4K76IA5sFNIsLXW9QC2ro8cDbOj' not found in your workspace"
}{
"error": "Cannot cancel email",
"message": "Email cannot be canceled. Current status: 'delivered'. Only 'scheduled', 'accepted', or 'attempted' emails can be canceled."
}{
"error": "Cannot cancel email",
"message": "Scheduled emails can only be canceled at least 3 minutes before the scheduled time. This email is scheduled to send in 2 minute(s)."
}Reintentar un email
Pone en cola una copia de un email que no llegó a su destino. La copia es un email nuevo con su propio ID, y el original conserva su estado.
/emails/{id}/retryFunciona con claves de API sending y full. La copia tiene el mismo remitente, destinatario, asunto, contenido, cabeceras, meta y configuración de seguimiento, con un Message-ID nuevo. Cuesta créditos como un envío nuevo: un crédito, o dos si es un email de campaña.
Puedes reintentar un email cuando:
- Su estado es
bounced,failed,suppressedoheld. - Se creó en los últimos 30 días.
- Tu periodo de retención no ha purgado su contenido y su dominio de envío sigue existiendo.
Soluciona antes la causa. Una dirección bloqueada que sigue en tu lista de direcciones bloqueadas se vuelve a bloquear, y un email retenido se vuelve a retener hasta que se resuelva el motivo por el que se retuvo.
Parámetros de ruta
idstringobligatorioDevuelve
objectstringemail.idstringoriginal_idstringtokenstringmessage_idstringMessage-ID del email nuevo.fromstringtostringsubjectstringstatusstringaccepted.created_atstringmessagestring{
"object": "email",
"id": "em_4KbeG9poqTmjvQZeN8pMoJkCVNd",
"original_id": "em_4KKrQ7TzsVtzsS8zG069B2aMtoK",
"token": "4KTnDU5PzzqDqp8UWb9qVhPVFOT",
"message_id": "<4KTnDU5PzzqDqp8UWb9qVhPVFOT@acme.com>",
"from": "Acme <hello@acme.com>",
"to": "ada@example.com",
"subject": "Welcome to Acme",
"status": "accepted",
"created_at": "2026-10-01T12:04:51.330482Z",
"message": "Email has been queued for retry"
}{
"error": "Insufficient credits",
"message": "Insufficient credits to retry this email. Required: 1, available: 0."
}{
"error": "Email not found",
"message": "Email with ID 'em_4KKrQ7TzsVtzsS8zG069B2aMtoK' not found in your workspace"
}{
"error": "Cannot retry email",
"message": "Only bounced, failed, suppressed, or held emails can be retried. Current status: 'delivered'"
}{
"error": "Cannot retry email",
"message": "Emails older than 30 days cannot be retried"
}{
"error": "Cannot retry email",
"message": "Email raw content has been purged and can no longer be retried"
}Reenviar un email
Envía el contenido de un email saliente a nuevos destinatarios como un email nuevo. El email original no cambia.
/emails/{id}/forwardFunciona con claves de API sending y full. Por defecto, el reenvío es un simple nuevo envío del HTML, el texto y los adjuntos originales. Activa include_headers para añadir un bloque «Forwarded message» y una nota opcional encima del contenido original.
Un reenvío es un envío nuevo, así que se aplican las reglas de Enviar un email: la dirección from debe pertenecer a un dominio de envío verificado, cada destinatario cuesta un crédito y cuenta para los límites de envío, el seguimiento sigue la configuración del dominio y se admite la cabecera Idempotency-Key. Además, un espacio de trabajo puede reenviar como máximo 3 emails por hora.
Solo se pueden reenviar los emails salientes, y solo mientras tu periodo de retención conserve su contenido. Para reenviar el correo recibido, usa una automatización.
Parámetros de ruta
idstringobligatorioCabeceras
Idempotency-KeystringParámetros del cuerpo
tostring | string[]obligatorioinclude_headersbooleanpor defecto: falseSi es true, añade un bloque «Forwarded message» con el remitente, la fecha, el asunto y el destinatario originales, y tu nota encima. Si es false, vuelve a enviar el contenido original sin cambios.
commentstringinclude_headers. También se acepta body como alias.htmlstringcomment escapado. Solo se usa con include_headers.textstringcomment. Solo se usa con include_headers.fromstringfrom del email original.subjectstringinclude_headers, Fwd: seguido del asunto original.Los adjuntos originales se incluyen si su tipo de archivo está permitido.
Devuelve
Devuelve el mismo objeto que Enviar un email, con dos campos adicionales:
original_idstringmessagestringSi se supera el límite de reenvíos, la API devuelve 429 con una cabecera retry-after.
curl -X POST https://api.emailit.com/v2/emails/em_4KYof1ZzXndZE2VPi0DgULiekG8/forward \
-H "Authorization: Bearer $EMAILIT_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: fwd-inv-1042-grace" \
-d '{
"to": ["grace@example.com"],
"include_headers": true,
"comment": "Grace, here is the invoice Ada asked about."
}'const email = await emailit.emails.forward('em_4KYof1ZzXndZE2VPi0DgULiekG8', {
to: ['grace@example.com'],
include_headers: true,
comment: 'Grace, here is the invoice Ada asked about.',
});email = client.emails.forward("em_4KYof1ZzXndZE2VPi0DgULiekG8", {
"to": ["grace@example.com"],
"include_headers": True,
"comment": "Grace, here is the invoice Ada asked about."
}){
"object": "email",
"id": "em_4K76IA5sFNIsLXW9QC2ro8cDbOj",
"original_id": "em_4KYof1ZzXndZE2VPi0DgULiekG8",
"token": "4KWzEED2cnej6UMjF4v508VqQIp",
"message_id": "<4KWzEED2cnej6UMjF4v508VqQIp@acme.com>",
"from": "Acme Billing <billing@acme.com>",
"to": ["grace@example.com"],
"subject": "Fwd: Your invoice INV-1042",
"status": "accepted",
"scheduled_at": null,
"created_at": "2026-10-01T13:20:07.915203Z",
"tracking": {
"loads": true,
"clicks": true
},
"message": "Email has been queued for forwarding"
}{
"error": "Validation failed",
"validation_errors": ["Invalid to email address at index 0: grace@example"]
}{
"error": "Email not found",
"message": "Email with ID 'em_4KYof1ZzXndZE2VPi0DgULiekG8' not found in your workspace"
}{
"error": "Cannot forward email",
"message": "Only outgoing emails can be forwarded"
}{
"error": "Cannot forward email",
"message": "Email raw content has been purged and can no longer be forwarded"
}{
"error": "too_many_requests",
"message": "Forwarding is limited to 3 emails per hour for this workspace. Try again later.",
"limit": 3,
"current": 4,
"retry_after": 2711
}Obtener solo el estado
Devuelve solo el estado actual de un email.
/email/{id}Requiere una clave de API full. Fíjate en que la ruta usa /email en singular. La respuesta es pequeña, lo que hace que este endpoint sea práctico para comprobar rápidamente el estado. Para conocer los cambios de estado a medida que se producen, usa webhooks en lugar de consultar periódicamente.
Parámetros de ruta
idstringobligatorioDevuelve
statusstringEl estado actual: accepted, scheduled, delivered, loaded, clicked, attempted, bounced, failed, rejected, suppressed, received, complained, canceled o held. Consulta Estados de los emails.
{
"status": "delivered"
}{
"error": "Email not found",
"message": "Email with ID 'em_4KYof1ZzXndZE2VPi0DgULiekG8' not found in your workspace"
}