Handling Message Disposition Notification with the JSON Meta Application Protocol (JMAP)
Extracted elements (23)
MDN/parse's 'forEmailId' property can be null or missing when the originalMessageId does not refer to an existing message or when the server cannot efficiently calculate the related message (e.g., multiple messages share the same Message-ID), avoiding a mandatory expensive lookup.
The 'reportingUA' field (Mail User Agent name) accepts a null value, noted to have better privacy properties, allowing implementations to avoid disclosing client software identity in MDN reports.
The server is made responsible for generating originalRecipient and originalMessageId (per RFC 8098) rather than the client, since these values must be derived from the authoritative server-side message data rather than potentially stale or spoofed client input.
If the accountId or identityId given to MDN/send cannot be found, the method call is rejected with an 'invalidArguments' error. Similarly, MDN/parse rejects with 'invalidArguments' if the accountId is not found.
Requesting an MDN when sending a message is done via the standard Email/set create method from RFC 8621 by adding a 'Disposition-Notification-To' header field; no separate MDN-specific method is needed for this use case.
Because keywords are case insensitive in IMAP but case sensitive in JMAP, the '$mdnsent' keyword MUST always be used in lowercase.
Disposition fields (actionMode, sendingMode, type) are defined as case insensitive in RFC 8098 but are case sensitive in this RFC and MUST be converted to lowercase by MDN/parse when parsing received MDNs.
Servers MUST support all properties specified for the new data types (MDN and Disposition) defined in this document.
Servers that include the 'urn:ietf:params:jmap:mdn' capability in one or more 'accountCapabilities' properties MUST also include the property in the top-level 'capabilities' property of the Session resource.
The actionMode field MUST be one of 'manual-action' or 'automatic-action'; sendingMode MUST be one of 'mdn-sent-manually' or 'mdn-sent-automatically'; type MUST be one of 'deleted', 'dispatched', 'displayed', or 'processed'.
The client MUST NOT issue an 'MDN/send' request if the message already has the '$mdnsent' keyword set. If the keyword is already set, the server returns an 'mdnAlreadySent' error.
The 'forEmailId' property MUST NOT be null for MDN/send requests, though it MAY be null in responses from MDN/parse when the original message cannot be identified.
The server MUST reject an MDN/send that does not result in setting the '$mdnsent' keyword; it MUST check that 'onSuccessUpdateEmail' is correctly set to update this keyword. This ensures the client explicitly tracks which messages have had MDNs sent.
When calling MDN/send, the 'using' property of the Request object MUST contain both 'urn:ietf:params:jmap:mdn' and 'urn:ietf:params:jmap:mail' capabilities, because MDN/send implicitly calls Email/set and uses Identity objects.
MDN/parse takes accountId and blobIds (Id[]) and returns parsed (Id[MDN]|null), notParsable (Id[]|null), and notFound (Id[]|null). It allows a client to extract structured MDN data from arbitrary blobs, such as those referenced in EmailSubmission.mdnBlobIds.
MDN/send response includes sent (Id[MDN]|null) containing server-set properties omitted by the client, and notSent (Id[SetError]|null). Recognized SetError types include notFound, forbidden, forbiddenFrom, overQuota, tooLarge, rateLimit, invalidProperties, and the new mdnAlreadySent.
MDN/send takes arguments: accountId (Id), identityId (Id), send (Id[MDN] map of creation id to MDN objects), and onSuccessUpdateEmail (Id[PatchObject]|null). The server uses the identity to determine the sender and derive the finalRecipient; it generates originalRecipient and originalMessageId per RFC 8098.
The Disposition object embedded in MDN has three required string properties: actionMode ('manual-action' or 'automatic-action'), sendingMode ('mdn-sent-manually' or 'mdn-sent-automatically'), and type ('deleted', 'dispatched', 'displayed', or 'processed'). These correspond to RFC 8098 disposition fields.
The MDN object models a Message Disposition Notification and includes properties: forEmailId, subject, textBody, includeOriginalMessage, reportingUA, disposition, mdnGateway, originalRecipient, finalRecipient, originalMessageId, error, and extensionFields. Server-set fields (mdnGateway, originalRecipient, originalMessageId, error) are populated by the server during MDN/send.
IANA has registered the 'mdnAlreadySent' error code in the JMAP Error Codes registry. It indicates the message already has the '$mdnsent' keyword and the client MUST NOT retry sending an MDN for that message.
IANA has registered 'urn:ietf:params:jmap:mdn' in the JMAP Capabilities registry with intended use 'common', change controller IETF. This capability signals support for the MDN data type and MDN/send and MDN/parse methods.
Setting 'includeOriginalMessage' to true causes the original message content to appear in the multipart/report MDN; RFC 8098 security considerations regarding content disclosure apply. The field defaults to false.
To reinforce trust regarding the relation between the user sending a message and their identity, the server SHOULD validate that the user is permitted to use the provided 'finalRecipient' value in conformance with the Identity, and return a 'forbiddenFrom' error if not.