RFC 8620: JMAP — Protocolo de Aplicación Meta JSON
Por Qué Existe
IMAP funciona, pero lleva décadas de complejidad:
- Conexiones TCP con estado. IMAP requiere una conexión persistente por buzón. Los clientes móviles en redes poco confiables se reconectan y resincronizan constantemente.
- Protocolo de texto personalizado. El formato de IMAP requiere analizadores especializados. Cada lenguaje necesita una biblioteca IMAP dedicada.
- Fragmentación de extensiones. Las características críticas (CONDSTORE, MOVE, SPECIAL-USE) son extensiones opcionales que los servidores pueden o no soportar.
- Limitaciones de notificaciones push. IMAP IDLE solo funciona para un buzón a la vez, y muchos proxies/cortafuegos terminan las conexiones TCP inactivas.
JMAP resuelve todo esto. Es sin estado (cada solicitud es independiente), usa HTTPS (funciona a través de cualquier proxy y cortafuegos), usa JSON (cada lenguaje tiene un analizador), y define notificaciones push como una característica de primera clase a través de EventSource o Web Push.
Cómo Funciona
Descubrimiento de Servicios
Un cliente descubre el punto final de JMAP a través de un URI conocido:
GET https://example.com/.well-known/jmap { "capabilities": { "urn:ietf:params:jmap:core": { ... }, "urn:ietf:params:jmap:mail": { ... } }, "apiUrl": "https://jmap.example.com/api/", "uploadUrl": "https://jmap.example.com/upload/{accountId}/", "downloadUrl": "https://jmap.example.com/download/{accountId}/{blobId}/{name}", "eventSourceUrl": "https://jmap.example.com/events/" }
Hacer Llamadas de API
Todas las operaciones JMAP se envían como un POST único a la URL de la API. El cuerpo de la solicitud contiene una matriz de llamadas de método, y la respuesta contiene los resultados correspondientes:
POST https://jmap.example.com/api/ { "using": ["urn:ietf:params:jmap:core", "urn:ietf:params:jmap:mail"], "methodCalls": [ ["Mailbox/get", { "accountId": "u1234", "ids": null }, "a"] ] } { "methodResponses": [ ["Mailbox/get", { "accountId": "u1234", "state": "m42", "list": [ { "id": "mb1", "name": "Inbox", "totalEmails": 142 }, { "id": "mb2", "name": "Sent", "totalEmails": 87 }, { "id": "mb3", "name": "Archive", "totalEmails": 4210 } ] }, "a"] ] }
Lotes y Referencias Inversas
Múltiples llamadas de método pueden agruparse en una única solicitud. Las referencias inversas permiten que una llamada use los resultados de una llamada anterior:
"methodCalls": [ ["Email/query", { "accountId": "u1234", "filter": { "inMailbox": "mb1", "after": "2025-03-01T00:00:00Z" }, "sort": [{ "property": "receivedAt", "isAscending": false }], "limit": 10 }, "q"], ["Email/get", { "accountId": "u1234", "#ids": { "resultOf": "q", "name": "Email/query", "path": "/ids" }, "properties": ["from", "subject", "receivedAt", "preview"] }, "g"] ]
Esto busca en la bandeja de entrada y obtiene los 10 resultados principales en un único viaje HTTP, algo que requeriría múltiples comandos IMAP.
Detalles Técnicos Clave
Cadenas de Estado y Sincronización
Cada respuesta JMAP /get incluye una cadena state. Para sincronizar cambios, el cliente llama a /changes con el último estado conocido:
["Email/changes", { "accountId": "u1234", "sinceState": "e789" }, "c"] ["Email/changes", { "oldState": "e789", "newState": "e801", "created": ["em500", "em501"], "updated": ["em480"], "destroyed": ["em312"] }, "c"]
El cliente luego obtiene solo los elementos creados/actualizados. Esto es más eficiente que CONDSTORE de IMAP porque funciona en todos los buzones simultáneamente y no requiere una conexión persistente.
Notificaciones Push
JMAP define dos mecanismos de push:
-
EventSource: El cliente abre una conexión SSE de larga duración a
eventSourceUrl. El servidor envía eventos de cambio de estado a medida que ocurren. - Web Push (RFC 8030): Para clientes móviles/de fondo. El servidor envía notificaciones push a una URL de suscripción de push proporcionada por el cliente.
El Patrón Foo/get, Foo/set, Foo/query
JMAP utiliza un patrón de método uniforme para cada tipo de dato:
| Método | Propósito |
|---|---|
Foo/get |
Obtener objetos por ID |
Foo/changes |
Obtener IDs de objetos cambiados desde un estado |
Foo/set |
Crear, actualizar o destruir objetos |
Foo/query |
Buscar/filtrar y ordenar, devolviendo IDs coincidentes |
Foo/queryChanges |
Actualizaciones incrementales a un resultado de consulta anterior |
Para correo electrónico, Foo es Email, Mailbox, Thread, EmailSubmission, etc. Esta consistencia significa que una vez que entiendes un tipo de dato, los entiendes todos.
Errores Comunes
- Tratar JMAP como una API REST tradicional. JMAP usa un único punto final con llamadas de método en el cuerpo de la solicitud, no URLs basadas en recursos. No intentes mapearlo a convenciones REST.
- Ignorar cadenas de estado. Cada respuesta tiene un estado. Si lo descartas, pierdes sincronización eficiente y debes recargar todo en la siguiente llamada.
-
Obtener todas las propiedades.
Email/getsin una listapropertiesdevuelve todo, incluyendo cuerpos de mensajes completos. Siempre especifica qué propiedades necesitas. - No usar referencias inversas. Hacer solicitudes HTTP separadas para consulta + obtención desperdicia un viaje. Usa referencias inversas para agruparlas.
- Asumir soporte universal del servidor. A partir de 2026, la adopción de JMAP está creciendo pero IMAP sigue siendo mucho más ampliamente desplegado. Fastmail es el proveedor JMAP más prominente. Verifica las capacidades del servidor antes de comprometerte solo con JMAP.
- Encuestar en lugar de usar push. JMAP proporciona EventSource y Web Push específicamente para que no tengas que encuestar. Úsalos.
Impacto en la Entregabilidad
-
JMAP es principalmente un protocolo de recuperación. Como IMAP y POP3, rige cómo los destinatarios acceden al correo, no cómo lo envías. Sin embargo, JMAP también define
EmailSubmissionpara envío, que podría reemplazar el envío SMTP en algunos casos de uso. - Mejor datos de engagement. El enfoque estructurado de JMAP para banderas y movimientos de buzón proporciona a los proveedores señales de engagement más limpias. Cuando un usuario mueve tu mensaje de Spam a Bandeja de Entrada a través de JMAP, el proveedor ve una señal clara.
- Sincronización de cliente más rápida. Porque la sincronización JMAP es más eficiente que IMAP, los clientes móviles se mantienen sincronizados más confiablemente. Esto significa que los destinatarios ven tus mensajes más rápido y el engagement (aperturas, clics) ocurre más rápido.
-
Objeto EmailSubmission. El método
EmailSubmission/setde JMAP permite enviar correo electrónico a través de la misma API utilizada para lectura. Para aplicaciones que tanto envían como reciben, esto unifica todo el flujo de trabajo de correo electrónico bajo un único protocolo.