JSON Meta Application Protocol
The JSON Meta Application Protocol (JMAP) is an open Internet standard protocol designed for efficiently querying, fetching, modifying, and synchronizing JSON-based data objects—such as email, calendars, and contacts—between clients and servers over HTTP, with built-in support for push notifications and fast resynchronization.[1] It serves as a modern alternative to legacy protocols like IMAP and CalDAV, optimizing for mobile and web environments by minimizing network usage through batched requests, delta updates, and stateless operations.[1] JMAP employs a uniform JSON API structure, where clients send authenticated POST requests containing method calls (e.g.,/get, /set, /query) to a server endpoint, receiving responses that enable real-time data handling without persistent connections.[1]
Developed initially by the email provider Fastmail to address limitations in traditional email protocols, JMAP emphasizes developer-friendliness, security via HTTPS, and scalability for large-scale deployments.[2] Its core specification, outlined in RFC 8620, provides a generic framework for data synchronization, while extensions like RFC 8621 define mail-specific capabilities, including mailboxes, threads, email objects, and submission processes compatible with IMAP semantics such as labels and keywords.[1][3] Key features include immutable object identifiers for reliable tracking, flood control to prevent abuse, out-of-band handling for binary data uploads/downloads, and push mechanisms for notifying clients of changes, such as new email arrivals.[1][3]
JMAP's data model supports internationalization, efficient searching with snippets, and account-level capabilities registration, allowing servers to advertise supported features dynamically.[3] It has been adopted in production by services like Fastmail and integrated into open-source projects such as Apache James and Stalwart Mail Server, promoting an ecosystem of interoperable clients and servers.[4][5] Standardized by the IETF in 2019, JMAP continues to evolve through community contributions, with ongoing extensions for areas like push delivery and event notifications.[1][6]
Introduction
Definition and Scope
The JSON Meta Application Protocol (JMAP) is an open Internet standard that enables clients to efficiently query, fetch, and modify JSON-based data objects stored on a server, with built-in support for push notifications of changes and efficient transfer of binary data.[7] Defined as a generic protocol, JMAP operates over HTTP/1.1 or HTTP/2 (with TLS required), allowing seamless integration with modern web and mobile applications by leveraging familiar JSON formats and HTTP semantics.[8] Its primary scope encompasses the synchronization of structured data such as email messages, calendars, contacts, and associated metadata between clients and servers, facilitating real-time updates without the inefficiencies of polling-based approaches.[9] Push notifications are handled via Server-Sent Events or pushes to a client-provided URL, with extensions available for WebSockets, enabling servers to proactively inform clients of data changes, which is particularly suited for resource-constrained environments like mobile devices.[10] While extensible to other object types through capability declarations, JMAP's technical boundaries focus on abstract object manipulation rather than domain-specific semantics, ensuring broad applicability while deferring specialized handling to extensions.[11] Central to JMAP's design are sessions tracked via state tokens that maintain synchronization context across stateless requests; capability discovery, where servers advertise supported features and data types through a capabilities object; and method-based requests and responses using a JSON format similar to JSON-RPC for structured invocations like object retrieval or updates.[8] These elements collectively provide a flexible framework for delta-based synchronization, reducing bandwidth and latency compared to legacy protocols.[12] The core protocol was specified in RFC 8620, published in July 2019 by Neil Jenkins of Fastmail and Chris Newman of Oracle, emphasizing generic mechanisms for object querying, creation, modification, and deletion to serve as a foundation for application-specific extensions.[13] This initial specification establishes JMAP as a modern alternative motivated by limitations in protocols like IMAP, though its evolution builds on broader needs for web-friendly data access.[9]Historical Context
The JSON Meta Application Protocol (JMAP) originated in 2014 when engineers at Fastmail began developing it as a modern alternative to legacy protocols like IMAP, aiming to enable more efficient synchronization of email and other data for mobile and web applications.[14] This initiative was driven by the need to overcome IMAP's limitations in the rising era of mobile computing during the 2010s, where constant polling for changes consumed excessive bandwidth and battery life on devices with constrained resources, while long-lived connections proved unreliable over intermittent networks.[14] Fastmail's early implementation focused on stateless, HTTP-based interactions using JSON, allowing for faster partial syncs and better scalability compared to IMAP's stateful model.[2] The protocol's formal development accelerated with the submission of the first Internet-Draft (draft-jenkins-jmap-00) on October 18, 2016, by Neil Jenkins of Fastmail, which outlined the core mechanisms for querying and modifying JSON data objects.[15] In March 2017, the IETF adopted JMAP as a working group candidate, marking its transition from a company-specific project to an open standardization effort under the JSON Mail Access Protocol (jmap) working group.[15] This adoption facilitated broader input from the community, refining the protocol's design to incorporate push notifications for real-time updates directly within the core specification.[7] Standardization culminated in July 2019 with the publication of RFC 8620, defining the core JMAP protocol for efficient data access and push support, and August 2019 for RFC 8621, specifying its application to mail synchronization.[13][16] These RFCs represented the culmination of five years of iteration, evolving JMAP from Fastmail's proprietary use into a vendor-neutral open standard hosted at jmap.io, influenced by RESTful principles for resource-oriented APIs and JSON-RPC for structured remote procedure calls.[2] Subsequent extensions, such as WebSocket bindings in RFC 8887 (2020), further expanded its capabilities for persistent connections. As of 2025, JMAP continues to evolve with recent RFCs like 9749 for Web Push authentication and specifications for calendars.[17]Protocol Design
Core Architecture
The JSON Meta Application Protocol (JMAP) establishes its core architecture through a session-based model that enables secure, efficient synchronization of JSON data between clients and servers. Session establishment begins with an authenticated HTTP GET request to the/jmap/session endpoint, which returns a comprehensive Session resource object. This object includes critical details such as the apiUrl for API requests, uploadUrl and downloadUrl for handling binary data, eventSourceUrl for push notifications, a list of available accounts with their IDs and names, and a state string representing the current server state. The Session object also advertises supported capabilities, allowing clients to negotiate features like mail or contacts handling during initialization. This discovery mechanism ensures clients can adapt to server-specific implementations without prior configuration.[8]
At the heart of JMAP's communication is a batched JSON-RPC 2.0 format over HTTP POST requests to the apiUrl. Each request object contains a using array specifying the capabilities in use (e.g., ["urn:ietf:params:jmap:core", "urn:ietf:params:jmap:mail"]) and a methodCalls array of invocations, where each invocation is [methodName, params, methodId]. For instance, a method like Email/query—prefixed by its capability—allows querying email data with parameters for filters and sorting. Responses mirror this structure with a methodResponses array of [methodName, resultOrError, methodId] and a sessionState string that updates to reflect any changes made during the batch. This batching supports multiple method calls per request, up to the maximum advertised by the server in the 'maxCallsInRequest' core capability property (at least 16), promoting efficiency by reducing round trips, while state tokens (via sessionState and capability-specific state properties) enable clients to track and resume synchronization from the last known server state, avoiding redundant data fetches.[18]
JMAP integrates push notifications to deliver real-time updates, primarily through the eventSourceUrl provided in the Session object, which supports Server-Sent Events (SSE) over HTTP for streaming StateChange objects that detail account modifications. Clients can subscribe to pushes using the PushSubscription capability, specifying verification mechanisms and delivery preferences, with fallbacks to client-initiated polling if real-time channels are unavailable. While core JMAP favors HTTP-based pushes, extensions like WebSocket subprotocols provide alternative channels for bidirectional communication in constrained environments. This design minimizes latency for updates across capabilities, such as email arrivals, without requiring constant polling.[10]
Error handling in JMAP is standardized across three levels to ensure robustness and idempotency. Request-level errors use HTTP status codes with JSON problem details (per RFC 7807), such as 401 for authentication failures. Method-level errors return objects with types like unknownMethod, invalidArguments, forbidden, or accountNotFound when an invalid account ID is used, prefixed with urn:ietf:params:jmap:error:. Set-level errors in methods like obj/set include types such as notFound, invalidProperties, or rateLimitExceeded for excessive operations, accompanied by descriptive messages. State management enhances idempotency: parameters like ifInState in update methods ensure actions apply only if the server's state matches the client's expectation, preventing duplicates or conflicts in concurrent scenarios.[19]
Transport in JMAP mandates secure, multiplexed connections to support its high-throughput needs. Servers must implement HTTP/2 (RFC 7540) for request multiplexing and flow control, enabling multiple concurrent streams over a single TCP connection. TLS 1.2 or later is required (with 1.3 recommended), ensuring all traffic—including session discovery and API calls—is encrypted end-to-end. Binary uploads and downloads leverage HTTP POST and GET with ranges for partial access, further optimized by HTTP/2's header compression and prioritization. This architecture prioritizes performance and security, making JMAP suitable for mobile and web clients handling large datasets.[20]
Data Model and Capabilities
The JSON Meta Application Protocol (JMAP) employs a core data model centered on JSON objects represented as unordered maps of name-value pairs, where each object corresponds to a record of a specific type with an immutable server-assignedid property that uniquely identifies it within the same account and type.[7] Properties within these objects are typed according to JSON standards, including strings, numbers, booleans, arrays, and nested objects, with certain properties marked as immutable to prevent changes after creation, ensuring consistency in data handling across operations.[7] This model supports efficient querying and modification by treating objects as self-contained entities, with the type property often implicit in the context of methods like Foo/get or Foo/set.[7]
JMAP's capability system enables modular extensibility by allowing servers to advertise supported features through the capabilities property in the Session object, which is a map of URI keys to capability-specific objects detailing supported versions and parameters.[7] Clients negotiate capabilities by including relevant URIs in the using array of their Request objects, restricting the session to those features and ensuring compatibility without assuming universal support.[7] Core capabilities, such as "urn:ietf:params:jmap:core", are mandatory for all JMAP servers and define baseline behaviors like error handling and method invocation.[7]
Object types in JMAP include generic constructs like the QueryMethod for performing complex filtering and searching across data sets, which accepts parameters such as filter, sort, and position to enable efficient pagination and conditional retrieval.[7] Accounts are organized via identifiers in the Session object's accounts map, with primary accounts for each capability indicated in the separate 'primaryAccounts' property of the Session object, facilitating multi-account management without conflating data scopes.[7]
Extensibility is achieved through custom properties prefixed with vendor-specific URIs in capability objects and data records, allowing implementations to add non-standard fields without conflicting with the core specification, as seen in extensions like "urn:ietf:params:jmap:submission".[7] Versioning ensures backward compatibility by associating specific protocol versions with capability URIs, permitting servers to evolve features incrementally while clients select compatible subsets during session negotiation.[7]
State management in JMAP relies on opaque server-generated state strings to track changes efficiently, with methods like Foo/changes using a sinceState parameter to retrieve only updates since the last synchronization, thereby avoiding full data resyncs and reducing bandwidth usage.[7] The state property in responses provides a new state string for clients to reference in future requests, enabling delta-based updates that maintain consistency across push notifications and polling.[7]
Specific Applications
Email Synchronization
The JSON Meta Application Protocol (JMAP) provides a structured approach to email synchronization by defining an Email object that encapsulates message metadata, headers, and body content in a JSON format. This object includes core properties such asid for unique identification, threadId for grouping related messages, mailboxIds to indicate storage locations, keywords for flags like $seen or $draft, and receivedAt for the receipt timestamp. Header fields are parsed into structured types, with from and to represented as arrays of EmailAddress objects containing names and email addresses, subject as a simple string, and messageId and references enabling threading by linking messages in conversation chains. Body-related properties include textBody and htmlBody for sequential plain-text or HTML content suitable for display, attachments as an array of non-inline parts like images or files, and bodyStructure detailing the full MIME tree for complex multipart messages.[21]
Key methods facilitate efficient email operations, with Email/query allowing clients to search and list emails using filters such as inMailbox for specific folders, text for full-text matching across body and attachments, or hasKeyword for flagged messages, alongside sorting options like receivedAt descending or subject ascending with Unicode collation support. The Email/get method retrieves detailed email data, supporting partial fetches via properties to limit to essentials like headers, or bodyProperties such as textBody and htmlBody for content, with bodyValues providing decoded text excerpts up to a server-defined byte limit. For modifications, Email/set handles creation of new drafts (initially marked with the $draft keyword), updates to properties like adding keywords or moving to different mailboxIds, and destruction of emails, all within atomic transactions to ensure consistency.[21]
Synchronization in JMAP relies on state strings to enable delta updates, where clients track the server's state value from responses and use Email/changes or Email/queryChanges methods with a sinceState parameter to fetch only modified, added, or removed emails since the last sync. Mailbox roles standardize organization, assigning special names like inbox for incoming messages, sent for outgoing, and drafts for unsent compositions, with each mailbox limited to a single role as per the IANA IMAP Mailbox Name Attributes registry. Servers enforce quotas through capabilities such as maxMailboxesPerEmail to prevent excessive folder assignments and maxSizeAttachmentsPerEmail to control storage, rejecting operations that exceed these limits with specific error codes like tooManyMailboxes.[21][22]
Attachments and MIME parsing are handled through inline integration within the Email object, where the bodyStructure property recursively describes all parts including types, subtypes, and dispositions (inline or attachment), allowing clients to reference specific partIds for fetching via Email/get with bodyValues. Non-display parts populate the attachments array with details like blobId for binary data retrieval, size in octets, and name for filenames, while hasAttachment flags messages with downloadable content. Servers support parsing via the Email/parse method, which processes raw blobs into structured objects, and offer server-side rendering options for textBody and htmlBody by extracting and decoding the primary text or HTML parts, potentially truncating long content or excluding certain MIME types for security.[21]
Search capabilities extend beyond basic filtering with full-text support in Email/query's text operator, which matches phrases case-insensitively across subjects, bodies, and attachments using server-indexed terms. The protocol includes the SearchSnippet/get method for retrieving contextual excerpts, limited to 255 octets per result, with matched terms highlighted using <mark> tags in properties like subjectSnippet or previewSnippet to aid user interfaces in displaying relevant previews. Advanced search features, such as refined snippet generation and additional operators, are part of the core mail capabilities in RFC 8621.[21]
Calendar and Contacts Handling
The JSON Meta Application Protocol (JMAP) extends its core capabilities to synchronize calendar data through a data model that includes Calendar objects as named collections of CalendarEvent objects, where events can belong to multiple calendars within an account.[23] CalendarEvent objects follow the JSCalendar Event format defined in RFC 8984, supporting properties such asstart (a LocalDateTime in the event's time zone), duration (an ISO 8601 duration string), utcStart and utcEnd (computed UTC timestamps), recurrenceRules (arrays of recurrence rule objects compatible with iCalendar RRULE semantics), and recurrenceOverrides for exceptions to recurring instances.[24] Attendees are modeled as participants within the event, each with properties like scheduleId (for scheduling identity), sendTo (email address for notifications), and participationStatus (e.g., accepted, declined).[23]
Methods for manipulating calendar data include CalendarEvent/get, which retrieves event details including iCalendar-compatible representations via an optional wantICal argument, and CalendarEvent/set, which creates, updates, or destroys events while supporting sendSchedulingMessages to automatically generate iCalendar messages for attendee invitations or updates.[23] Free-busy lookups are handled via the Principal/getAvailability method on the Principal object, specifying a time range with utcStart and utcEnd to return BusyPeriod objects indicating unavailable intervals.[23] Push notifications for calendar changes are enabled through the urn:ietf:params:jmap:calendars capability, allowing clients to subscribe to CalendarAlert events for real-time updates on event modifications.[23]
For contacts, JMAP defines AddressBook objects as collections of ContactCard objects via RFC 9610 (2024), where each ContactCard represents an individual or group in the JSContact format defined in RFC 9553.[25][26] Contact properties include name (a structured full name), emails (arrays of email addresses with labels and types), addresses (postal addresses with components like street, city, and country), and photos (references to blob IDs for image data).[25] Searches are performed using the Card/query method, which supports filters on properties like name, email, or inAddressBook and sorting by fields such as created or name/given, with compatibility for vCard-based imports and exports through JSContact mappings.[25]
Integration across calendars and contacts leverages JMAP's access control lists (ACLs) for sharing, where Calendar and AddressBook objects include shareWith (a map of principal IDs to rights like read, write, or admin) and myRights (the current user's permissions). Time zone support uses IANA Time Zone Database identifiers (e.g., "America/New_York") for events, with fallback to account or principal defaults, and internationalization follows JSCalendar and JSContact guidelines for multilingual names and locales.[24] Calendar events can reference email attachments as blobs via JMAP's core data model, enabling seamless inclusion of files from mailboxes.[8]
Advantages and Comparisons
Improvements over Legacy Protocols
The JSON Meta Application Protocol (JMAP) addresses several architectural shortcomings in legacy email protocols such as IMAP, POP3, and SMTP by introducing a more efficient, flexible, and unified approach to data synchronization. Unlike IMAP and POP3, which often require downloading entire messages or maintaining complex stateful connections, JMAP enables batched requests where multiple API calls can be combined into a single HTTP request, significantly reducing the number of round trips between client and server.[27] Additionally, JMAP supports partial fetches, allowing clients to retrieve only specific properties of objects—such as email headers or attachments—rather than full message bodies as typically mandated by IMAP, thereby optimizing bandwidth usage especially in scenarios with limited connectivity.[28] In terms of real-time capabilities, JMAP provides native push notifications through mechanisms like Server-Sent Events, eliminating the need for the polling-based IDLE command in IMAP, which can drain battery life on mobile devices and introduce delays in low-bandwidth environments.[29] This stateless HTTP-based design contrasts with IMAP's reliance on persistent, stateful TCP connections that are prone to interruptions, drops, and reconnection overhead, making JMAP more resilient for intermittent networks common in modern usage.[30] POP3's unidirectional nature, which primarily supports downloading messages without efficient upstream synchronization, is also mitigated in JMAP through bidirectional change tracking that facilitates seamless updates across devices.[31] JMAP's use of JSON over HTTP further simplifies protocol interactions compared to the text-based, MIME-encoded commands of IMAP and SMTP, which demand intricate parsing and can be hindered by firewalls or proxies that restrict non-HTTP traffic.[32] This web-friendly format eases integration with contemporary development tools and reduces the cognitive load for implementers, as JSON structures are more intuitive and less error-prone than the hierarchical, literal-string handling in legacy protocols.[33] A key advancement lies in JMAP's unified data model, which extends beyond email to encompass calendars, contacts, and other types within a single, consistent framework, filling standardization gaps in IMAP and POP3 that lack native support for non-email synchronization and require separate protocols like CalDAV or CardDAV.[27] By design, JMAP overcomes these silos, enabling a cohesive API for diverse data types while avoiding the fragmentation and interoperability issues prevalent in the ad-hoc extensions of older standards.[27]Performance and Security Features
The JSON Meta Application Protocol (JMAP) incorporates several performance optimizations designed to minimize network overhead and improve synchronization efficiency. By leveraging HTTP/2 or later, JMAP supports multiplexing, allowing multiple API method calls to be batched within a single request and response, which reduces the number of round trips compared to traditional protocols that require sequential operations. Additionally, HTTP compression mechanisms such as gzip are applicable to JMAP's JSON payloads, enabling compact data transmission over the wire. The protocol's state-based synchronization model further enhances efficiency through methods likeFoo/changes, which return only the deltas (created, updated, or destroyed items) since a specified account state, avoiding the need to re-fetch entire datasets during incremental updates.
JMAP includes built-in mechanisms for resource management to prevent abuse and ensure scalability. Servers may implement rate limiting by rejecting excessive concurrent requests or throttling based on client behavior, returning appropriate error codes such as "rateLimit" to prompt client-side backoff strategies.[34] Quota management is supported via dedicated methods like Quota/getQuota, allowing servers to enforce limits on storage and operations while providing clients with visibility into usage, which helps in graceful handling of constraints without disrupting service.[35]
On the security front, JMAP mandates the use of TLS version 1.2 or higher for all communications, ensuring encrypted transport and protecting against eavesdropping and tampering; TLS 1.3 is recommended for enhanced security. Authentication relies on HTTP authentication schemes, with bearer tokens or OAuth 2.0 commonly used in implementations to provide secure, token-based access without exposing credentials; basic authentication is discouraged in favor of application-specific passwords. Fine-grained access control is enforced through access control lists (ACLs) and permission checks, where unauthorized operations result in "forbidden" errors, enabling secure sharing of resources like mailboxes while restricting sensitive data exposure.
JMAP's design promotes privacy by maintaining a stateless protocol, where the server does not retain persistent state for individual clients beyond session authentication, reducing the risk of data leakage from stored session information. In mail-specific extensions, partial account access limits metadata exposure during queries by treating inaccessible data as non-existent, further supporting privacy-conscious operations.[36] As of November 2025, JMAP continues to evolve with extensions like RFC 9425 for quotas (2023), RFC 9670 for sharing (2024), and RFC 9749 for Web Push authentication (2025), enhancing its performance and security features.[35][37][38]