Encola un mensaje
Una respuesta 202 significa que el mensaje quedó en cola duradera. Después observa message.sent, message.delivered, message.bounced o message.failed.
const queued = await maildeck.messages.send(
{
fromMailboxId: 'mailbox_id',
to: ['cliente@example.com'],
subject: 'Tu recibo',
text: 'Gracias por tu pedido.',
},
{ idempotencyKey: crypto.randomUUID() },
);
Contrato de la solicitud
fromMailboxId debe identificar un buzón del tenant de la credencial. to exige 1–50 direcciones válidas; cc y bcc admiten hasta 50 cada uno. subject acepta hasta 998 caracteres, text hasta 1.000.000, html hasta 2.000.000 y attachmentIds hasta 20 UUID. Antes de encolar se validan ownership y capacidad actual del plan.
Proceso asíncrono de entrega
La API reserva la idempotencia durante 24 horas, crea el job outbound, escribe contexto de auditoría y devuelve { id, object: "message", status: "queued" }. Un worker construye MIME, guarda el objeto enviado, lo entrega a SES y emite message.sent. Las notificaciones posteriores de SES se convierten en message.delivered, message.bounced o message.failed.
- 202 queued es aceptación durable, no entrega al destinatario
- El id devuelto correlaciona API, job, eventos, webhooks y logs de soporte
- Consulta estado para conciliación; usa webhooks para baja latencia
Reintenta con seguridad
Usa 8–255 caracteres opacos y reutiliza la misma Idempotency-Key solo con la misma solicitud lógica. Un reintento completado devuelve status e ID originales con Idempotent-Replayed: true. Un body diferente produce idempotency_conflict; una primera solicitud aún activa produce idempotency_pending.
Añade adjuntos antes de enviar
Prepara con POST /v1/attachments/uploads, Idempotency-Key, mailboxId, filename, mediaType, sizeBytes y SHA-256 hexadecimal. Haz PUT de los bytes con los headers devueltos a la URL de diez minutos y confirma con POST /v1/attachments/uploads/{uploadId}/complete. Repetir la confirmación devuelve el mismo ID. GET /v1/attachments/{attachmentId}/download-url permite descargar durante sesenta segundos; cada invocación verifica autorización y visibilidad vigentes. No envíes API keys al storage ni registres URLs firmadas. El límite por archivo y por correo MIME completo es 25 MiB; MIME incluye el crecimiento por base64. Se conserva JSON para archivos pequeños. No hay antivirus implementado
Actualiza el estado del mensaje
PATCH /v1/messages/{messageId} exige messages:write, mailboxId y al menos una mutación: isRead, isStarred o folder. Las carpetas admitidas son inbox, sent, archive, spam y trash. Cada mutación correcta emite message.updated para que Webmail, API y receptores webhook converjan.