mailmaint H. J. Happel Internet-Draft audriga Intended status: Standards Track L. Dusseault Expires: 18 March 2027 Data Transfer Initiative A. Melnikov Isode Ltd 14 September 2026 Personal Data Portability Archive draft-ietf-mailmaint-pdparchive-02 Abstract This document proposes the Personal Data Portability Archive format (PDPA), suitable for import/export, backup/restore, and data transfer scenarios for personal data. About This Document This note is to be removed before publishing as an RFC. The latest revision of this draft can be found at https://lisad.github.io/draft-happel-mailmaint-pdparchive/draft-ietf- mailmaint-pdparchive.html. Status information for this document may be found at https://datatracker.ietf.org/doc/draft-ietf-mailmaint- pdparchive/. Discussion of this document takes place on the mailmaint Working Group mailing list (mailto:mailmaint@ietf.org), which is archived at https://mailarchive.ietf.org/arch/browse/mailmaint/. Subscribe at https://www.ietf.org/mailman/listinfo/mailmaint/. Source for this draft and an issue tracker can be found at https://github.com/lisad/draft-happel-mailmaint-pdparchive. Status of This Memo This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79. Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet- Drafts is at https://datatracker.ietf.org/drafts/current/. Happel, et al. Expires 18 March 2027 [Page 1] Internet-Draft PDPArchive September 2026 Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress." This Internet-Draft will expire on 18 March 2027. Copyright Notice Copyright (c) 2026 IETF Trust and the persons identified as the document authors. All rights reserved. This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/ license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License. Table of Contents 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 2. Conventions and Definitions . . . . . . . . . . . . . . . . . 4 3. Goals . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 3.1. Use cases . . . . . . . . . . . . . . . . . . . . . . . . 5 3.1.1. Data portability . . . . . . . . . . . . . . . . . . 5 3.1.2. Read-only data access . . . . . . . . . . . . . . . . 5 3.1.3. Incremental data access . . . . . . . . . . . . . . . 5 3.1.4. Synchronization . . . . . . . . . . . . . . . . . . . 6 3.1.5. Dataset exchange . . . . . . . . . . . . . . . . . . 6 3.1.6. Data persistence . . . . . . . . . . . . . . . . . . 7 3.2. Technical Goals . . . . . . . . . . . . . . . . . . . . . 7 3.2.1. Email standards compatibility . . . . . . . . . . . . 7 3.2.2. Interoperability . . . . . . . . . . . . . . . . . . 7 3.2.3. Extensibility . . . . . . . . . . . . . . . . . . . . 7 3.2.4. Flexible granularity . . . . . . . . . . . . . . . . 8 3.2.5. Accessible for local tooling . . . . . . . . . . . . 8 3.2.6. Efficiency . . . . . . . . . . . . . . . . . . . . . 8 3.3. Related work . . . . . . . . . . . . . . . . . . . . . . 8 4. Approach . . . . . . . . . . . . . . . . . . . . . . . . . . 9 4.1. Using JSON (mostly) . . . . . . . . . . . . . . . . . . . 9 4.2. Approach to partial updates . . . . . . . . . . . . . . . 9 4.3. Approach to synchronization . . . . . . . . . . . . . . . 10 5. Solution Requirements . . . . . . . . . . . . . . . . . . . . 11 6. File format . . . . . . . . . . . . . . . . . . . . . . . . . 12 6.1. Archive metadata file . . . . . . . . . . . . . . . . . . 12 Happel, et al. Expires 18 March 2027 [Page 2] Internet-Draft PDPArchive September 2026 6.2. Folder structure . . . . . . . . . . . . . . . . . . . . 17 6.2.1. File and folder names . . . . . . . . . . . . . . . . 20 6.3. Data formats . . . . . . . . . . . . . . . . . . . . . . 20 6.3.1. Email . . . . . . . . . . . . . . . . . . . . . . . . 21 6.3.2. Contacts . . . . . . . . . . . . . . . . . . . . . . 28 6.3.3. Using RFC9610 address book objects . . . . . . . . . 32 6.3.4. Calendar events, tasks and groups . . . . . . . . . . 35 6.3.5. Calendar Collection Items . . . . . . . . . . . . . . 45 6.3.6. Notes . . . . . . . . . . . . . . . . . . . . . . . . 55 6.3.7. Attachments . . . . . . . . . . . . . . . . . . . . . 57 6.3.8. Out of Scope . . . . . . . . . . . . . . . . . . . . 59 6.4. Synchronization requirements . . . . . . . . . . . . . . 60 6.4.1. Always include 'uid' and 'updated' . . . . . . . . . 60 6.4.2. Synchronizing mailbox folders . . . . . . . . . . . . 63 6.4.3. Synchronizing files and attachments . . . . . . . . . 64 7. Open issues . . . . . . . . . . . . . . . . . . . . . . . . . 64 7.1. Container format . . . . . . . . . . . . . . . . . . . . 64 7.2. Encryption . . . . . . . . . . . . . . . . . . . . . . . 65 8. Implementation status . . . . . . . . . . . . . . . . . . . . 66 9. Security Considerations . . . . . . . . . . . . . . . . . . . 66 9.1. Threat model . . . . . . . . . . . . . . . . . . . . . . 66 9.2. Suggested privacy protections . . . . . . . . . . . . . . 67 9.3. Considerations for importers . . . . . . . . . . . . . . 68 9.4. Other . . . . . . . . . . . . . . . . . . . . . . . . . . 69 10. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 69 10.1. File extension . . . . . . . . . . . . . . . . . . . . . 69 11. References . . . . . . . . . . . . . . . . . . . . . . . . . 69 11.1. Normative References . . . . . . . . . . . . . . . . . . 69 11.2. Informative References . . . . . . . . . . . . . . . . . 70 Appendix A. Base Contact Schema . . . . . . . . . . . . . . . . 72 Appendix B. Extended Example: Folder Nesting vs. Collection IDs . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . 76 Changes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 Changes in draft-ietf-mailmaint-pdparchive-02 . . . . . . . . . 77 Changes in draft-ietf-mailmaint-pdparchive-01 . . . . . . . . . 77 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 77 1. Introduction As part of communication protocols, the IETF has standardized a number of data formats such as the Internet Message Format [RFC5322], [vCard], [iCalendar], or, more recently, [JSContact] and [JSCalendar]. While mainly designed for interoperability, many of these data formats have also become popular for data portability, i.e., the import/export of data across different services. The growing Happel, et al. Expires 18 March 2027 [Page 3] Internet-Draft PDPArchive September 2026 importance of data portability however demands an open standard archive format which can deal with different types of personal data in a homogeneous fashion. To this end, this document proposes the Personal Data Portability Archive format (PDPArchive), suitable for import/export, backup/ restore, and data transfer scenarios for personal data. It is compatible with both IMAP and JMAP and should be suitable as an interchange format between related software and services such as for email, contacts, calendaring, tasks, or files. The approach is to define JSON formats, folder structure, and a common compression format. Additional specifications will likely define a protocol how these files can be requested from, imported into, or transferred between servers, but this specification can be used as-is with user-directed imports or exports. 2. Conventions and Definitions The term "personal data" refers to persistent data which users created and managed within applications or services. Classic examples are emails, contacts, calendars, tasks, notes, or files. Other examples might be fitness tracking records, energy bills, or location history. The term "data portability" refers to the right or technical procedure to use or transfer personal data across different applications or services. The terms "message" and "email message" refer to "electronic mail messages" or "emails" as specified in [RFC5322]. The term "Message User Agent" (MUA) denotes an email client application as per [RFC5598]. The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here. 3. Goals The core goal is to provide an open and extensible archive and transfer format for personal data. This includes data types that are subject of existing IETF protocols, such as email and groupware data (e.g., contacts, calendars, tasks) but may also include further types of personal data. Happel, et al. Expires 18 March 2027 [Page 4] Internet-Draft PDPArchive September 2026 Goals will be refined by use cases and cross-cutting technical goals in the following sub-sections. JSON is used as a widely interoperable base format that systems can easily translate their internal data representation into. Wherever possible, fields, values and data structures are derived from existing IMAP/JMAP specifications to remain compatible with both. 3.1. Use cases Many of these use cases benefit greatly from a simple, read-only export format, compared to having IMAP and CalDAV access to personal data. While these use cases may suggest interesting niche features, adding those may be left to future specs. For example, legal and forensics use cases might benefit from signing features, but nevertheless this specification would advance those use cases even without signing features. 3.1.1. Data portability A main use case for the novel format is to allow exporting the full user data managed by services or software products into a simple file (or set of files) which is under full control of the user. The user might use such an export for backup, archiving, or for importing when switching to another service or software (i.e., migration). Depending on the type of data, exporting/importing can be a time- consuming process. Particularly for the case of switching services, PDPA should allow to minimize the time period during which a user cannot use the origin system but also the destination system is not yet ready. 3.1.2. Read-only data access General access to data powers all kinds of analysis and applications. Exporting content and metadata in a structure suitable for ease of use in data pipelines or analysis tools would make these much easier. 3.1.3. Incremental data access Beyond snapshot backups/exports, the format should optionally allow for incremental data access - knowing what new data has been added. * Automated maintenance of a permanent, incremental mirror of user data, e.g. for instant restore Happel, et al. Expires 18 March 2027 [Page 5] Internet-Draft PDPArchive September 2026 * Compliance or audit logs * Spam tracking and analysis * CRM or productivity integration scenarios that are read-only 3.1.4. Synchronization Data portability does not just allow users to switch from one service to another one, but to let users benefit from 3rd party services with ongoing access to their data (authorized by the user). Simple synchronization features could make this much better. For example, current online systems that allow importing contacts are not often suited to maintaining one's address book on two systems. Re-importing a contact into a system that already has that contact often results in duplicating the exact same contact, whether or not there have been edits, making repeated synchronization practically infeasible. It should be easy to do a significantly better job of this with some attention to object IDs and modification timestamps. We however do not attempt to solve two-way synchronization via export files. It would require significant additional work to allow two systems, neither of which is agreed-upon to be the source of truth, to reliably synchronize changes from both. In comparison, solving one-way synchronization only requires agreed-upon usage of existing fields and values. 3.1.5. Dataset exchange PDPArchive should be usable to exchange and share larger data sets than just one user, or to share a single user's data outside the context where the user knows what it is and where it came from. Potential applications of this are: * The ability to exchange test data and known mailstore state, e.g. for conformance testing or internal functional tests * Legal discovery and forensics use cases may benefit from a standard export format, such that investigators can expect a great deal of consistency when collecting data from different systems. * Researchers may be able to collect archive files through data donations and use as input to research. Happel, et al. Expires 18 March 2027 [Page 6] Internet-Draft PDPArchive September 2026 3.1.6. Data persistence The format MAY be used as a development-time active persistence layer for user data in, e.g., email clients or applications. It is not intended as, or suitable for, a production-level persistence layer. 3.2. Technical Goals Besides actual use cases, there are a number of side requirements and goals for PDPA. 3.2.1. Email standards compatibility Data definitions have to be compatible with widespread calendar and email standards, although need not be limited to only what is in those standards. Data serialization formats should aim for compatibility with JMAP data formats for the sake of interoperability and synergies in software libraries. Dedicated JMAP API methods or client/server protocol messages for exporting and importing the format described here are out of scope of this document. Server-to-server transfer protocols for sending or requesting this format are out of the scope of this document. Due to its specifics and ubiquitous usage, the Internet Message Format [RFC5322]; latest revision of [RFC2822]/[RFC822] should be the core of representing individual email data. This specification should ideally describe mappings between PDPA and existing mailbox persistence schemes such as Maildir or [MBOX]. 3.2.2. Interoperability It should be mostly possible to use personal data exports from one system with different software or services. When a source exports personal data it can include all the information it would need for a fully-functional import, _however_ destination systems running different software may not be able to import all of that information (especially if it includes non-standard features) and use it exactly the same way. This specification does not attempt to achieve perfect interoperability between diverse systems, but instead to make reasonable trade-offs. 3.2.3. Extensibility This format should be extensible to accommodate types of personal data not explicitly mentioned or foreseen when writing these specs. Happel, et al. Expires 18 March 2027 [Page 7] Internet-Draft PDPArchive September 2026 3.2.4. Flexible granularity This format should allow flexible granularity in two ways: 1) It should enable easy access to separate types of data (e.g., emails vs. contacts), e.g. to allow for partial imports or exports 2) While ideally representable as a single file, archives may also span several files due to reasons such as file size restrictions or incremental generation logic. (The ability for a user to export and/or backup an entire email account requires some accommodation of large amounts of data and risks of interruptions in downloads. Splitting exports into multiple files during export is one possible solution.) 3.2.5. Accessible for local tooling PDPA should allow easy access for local tools (e.g., CLIs). While this may sound obvious, it is a key factor for the intended versatility of the format. 3.2.6. Efficiency Since certain kinds of personal data might involve large quantities of data, major use cases for PDPA should be realizable in an efficient manner. For now, this is stated as an abstract guiding principle. Its actual dimensions and trade-offs need to be refined while evolving this specification. 3.3. Related work Many email server implementors have found it desirable to have one or more file formats for storing email in a file system even when the primary active email storage is more commonly a database. Examples include [PST] files (Outlook), NSF (Notes), [GoogleTakeout], Maildir, MBOX. File formats are already used for interoperability in many cases even when not standardized. This specification follows that pattern in order to build on these partial successes. By standardizing one format, we expect to be able to satisfy use cases that are harder to satisfy with a plurality of formats, such as use cases for server-to-server transfer of email account data during account migrations. Specifications that explain how to create these archives in different situations can refer to this specification. Happel, et al. Expires 18 March 2027 [Page 8] Internet-Draft PDPArchive September 2026 4. Approach 4.1. Using JSON (mostly) JSON is used in this spec for new metadata and for objects including contacts, tasks, events and notes. However, the Email Message Format [RFC5322] is used for email message content. Individual items are stored in individual files, which are referenced in collection metadata. Finally these JSON and other file formats are packaged and compressed together in a standard but flexible way. Our rationale for using JSON to the extent reasonable: * We envision an export format being used not just by developers of full IMAP servers but also by developers building task management systems, calendar systems that don't include email, etc. * We should minimize requiring multiple libraries to parse different formats. If the Metadata is going to be in JSON, it would really help to have the item data in JSON. * Personal data formats must be extensible and extensibility for JSON is well-understood. Using JSON for all the data _except_ EML files was carefully considered. EML files are rather specialized and more challenging to replace. Much of email is not structured data but content and involves MIME. EML is more likely to be a system's native data store, unlike VCARD and VTODO which are most commonly transformed for use in a relational data store for active use. Finally, email signature implementations like S/MIME and OpenPGP would be less disrupted by keeping EML. Information not covered by these existing file formats, but still necessary for migration or backup/restore of an email account, is packaged into JSON files. JSON structure and values are defined with CDDL [RFC8610]. The JSON files for email folders and other collections contain references to individual resources by unique ID and filename. 4.2. Approach to partial updates Our use case requirements above (use_cases) included some very common personal use cases that motivate exporting only a time-limited set of items, but retaining the ability to use that subset export to update a previously acquired or maintained snapshot. These are partial updates - partial exports able to update a full copy. Our approach is to define a version of the archive format that includes a subset Happel, et al. Expires 18 March 2027 [Page 9] Internet-Draft PDPArchive September 2026 of a repository's content, and additionally some change markers necessary to maintain consistency. A partial-update export * Contains new items just like a full export. * Omits unchanged items from before the time cutoff. * Does NOT list unchanged items in folder listings either. * Allows updated items to be identified so they can replace previous versions * Allows deleted items to be identified so they could be removed in the updated snapshot The existing definitions for UIDs and 'updated' in JMAP and IMAP should make this quite possible. Also IMAP MODSEQs [RFC7162] can be used for flag changes. 4.3. Approach to synchronization Email and calendaring services appear to already do synchronization just fine, but this is via a client-server model. The client drives the read and write requests until content is synchronized, using mostly UIDs and timestamps. Archive and export formats aren't part of this client-server model, and the work to make server-to-server or peer-to-peer synchronization work perfectly is substantial (involving features such as version numbers or change logs -- features that aren't commonly standardized for the objects handled in this spec). Still, there are some things possible with archive formats and the current object definitions that are sensible. Our approach is to describe what is possible with the fields that exist, and mandate those fields be used, so that users aren't left with multiple locations for their data and no way to repeatedly synchronize them. As an illustrative use case, let the user have contacts stored in one email service and also in one mobile device platform doing online backups. The email platform creates contacts when the user emails new recipients, or receives contact information over email. The mobile device platform synchronizes contact information from a phone. The email service is not a client of the mobile device platform, nor is the mobile device platform a client of the email service, so client-to-server protocols cannot directly synchronize the data between these two services. A user attempting to solve this by Happel, et al. Expires 18 March 2027 [Page 10] Internet-Draft PDPArchive September 2026 repeatedly importing contacts into one system from the other may find this works poorly - for example, it might create new contact objects over and over for the same contact data even if it is unchanged, and deleted objects may re-animate after being re-copied. Both servers ought to allow exporting of contact data (along with any other data covered in this specification), including especially the UID and updated (timestamp) fields. This would allow at least some sensible personal workflows or for 3rd party tools to make synchronization work better. When importing contact data (along with any other data covered in this specification), a service needs to take note of the UID in the import, and use it as the UID for creating a new object, so that it may be later avoid being recreated. If the service importing already has the said UID, the service should compare 'updated' timestamps and use that to decide how to update the object with new values. An object that hasn't changed since last imported should remain unchanged and not updated. This approach to synchronization is imperfect. Let the user have performed one synchronization by exporting from the email service and importing to the mobile device platform. If the user updates a contact on the email service (e.g adding a street address) and the mobile platform also updates the contact (e.g. adding an avatar link), then the user attempts to repeat the synchronization, both services will have a new 'updated' timestamp on the same object UID, and the earlier of the two changes will get wiped out. Nevertheless, a disciplined user can remember to only make changes on the email service and always copy them over to the mobile platform, and avoid many such lost updates. Based on the approach described here, this specification standardizes some behavior for both exporters and importers, to maximize potential success. 5. Solution Requirements These technical requirements on the solution are intended to meet the goals above, and to add more specifics about how those goals are intended to be met with the architecture chosen. This section does not attempt to translate the solution requirements into implementor requirements. Folder format requirements * can include partial results, showing only a subset of objects within the folder Happel, et al. Expires 18 March 2027 [Page 11] Internet-Draft PDPArchive September 2026 * can include a human-readable representation of the meaning of that subset (e.g. a date filter, or recipient filter) Email object format requirements * can maintain full fidelity including preserving character sets, content transfer encoding of body parts and exact MIME structure Compression and packaging of resources * Servers can bundle resources together in different ways to be flexible in handling size and network limitations. Servers must be able to choose optimal file size and organization of information within files. Synchronization requirements * Can see which items are identical in two systems, e.g. one system previously imported an item exported by the other. * Can detect changes made since the last time an item was imported, in a way that supports replacing an older version previously synchronized with a newer version that has edits. 6. File format This section describes the internal "raw" file format of a personal data portability archive. For discussion about a surrounding container format, see section "open issues". PDPArchive in general consists of: * A main metadata file ("archive.json") * Top-level folders for each data type ("/mail") * Subfolders representing actual collections of individual data items plus additional metadata files 6.1. Archive metadata file The archive.json file consists of three main sections with metadata about the archive as exported, the dataset used, and the source of the data. * archive: general information about the archive * dataset: characteristics of the dataset itself Happel, et al. Expires 18 March 2027 [Page 12] Internet-Draft PDPArchive September 2026 * datasource: meta-information about the dataset Happel, et al. Expires 18 March 2027 [Page 13] Internet-Draft PDPArchive September 2026 +=============+========================================+ | Key | Description and requirements | +=============+========================================+ | archive/id | Archive identifier, generated by | | | archive generator, MUST be unique | +-------------+----------------------------------------+ | archive/ | Human readable label | | name | | +-------------+----------------------------------------+ | archive/ | Note for human use and display | | note | (optional) | +-------------+----------------------------------------+ | archive/ | Legal desclaimer (optional) | | legal | | +-------------+----------------------------------------+ | archive/ | Archive timestamp | | timestamp | | +-------------+----------------------------------------+ | archive/ | PDPA spec version | | version | | +-------------+----------------------------------------+ | archive/ | Archive generator | | generator | | +-------------+----------------------------------------+ | dataset/ | Extent of the archive (full, partial) | | extent | | +-------------+----------------------------------------+ | dataset/ | Human readable description, containing | | description | e.g. date, folder, size (optional) | +-------------+----------------------------------------+ | dataset/ | List of data types | | datatypes | | +-------------+----------------------------------------+ | dataset/ | BCP 47 language tag for the dominant | | languagetag | language in the dataset | +-------------+----------------------------------------+ | dataset/ | IANA tz identifier for the dataset | | timezone | | +-------------+----------------------------------------+ | datasource/ | Information about the source service | | service | (id, url, ..) | +-------------+----------------------------------------+ | datasource/ | Information about the source account | | account | (id, type, ...) | +-------------+----------------------------------------+ Table 1 Happel, et al. Expires 18 March 2027 [Page 14] Internet-Draft PDPArchive September 2026 More formally: { "$id": "https://id.schemas.pub/o/DTI/PDPArchive/archive", "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "Schema for Personal Data Portability Archive (pdparchive) Archive Metadata", "type": "object", "required": ["archive", "dataset", "datasource"], "archive": { "type": "object", "required": ["id", "name", "timestamp", "version", "generator"], "properties": { "id": { "type": "string" }, "generator": { "type": "string" }, "legal": { "type": "string" }, "name": { "type": "string" }, "note": { "type": "string" }, "timestamp": { "type": "string", "format": "date-time" }, "version": { "type": "string" } } }, "dataset": { "type": "object", "required": ["extent", "languagetag", "timezone"], "properties": { "datatypes": { "type": "array", "items": { "type": "string" } }, "extent": { "type": "string" Happel, et al. Expires 18 March 2027 [Page 15] Internet-Draft PDPArchive September 2026 }, "languagetag": { "type": "string" }, "description": { "type": "string" }, "timezone": { "type": "string" } } }, "datasource": { "type": "object", "properties": { "account": { "type": "string" }, "service": { "type": "string" } } } } Figure 1: General JSON Schema for archive.json Example of archive.json (full export): Happel, et al. Expires 18 March 2027 [Page 16] Internet-Draft PDPArchive September 2026 { "$schema": "https://id.schemas.pub/o/DTI/PDPArchive/archive", "archive": { "id": "b47c1b85-c085-48b9-ae15-cb1b455422cd", "archive_id": "123", "name": "Jane's data export (2025-10-19)", "note": "Personal account export", "timestamp": "2025-10-18T23:20:59Z", "version": "PDPA v1.0", "generator": "PDPA exporter v0.9" }, "dataset": { "description": "Export generated for account holder Oct 19, 2025 (scope: Oct 19, 2024 - Oct 19, 2025)", "extent": "FULL", "datatypes": ["MAIL"], "languagetag": "en_ca", "timezone": "America/Montreal" }, "datasource": { "account": "marieclaire" } } Figure 2: A basic archive.json example PDPArchive generators MUST use [IJSON] to more safely generate this and other JSON outputs. 6.2. Folder structure Folder structure of source data is expressed in exported data using a mirrored structure in the file system directory. Folders hold archive metadata, folder metadata, item data and nested folders. This makes an export that can reasonably (not necessarily "easily") be navigated by a user interacting with their exported data via the file system. * Folders can be nested. Any kind of content here can be within nested folders. Support for IMAP/JMAP requires nested folders. * Names of files do not have to be globally unique. Indexes and folder contents listings can name files relatively to their location in the archive structure, which means that references may not be resolvable if that context is lost. Happel, et al. Expires 18 March 2027 [Page 17] Internet-Draft PDPArchive September 2026 * Individual content items are individual files. This may not always be the easiest choice for exporters who must generate a large number of files for individually small items (contrast to a JSON stream including all objects) but as an archive format, the individual files allow more clarity in individual handling, transactions and errors. Example overall archive structure Happel, et al. Expires 18 March 2027 [Page 18] Internet-Draft PDPArchive September 2026 archive.json /mail/ /Archive/ folder.json m1.eml m2.eml m3.eml ... /Archive/2023/ folder.json m1.eml m2.eml m3.eml ... /Archive/2024/ folder.json m1.eml m2.eml m3.eml .. /INBOX/ folder.json m1.eml m2.eml m3.eml ... /Sent Mail/ folder.json m1.eml m2.eml ... /contacts/ contact1.json contact2.json ... /calendars/ /calendar2/ calendar1.json event1.json event2.json /sieve/ /blob/ ...? Folder structure in the export is generally meaningful, not just an arbitrary way to paginate data. Happel, et al. Expires 18 March 2027 [Page 19] Internet-Draft PDPArchive September 2026 When an explicit ID mechanism exists for indicating containers/ collections, the explicit ID mechanism takes precedence over folder nesting. Using AddressBookIds in contacts data means the individual contact item may show up in more than one AddressBook item. The exporter can choose how to export contacts to folders within the export, but it is RECOMMENDED that the exporter only include one copy of a given item rather than one copy per collection it should appear in. This precedence rule applies also to other kinds of data with collection IDs. For example, a user might keep her sister Marianne's contact information in both her "Favorites" and "Family" address books. The exporter places marianne-dashwood.json under only one of the two corresponding folders in the export, rather than duplicating the file, because the addressBookIds field on the contact itself -- not its location in the export -- is what tells an importer which address books it belongs to. See Appendix B for the full worked example. Folders MUST be nested when the source data has nested folders. A user mailbox with nested folders cannot be accurately copied unless folder structure can also be copied. 6.2.1. File and folder names Because filenames can be generated by the exporting server, it is always possible to generate non-colliding filenames. Display names are NOT intended to be determined by file names, but instead by fields within each file. Similarly, filenames are NOT intended to be globally unique IDs. Mail folder names are defined in [RFC9051] (IMAP v4 rev2) with great freedom for servers. Servers may or may not treat mailbox names as case sensitive. Folder names may even include non-graphic characters, "%" and "*". Hierarchy separators may even differ among IMAP servers although "/" is probably most common. Since this specification is new, it is possible to be more constrained. This specification only supports "/" as a folder separator. 6.3. Data formats Happel, et al. Expires 18 March 2027 [Page 20] Internet-Draft PDPArchive September 2026 6.3.1. Email Each IMAP/JMAP folder is represented as subdirectory under "mail" directory. For example, the folder INBOX would be represented as "mail/INBOX", and the folder "Archive/2024/2024-12" would be represented as "mail/Archive/2024/2024-12". Folder names are encoded in UTF-8. Each email folder's metatadata is described by "folder.json" (this name is REQUIRED), which has the following fields: +==================+=============+============+=====================+ | Attribute Name | Type | Mandatory? | Comment | +==================+=============+============+=====================+ | allowed_keywords | array of | No | PERMANENTFLAGS | | | strings | | minus "\*" [IMAP4] | | | (IMAP | | | | | keywords) | | | +------------------+-------------+------------+---------------------+ | uid | string | SHOULD* | Use OBJECTID from | | | | | [RFC8474] | +------------------+-------------+------------+---------------------+ | last_uid | unsigned 32 | Yes | Last UID assigned | | | bit integer | | in the folder. It | | | | | is UIDNEXT value | | | | | minus 1 [IMAP4] | +------------------+-------------+------------+---------------------+ | recent_uid | unsigned 32 | No | Lowest UID of a | | | bit integer | | message with the | | | | | \Recent flag | | | | | [IMAP4] | +------------------+-------------+------------+---------------------+ | uidvalidity | unsigned 32 | Yes | UIDVALIDITY value | | | bit integer | | [IMAP4] | +------------------+-------------+------------+---------------------+ | is_subscribed | boolean | Yes | Is the folder | | | | | returned by IMAP | | | | | LSUB? [IMAP4] | +------------------+-------------+------------+---------------------+ | deleted_at | string | No | Folder has been | | | (timestamp) | | DELETED - this is | | | or null | | a tombstone | +------------------+-------------+------------+---------------------+ | myrights | string | No | See Section 3.5 of | | | | | [RFC4314]. For | | | | | example | | | | | "rwiptsldaex" | +------------------+-------------+------------+---------------------+ Happel, et al. Expires 18 March 2027 [Page 21] Internet-Draft PDPArchive September 2026 | highest_modseq | unsigned 64 | No | HIGHESTMODSEQ | | | bit integer | | value [RFC7162] | +------------------+-------------+------------+---------------------+ | special_use | string | No | [RFC6154] SPECIAL- | | | | | USE value. E.g. | | | | | "inbox", "sent", | | | | | "drafts", "junk", | | | | | etc. | +------------------+-------------+------------+---------------------+ | sort_order | | No | See Section 2, | | | | | [JMAP]] | +------------------+-------------+------------+---------------------+ | items | array of | Yes | Mapping from UIDs | | | content | | to corresponding | | | item names | | message files | | | and flags | | included in the | | | | | archive | +------------------+-------------+------------+---------------------+ | original_name | string | No | Original folder | | | | | name (relative to | | | | | its parent, if | | | | | any) if the name | | | | | can't be | | | | | represented in | | | | | filesystem, e.g. | | | | | if it includes | | | | | special characters | +------------------+-------------+------------+---------------------+ | comment | string | No | Can include | | | | | information about | | | | | partial export or | | | | | filter used in | | | | | human readable | | | | | UTF-8 text | +------------------+-------------+------------+---------------------+ | removed | array of | No | List of messages | | | unsigned 32 | | (UIDs) removed | | | bit | | since the last | | | integers | | export | +------------------+-------------+------------+---------------------+ Table 2 The uid for a folder SHOULD be present. For IMAP folders, this SHOULD be the OBJECTID defined by [RFC8474]. Happel, et al. Expires 18 March 2027 [Page 22] Internet-Draft PDPArchive September 2026 In an incremental update, a folder can both have items added/removed and be deleted in the time period elapsed, so it could have removed messages and flags as well as be a tombstone. A full archive or snapshot SHOULD NOT include deleted folders with the deleted_at value. The folder.json format can be defined generally as follows. Note that this covers folders containing tasks, notes or emails, so the fields that are specific to IMAP folders are not required. The folder.json format is NOT used for calendars or address books, which already have their own JSON format defined. { "$id": "https://id.schemas.pub/o/DTI/PDPArchive/folder", "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "Schema for Personal Data Portability Archive (pdparchive) Folder Manifest", "$defs": { "mod-sequence-value": { "type": "integer", "minimum": 0, "exclusiveMaximum": 18446744073709551616, "$comment": "Per RFC4551, a 'mod-sequence-value' is a positive unsigned 64-bit integer" }, "imap-number": { "type": "integer", "minimum": 0, "exclusiveMaximum": 4294967296, "$comment": "IMAP unsigned 32-bit integer" }, "imap-nz-number": { "type": "integer", "minimum": 1, "exclusiveMaximum": 4294967296, "$comment": "IMAP non-zero unsigned 32-bit integer" } }, "type": "object", "required": ["name", "items"], "properties": { "name": { "type": "string" }, "uid": { "type": "string" }, "removed": { Happel, et al. Expires 18 March 2027 [Page 23] Internet-Draft PDPArchive September 2026 "type": "array", "items": { "type": "string" } }, "comment": { "type": "string" }, "original_name": { "type": "string" }, "sort_order": { "type": "integer", "minimum": 1, "exclusiveMaximum": 2147483648 }, "modseqs": { "type": "object", "additionalProperties": { "$ref": "#/$defs/mod-sequence-value" } }, "highest_modseq": { "$ref": "#/$defs/mod-sequence-value" }, "special_use": { "type": "string", "description": "Can be \\All, \\Archive, \\Drafts, \\Flagged, \\Junk, \\Sent or \\Trash as per RFC6154.", "pattern": "^\\\\" }, "myrights": { "type": "string" }, "is_subscribed": { "type": "boolean" }, "deleted_at": { "type": "string", "format": "date-time" }, "last_uid": { "description": "Follows the IMAP4 requirements for unsigned 32-bit int", "$ref": "#/$defs/imap-number" }, "recent_uid": { "description": "Follows the IMAP4 requirements for unsigned 32-bit int", "$ref": "#/$defs/imap-number" }, Happel, et al. Expires 18 March 2027 [Page 24] Internet-Draft PDPArchive September 2026 "uidvalidity": { "description": "Follows the IMAP4 requirements for non-zero unsigned 32-bit int", "$ref": "#/$defs/imap-nz-number" }, "items": { "type": "array", "items": { "type": "object", "required": ["uid", "filename"], "properties": { "uid": { "description": "Either an IMAP UID (non-zero unsigned 32-bit integer) or a string identifier such as a UUID", "oneOf": [ { "$ref": "#/$defs/imap-nz-number" }, { "type": "string" } ] }, "filename": { "type": "string" }, "flags": { "type": "array", "items": { "type": "string" } } } } }, "flags": { "type": "object", "additionalProperties": { "type": "array", "items": { "type": "string" } } }, "allowed_keywords": { "type": "array", "items": { "type": "string" } } Happel, et al. Expires 18 March 2027 [Page 25] Internet-Draft PDPArchive September 2026 } } Figure 3: General JSON Schema for folder.json Example of folder.json (full export): { "$schema": "https://id.schemas.pub/o/DTI/PDPArchive/folder", "name": "AVClub", "uid": "M6d99ac3275bb4e", "allowed_keywords": ["$forwarded", "$MDNSent", "$ismailinglist"], "last_uid": 16, "highest_modseq": 6371729, "recent_uid": 15, "uidvalidity": 1107190787, "is_subscribed": true, "special_use": "\\Sent", "sort_order": 1, "myrights": "rwiptsldaex", "items": [ { "uid": "1", "filename": "msg-1.eml", "flags": ["$seen"] }, { "uid": "3", "filename": "msg-3.eml", "flags": ["$seen", "$flagged"] }, { "uid": "15", "filename": "imported-ABC.eml", "flags": ["$answered", "$forwarded"] } ] } Figure 4: A basic folder.json example UIDs SHOULD always be strings. This allows systems with UIDs that are not integers to export and synchronize data reliably. IMAP UIDs can always be converted back to integers. Happel, et al. Expires 18 March 2027 [Page 26] Internet-Draft PDPArchive September 2026 Example of folder.json that shows incremental changes from the previous export shown above. In this example 2 messages with UIDs 3 and 15 were removed. Message with UID 1 has updated flags. Several new messages were added, some of them are with flags set. { "$schema": "https://id.schemas.pub/o/DTI/PDPArchive/folder", "name": "AVClub", "allowed_keywords": ["$forwarded", "$MDNSent", "$ismailinglist"], "last_uid": 21, "highest_modseq": 6371845, "recent_uid": 20, "uidvalidity": 1107190787, "is_subscribed": true, "special_use": "\\Sent", "sort_order": 1, "myrights": "rwiptsldaex", "removed": ["3", "15"], "items": [ { "uid": "1", "filename": "msg-1.eml", "flags": ["$seen", "$answered"] }, { "uid": "17", "filename": "msg-17.eml", "flags": ["$seen", "$answered", "$forwarded"] }, { "uid": "19", "filename": "msg-19.eml", "flags": ["$seen"] }, { "uid": "20", "filename": "msg-20.eml" }, { "uid": "21", "filename": "msg-21.eml" } ] } Figure 5: A folder.json example with incremental changes Happel, et al. Expires 18 March 2027 [Page 27] Internet-Draft PDPArchive September 2026 Finally, to show an example containing no IMAP content but also meets schema requirements: { "$schema": "https://id.schemas.pub/o/DTI/PDPArchive/folder", "name": "AVClub Tasks", "sort_order": 2, "myrights": "rwiptsldaex", "items": [ { "uid": "56cb57e3-dfa9-40b5-9011-fe658909d138", "filename": "elect a new chair.json" }, { "uid": "65047c09-f236-485b-a011-5f68580c0d4d", "filename": "send Jan newsletter.json" }, { "uid": "bd57adf2-3862-4256-ac2e-aafaf2ce8d71", "filename": "add Mary to project folders.json" } ] } Figure 6: A folder.json example with incremental changes 6.3.2. Contacts [vCard] has long been the basis for address book and contact data representation in structured data files. The specifications for [JSContact] and JMAP for Contacts [RFC9610] do a bunch of the work to explain how to do this in JSON, and in particular RFC9610 explains how to express references between objects (e.g. an address book and a contact in that address book) which is useful for a full export that can have its references reconstructed. This section explains how to use the fields and structures of those specifications within a PDP Archive export. 6.3.2.1. Individual Contact Items Individual contact items build on [RFC9610] and [JSContact] which build on [vCard]. Happel, et al. Expires 18 March 2027 [Page 28] Internet-Draft PDPArchive September 2026 * The @type property should be "Card" because [JSContact] uses a value of "Card" for @type and registers that in https://www.iana.org/assignments/jscontact/jscontact.xhtml. JMAP for Contacts uses "ContactCard" and registers that in https://www.iana.org/assignments/jmap/jmap.xhtml but does not use that as a @type value directly. * The rev property defined in [vCard], which is not included in [JSContact], may already be available in implementations. It MAY also be included as a field on a contact, in which case it is a simple value field holding a timestamp. When a Card is exported as a standalone Contact item in PDP Archive, it MUST meet an extended schema, compared to other contexts where JSON Card data may be found. Unique uid and updated MUST be included. This specification extends the base schema (see Appendix A) to require uid, updated, and a non-empty addressBookIds. { "$id": "https://id.schemas.pub/o/DTI/PDPArchive/pdpa-contact", "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "Schema for Personal Data Portability Archive (pdparchive) Contact", "description": "Extends the base JSContact Card schema (contact-schema.json) with the `uid`, `updated`, and `addressBookIds` values required when a Card is exported as a standalone PDPArchive Contact item, as opposed to a Card embedded in some other object.", "allOf": [ { "$ref": "https://id.schemas.pub/o/DTI/PDPArchive/contact" }, { "type": "object", "required": ["uid", "updated", "addressBookIds"], "properties": { "addressBookIds": { "minProperties": 1 } } } ] } Figure 7: Schema for a standalone PDPArchive Contact item, extending the base Card schema Synchronization requirements for the updated and uid values apply to Contact items too (see Section 6.4.1). Cards can also have an id value; nevertheless uid is required by this specification for consistency of identifying different kinds of objects. See also how [RFC9610] contrasts id with uid. Happel, et al. Expires 18 March 2027 [Page 29] Internet-Draft PDPArchive September 2026 A contact can be exported in a file with an arbitrary name using a limited set of characters suitable for interoperability across filesystems. For example, a file called 'contact1.json' could contain: { "$schema": "https://id.schemas.pub/o/DTI/PDPArchive/pdpa-contact", "@type": "Card", "version": "1.0", "uid": "22B2C7DF-9120-4969-8460-05956FE6B065", "id": "42", "created": "2021-10-31T22:27:10Z", "updated": "2021-10-31T22:27:10Z", "kind": "individual", "addressBookIds": { "062adcfa-105d-455c-bc60-6db68b69c3f3": true }, "name": { "components": [ { "kind": "given", "value": "John" }, { "kind": "surname", "value": "Doe" } ], "isOrdered": true }, "relatedTo": { "urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6": { "relation": { "friend": true } } }, "notes": { "n1": { "note": "Open office hours are 1600 to 1715 EST, Mon-Fri", "created": "2022-11-23T15:01:32Z", "author": { "name": "John" } } } } Figure 8: A contact example called contact1.json in the export Happel, et al. Expires 18 March 2027 [Page 30] Internet-Draft PDPArchive September 2026 For clarity, this example includes: * How a card can reference address books which are exported as separate files in the overall export * How a card can reference other cards using relatedTo * A card can contain arbitrary notes - those are not necessarily exported as separate files even though notes are also an object that can be included as individual files in a PDPArchive export. Because a ContactCard item can reference an AddressBook item, if a system exports contacts belonging to address books it SHOULD also export the referenced AddressBook objects. Likewise, it SHOULD export the other ContactCard objects that are referenced in the 'relatedTo' field. A permission or scope inconsistency would be one reason why the exporting system would not do so. For example, if the user chose to export only a public address book containing the "John Doe" contact, and not the private "Wedding guests" address book that John Doe also belonged to, then the private address book would either appear as an unresolvable ID or be cleaned up so that it didn't appear (implementor's choice). Likewise, when "John Doe" is exported as part of a single address book export, but the friend relation in relatedTo is not exported because they're not in the same address book, the relatedTo value may be included in the export even if not resolvable by some users of the export file. 6.3.2.2. Group Contact Items Group contact items also refer to other contact items. A file with an arbitrary name like "contact2.json" could include: { "$schema": "https://id.schemas.pub/o/DTI/PDPArchive/pdpa-contact", "@type": "Card", "version": "1.0", "kind": "group", "name": { "full": "The Doe family" }, "uid": "urn:uuid:ab4310aa-fa43-11e9-8f0b-362b9e155667", "updated": "2021-10-31T22:27:10Z", "addressBookIds": { "062adcfa-105d-455c-bc60-6db68b69c3f3": true }, "members": { "urn:uuid:03a0e51f-d1aa-4385-8a53-e29025acd8af": true, "urn:uuid:b8767877-b4a1-4c70-9acc-505d3819e519": true } } Figure 9: A group contact file example in the export as contact2.json Happel, et al. Expires 18 March 2027 [Page 31] Internet-Draft PDPArchive September 2026 As with individual ContactCard items referencing objects that are not exported at the same time, a group contact can contain references that are not resolvable within the export. If the user chooses to export all address books then presumably the "The Doe family" group members can all be found somewhere in the export, but if they export only the address book containing "The Doe family" group and not the address books containing individual members, those IDs would not be found in the export. 6.3.3. Using RFC9610 address book objects The [vCard] specifications never defined a representation for address books. Nor did [JSContact]. JMAP for Contacts [RFC9610] does. Its model is clearly that of non-exclusive collection membership: a Contact item may appear with the same UID in multiple Address Books, and if the Contact item with that UID is updated in one it is updated in the other also. Individual address book objects are returned in JMAP protocol messages with protocol wrappers. It is the items inside the "list" element inside "AddressBook/get" that are nearly ready to be represented as individual files in a PDPArchive. However, some things are missing: * uid is called 'id' in JMAP for Contacts but this specification REQUIRES uid. * updated is required * The @type of AddressBook should be included within the data In the schema below, myRights (camelCase) is a JSON object with named boolean fields, unlike the IMAP myrights property which is a compact string of right-characters (e.g. "rwiptsld"). { "$id": "https://id.schemas.pub/o/DTI/PDPArchive/address-book", "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "Schema for Personal Data Portability Archive (pdparchive) Address Book", "type": "object", "required": ["@type", "uid", "updated", "name"], "$defs": { "rights": { "type": "object", "properties": { "mayRead": { "type": "boolean" }, "mayWrite": { "type": "boolean" }, "mayShare": { "type": "boolean" }, "mayDelete": { "type": "boolean" } } } }, "properties": { Happel, et al. Expires 18 March 2027 [Page 32] Internet-Draft PDPArchive September 2026 "@type": { "type": "string", "const": "AddressBook" }, "uid": { "description": "Globally unique identifier for the address book", "type": "string" }, "id": { "description": "JMAP server-set ID for the address book", "type": "string" }, "updated": { "type": "string", "format": "date-time" }, "name": { "type": "string", "minLength": 1, "maxLength": 255 }, "description": { "type": ["string", "null"] }, "sortOrder": { "type": "integer", "minimum": 0, "maximum": 2147483647 }, "isDefault": { "type": "boolean" }, "isSubscribed": { "type": "boolean" }, "shareWith": { "description": "Maps principal IDs to their rights; null if not shared", "type": ["object", "null"], "additionalProperties": { "$ref": "#/$defs/rights" } }, "myRights": { "$ref": "#/$defs/rights" } } } Happel, et al. Expires 18 March 2027 [Page 33] Internet-Draft PDPArchive September 2026 Figure 10: Schema for address book objects This example copies the examples in [RFC9610] so that interoperability between this spec and that one is clear. A file with an arbitrary name like address-book1.json would contain: { "$schema": "https://id.schemas.pub/o/DTI/PDPArchive/address-book", "@type": "AddressBook", "uid": "062adcfa-105d-455c-bc60-6db68b69c3f3", "updated": "2020-01-09T14:32:01Z", "name": "Personal", "description": null, "sortOrder": 0, "isDefault": true, "isSubscribed": true, "shareWith": { "3f1502e0-63fe-4335-9ff3-e739c188f5dd": { "mayRead": true, "mayWrite": false, "mayShare": false, "mayDelete": false } }, "myRights": { "mayRead": true, "mayWrite": true, "mayShare": true, "mayDelete": false } } Figure 11: An address book file example address-book2.json would contain: Happel, et al. Expires 18 March 2027 [Page 34] Internet-Draft PDPArchive September 2026 { "$schema": "https://id.schemas.pub/o/DTI/PDPArchive/address-book", "@type": "AddressBook", "uid": "cd40089d-35f9-4fd7-980b-ba3a9f1d74fe", "updated": "2020-01-09T14:32:01Z", "name": "Autosaved", "description": null, "sortOrder": 1, "isDefault": false, "isSubscribed": true, "shareWith": null, "myRights": { "mayRead": true, "mayWrite": true, "mayShare": true, "mayDelete": false } } Figure 12: Another address book file example Note that the first example includes a shareWith value, showing that the user's AddressBook has been shared with in this case one other principal with the id "3f1502e0-63fe-4335-9ff3-e739c188f5dd". This information can be exported and may be quite useful in case of backup/restore use cases. However, it may not be useful in other administrative domains where the same concept of principals does not allow the Principal ID to be resolved against the correct account. In any case, the object referred to by this Principal ID is not itself given representation in the PDP Archive export. See also Section 9 on trusting sharing information in exported data. 6.3.4. Calendar events, tasks and groups [JSCalendar] is the basis for representing events, tasks and groups in JSON. This section explains how to export individual events and tasks within an archive. JMAP for Calendars ([JMAPCalendars]) does provide some additional considerations when producing calendar data from a JMAP system or to be consumed by a JMAP system, so it is also a normative reference. Note on [CalDAV] compatibility: Although CalDAV servers are fairly common, they support the older VEVENT and VTODO syntax. This specification requires the JSCalendar syntax instead. Either way, a server building a personal data archive is likely transforming an internal implementation-specific relational data format to an export format. Happel, et al. Expires 18 March 2027 [Page 35] Internet-Draft PDPArchive September 2026 Note on ETag: CalDAV servers use the event's UID to identify the same object, and use ETags to identify changed events, so that a CalDAV client may make sure it has the version a server has before it updates an item, solving the lost-update problem. Since this specification doesn't attempt to solve the lost-update problem as well as client-server protocols can, and since JSCalendar does not include the ETag of a calendar event in any way, this specification does not include any requirements for ETags. Notes on specific fields: * The globally unique uid property is mandatory in JSCalendar and MUST be included. See Section 1.4.1 of [JMAPCalendars] for when the uid property can appear the same for multiple recurrences of the same underlying event. * The updated property is mandatory in JSCalendar and MUST be included. * The sequence value is optional in JSCalendar but SHOULD be included if available. * The @type property for one of these items MUST be "Event", "Task" or "Group". * Recurrence rules SHOULD be fully exported, unless it's clear from the use case or user request that the destination for the data wants expanded recurrences within a specific time period. * The calendarIds field defined in JMAP Calendars is REQUIRED in order to match up events to the calendar they are supposed to appear in. As with addressBookIds for contacts, this explicit ID mechanism takes precedence over any folder nesting in the export; see Section 6.2. { "$id": "https://id.schemas.pub/o/DTI/PDPArchive/event", "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "Schema for Personal Data Portability Archive (pdparchive) Calendar Event", "description": "A JSCalendar Event object as defined in RFC 8984, extended with the calendarIds property from JMAP for Calendars.", "type": "object", "required": ["@type", "uid", "updated", "calendarIds"], "$defs": { "LocalDateTime": { "type": "string", "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}$", "$comment": "ISO 8601 date-time with no UTC offset; interpreted in the timeZone property" }, Happel, et al. Expires 18 March 2027 [Page 36] Internet-Draft PDPArchive September 2026 "participant": { "type": "object", "properties": { "@type": { "type": "string", "const": "Participant" }, "name": { "type": "string" }, "email": { "type": "string", "format": "email" }, "sendTo": { "type": "object", "additionalProperties": { "type": "string" } }, "kind": { "type": "string", "enum": ["individual", "group", "resource", "location"] }, "roles": { "type": "object", "additionalProperties": { "type": "boolean" } }, "participationStatus": { "type": "string", "enum": ["needs-action", "accepted", "declined", "tentative", "delegated"] }, "participationComment": { "type": "string" }, "expectReply": { "type": "boolean" }, "delegatedTo": { "type": "object", "additionalProperties": { "type": "boolean" } }, "delegatedFrom": { "type": "object", Happel, et al. Expires 18 March 2027 [Page 37] Internet-Draft PDPArchive September 2026 "additionalProperties": { "type": "boolean" } }, "memberOf": { "type": "object", "additionalProperties": { "type": "boolean" } } } }, "location": { "type": "object", "properties": { "@type": { "type": "string", "const": "Location" }, "name": { "type": "string" }, "description": { "type": "string" }, "coordinates": { "description": "Geo URI as defined in RFC 5870", "type": "string", "format": "uri" }, "timeZone": { "type": "string" }, "relativeTo": { "type": "string", "enum": ["start", "end"] }, "links": { "type": "object", "additionalProperties": { "$ref": "https://id.schemas.pub/o/DTI/PDPArchive/link" } } } }, "alert": { "type": "object", "required": ["@type", "trigger"], Happel, et al. Expires 18 March 2027 [Page 38] Internet-Draft PDPArchive September 2026 "properties": { "@type": { "type": "string", "const": "Alert" }, "trigger": { "oneOf": [ { "description": "Offset-based trigger relative to event start or end", "type": "object", "required": ["@type", "offset"], "properties": { "@type": { "type": "string", "const": "OffsetTrigger" }, "offset": { "description": "ISO 8601 duration (may be negative for before-start alerts)", "type": "string" }, "relativeTo": { "type": "string", "enum": ["start", "end"] } } }, { "description": "Absolute date-time trigger", "type": "object", "required": ["@type", "when"], "properties": { "@type": { "type": "string", "const": "AbsoluteTrigger" }, "when": { "type": "string", "format": "date-time" } } } ] }, "acknowledged": { "type": "string", "format": "date-time" }, "action": { Happel, et al. Expires 18 March 2027 [Page 39] Internet-Draft PDPArchive September 2026 "type": "string", "enum": ["display", "email", "uri"] } } }, "recurrenceRule": { "description": "Recurrence rule as defined in RFC 8984 section 4.3.2", "type": "object", "required": ["frequency"], "properties": { "@type": { "type": "string", "const": "RecurrenceRule" }, "frequency": { "type": "string", "enum": ["secondly", "minutely", "hourly", "daily", "weekly", "monthly", "yearly"] }, "interval": { "type": "integer", "minimum": 1 }, "rscale": { "type": "string" }, "skip": { "type": "string", "enum": ["omit", "backward", "forward"] }, "firstDayOfWeek": { "type": "string", "enum": ["mo", "tu", "we", "th", "fr", "sa", "su"] }, "byDay": { "type": "array", "items": { "type": "object", "required": ["day"], "properties": { "@type": { "type": "string", "const": "NDay" }, "day": { "type": "string", "enum": ["mo", "tu", "we", "th", "fr", "sa", "su"] }, "nthOfPeriod": { "type": "integer" } } Happel, et al. Expires 18 March 2027 [Page 40] Internet-Draft PDPArchive September 2026 } }, "byMonthDay": { "type": "array", "items": { "type": "integer" } }, "byMonth": { "type": "array", "items": { "type": "string" } }, "byYearDay": { "type": "array", "items": { "type": "integer" } }, "byWeekNo": { "type": "array", "items": { "type": "integer" } }, "byHour": { "type": "array", "items": { "type": "integer", "minimum": 0, "maximum": 23 } }, "byMinute": { "type": "array", "items": { "type": "integer", "minimum": 0, "maximum": 59 } }, "bySecond": { "type": "array", "items": { "type": "integer", "minimum": 0, "maximum": 60 } }, "bySetPosition": { "type": "array", "items": { "type": "integer" } }, "count": { "type": "integer", "minimum": 1 }, "until": { "description": "LocalDateTime giving the last allowed occurrence", "$ref": "#/$defs/LocalDateTime" } } } }, "properties": { "@type": { "type": "string", Happel, et al. Expires 18 March 2027 [Page 41] Internet-Draft PDPArchive September 2026 "const": "Event" }, "uid": { "description": "Globally unique identifier for this event; stable across recurrences", "type": "string" }, "id": { "description": "JMAP server-set ID for the event", "type": "string" }, "created": { "type": "string", "format": "date-time" }, "updated": { "description": "Last-modified timestamp; MUST be included for synchronization", "type": "string", "format": "date-time" }, "prodId": { "type": "string" }, "sequence": { "description": "Monotonically increasing revision counter; SHOULD be included if available", "type": "integer", "minimum": 0 }, "title": { "type": "string" }, "description": { "type": "string" }, "descriptionContentType": { "type": "string" }, "start": { "$ref": "#/$defs/LocalDateTime" }, "timeZone": { "description": "IANA time zone identifier for the start time", "type": "string" }, "duration": { "description": "ISO 8601 duration string", "type": "string" }, "status": { Happel, et al. Expires 18 March 2027 [Page 42] Internet-Draft PDPArchive September 2026 "type": "string", "enum": ["confirmed", "cancelled", "tentative"] }, "priority": { "type": "integer", "minimum": 0, "maximum": 9 }, "privacy": { "type": "string", "enum": ["public", "private", "secret"] }, "freeBusyStatus": { "type": "string", "enum": ["free", "busy"] }, "color": { "description": "CSS color value for display purposes", "type": "string" }, "calendarIds": { "type": "object", "minProperties": 1, "additionalProperties": { "type": "boolean" } }, "participants": { "type": "object", "additionalProperties": { "$ref": "#/$defs/participant" } }, "locations": { "type": "object", "additionalProperties": { "$ref": "#/$defs/location" } }, "virtualLocations": { "description": "Maps virtual location IDs to VirtualLocation objects (e.g. video conference links)", "type": "object", "additionalProperties": { "type": "object", "properties": { "@type": { "type": "string", "const": "VirtualLocation" }, "name": { "type": "string" }, "description": { "type": "string" }, Happel, et al. Expires 18 March 2027 [Page 43] Internet-Draft PDPArchive September 2026 "uri": { "type": "string", "format": "uri" } } } }, "links": { "description": "Maps link IDs to Link objects (attachments, references)", "type": "object", "additionalProperties": { "$ref": "https://id.schemas.pub/o/DTI/PDPArchive/link" } }, "keywords": { "type": "object", "additionalProperties": { "type": "boolean" } }, "categories": { "type": "object", "additionalProperties": { "type": "boolean" } }, "alerts": { "description": "Maps alert IDs to Alert objects", "type": "object", "additionalProperties": { "$ref": "#/$defs/alert" } }, "useDefaultAlerts": { "type": "boolean" }, "recurrenceRules": { "type": "array", "items": { "$ref": "#/$defs/recurrenceRule" } }, "excludedRecurrenceRules": { "type": "array", "items": { "$ref": "#/$defs/recurrenceRule" } }, "recurrenceOverrides": { "type": "object", "additionalProperties": { Happel, et al. Expires 18 March 2027 [Page 44] Internet-Draft PDPArchive September 2026 "type": "object" } } } } Figure 13: Schema for events For example, a file called event1.json could contain: { "$schema": "https://id.schemas.pub/o/DTI/PDPArchive/event", "@type": "Event", "uid": "2a358cee-6489-4f14-a57f-c104db4dc2f2", "updated": "2020-01-09T14:32:01Z", "title": "Board Meeting", "start": "2024-10-25T09:00:00", "timeZone": "Europe/London", "duration": "PT1H30M", "participants": { "1": { "@type": "Participant", "name": "Jane Doe", "sendTo": { "mailto": "jane@example.com" }, "roles": { "attendee": true } } }, "calendarIds": { "062adcfa-105d-455c-bc60-6db68b69c3f3": true } } Figure 14: Event example The event object includes a calendarIds property, which links it to the calendar collections it belongs to. 6.3.5. Calendar Collection Items Calendar collection items are built using JMAP for Calendars ([JMAPCalendars]). If a system exports events belonging to calendars, it SHOULD also export the referenced Calendar objects. Happel, et al. Expires 18 March 2027 [Page 45] Internet-Draft PDPArchive September 2026 myRights uses the same JSON object structure as in the Address Book schema, but the set of rights is defined by JMAP Calendars rather than JMAP Contacts, so the property names differ. { "$id": "https://id.schemas.pub/o/DTI/PDPArchive/calendar", "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "Schema for Personal Data Portability Archive (pdparchive) Calendar Collection", "description": "A Calendar collection object as defined in JMAP for Calendars (draft-ietf-jmap-calendars).", "type": "object", "required": ["@type", "uid", "updated", "name"], "$defs": { "calendarRights": { "description": "CalendarRights object as defined in JMAP for Calendars", "type": "object", "properties": { "mayReadFreeBusy": { "type": "boolean" }, "mayReadItems": { "type": "boolean" }, "mayWriteAll": { "type": "boolean" }, "mayWriteOwn": { "type": "boolean" }, "mayUpdatePrivate": { "type": "boolean" }, "mayRSVP": { "type": "boolean" }, "mayShare": { "type": "boolean" }, "mayDelete": { "type": "boolean" } } }, "alert": { "type": "object", "required": ["@type", "trigger"], "properties": { "@type": { "type": "string", "const": "Alert" }, "trigger": { "oneOf": [ { "type": "object", "required": ["@type", "offset"], "properties": { "@type": { "type": "string", "const": "OffsetTrigger" }, "offset": { "type": "string" }, "relativeTo": { "type": "string", "enum": ["start", "end"] } } }, { "type": "object", "required": ["@type", "when"], "properties": { "@type": { "type": "string", "const": "AbsoluteTrigger" }, "when": { "type": "string", "format": "date-time" } Happel, et al. Expires 18 March 2027 [Page 46] Internet-Draft PDPArchive September 2026 } } ] }, "acknowledged": { "type": "string", "format": "date-time" }, "action": { "type": "string", "enum": ["display", "email", "uri"] } } } }, "properties": { "@type": { "type": "string", "const": "Calendar" }, "uid": { "description": "Globally unique identifier for the calendar; referenced by Event calendarIds", "type": "string" }, "id": { "description": "JMAP server-set ID for the calendar", "type": "string" }, "updated": { "type": "string", "format": "date-time" }, "name": { "type": "string", "minLength": 1, "maxLength": 255 }, "description": { "type": ["string", "null"] }, "color": { "description": "CSS color value used to distinguish the calendar visually", "type": "string" }, "sortOrder": { "type": "integer", "minimum": 0, "maximum": 2147483647 }, "isDefault": { "type": "boolean" }, "isSubscribed": { "type": "boolean" Happel, et al. Expires 18 March 2027 [Page 47] Internet-Draft PDPArchive September 2026 }, "isVisible": { "type": "boolean" }, "includeInAvailability": { "description": "Which events contribute to free/busy availability", "type": "string", "enum": ["all", "attending", "none"] }, "timeZone": { "description": "IANA time zone identifier used as default for events without their own time zone", "type": ["string", "null"] }, "defaultAlertsWithTime": { "description": "Default alerts applied to timed events when the event has useDefaultAlerts: true; null clears inherited defaults", "type": ["object", "null"], "additionalProperties": { "$ref": "#/$defs/alert" } }, "defaultAlertsWithoutTime": { "description": "Default alerts applied to all-day events when the event has useDefaultAlerts: true; null clears inherited defaults", "type": ["object", "null"], "additionalProperties": { "$ref": "#/$defs/alert" } }, "shareWith": { "description": "Maps principal IDs to their CalendarRights; null if not shared", "type": ["object", "null"], "additionalProperties": { "$ref": "#/$defs/calendarRights" } }, "myRights": { "$ref": "#/$defs/calendarRights" } } } Figure 15: Schema for calendar collections A file with an arbitrary name, such as calendar1.json, in a directory (e.g., /calendars/calendar2/) would contain the calendar's metadata: Happel, et al. Expires 18 March 2027 [Page 48] Internet-Draft PDPArchive September 2026 { "$schema": "https://id.schemas.pub/o/DTI/PDPArchive/calendar", "@type": "Calendar", "uid": "062adcfa-105d-455c-bc60-6db68b69c3f3", "updated": "2020-01-09T14:32:01Z", "name": "Work Calendar", "color": "#123456", "sortOrder": 0, "isDefault": true, "isSubscribed": true, "myRights": { "mayReadFreeBusy": true, "mayReadItems": true, "mayWriteAll": true, "mayWriteOwn": true, "mayUpdatePrivate": true, "mayRSVP": true, "mayShare": true, "mayDelete": false } } Figure 16: Calendar example The uid value here corresponds to the ID used in the calendarIds property of the individual event item. 6.3.5.1. Tasks Tasks are also defined by [JSCalendar] using the "Task" object type. As with events, tasks MUST include the uid and updated fields to support synchronization. { "$id": "https://id.schemas.pub/o/DTI/PDPArchive/task", "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "Schema for Personal Data Portability Archive (pdparchive) Task", "description": "A JSCalendar Task object as defined in RFC 8984.", "type": "object", "required": ["@type", "uid", "updated"], "$defs": { "LocalDateTime": { "type": "string", "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}$", "$comment": "ISO 8601 date-time with no UTC offset; interpreted in the timeZone property" }, "participant": { "type": "object", Happel, et al. Expires 18 March 2027 [Page 49] Internet-Draft PDPArchive September 2026 "properties": { "@type": { "type": "string", "const": "Participant" }, "name": { "type": "string" }, "email": { "type": "string", "format": "email" }, "sendTo": { "type": "object", "additionalProperties": { "type": "string" } }, "kind": { "type": "string", "enum": ["individual", "group", "resource", "location"] }, "roles": { "type": "object", "additionalProperties": { "type": "boolean" } }, "participationStatus": { "type": "string", "enum": ["needs-action", "accepted", "declined", "tentative", "delegated"] }, "participationComment": { "type": "string" }, "expectReply": { "type": "boolean" } } }, "alert": { "type": "object", "required": ["@type", "trigger"], "properties": { "@type": { "type": "string", "const": "Alert" }, "trigger": { "oneOf": [ { "type": "object", "required": ["@type", "offset"], "properties": { "@type": { "type": "string", "const": "OffsetTrigger" }, "offset": { "type": "string" }, "relativeTo": { "type": "string", "enum": ["start", "end"] } } }, { "type": "object", "required": ["@type", "when"], "properties": { "@type": { "type": "string", "const": "AbsoluteTrigger" }, "when": { "type": "string", "format": "date-time" } } } Happel, et al. Expires 18 March 2027 [Page 50] Internet-Draft PDPArchive September 2026 ] }, "acknowledged": { "type": "string", "format": "date-time" }, "action": { "type": "string", "enum": ["display", "email", "uri"] } } }, "location": { "type": "object", "properties": { "@type": { "type": "string", "const": "Location" }, "name": { "type": "string" }, "description": { "type": "string" }, "coordinates": { "description": "Geo URI as defined in RFC 5870", "type": "string", "format": "uri" }, "timeZone": { "type": "string" }, "relativeTo": { "type": "string", "enum": ["start", "end"] }, "links": { "type": "object", "additionalProperties": { "$ref": "https://id.schemas.pub/o/DTI/PDPArchive/link" } } } }, "recurrenceRule": { "type": "object", "required": ["frequency"], "properties": { "@type": { "type": "string", "const": "RecurrenceRule" }, "frequency": { "type": "string", "enum": ["secondly", "minutely", "hourly", "daily", "weekly", "monthly", "yearly"] }, "interval": { "type": "integer", "minimum": 1 }, "firstDayOfWeek": { "type": "string", "enum": ["mo", "tu", "we", "th", "fr", "sa", "su"] }, "byDay": { "type": "array", "items": { "type": "object", "required": ["day"], "properties": { "@type": { "type": "string", "const": "NDay" }, "day": { "type": "string", Happel, et al. Expires 18 March 2027 [Page 51] Internet-Draft PDPArchive September 2026 "enum": ["mo", "tu", "we", "th", "fr", "sa", "su"] }, "nthOfPeriod": { "type": "integer" } } } }, "byMonthDay": { "type": "array", "items": { "type": "integer" } }, "byMonth": { "type": "array", "items": { "type": "string" } }, "count": { "type": "integer", "minimum": 1 }, "until": { "description": "LocalDateTime giving the last allowed occurrence", "$ref": "#/$defs/LocalDateTime" } } } }, "properties": { "@type": { "type": "string", "const": "Task" }, "uid": { "type": "string" }, "id": { "description": "JMAP server-set ID for the task", "type": "string" }, "created": { "type": "string", "format": "date-time" }, "updated": { "description": "Last-modified timestamp; MUST be included for synchronization", "type": "string", "format": "date-time" }, "prodId": { "type": "string" }, "sequence": { "type": "integer", "minimum": 0 }, "title": { "type": "string" }, "description": { Happel, et al. Expires 18 March 2027 [Page 52] Internet-Draft PDPArchive September 2026 "type": "string" }, "descriptionContentType": { "type": "string" }, "start": { "$ref": "#/$defs/LocalDateTime" }, "due": { "$ref": "#/$defs/LocalDateTime" }, "timeZone": { "description": "IANA time zone identifier for the start and due times", "type": "string" }, "estimatedDuration": { "description": "ISO 8601 duration string estimating time to complete", "type": "string" }, "percentComplete": { "type": "integer", "minimum": 0, "maximum": 100 }, "progress": { "description": "Task progress status per RFC 8984", "type": "string", "enum": ["needs-action", "in-progress", "completed", "failed", "cancelled"] }, "progressUpdated": { "type": "string", "format": "date-time" }, "priority": { "type": "integer", "minimum": 0, "maximum": 9 }, "privacy": { "type": "string", "enum": ["public", "private", "secret"] }, "color": { "type": "string" }, "participants": { "type": "object", "additionalProperties": { "$ref": "#/$defs/participant" } Happel, et al. Expires 18 March 2027 [Page 53] Internet-Draft PDPArchive September 2026 }, "locations": { "description": "Maps location IDs to Location objects", "type": "object", "additionalProperties": { "$ref": "#/$defs/location" } }, "virtualLocations": { "description": "Maps virtual location IDs to VirtualLocation objects (e.g. video conference links)", "type": "object", "additionalProperties": { "type": "object", "properties": { "@type": { "type": "string", "const": "VirtualLocation" }, "name": { "type": "string" }, "description": { "type": "string" }, "uri": { "type": "string", "format": "uri" } } } }, "relatedTo": { "description": "Maps related object UIDs to Relation objects describing the relationship", "type": "object", "additionalProperties": { "type": "object", "properties": { "@type": { "type": "string", "const": "Relation" }, "relation": { "description": "Maps relation type (e.g. parent, child, first, next) to true", "type": "object", "additionalProperties": { "type": "boolean" } } } } }, "links": { "type": "object", "additionalProperties": { "$ref": "https://id.schemas.pub/o/DTI/PDPArchive/link" } }, "keywords": { "type": "object", "additionalProperties": { "type": "boolean" } }, "categories": { "type": "object", "additionalProperties": { "type": "boolean" } }, "alerts": { "type": "object", Happel, et al. Expires 18 March 2027 [Page 54] Internet-Draft PDPArchive September 2026 "additionalProperties": { "$ref": "#/$defs/alert" } }, "useDefaultAlerts": { "type": "boolean" }, "recurrenceRules": { "type": "array", "items": { "$ref": "#/$defs/recurrenceRule" } }, "excludedRecurrenceRules": { "type": "array", "items": { "$ref": "#/$defs/recurrenceRule" } }, "recurrenceOverrides": { "type": "object", "additionalProperties": { "type": "object" } } } } Figure 17: Schema for tasks For example, a file called task1.json could contain: { "$schema": "https://id.schemas.pub/o/DTI/PDPArchive/task", "@type": "Task", "uid": "7b0f69a6-6e3e-4f1b-85d8-c89b43d2f2a1", "updated": "2022-11-23T15:01:32Z", "title": "Submit Quarterly Report", "progress": "in-progress", "priority": 1, "due": "2024-12-31T23:59:59" } Figure 18: Task example 6.3.6. Notes Notes are simple, free-form text or documents, typically attached to a task, contact, or event, or kept standalone (e.g. a personal notebook). VJournal, first defined in [iCalendar] and also used by [CalDAV], was not carried forward into [JSCalendar] (see https://jmap.io/spec-calendars.html), so there is no existing JSON format for notes to build on. Happel, et al. Expires 18 March 2027 [Page 55] Internet-Draft PDPArchive September 2026 This specification therefore defines a minimal, PDPArchive-specific Note schema, following the same uid/updated conventions used elsewhere for synchronization (see Section 6.4.1). { "$id": "https://id.schemas.pub/o/DTI/PDPArchive/note", "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "Schema for Personal Data Portability Archive (pdparchive) Note", "description": "A minimal note format defined by this specification. Neither JSContact nor JSCalendar define a JSON note type; iCalendar's VJOURNAL was not carried forward into JSCalendar (RFC 8984).", "type": "object", "required": ["@type", "uid", "updated", "body"], "properties": { "@type": { "type": "string", "const": "Note" }, "uid": { "description": "Globally unique identifier for the note", "type": "string" }, "created": { "type": "string", "format": "date-time" }, "updated": { "description": "Last-modified timestamp; MUST be included for synchronization", "type": "string", "format": "date-time" }, "title": { "type": "string" }, "body": { "description": "The note's content", "type": "string" }, "contentType": { "description": "MIME type of body; body is plain text if this is absent", "type": "string", "enum": ["text/plain", "text/html", "text/markdown"] }, "links": { "type": "object", "additionalProperties": { "$ref": "https://id.schemas.pub/o/DTI/PDPArchive/link" } } } } Happel, et al. Expires 18 March 2027 [Page 56] Internet-Draft PDPArchive September 2026 Figure 19: Schema for notes For example, a file called note1.json could contain: { "$schema": "https://id.schemas.pub/o/DTI/PDPArchive/note", "@type": "Note", "uid": "9f1c1e3a-2b34-4b8e-8b70-5e6f2f6b9a11", "created": "2024-02-14T09:05:00Z", "updated": "2024-03-02T18:22:00Z", "title": "Garden plan", "body": "California wildflowers - ORDERED, poppies - have seed.", "contentType": "text/plain", "links": { "1": { "@type": "Link", "rel": "enclosure", "blobId": "e612afe4-2962-42f1-bcd1-073368274c24", "contentType": "image/png", "size": 84213, "title": "garden-sketch.png" } } } Figure 20: Note example The contentType field indicates how to interpret body; if contentType is absent, body is plain text. An exporter that only has an HTML- formatted note SHOULD set contentType to "text/html" rather than attempt a lossy conversion to plain text. A note that has attachments can reference them using links (see Section 6.3.7). 6.3.7. Attachments An attachment MAY be stored as a separate file with the filename used as the blobId, as opposed to inline or referenced externally. This section explains how to handle enclosed or included attachments that are not inline. This proposal follows the lead of [JMAPCalendars], using the links field on objects that have attachments. The links field holds Link Objects, defined in [JSCalendar], which uses href and requires a URI value. Using href is problematic: it is defined to have a URI value, but no commonly used URI supports partial local file paths or unique file names. The [JMAPCalendars] spec, to deal with this, adds blobId Happel, et al. Expires 18 March 2027 [Page 57] Internet-Draft PDPArchive September 2026 to identify the attachment. This can work OK in a structured file export, because it is possible for software importing or working with the export files to look through the various sub-directories until it finds the file named with the exact blobId value. Although this pattern is copied from JMAP, it should not be necessary to implement JMAP to assign blobs a blobId that is unique within an export, and use that blobId value in link object data. The blobId values assigned MUST be unique across the export. The location of attachments within folders or sub-folders in the export is defined by the exporting service. Software generating PDPArchives MAY put attachments in a single folder, multiple folders, or nested folders. Software importing or interpreting PDPArchives MUST be prepared to search through the archive folders to find the correct attachment with matching blobId name. NOTE: This offers no explicit support for exported files that are standalone and not attachments. While those kinds of files could always just be part of the export, there's nothing in this specification to say where those would be listed or what role they would serve. The Link object is shared by the Note, Task, and Event schemas (Figure 19, Figure 17, Figure 13), so it is defined once here: Happel, et al. Expires 18 March 2027 [Page 58] Internet-Draft PDPArchive September 2026 { "$id": "https://id.schemas.pub/o/DTI/PDPArchive/link", "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "Schema for Personal Data Portability Archive (pdparchive) Link", "description": "The Link object from RFC 8984 (JSCalendar), shared by the Note, Task, and Event schemas. A Link is a general-purpose reference and is not necessarily an attachment; `rel` set to \"enclosure\" is what marks a Link as an attachment, following draft-ietf-jmap-calendars. Following that same precedent, `blobId` MAY be used instead of `href` on an attachment Link, to reference binary content stored as a file elsewhere in the archive rather than at a URI.", "type": "object", "anyOf": [ { "required": ["href"] }, { "required": ["blobId"] } ], "properties": { "@type": { "type": "string", "const": "Link" }, "href": { "type": "string", "format": "uri" }, "blobId": { "description": "The filename of this attachment's binary content, used instead of href when the content is stored as a file in the archive rather than at a URI. Not necessarily a path relative to the archive root: the exporter may place the file in any folder, so an importer locates it by searching the archive for a file named with this exact value. Named after the JMAP blobId (RFC 9404) and used the way draft-ietf-jmap-calendars uses it for CalendarEvent attachments, but here it directly names a file within the archive rather than a handle resolved via Blob/get against a live server.", "type": "string" }, "cid": { "type": "string" }, "contentType": { "type": "string" }, "size": { "type": "integer", "minimum": 0 }, "rel": { "type": "string", "description": "Relationship of the link's target to the containing object, as in RFC 8984. \"enclosure\" marks the Link as an attachment (following draft-ietf-jmap-calendars); other values MAY be used for links that are not attachments, such as references to related resources.", "examples": ["enclosure"] }, "display": { "type": "string", "enum": ["badge", "graphic", "fullsize", "thumbnail"] }, "title": { "type": "string" } } } Figure 21: Schema for Link objects (attachments and references) If the value of "rel" for the link object is "enclosure", then the attachment SHOULD be included in the PDPArchive. If the value of "rel" is another value, the target or attachment MAY be included in the PDPArchive export. 6.3.8. Out of Scope Groups as defined in JSCalendar are NOT part of this archive format. Groups in JSCalendar can combine events and tasks in a container. This specification, for consistency and simplicity, uses folders and requires individual objects to be in separate files. Happel, et al. Expires 18 March 2027 [Page 59] Internet-Draft PDPArchive September 2026 VFREEBUSY objects are not part of this archive format. Calendar software can calculate freebusy time from event data. Use cases that are not satisfied by this limitation could extend this archive format but understanding what it means to backup, restore, export or import freebusy data would need to be fleshed out. VTIMEZONE objects are not part of this archive format. Timezones are more likely to be system objects referred to by calendar objects in modern calendar systems, than personal data. If there are use cases for timezones as personal data, this specification can be extended to explain how that would work. 6.4. Synchronization requirements This section describes the requirements to achieve repeated one-way synchronization via export/import operations between software by different vendors. While limited, this still provides better functionality than what many end-users experience with their groupware software and services today. Supporting _repeated_ synchronization means that the export from system A and import to system B can happen over and over again without needlessly duplicating items. Supporting _one-way_ synchronization means that changes in the system with the exporter role propagate reliably to the system with the importer role, but not in the reverse direction. Some of the constraints here arise from the fact that the two systems may not directly connect, and the import may be time-delayed from the export. This limited solution for export/import sync may also be used for more direct system-to-system transfers such as service-to-service data transfers, repeated data access requests or data migrations, although some of those use cases could be solved much better with direct negotiation of features. 6.4.1. Always include 'uid' and 'updated' These requirements apply to [JSContact], JSTask and [JSCalendar] objects when exported or imported using the formats in this specification, because these all have 'uid' and 'updated' values. Requirements: * exporters MUST include the UID and updated fields. * The 'updated' field MUST be exported in UTC and interpreted in UTC. Accurate system time is important. Happel, et al. Expires 18 March 2027 [Page 60] Internet-Draft PDPArchive September 2026 * importers MUST use the UID in an imported object, if the importer is creating a new object, rather than invent a new UID. * importers MUST search for existing objects with the same UID, and if the object in storage is _similar enough_ (see Note below) to the import data, the importer SHOULD NOT change the object and MUST NOT update its 'updated' timestamp. Recommendations: * Importers SHOULD use caution with fields that are system-updated, especially frequently updated. Such fields SHOULD NOT change the value of 'updated' that is exported or used to decide whether to update an object during an import operation. See note below on 'updated'. * Importers SHOULD apply common sense in updating internal or implementation-specific fields. This specification does not require the importer to include, omit, handle or disregard values for fields that it believes are internally-generated or implementation-specific. For example, a system in the role of exporter might export an event object with a video-conference room ID in a custom field. It can decide that it is sensible to export that value as a URL for external use. Later, the same system or one with code written for compatibility could import that event with the video-conference URL, and it would be sensible to avoid overwriting its own knowledge of the room ID with the URL. * When importing a _changed_ or _new_ object with a UID and 'updated' value, the importer SHOULD set the 'updated' value to the one imported. Thus, if a Contact is updated on Jan 1, exported on Jan 2 and imported on Jan 3, the new or updated imported contact would show an 'updated' value of Jan 1. Happel, et al. Expires 18 March 2027 [Page 61] Internet-Draft PDPArchive September 2026 Note on _similar enough_: This specification requires nuance in order to allow both reasonably consistent synchronization and reasonable behavior in a wide variety of use cases and implementations. The language above is intended to give implementors both guidance and wiggle room. For example, the importer could convert a DTSTART time from UTC to the user's local time and save it as the displayed start time. Later, re-importing the same object with the same UID, the importing code could be smart enough to realize that the time hasn't _actually_ changed, and avoid changing the 'updated' timestamp or creating a conflicting event. This logic could be implemented by saving separate fields (imported time vs display time), by keeping a log of updates (log entry stating that the system auto-converted start time from X to Y), or by other clever algorithms. Thus, the clever implementation can avoid the appearance of an object that changes every time the calendar is synchronized. Note on _updated_: The definition of 'updated' in [JSContact] is not rigorous or nuanced. "when the data in the Card was last modified" could refer to several instances of the card -- its internal implementation, its representation in an email share, its representation in an HTTP GET response ([CardDAV]). It's not specified whether 'updated' is the same as REV in [vCard], which is defined differently. Neither definition explicitly covers vendor- specific fields. Thus, this specification makes additional recommendations for handling 'updated': * The value of 'updated' SHOULD only change when two conditions hold: the end-user makes a decision to change a value of a user- visible field, AND the export of the JSContact shows a different value. * Thus, non-user-visible fields like 'version' could be changed without causing the 'updated' value to change. A value such as 'language' could be set without changing 'updated' (if an implementation infers the language tag and begins to include 'fr- CA' as the language value in exports instead of no language, nevertheless this doesn't change the user-visible content). * If implementations need to manage the synchronization of vendor- specific fields, a vendor-specific field like 'example.com:updated' can be used rather than affect the user- visible synchronization made possible by 'updated'. Implementations could possibly also handle 'updated' differently when used for export/import using the formats in this specification, than when the same field is handled in other code paths. Happel, et al. Expires 18 March 2027 [Page 62] Internet-Draft PDPArchive September 2026 We recognize that this understanding of 'updated' is highly judgement-dependent. The same field can change in one way and cause a change to 'updated' and in another way may not (the example of server inferring the language is 'fr-CA' vs the user explicitly setting it). It is likely to be frustrating to protocol designers and implementors (as it is to the authors of this specification) that the definition is so wobbly. We'd love to know of better solutions that work with the status quo. 6.4.1.1. Synchronizing from and to CalDAV servers [CalDAV] uses URLs, ETags and UIDs for synchronizing changes between two systems reliably, but it relies upon client-server architecture, where the server is the "source of truth" and the client must manage its local history and decide which things to update from the server and which things to tell the server to update. If a user is setting up synchronization or an implementor is building a system that involves synchronization, it may be best to use CalDAV if that is a feasible solution. Nevertheless, we believe some of the use cases in our use case section (use_cases) motivate not only including calendar data from CalDAV servers in these archives for backup purposes, but also for partial updates. An export from a CalDAV server can follow all the requirements of this specification, and will in fact be more limited (for example, CalDAV does not allow events to appear in multiple calendars, while this export format does). 6.4.2. Synchronizing mailbox folders Because servers may differ in which characters they support in folder names, how many levels deep folders may be created, and even in what separator character is used to indicate folder hierarchy, difficulties in synchronizing folder names will definitely arise. If an exporter encounters folder names that are not likely to be widely supported in other systems, it SHOULD translate those for export using a consistent mapping algorithm, such that the folder has the same mapped name every time it is exported. The goal is to choose a mapping that allows another system importing the data repeated to recognize foldrs it has imported before. A reversible mapping would also help the exporter be able to import its own data if necessary, without duplicating folders erroneously. Systems that support mailbox IDs MUST include them in exports. Systems that do not (though it's strongly encouraged) SHOULD use the full mailbox name as the unique identifier value. Happel, et al. Expires 18 March 2027 [Page 63] Internet-Draft PDPArchive September 2026 Systems importing data in order to port a user's account to a new service MUST preserve the nesting structure of folders. Other kinds of importers may not preserve folder structure (for example, mail may be imported into a database for searching, for legal discovery purposes, or for compliance records and these databases need not maintain folder nesting). TODO: Also it would be good to include a "display name" in case the server has had to translate the mailbox name for compatibility. E.g. a server that has a mailbox named "%L33T%", but knows the "%" should not be exported because many servers forbid the "%", would translate the name consistently to _pc_L33T_pc_ or another set of safe characters and include a display name of "%L33T%" for reference and debugging. 6.4.3. Synchronizing files and attachments blobId values (see Section 6.3.7) SHOULD remain stable across repeated exports of the same underlying binary content, so that importers can recognize an attachment they have already synchronized and avoid re-transferring it. This mirrors the uid stability requirement in Section 6.4.1, applied to attachments and their blobId. 7. Open issues 7.1. Container format This document leverages existing data formats and adds certain files for representing metadata. While one may work with this raw data, most import/export scenarios will rather require the bundling of individual data items into one or few container files. This document does not strive to invent its own container format, but may refer to existing ones. High level options would be: * Recommend using a container format without preferring a particular one * Mandating a specific format * ...? Actual container formats likely differ in various dimensions: * Ease of adding incremental data Happel, et al. Expires 18 March 2027 [Page 64] Internet-Draft PDPArchive September 2026 * Ease of updating existing data * Ease of accessing files * Support for compression * Support for data streaming * Availability of library/tool support across platforms * Internal file references * Open standard * ...? Candidates * tar/gz * zip * 7z * zpaq * ...? See https://github.com/hhappel/draft-happel-mailmaint-pdparchive/ issues/13 7.2. Encryption Support for encryption of any kind is so far no requirement in the draft. However, an increasing number of services offers forms of data encryption. Implications for this draft may be considered. "Encryption" might refer to various aspects: * Existing encryption of individual files in the export * Encrypting the complete export (incl. metadata?) * ...? See https://github.com/hhappel/draft-happel-mailmaint-pdparchive/ issues/14 Happel, et al. Expires 18 March 2027 [Page 65] Internet-Draft PDPArchive September 2026 8. Implementation status < RFC Editor: before publication please remove this section and the reference to [RFC7942] > This section records the status of known implementations of the protocol defined by this specification at the time of posting of this Internet-Draft, and is based on a proposal described in [RFC7942]. The description of implementations in this section is intended to assist the IETF in its decision processes in progressing drafts to RFCs. Please note that the listing of any individual implementation here does not imply endorsement by the IETF. Furthermore, no effort has been spent to verify the information presented here that was supplied by IETF contributors. This is not intended as, and must not be construed to be, a catalog of available implementations or their features. Readers are advised to note that other implementations may exist. According to [RFC7942], "this will allow reviewers and working groups to assign due consideration to documents that have the benefit of running code, which may serve as evidence of valuable experimentation and feedback that have made the implemented protocols more mature. It is up to the individual working groups to use this information as they see fit". 9. Security Considerations Privacy of personal information is important, and an archive can provide a convenient way to exfiltrate large amounts of private data. Several cautions and remediations are advised below. In addition some protections are REQUIRED: * A producer of PDPArchive exports MUST conform with [IJSON] requirements. Authors of protocols or other standards that are defined to create PDPArchive exports or gate access to PDPArchive exports (such as JMAP or CalDAV extensions or OAuth scopes) will have to consider appropriate privacy and authorization protections specific to their purpose and context. 9.1. Threat model Making something convenient is often great for users, but also often creates an attractive target for attackers. Even if a service does not experience organized attacks at one point, convenience and time may lead to coordinated attacks. Happel, et al. Expires 18 March 2027 [Page 66] Internet-Draft PDPArchive September 2026 Large amounts of information also create risks just by aggregating. With a large amount of information, correlating to discover private information not directly in the export may be possible. In particular, these personal data exports contain PII - information about people invited to meetings or in address books - who did not consent to an export. Many attacks involve gaining account access. Others do not require taking control of the account but instead rely on deceiving the account holder or authorized agent. Access controls implemented at the data source might not transfer reliably with the data. Access controls may be implied by shareWith or by roles and participation status data that is part of this export, or be provided in custom fields extending these formats. An importing service should note whether it is making decisions to allow access based on trusted role or access information provided during an import, or untrusted (could be tampered with, including by the user providing an upload). Data retention rules that services or organizations attempt to follow may find that extra copies of exported data violate those rules. 9.2. Suggested privacy protections It is not expected that services would implement all of these mitigations and partial protections at all times, but consider the applicability for each situation. * Use appropriate authentication and authorization. In addition, services might ask for a quick reconfirmation of identity, authentication or authorization before sending new private data. The service might ask for a password to be re-entered, a one-time- password to be provided, or email re-confirmed. * Services might notify or inform users of significant data access. Some existing platforms send an email to the account to make sure that the account holder knows of the transfer. A history of data transfers might be available in account information. * Transport encryption is advised when sending archive files. * A service may encrypt an archive file intended for download, using existing password/encryption approaches, such as a ZIP archive encrypted with AES-256 [ZIPAES] (a convention with broad tool support). The service may use a side-channel to communicate with the account owner or ask them to choose a password when setting up the export. Happel, et al. Expires 18 March 2027 [Page 67] Internet-Draft PDPArchive September 2026 * If interacting directly with the user, either because the user has initiated an export or has been prompted to approve one via flows like OAuth, the service may provide GUI to offer filtering personal data before exporting. For example, a user authorizing transfer of a photo album may be offered a chance to filter out document scans. Because email is routinely used to send password reset links or login links, email is especially vulnerable to accidental export of more sensitive data/access than was intended. * Verify the identity of third-party data requestors. This can be applied if there are any third-party data request mechanisms outside the scope of PDPArchive, implemented for example with GUI to generate authorization keys or capability URLs, and then providing those keys/URLs to a third-party in configuration data or third-party GUI. Source services routinely check for impersonation through third-party API keys and vetting processes to obtain those keys. * Exporters should be wary of deserializers, especially generic object deserializers. Fields to be exported should be specified or allow-listed rather than default to export. Exporters should take extra care not to export credentials, access tokens, or other secrets. 9.3. Considerations for importers Software importing data have rather different considerations than exporters, but these also matter to security and privacy. * Importing services should consider appropriate safety checking before handling JSON files. Differences in JSON parsing (such as how to handle multiple instances of the same key in the same location) can open avenues ot "smuggling" bugs. An export that does not meet [IJSON] requirements MAY be rejected. * Importing services handling cross-references should scope these cross-references within the appropriate folder context. Other cross-referencing risks should be considered, such as references that trigger fetching new content over the network, or using relative paths improperly. * Importers may be vulnerable to resource exhaustion through mechanisms like unbounded calendar recurrence expansion or oversized inline data. * Generic object polymorphic deserialization can be a code-execution bug vector. Happel, et al. Expires 18 March 2027 [Page 68] Internet-Draft PDPArchive September 2026 * Checking the size of blobs and attachments against their metadata might be useful. * Keep IDs as strings rather than convert to numbers. 9.4. Other Exporting services should plan for appropriate throttling to protect their own resources. Though the exact protocols by which third parties or users may request exports are undefined in this specification, download/export links in Web pages may lead to large amounts of traffic that need management. 10. IANA Considerations 10.1. File extension Register .pdpa? 11. References 11.1. Normative References [CardDAV] Daboo, C., "CardDAV: vCard Extensions to Web Distributed Authoring and Versioning (WebDAV)", RFC 6352, DOI 10.17487/RFC6352, August 2011, . [IJSON] Bray, T., Ed., "The I-JSON Message Format", RFC 7493, DOI 10.17487/RFC7493, March 2015, . [JMAP] Jenkins, N. and C. Newman, "The JSON Meta Application Protocol (JMAP) for Mail", RFC 8621, DOI 10.17487/RFC8621, August 2019, . [JMAPCalendars] Jenkins, N. and M. Douglass, "JSON Meta Application Protocol (JMAP) for Calendars", Work in Progress, Internet-Draft, draft-ietf-jmap-calendars-28, 12 August 2026, . [JSCalendar] Jenkins, N. and R. Stepanek, "JSCalendar: A JSON Representation of Calendar Data", RFC 8984, DOI 10.17487/RFC8984, July 2021, . Happel, et al. Expires 18 March 2027 [Page 69] Internet-Draft PDPArchive September 2026 [JSContact] Stepanek, R. and M. Loffredo, "JSContact: A JSON Representation of Contact Data", RFC 9553, DOI 10.17487/RFC9553, May 2024, . [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, . [RFC5322] Resnick, P., Ed., "Internet Message Format", RFC 5322, DOI 10.17487/RFC5322, October 2008, . [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, . [RFC8474] Gondwana, B., Ed., "IMAP Extension for Object Identifiers", RFC 8474, DOI 10.17487/RFC8474, September 2018, . [RFC9051] Melnikov, A., Ed. and B. Leiba, Ed., "Internet Message Access Protocol (IMAP) - Version 4rev2", RFC 9051, DOI 10.17487/RFC9051, August 2021, . [RFC9610] Jenkins, N., Ed., "JSON Meta Application Protocol (JMAP) for Contacts", RFC 9610, DOI 10.17487/RFC9610, December 2024, . 11.2. Informative References [CalDAV] Daboo, C., Desruisseaux, B., and L. Dusseault, "Calendaring Extensions to WebDAV (CalDAV)", RFC 4791, DOI 10.17487/RFC4791, March 2007, . [GoogleTakeout] Google, "Google Takeout", . [iCalendar] Desruisseaux, B., Ed., "Internet Calendaring and Scheduling Core Object Specification (iCalendar)", RFC 5545, DOI 10.17487/RFC5545, September 2009, . Happel, et al. Expires 18 March 2027 [Page 70] Internet-Draft PDPArchive September 2026 [IMAP4] Crispin, M., "INTERNET MESSAGE ACCESS PROTOCOL - VERSION 4rev1", RFC 3501, DOI 10.17487/RFC3501, March 2003, . [MBOX] Hall, E., "The application/mbox Media Type", RFC 4155, DOI 10.17487/RFC4155, September 2005, . [PST] Microsoft, "[MS-PST]: Outlook Personal Folders (.pst) File Format", . [RFC822] Crocker, D., "STANDARD FOR THE FORMAT OF ARPA INTERNET TEXT MESSAGES", STD 11, RFC 822, DOI 10.17487/RFC822, August 1982, . [RFC2822] Resnick, P., Ed., "Internet Message Format", RFC 2822, DOI 10.17487/RFC2822, April 2001, . [RFC4314] Melnikov, A., "IMAP4 Access Control List (ACL) Extension", RFC 4314, DOI 10.17487/RFC4314, December 2005, . [RFC5598] Crocker, D., "Internet Mail Architecture", RFC 5598, DOI 10.17487/RFC5598, July 2009, . [RFC6154] Leiba, B. and J. Nicolson, "IMAP LIST Extension for Special-Use Mailboxes", RFC 6154, DOI 10.17487/RFC6154, March 2011, . [RFC7162] Melnikov, A. and D. Cridland, "IMAP Extensions: Quick Flag Changes Resynchronization (CONDSTORE) and Quick Mailbox Resynchronization (QRESYNC)", RFC 7162, DOI 10.17487/RFC7162, May 2014, . [RFC7942] Sheffer, Y. and A. Farrel, "Improving Awareness of Running Code: The Implementation Status Section", BCP 205, RFC 7942, DOI 10.17487/RFC7942, July 2016, . Happel, et al. Expires 18 March 2027 [Page 71] Internet-Draft PDPArchive September 2026 [RFC8610] Birkholz, H., Vigano, C., and C. Bormann, "Concise Data Definition Language (CDDL): A Notational Convention to Express Concise Binary Object Representation (CBOR) and JSON Data Structures", RFC 8610, DOI 10.17487/RFC8610, June 2019, . [vCard] Perreault, S., "vCard Format Specification", RFC 6350, DOI 10.17487/RFC6350, August 2011, . [ZIPAES] WinZip Computing, "AES Encryption Information", . Appendix A. Base Contact Schema A JSContact Card is not always exported as a standalone PDPArchive Contact item. The same Card structure is sometimes found embedded within another object (for example, a domain name registration record) and in that context it has neither a globally unique uid nor an addressBookIds value. For that reason this specification defines a base Card schema intended to be consistent with JSContact in broader contexts. { "$id": "https://id.schemas.pub/o/DTI/PDPArchive/contact", "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "Schema for a JSContact Card", "description": "Base fields for a JSContact Card, usable on its own for Card objects embedded in other data (e.g. a registrant Card inside a domain registration record) where a `uid` and `addressBookIds` are not necessarily present. See pdpa-contact-schema.json, which extends this schema with the fields required for a Card to be exported as a standalone PDPArchive Contact item.", "type": "object", "required": ["@type", "version"], "properties": { "@type": { "type": "string", "const": "Card" }, "version": { "type": "string" }, "uid": { "description": "Globally unique identifier for the contact", "type": "string" }, "id": { "description": "JMAP ID for the contact", "type": "string" }, "created": { "type": "string", Happel, et al. Expires 18 March 2027 [Page 72] Internet-Draft PDPArchive September 2026 "format": "date-time" }, "updated": { "type": "string", "format": "date-time" }, "rev": { "description": "Revision timestamp from vCard RFC6350; may be included alongside updated", "type": "string", "format": "date-time" }, "kind": { "type": "string", "enum": ["individual", "group", "org", "location", "device", "application"] }, "addressBookIds": { "type": "object", "additionalProperties": { "type": "boolean" } }, "name": { "type": "object", "properties": { "full": { "type": "string" }, "defaultSeparator": { "type": "string" }, "isOrdered": { "type": "boolean" }, "components": { "type": "array", "items": { "type": "object", "required": ["kind", "value"], "properties": { "kind": { "type": "string", "enum": ["title", "given", "given2", "surname", "surname2", "generation", "credential", "separator"] }, "value": { "type": "string" }, "phonetic": { Happel, et al. Expires 18 March 2027 [Page 73] Internet-Draft PDPArchive September 2026 "type": "string" } } } } } }, "members": { "description": "For group contacts; maps member UIDs to true", "type": "object", "additionalProperties": { "type": "boolean" } }, "relatedTo": { "description": "Maps UIDs of related contacts to relation objects", "type": "object", "additionalProperties": { "type": "object", "properties": { "relation": { "type": "object", "additionalProperties": { "type": "boolean" } } } } }, "notes": { "description": "Maps note IDs to note objects", "type": "object", "additionalProperties": { "type": "object", "required": ["note"], "properties": { "note": { "type": "string" }, "created": { "type": "string", "format": "date-time" }, "author": { "type": "object", "properties": { "name": { "type": "string" Happel, et al. Expires 18 March 2027 [Page 74] Internet-Draft PDPArchive September 2026 } } } } } } } } Figure 22: Base schema for a JSContact Card The PDPArchive Contact item schema in Figure 7 extends this base schema. Appendix B. Extended Example: Folder Nesting vs. Collection IDs Section 6.2 explains that when an explicit ID mechanism exists for indicating containers or collections, that mechanism takes precedence over folder nesting in the export. This appendix works through a full example of that principle using addressBookIds. Suppose Elinor keeps her sister's contact information in both her "Favorites" and "Family" address books. The exporter places marianne-dashwood.json under only one of the two corresponding folders in the export -- it does not also create a duplicate copy under the other: /contacts/ favorites.json family.json Family/ marianne-dashwood.json Figure 23: One physical file for a contact that belongs to two address books The two AddressBook objects are flat files; their uid values, not their location in the export, are what matters: { "$schema": "https://id.schemas.pub/o/DTI/PDPArchive/address-book", "@type": "AddressBook", "uid": "a3d1f7e2-4b6a-4c9e-9f21-7e6d5c4b3a20", "updated": "2024-03-01T12:00:00Z", "name": "Favorites" } Figure 24: favorites.json Happel, et al. Expires 18 March 2027 [Page 75] Internet-Draft PDPArchive September 2026 { "$schema": "https://id.schemas.pub/o/DTI/PDPArchive/address-book", "@type": "AddressBook", "uid": "f9b6c2d4-8e1a-4f3b-9c5d-6a7b8c9d0e1f", "updated": "2024-03-01T12:00:00Z", "name": "Family" } Figure 25: family.json Marianne's contact item declares membership in both address books via addressBookIds, regardless of which single folder holds the file: { "$schema": "https://id.schemas.pub/o/DTI/PDPArchive/pdpa-contact", "@type": "Card", "version": "1.0", "uid": "9c2e6b7a-1f3d-4a5e-8b6c-2d4e6f8a0b1c", "updated": "2024-03-01T12:00:00Z", "addressBookIds": { "a3d1f7e2-4b6a-4c9e-9f21-7e6d5c4b3a20": true, "f9b6c2d4-8e1a-4f3b-9c5d-6a7b8c9d0e1f": true }, "name": { "components": [ { "kind": "given", "value": "Marianne" }, { "kind": "surname", "value": "Dashwood" } ], "isOrdered": true } } Figure 26: Family/marianne-dashwood.json An importer MUST NOT infer that Marianne belongs only to "Family" because that's where her file happens to live; it MUST add her to both address books indicated by addressBookIds if it maintains address books. Acknowledgments TODO acknowledge. Changes Happel, et al. Expires 18 March 2027 [Page 76] Internet-Draft PDPArchive September 2026 Changes in draft-ietf-mailmaint-pdparchive-02 * Restructed the contact schema to allow direct use of base schema in cases where UID is not a required field * Proposed how collection ID and folder nesting work together * Proposed how references to other objects work generally * Proposed how attachments and blobs work specifically * Drafted Security Considerations including privacy Changes in draft-ietf-mailmaint-pdparchive-01 * Added JSON Schema (draft 2020-12) files for all defined data types: folder, archive, contact, address book, calendar, event, and task. * Added a folder tombstone mechanism to support incremental exports that delete previously exported folders. Authors' Addresses Hans-Joerg Happel audriga Email: hans-joerg@audriga.com Lisa Dusseault Data Transfer Initiative Email: lisa@dtinit.org Alexey Melnikov Isode Ltd Email: Alexey.Melnikov@isode.com Happel, et al. Expires 18 March 2027 [Page 77]