JMAP recoverable mail

The Nixt Server JMAP extension for listing and putting back mail a person deleted that can still be got back.

This page defines a small JMAP extension. Its capability is named by this page’s address:

https://nixtoffice.com/docs/server/jmap-recoverable

With it, an app shows a person the mail they deleted that can still be got back, and puts it back. Nixt Mail uses it for Recover items deleted from Trash, and any JMAP client may. What happens to deleted mail on a Nixt Server is described in Getting deleted mail back.

The capability

The session lists the capability, with an empty object, in capabilities and in the accountCapabilities of the person’s own account:

"https://nixtoffice.com/docs/server/jmap-recoverable": {}

An account the person reaches as somebody else’s delegate does not offer it: a person’s deleted mail is theirs alone, and a request naming such an account is refused.

A request that uses the methods below names the capability in using, beside urn:ietf:params:jmap:core and urn:ietf:params:jmap:mail.

The deleted mail is kept in a mailbox that is never listed, so no mail app sees it as a mailbox or its messages as Email objects. These methods are the only way to it.

RecoverableEmail/get

Lists what can be got back, the most recently deleted first.

ArgumentTypeMeaning
accountIdIdThe account.
searchString or nullWords the sender, the subject or the folder it was deleted from must contain, in any case.
afterUTCDate or nullOnly mail deleted at or after this moment.
beforeString or nullThe next value a previous answer gave, to read the next page.
limitUnsignedInt or nullHow many to answer, at most 500.

The answer:

PropertyTypeMeaning
accountIdIdThe account.
listObject[]The deleted messages, each with id (the Email id it had, and has again once put back), from, subject, receivedAt, deletedAt, size and mailboxName, the folder it was deleted from.
nextString or nullPass as before for the next page; null when there is no more.
totalUnsignedIntHow many messages can be got back.
sizeUnsignedIntHow many bytes they take, which count toward the account’s quota until the window ends.
windowDaysUnsignedIntThe organisation’s window, in days.

RecoverableEmail/restore

Puts messages back.

ArgumentTypeMeaning
accountIdIdThe account.
idsId[]The messages to put back, by the id from RecoverableEmail/get.

Each message goes back to the mailbox it was deleted from, or to the Inbox if that mailbox is gone, without the $deleted keyword. The answer:

PropertyTypeMeaning
accountIdIdThe account.
restoredId[Object]For each message put back, mailboxId, the mailbox it is in now, and whereItWas, whether that is the one it was deleted from.
notRestoredId[SetError]For each id that is not deleted mail that can be got back, a notFound error.
oldState, newStateStringThe account’s Email state before and after, since putting mail back changes it.

RecoverableEmail/destroy

Deletes messages for good, before the recovery window ends.

ArgumentTypeMeaning
accountIdIdThe account.
idsId[]The messages to delete for good, by the id from RecoverableEmail/get.

The messages can’t be got back afterwards. If the organisation keeps the account’s mail under a legal hold or a retention policy, the server still keeps them, out of the person’s sight, as it would at the end of the window. The answer:

PropertyTypeMeaning
accountIdIdThe account.
destroyedId[]The messages deleted for good.
notDestroyedId[SetError]For each id that is not deleted mail that can be got back, a notFound error.
oldState, newStateStringThe account’s Email state before and after.

Example

[["RecoverableEmail/get", {
  "accountId": "a1",
  "search": "invoice",
  "limit": 20
}, "0"]]
[["RecoverableEmail/restore", {
  "accountId": "a1",
  "ids": ["m42"]
}, "1"]]

Something unclear or out of date on this page? Tell us.