General documentation / cheat sheets for various languages and services


Specifically (mostly), IMAP version 4 revision 1, which is the current version.

This document strives for a description midway between IMAP on Wikipedia, which is helpful but does not dive into specifics, and the RFC, which is tedious.

History in RFCs

POP came first.

Then Crispin developed a replacement, IMAP, in 1986.

IMAP depends on a few independent RFCs:

The benefits of IMAP

General structure

Unique Identifiers (UID)

Each message has a 64-bit (integer?) value that is universally and eternally unique, at least in a single mailbox (which I presume means an IMAP user’s account). Actually, eternal uniqueness is only a suggestion, so the message’s unique ID may change across sessions.

UIDVALIDITY is a 32-bit value that’s constant for the life of a mailbox. If you’re fine with the mandate that deleted mailboxes can never be recreated with the same name, 1 is an acceptable value for UIDVALIDITY. But if you might consider reinstating a deleted mailbox at some time in the future, you have to use a different UIDVALIDITY, in which case, the mailbox’s creation timestamp would be a decent choice.

Message sequence number

This number is much more flexible. It’s a 1-based index, and refers to the position of a message in a mailbox (or folder?). The message sequence number must be monotonic with the message’s UID. I.e., messages cannot be reordered, once received.


There are two types of “flags” (each message is associated with a set of flags):

  1. System flags all start with \. They are mostly used for tracking message state.
  2. User flags are also called keywords (?), and do not begin with \. They are different from IMAP folders.

Flags can be permanent or session-only. Most are permanent. \Deleted and \Recent are examples of session-only flags.


A message can be partially retrieved; its header, body, or MIME body part can be fetched independently.

Data structures

Data can take the form of a:

… continue from




SELECT inbox

FETCH 12 full
FETCH 12 body[header]

STORE 12 +flags \Deleted

FETCH 68:* (BODY[])


Maybe some examples using the Node.js library,