RFC 2060
Internet Message Access Protocol - Version 4rev1
RFC 2060: INTERNET MESSAGE ACCESS PROTOCOL - VERSION 4rev1 ๐
Request for Comments: 2060 ๐ฌ Author: M. Crispin, University of Washington ๐ Date: December 1996 ๐๏ธ Category: Standards Track โจ Obsoletes: RFC 1730 ๐ Working Group: Network Working Group ๐ธ
Okay bestie, this is the big one: IMAP4rev1, the protocol that lets your email app talk to the mail server. It's a Standards Track doc, which means it's the real deal, and it obsoletes RFC 1730 ๐ . So if you ever run into the old version, this is the upgrade. Iconic. ๐
Status of This Memo โจ
Okay so this is the official "what kind of document is this" part ๐ง. It specifies an Internet standards track protocol for the Internet community, and it's basically inviting everyone to discuss it and suggest improvements ๐ฌ. If you want to know where the protocol stands in the official standardization world, check the current edition of the "Internet Official Protocol Standards" (STD 1) ๐. And the best part? Distribution of this memo is unlimited ๐. Anyone can read it, no cap ๐ซถ.
Abstract
So, the vibe of IMAP4rev1 is: it lets a client access and manipulate email messages that are sitting on a server ๐จโจ. It treats remote message folders, called "mailboxes," as functionally equivalent to local mailboxes, which is honestly so main character ๐. It also gives an offline client the ability to resynchronize with the server (see also [IMAP-DISC]) ๐๐ฆ.
The protocol is packed with operations ๐. You can create, delete, and rename mailboxes ๐; check for new messages ๐; permanently remove messages ๐๏ธ; set and clear flags ๐ฉ; do [RFC-822] and [MIME-IMB] parsing ๐งฉ; search ๐; and selectively fetch message attributes, texts, and portions of them ๐. Messages are accessed by numbers, and those numbers are either message sequence numbers or unique identifiers ๐ข. Iykyk, the number game is a whole thing ๐.
IMAP4rev1 supports a single server ๐ฅ๏ธ. If you need configuration info to handle multiple IMAP4rev1 servers, that's covered in [ACAP] ๐ง.
Also, IMAP4rev1 does NOT handle posting mail. That job goes to a mail transfer protocol like [SMTP] ๐ฎ. Different friend, different job, periodt ๐ .
IMAP4rev1 is designed to be upwards compatible with the [IMAP2] and the unpublished IMAP2bis protocols ๐ค. Over time, some stuff from the earlier protocol became obsolete ๐ฐ๏ธ. The obsolete commands, responses, and data formats an IMAP4rev1 implementation might run into when talking to an earlier implementation are described in [IMAP-OBSOLETE] ๐๏ธ.
For other compatibility drama with IMAP2bis, the most common variant of the earlier protocol, check [IMAP-COMPAT] ๐ง. And for the rare (and presumed extinct) variants of [IMAP2], there's a full write-up in [IMAP-HISTORICAL]. Honestly that one is mostly for history nerds ๐๐.
Table of Contents ๐
IMAP4rev1 Protocol Specification .................................. 4
1. How to Read This Document ................................. 4
1.1. Organization of This Document ............................. 4
1.2. Conventions Used in This Document ......................... 4
2. Protocol Overview ......................................... 5
2.1. Link Level ................................................ 5
2.2. Commands and Responses .................................... 6
2.2.1. Client Protocol Sender and Server Protocol Receiver ....... 6
2.2.2. Server Protocol Sender and Client Protocol Receiver ....... 7
2.3. Message Attributes ........................................ 7
2.3.1. Message Numbers ........................................... 7
2.3.1.1. Unique Identifier (UID) Message Attribute ......... 7
2.3.1.2. Message Sequence Number Message Attribute ......... 9
2.3.2. Flags Message Attribute .................................... 9
2.3.3. Internal Date Message Attribute ........................... 10
2.3.4. [RFC-822] Size Message Attribute .......................... 11
2.3.5. Envelope Structure Message Attribute ...................... 11
2.3.6. Body Structure Message Attribute .......................... 11
2.4. Message Texts ............................................. 11
3. State and Flow Diagram .................................... 11
3.1. Non-Authenticated State ................................... 11
3.2. Authenticated State ....................................... 11
3.3. Selected State ............................................ 12
3.4. Logout State .............................................. 12
4. Data Formats .............................................. 12
4.1. Atom ...................................................... 13
4.2. Number .................................................... 13
4.3. String ..................................................... 13
4.3.1. 8-bit and Binary Strings .................................. 13
4.4. Parenthesized List ........................................ 14
4.5. NIL ....................................................... 14
5. Operational Considerations ................................ 14
5.1. Mailbox Naming ............................................ 14
5.1.1. Mailbox Hierarchy Naming .................................. 14
5.1.2. Mailbox Namespace Naming Convention ....................... 14
5.1.3. Mailbox International Naming Convention ................... 15
5.2. Mailbox Size and Message Status Updates ................... 16
5.3. Response when no Command in Progress ...................... 16
5.4. Autologout Timer .......................................... 16
5.5. Multiple Commands in Progress ............................. 17
6. Client Commands ........................................... 17
6.1. Client Commands - Any State ............................... 18
6.1.1. CAPABILITY Command ........................................ 18
6.1.2. NOOP Command .............................................. 19
6.1.3. LOGOUT Command ............................................ 20
6.2. Client Commands - Non-Authenticated State ................. 20
6.2.1. AUTHENTICATE Command ...................................... 21
6.2.2. LOGIN Command ............................................. 22
6.3. Client Commands - Authenticated State ..................... 22
6.3.1. SELECT Command ............................................ 23
6.3.2. EXAMINE Command ........................................... 24
6.3.3. CREATE Command ............................................ 25
6.3.4. DELETE Command ............................................ 26
6.3.5. RENAME Command ............................................ 27
6.3.6. SUBSCRIBE Command ......................................... 29
6.3.7. UNSUBSCRIBE Command ....................................... 30
6.3.8. LIST Command .............................................. 30
6.3.9. LSUB Command .............................................. 32
6.3.10. STATUS Command ............................................ 33
6.3.11. APPEND Command ............................................ 34
6.4. Client Commands - Selected State .......................... 35
6.4.1. CHECK Command ............................................. 36
6.4.2. CLOSE Command ............................................. 36
6.4.3. EXPUNGE Command ........................................... 37
6.4.4. SEARCH Command ............................................ 37
6.4.5. FETCH Command ............................................. 41
6.4.6. STORE Command ............................................. 45
6.4.7. COPY Command .............................................. 46
6.4.8. UID Command ............................................... 47
6.5. Client Commands - Experimental/Expansion .................. 48
6.5.1. X<atom> Command ........................................... 48
7. Server Responses .......................................... 48
7.1. Server Responses - Status Responses ....................... 49
7.1.1. OK Response ............................................... 51
7.1.2. NO Response ............................................... 51
7.1.3. BAD Response .............................................. 52
7.1.4. PREAUTH Response .......................................... 52
7.1.5. BYE Response .............................................. 52
7.2. Server Responses - Server and Mailbox Status .............. 53
7.2.1. CAPABILITY Response ....................................... 53
7.2.2. LIST Response .............................................. 54
7.2.3. LSUB Response ............................................. 55
7.2.4 STATUS Response ........................................... 55
7.2.5. SEARCH Response ........................................... 55
7.2.6. FLAGS Response ............................................ 56
7.3. Server Responses - Mailbox Size ........................... 56
7.3.1. EXISTS Response ........................................... 56
7.3.2. RECENT Response ........................................... 57
7.4. Server Responses - Message Status ......................... 57
7.4.1. EXPUNGE Response .......................................... 57
7.4.2. FETCH Response ............................................ 58
7.5. Server Responses - Command Continuation Request ........... 63
8. Sample IMAP4rev1 connection ............................... 63
9. Formal Syntax ............................................. 64
10. Author's Note ............................................. 74
11. Security Considerations ................................... 74
12. Author's Address .......................................... 75
Appendices ........................................................ 76
A. References ................................................ 76
B. Changes from RFC 1730 ..................................... 77
C. Key Word Index ............................................ 79
โจ Heads up, we're only on part 1 of 18, so the real protocol meat (the actual commands, responses, and formal syntax) is still coming, bestie ๐ซถ๐
1. How to Read This Document โจ
1.1. Organization of This Document
Okay bestie, this doc is written for the implementor ๐ ๏ธ of an IMAP4rev1 client or server. Apart from the protocol overview in section 2, it's not really built for someone who just wants to understand how the protocol works ๐ซถ The stuff in sections 3 through 5 gives you the general context and definitions that IMAP4rev1 runs on ๐
Sections 6, 7, and 9 cover the IMAP commands, responses, and syntax ๐ฆ They're all so tangled together that it's almost impossible to understand any one of them on its own ๐ญ So please don't try to figure out command syntax from the command section alone ๐ Go to the Formal Syntax section instead ๐
1.2. Conventions Used in This Document
In examples, C: and S: show lines sent by the client and the server ๐ธ
These are the terms this document uses to signal how strict each requirement is ๐
- MUST, or the adjective REQUIRED, means that the definition is an absolute requirement of the specification.
- MUST NOT means that the definition is an absolute prohibition of the specification.
- SHOULD means that there may exist valid reasons in particular circumstances to ignore a particular item, but the full implications MUST be understood and carefully weighed before choosing a different course.
- SHOULD NOT means that there may exist valid reasons in particular circumstances when the particular behavior is acceptable or even useful, but the full implications SHOULD be understood and the case carefully weighed before implementing any behavior described with this label.
- MAY, or the adjective OPTIONAL, means that an item is truly optional. One vendor may choose to include the item because a particular marketplace requires it or because the vendor feels that it enhances the product, while another vendor may omit the same item ๐ An implementation which does not include a particular option MUST be prepared to interoperate with another implementation which does include the option ๐ค
"Can" is used instead of "may" when referring to a possible circumstance or situation, as opposed to an optional facility of the protocol. So it's a vibe check: "can" is about what's possible, "may" is about what's optional ๐
"User" refers to a human user, whereas "client" refers to the software the user is running ๐ง
"Connection" refers to the entire sequence of client/server interaction, from the moment the network connection is set up until it's terminated ๐ฅ "Session" refers to the sequence of client/server interaction from the time a mailbox is selected (SELECT or EXAMINE command) until that selection ends. That happens when you SELECT or EXAMINE another mailbox, send a CLOSE command, or terminate the connection ๐
Characters are 7-bit US-ASCII unless otherwise specified ๐ธ Other character sets are indicated using a "CHARSET", as described in [MIME-IMT] and defined in [CHARSET]. CHARSETs have important additional semantics beyond defining a character set, so go check those documents for the details ๐
2. Protocol Overview ๐ฆ
2.1. Link Level
IMAP4rev1 assumes a reliable data stream, like the one TCP provides ๐งท When TCP is used, an IMAP4rev1 server listens on port 143 ๐
2.2. Commands and Responses
An IMAP4rev1 connection is made up of three things: setting up a client/server network connection, an initial greeting from the server, and then client/server interactions โจ Each of those interactions is a client command, server data, and a server completion result response ๐
Everything the client and server send is in the form of lines, meaning strings that end with a CRLF ๐ The protocol receiver of an IMAP4rev1 client or server is either reading a line, or reading a sequence of octets with a known count followed by a line ๐
2.2.1. Client Protocol Sender and Server Protocol Receiver
The client command kicks off an operation ๐ Every client command gets prefixed with an identifier called a "tag". It's usually a short alphanumeric string, like A0001, A0002, and so on ๐ท๏ธ The client generates a different tag for each command ๐
There are two cases where a line from the client isn't a complete command ๐ In the first, a command argument is quoted with an octet count (see the description of literal in String under Data Formats). In the second, the command arguments need server feedback (see the AUTHENTICATE command). Either way, if the server is ready for the octets (where that applies) and the rest of the command, it sends a command continuation request response, which is prefixed with the token + ๐ฆ
Note: If the server instead detects an error in the command, it sends a BAD completion response with a tag matching the command (as described below). This rejects the command and stops the client from sending any more of it ๐ซ
It's also possible for the server to send a completion response for some other command (if multiple commands are in progress), or to send untagged data ๐ In either case, the command continuation request is still pending. The client takes the appropriate action for the response and reads another response from the server ๐ง In all cases, the client MUST send a complete command (including receiving all command continuation request responses and command continuations for the command) before initiating a new command ๐
The protocol receiver of an IMAP4rev1 server reads a command line from the client, parses the command and its arguments, and then transmits server data and a server command completion result response ๐
2.2.2. Server Protocol Sender and Client Protocol Receiver
Data the server sends to the client, and status responses that don't indicate command completion, are prefixed with the token *. These are called untagged responses ๐ธ
Server data MAY be sent as a result of a client command, or MAY be sent unilaterally by the server ๐ซ There's no syntactic difference between server data that came from a specific command and server data that was sent unilaterally ๐ซถ
The server completion result response tells you whether the operation succeeded or failed ๐ It's tagged with the same tag as the client command that started the operation ๐ท๏ธ So if more than one command is in progress, the tag on a server completion response tells you which command it applies to ๐ There are three possible server completion responses: OK (success), NO (failure), and BAD (protocol error, like an unrecognized command or a command syntax error) ๐
The protocol receiver of an IMAP4rev1 client reads a response line from the server. It then acts on the response based on its first token, which can be a tag, a *, or a + ๐ง
A client MUST be prepared to accept any server response at all times ๐ก๏ธ This includes server data that wasn't requested. Server data SHOULD be recorded, so the client can reference its recorded copy instead of sending a command to the server to request the data again โจ For certain server data, the data MUST be recorded ๐
This topic is discussed in greater detail in the Server Responses section ๐
2.3. Message Attributes
Besides the message text, each message has several attributes attached to it ๐ These attributes can be retrieved individually, or together with other attributes or message texts ๐ฆ
2.3.1. Message Numbers โจ
okay so messages in IMAP4rev1 can be accessed by one of two numbers ๐: the unique identifier and the message sequence number. two different vibes, both iconic ๐
2.3.1.1. Unique Identifier (UID) Message Attribute ๐ฆ
a UID is a 32-bit value given to each message. paired with the UID validity value (more on that in a sec), it becomes a 64-bit value that is permanently guaranteed to never point at any other message in the mailbox ๐ that's literally the whole point bestie. UIDs are assigned in a strictly ascending order in the mailbox, so every new message that shows up gets a higher UID than the ones that came before it ๐
unlike message sequence numbers, UIDs are not necessarily contiguous (aka there can be gaps, no cap ๐). UIDs also persist across sessions, which lets a client resync its state from a previous session with the server. this is super useful for disconnected or offline access clients, and [IMAP-DISC] goes deeper on it ๐ธ
every mailbox has its own unique identifier validity value. it gets sent in an UIDVALIDITY response code inside an OK untagged response when the mailbox gets selected ๐ if the UIDs from an earlier session don't carry over into this session, the unique identifier validity value MUST be greater than the one used in the earlier session. that's the signal that says "hey, the old UIDs are not it anymore" ๐จ
Note: UIDs MUST be strictly ascending in the mailbox at all times. ๐ if a non-IMAP agent reorders the physical message store, the UIDs in the mailbox have to be regenerated, because the old ones won't be ascending anymore after the shuffle. another situation where UIDs get regenerated is when the message store has no way to store UIDs at all. the spec admits this might be unavoidable in some server setups, but it strongly encourages message store implementations that dodge this problem entirely ๐ซถ
Note (continued): another way UIDs stop persisting is when a mailbox gets deleted and a new one with the same name gets created later. since the name matches, a client can't tell it's a brand new mailbox unless the UID validity value is different ๐ a good value for it is a 32-bit representation of the mailbox's creation date/time โจ using a constant like 1 is alright too, but ONLY if it's guaranteed that UIDs will never be reused, even if the mailbox gets deleted (or renamed) and a new one with the same name shows up later. no cheating ๐ค
the UID of a message MUST NOT change during the session, and SHOULD NOT change between sessions. however, if it's not possible to keep a message's UID in a later session, then each subsequent session MUST have a new UID validity value that's larger than any used before. the vibe is always "newer is bigger" ๐
2.3.1.2. Message Sequence Number Message Attribute ๐ง
a message sequence number is a relative position, going from 1 up to the number of messages in the mailbox. this position MUST be ordered by ascending UID ๐ as each new message is added, it gets a sequence number that is 1 higher than the number of messages in the mailbox before it got added. easy peasy ๐
sequence numbers can get reassigned during the session. for example, when a message gets permanently removed (expunged) from the mailbox, the sequence number of every message after it goes down by one ๐ and a new message can end up with a sequence number that some other message used to have before an expunge. it's a lot, but it's giving chaos in a fun way ๐ช๏ธ
the cool part is that sequence numbers can also be used in math, not just to point at a message by its spot in the mailbox ๐งฎ for example, if an untagged EXISTS 11 shows up and an untagged 8 EXISTS came through earlier, that means three new messages arrived, with sequence numbers 9, 10, and 11. another example: if message 287 in a 523 message mailbox has UID 12345, then there are exactly 286 messages with lesser UIDs and 236 messages with greater UIDs. the way the numbers line up is honestly so satisfying ๐ญ๐ซถ
2.3.2. Flags Message Attribute ๐ณ๏ธโ๐
flags are a list of zero or more named tokens attached to the message. setting a flag means adding it to that list, and clearing it means removing it ๐ there are two types of flags in IMAP4rev1, and any flag of either type can be permanent or session-only ๐
a system flag is a flag name that's already pre-defined in this specification. every system flag starts with "" ๐ซ a couple of them (\Deleted and \Seen) have special semantics that get described elsewhere. the currently defined system flags are:
\Seen Message has been read
\Answered Message has been answered
\Flagged Message is "flagged" for urgent/special attention
\Deleted Message is "deleted" for removal by later EXPUNGE
\Draft Message has not completed composition (marked as a
draft).
\Recent Message is "recently" arrived in this mailbox. This
session is the first session to have been notified
about this message; subsequent sessions will not see
\Recent set for this message. This flag can not be
altered by the client.
If it is not possible to determine whether or not
this session is the first session to be notified
about a message, then that message SHOULD be
considered recent.
If multiple connections have the same mailbox
selected simultaneously, it is undefined which of
these connections will see newly-arrives messages
with \Recent set and which will see it without
\Recent set.
okay the \Recent one is the main character of this whole list ๐ญ it means a message just showed up in this mailbox, and this session is the first one to be told about it. later sessions won't see \Recent set for that message ๐ and if you can't figure out whether this session is the first one to be notified, that message SHOULD be considered recent. if a bunch of connections have the same mailbox selected at once, it's undefined which of them sees new messages with \Recent set and which ones don't. chaotic but valid ๐
a keyword is defined by the server implementation. keywords do not begin with "". servers MAY let the client define new keywords in the mailbox (check out the PERMANENTFLAGS response code for the deets ๐).
a flag can be permanent or session-only on a per-flag basis. permanent flags are the ones the client can add or remove from the message flags permanently, which means later sessions will see any change to them ๐ changes to session flags only count inside that session, and then they vanish ๐ซง
Note: the\Recentsystem flag is a special case of a session flag.\Recentcan not be used as an argument in aSTOREcommand, so it literally can't be changed at all ๐ โโ๏ธ
2.3.3. Internal Date Message Attribute ๐
this is the internal date and time of the message on the server. it's NOT the date and time in the [RFC-822] header ๐
โโ๏ธ it's the date and time that reflects when the message was received. for messages delivered via [SMTP], this SHOULD be the date and time of final delivery of the message as defined by [SMTP]. for messages delivered by the IMAP4rev1 COPY command, this SHOULD be the internal date and time of the source message. for messages delivered by the IMAP4rev1 APPEND command, this SHOULD be the date and time specified in the APPEND command description. everything else is implementation defined ๐ ๏ธ
2.3.4. [RFC-822] Size Message Attribute ๐
this is the number of octets in the message, written in [RFC-822] format. simple, clean, no drama ๐ฐ
2.3.5. Envelope Structure Message Attribute ๐
this is a parsed representation of the [RFC-822] envelope information. it's not the same thing as an [SMTP] envelope, so don't mix them up bestie ๐ the envelope is basically the message's parsed "wrapper info", and it's kinda iconic ๐ฆ
2.3.6. Body Structure Message Attribute ๐งฉ
okay so this one is giving parsed representation energy ๐ it's a parsed version of the [MIME-IMB] body structure info of the message. the structure is the whole vibe ๐ฆ
2.4. Message Texts ๐จ
bestie, besides grabbing the full [RFC-822] text of a message, IMAP4rev1 lets you fetch just the pieces โจ specifically: the [RFC-822] message header, the [RFC-822] message body, a [MIME-IMB] body part, or a [MIME-IMB] header. slay ๐
3. State and Flow Diagram ๐บ๏ธ
okay so an IMAP4rev1 server is in one of four states ๐ most commands only work in certain states, and if the client tries a command while the connection is in the wrong state, that's a protocol error ๐ in that case the server answers with a BAD or NO (depending on how the server was built) as the command completion result ๐
3.1. Non-Authenticated State ๐
in non-authenticated state, the client MUST supply authentication credentials before most commands are allowed ๐ซถ you land here when a connection starts, unless it was already pre-authenticated.
3.2. Authenticated State ๐
in authenticated state, the client is authenticated and MUST select a mailbox to access before commands that touch messages will work ๐ you get here when a pre-authenticated connection starts, when acceptable credentials have been provided, or after an error while selecting a mailbox.
3.3. Selected State ๐ฌ
in selected state, a mailbox has been selected to access. this is where you end up once a mailbox is successfully selected โจ
3.4. Logout State ๐ช
in logout state, the connection is being terminated and the server will close it ๐ญ this can happen because the client asked for it, or because the server decided on its own.
Here's the state map, it's giving subway diagram ๐
+--------------------------------------+
|initial connection and server greeting|
+--------------------------------------+
|| (1) || (2) || (3)
VV || ||
+-----------------+ || ||
|non-authenticated| || ||
+-----------------+ || ||
|| (7) || (4) || ||
|| VV VV ||
|| +----------------+ ||
|| | authenticated |<=++ ||
|| +----------------+ || ||
|| || (7) || (5) || (6) ||
|| || VV || ||
|| || +--------+ || ||
|| || |selected|==++ ||
|| || +--------+ ||
|| || || (7) ||
VV VV VV VV
+--------------------------------------+
| logout and close connection |
+--------------------------------------+
(1) connection without pre-authentication (OK greeting)
(2) pre-authenticated connection (PREAUTH greeting)
(3) rejected connection (BYE greeting)
(4) successful LOGIN or AUTHENTICATE command
(5) successful SELECT or EXAMINE command
(6) CLOSE command, or failed SELECT or EXAMINE command
(7) LOGOUT command, server shutdown, or connection closed
4. Data Formats ๐
IMAP4rev1 uses textual commands and responses ๐ data can come in one of a few forms: atom, number, string, parenthesized list, or NIL.
4.1. Atom ๐
an atom is one or more non-special characters.
4.2. Number ๐ข
a number is one or more digit characters, and it represents a numeric value.
4.3. String ๐งถ
a string comes in two forms: literal and quoted string. the literal form is the general one ๐ the quoted string is an alternative that skips the overhead of processing a literal, but you get limits on which characters you can use in it.
a literal is a sequence of zero or more octets (including CR and LF), prefix-quoted with an octet count in the form of an open brace ({), the number of octets, a close brace (}), and CRLF. for literals sent from server to client, the CRLF is immediately followed by the octet data. for literals sent from client to server, the client MUST wait to receive a command continuation request (described later in this document) before sending the octet data and the rest of the command ๐ซถ
a quoted string is a sequence of zero or more 7-bit characters, excluding CR and LF, with double quote (") characters at each end ๐ธ
the empty string can be written as either "" (a quoted string with zero characters between the double quotes) or as {0} followed by CRLF (a literal with an octet count of 0) ๐
Note: Even if the octet count is 0, a client transmitting a literal MUST wait to receive a command continuation request. โ ๏ธ
4.3.1. 8-bit and Binary Strings ๐
8-bit textual and binary mail is supported through a [MIME-IMB] content transfer encoding โจ IMAP4rev1 implementations MAY transmit 8-bit or multi-octet characters in literals, but SHOULD do so only when the [CHARSET] is identified.
ngl binary strings are a no-go ๐ โโ๏ธ although a BINARY body encoding is defined, unencoded binary strings are not permitted. a "binary string" is any string with NUL characters. implementations MUST encode binary data into a textual form such as BASE64 before transmitting the data. a string with an excessive amount of CTL characters MAY also be considered to be binary ๐
4.4. Parenthesized List ๐ท
data structures are shown as a "parenthesized list": a sequence of data items, separated by spaces and wrapped in parentheses at each end. a parenthesized list can hold other parenthesized lists, with more levels of parentheses for nesting ๐ช
the empty list is written as (), a parenthesized list with no members.
4.5. NIL ๐ซฅ
the special atom "NIL" stands for the non-existence of a data item that would be a string or a parenthesized list. it's different from the empty string "" or the empty parenthesized list () ๐
5. Operational Considerations ๐ ๏ธ
5.1. Mailbox Naming ๐ซ
the way mailbox names get interpreted is up to the implementation ๐คทโโ๏ธ the case-insensitive mailbox name INBOX is special though, reserved to mean "the primary mailbox for this user on this server" ๐
5.1.1. Mailbox Hierarchy Naming ๐ณ
if you want to export hierarchical mailbox names, mailbox names MUST be left-to-right hierarchical, using a single character to separate the levels ๐ the same separator character is used for every level within a single name.
5.1.2. Mailbox Namespace Naming Convention ๐ท๏ธ
by convention, the first hierarchical element of any mailbox name that begins with "#" identifies the "namespace" of the rest of the name โจ this makes it possible to tell apart different types of mailbox stores, each with their own namespaces ๐ฆ
for example, implementations that offer access to USENET newsgroups MAY use the #news namespace to split the USENET newsgroup namespace off from other mailboxes ๐ฐ so the comp.mail.misc newsgroup would have a mailbox name of #news.comp.mail.misc, and the name comp.mail.misc could refer to a totally different object (e.g. a user's private mailbox) ๐ iykyk.
5.1.3. Mailbox International Naming Convention ๐
okay so international mailbox names follow a convention: they use a modified version of the UTF-7 encoding from [UTF-7]. bestie, the modifications fix five real problems with plain UTF-7 ๐:
- UTF-7 uses "+" for shifting, which clashes with "+" showing up in mailbox names, especially USENET newsgroup names ๐
- UTF-7's encoding is BASE64, which uses "/", and that clashes with "/" being a super popular hierarchy delimiter ๐
- UTF-7 prohibits unencoded "", which clashes with "" being a popular hierarchy delimiter ๐
- UTF-7 prohibits unencoded "~", which clashes with "~" as a home directory indicator on some servers ๐
- UTF-7 allows multiple alternate forms for the same string. Printable US-ASCII characters can be written in encoded form too, which is a lot ๐
In modified UTF-7, printable US-ASCII characters (except "&") represent themselves. That means octet values 0x20-0x25 and 0x27-0x7e. The "&" (0x26) gets written as the two-octet sequence &- ๐
All other characters (octet values 0x00-0x1f, 0x7f-0xff, and all Unicode 16-bit octets) are written in modified BASE64. There's one more tweak from [UTF-7] here: "," is used instead of "/". Modified BASE64 MUST NOT be used to represent any printing US-ASCII character which can represent itself. โจ
"&" shifts into modified BASE64, and "-" shifts back to US-ASCII. All names start in US-ASCII and MUST end in US-ASCII. So a name that ends with a Unicode 16-bit octet MUST end with a "-". ๐ซถ
Here's an example mailbox name that mixes English, Japanese, and Chinese text:
~peter/mail/&ZeVnLIqe-/&U,BTFw-
5.2. Mailbox Size and Message Status Updates ๐ฌ
At any time, a server can send data that the client did not request. Sometimes this is REQUIRED ๐ญ. For example, agents other than the server MAY add messages to the mailbox (like new mail delivery), change the flags of messages in the mailbox (like simultaneous access to the same mailbox by multiple agents), or even remove messages from the mailbox. A server MUST send mailbox size updates automatically if a mailbox size change is observed during the processing of a command. A server SHOULD send message flag updates automatically, without requiring the client to ask for them explicitly. There are special rules for server notification of a client about removed messages, so nothing gets out of sync. See the description of the EXPUNGE response for more detail ๐ฅ.
Regardless of what a client decides to remember from the server, a client implementation MUST record mailbox size updates. It MUST NOT assume that any command after initial mailbox selection will return the size of the mailbox. Main character energy is knowing when the numbers changed ๐.
5.3. Response when no Command in Progress ๐ญ
Server implementations are allowed to send an untagged response (except for EXPUNGE) while there is no command in progress. Server implementations that do this MUST deal with flow control. Specifically, they MUST either (1) verify that the size of the data does not exceed the underlying transport's available window size, or (2) use non-blocking writes. Ngl this is the kind of careful planning I respect ๐ง.
5.4. Autologout Timer โฐ
If a server has an inactivity autologout timer, that timer MUST be at least 30 minutes long. Receiving ANY command from the client during that interval SHOULD be enough to reset the autologout timer ๐ธ.
5.5. Multiple Commands in Progress ๐
The client MAY send another command without waiting for the completion result response of a command. This is subject to ambiguity rules (see below) and flow control constraints on the underlying data stream. In the same way, a server MAY begin processing another command before finishing the current one, subject to ambiguity rules. However, any command continuation request responses and command continuations MUST be negotiated before any subsequent command is initiated. ๐งต
The exception is when an ambiguity would result because one command would affect the results of other commands. Clients MUST NOT send multiple commands without waiting if an ambiguity would result. If the server detects a possible ambiguity, it MUST execute commands to completion in the order the client gave them ๐ฆ.
The most obvious example of ambiguity is when one command would affect the results of another, like a FETCH of a message's flags and a STORE of that same message's flags ๐.
A non-obvious ambiguity happens with commands that permit an untagged EXPUNGE response (commands other than FETCH, STORE, and SEARCH). An untagged EXPUNGE response can invalidate sequence numbers in a later command. This is not a problem for FETCH, STORE, or SEARCH because servers are prohibited from sending EXPUNGE responses while any of those commands are in progress. So if the client sends any command other than FETCH, STORE, or SEARCH, it MUST wait for a response before sending a command with message sequence numbers. ๐
For example, these non-waiting command sequences are invalid:
FETCH + NOOP + STORE
STORE + COPY + FETCH
COPY + COPY
CHECK + FETCH
These are valid non-waiting command sequences:
FETCH + STORE + SEARCH + CHECK
STORE + COPY + EXPUNGE
6. Client Commands โจ
IMAP4rev1 commands are described in this section. Commands are grouped by the state in which they're permitted. Commands that are permitted in multiple states are listed under the minimum permitted state. For example, commands valid in the authenticated and selected states are listed under the authenticated state commands ๐.
Command arguments, marked "Arguments:" in the command descriptions below, are described by what they do, not by their syntax. The exact syntax of command arguments is in the Formal Syntax section ๐.
Some commands cause specific server responses, which are marked "Responses:" in the command descriptions. For information on those responses, see the response descriptions in the Responses section, and the Formal Syntax section for their exact syntax. Server data can be sent as a result of any command, so commands that don't specifically need server data say "no specific responses for this command" instead of "none" ๐ฆ.
The "Result:" in each command description refers to the possible tagged status responses to a command, plus any special meaning for those status responses ๐ง.
6.1. Client Commands - Any State ๐ซถ
These commands are valid in any state: CAPABILITY, NOOP, and LOGOUT. ๐
6.1.1. CAPABILITY Command ๐งข
Arguments: none
Responses: REQUIRED untagged response: CAPABILITY
Result: OK - capability completed
BAD - command unknown or arguments invalid
The CAPABILITY command asks for a list of the capabilities the server supports. The server MUST send a single untagged CAPABILITY response with "IMAP4rev1" as one of the listed capabilities, before the (tagged) OK response. This list doesn't depend on connection state or user, so there's no need to issue a CAPABILITY command more than once in a connection ๐.
A capability name that begins with "AUTH=" tells you the server supports that particular authentication mechanism. All such names are, by definition, part of this specification. For example, the authorization capability for an experimental "blurdybloop" authenticator would be AUTH=XBLURDYBLOOP, and NOT XAUTH=BLURDYBLOOP or XAUTH=XBLURDYBLOOP ๐ค.
Other capability names refer to extensions, revisions, or amendments to this specification. See the documentation of the CAPABILITY response for more info. No capabilities beyond the base IMAP4rev1 set in this specification are enabled unless the client explicitly takes action to invoke them ๐.
For info about the form of site or implementation-specific capabilities, see the section called "Client Commands - Experimental/Expansion" ๐.
Example:
C: abcd CAPABILITY
S: * CAPABILITY IMAP4rev1 AUTH=KERBEROS_V4
S: abcd OK CAPABILITY completed
6.1.2. NOOP Command ๐ด
Arguments: none
Responses: no specific responses for this command (but see below)
Result: OK - noop completed
BAD - command unknown or arguments invalid
The NOOP command always succeeds. It does nothing, iconic behavior honestly ๐.
Since any command can return a status update as untagged data, NOOP can be used as a periodic poll for new messages or message status updates during a quiet stretch. NOOP can also be used to reset any inactivity autologout timer on the server โฑ๏ธ.
Example:
C: a002 NOOP
S: a002 OK NOOP completed
. . .
C: a047 NOOP
S: * 22 EXPUNGE
S: * 23 EXISTS
S: * 3 RECENT
S: * 14 FETCH (FLAGS (\Seen \Deleted))
S: a047 OK NOOP completed
6.1.3. LOGOUT Command ๐
Arguments: none
Responses: REQUIRED untagged response: BYE
Result: OK - logout completed
BAD - command unknown or arguments invalid
The LOGOUT command tells the server the client is done with the connection. The server MUST send a BYE untagged response before the (tagged) OK response, and then close the network connection ๐ซก.
Example:
C: A023 LOGOUT
S: * BYE IMAP4rev1 Server logging out
S: A023 OK LOGOUT completed
(Server and client then close the connection)
6.2. Client Commands - Non-Authenticated State ๐
In the non-authenticated state, the AUTHENTICATE or LOGIN command sets up authentication and moves the connection into the authenticated state. AUTHENTICATE is a general mechanism for many authentication techniques, while LOGIN uses the classic user name and plaintext password pair ๐๏ธ.
Server implementations MAY allow non-authenticated access to certain mailboxes. The convention is to use a LOGIN command with the userid "anonymous". A password is REQUIRED. What requirements (if any) apply to the password, and what access restrictions apply to anonymous users, is up to each implementation ๐ต๏ธ.
Once authenticated (including as "anonymous"), it is not possible to re-enter the non-authenticated state. No takebacks ๐ซ.
In addition to the universal commands (CAPABILITY, NOOP, and LOGOUT), the following commands are valid in the non-authenticated state: AUTHENTICATE and LOGIN ๐ .
6.2.1. AUTHENTICATE Command โจ
Arguments: authentication mechanism name
Responses: continuation data can be requested
Result: OK - authenticate completed, now in authenticated state
NO - authenticate failure: unsupported authentication
mechanism, credentials rejected
BAD - command unknown or arguments invalid,
authentication exchange cancelled
okay bestie, so AUTHENTICATE is how the client tells the server which auth mechanism it wants, like the ones described in [IMAP-AUTH] ๐. If the server supports that mechanism, it runs an authentication protocol exchange to authenticate and identify the client ๐ซถ. It MAY also negotiate an OPTIONAL protection mechanism for later protocol interactions โจ. If the requested mechanism isn't supported, the server SHOULD reject the command by sending a tagged NO response ๐ โโ๏ธ.
the exchange itself is a bunch of server challenges and client answers that depend on the mechanism ๐ฆ. A server challenge is a command continuation request response with the + token followed by a BASE64 encoded string. The client answer is a line with a BASE64 encoded string. If the client wants to cancel, it sends a line with just a single *. If the server gets that, it MUST reject the AUTHENTICATE command by sending a tagged BAD response ๐.
now the protection mechanism, which is giving integrity and privacy for the connection ๐ธ. If one is negotiated, it covers ALL the data sent after that point. It kicks in right after the CRLF that ends the client's side of the exchange, and right after the CRLF of the tagged OK response for the server. Once it's on, the stream of command and response octets gets processed into buffers of ciphertext. Each buffer goes over the connection as a stream of octets with a four octet field in network byte order in front of it, showing the length of the data that follows. The maximum ciphertext buffer length is defined by the protection mechanism ๐ง.
Here's the big picture on OPTIONAL-ness ๐. Authentication mechanisms are OPTIONAL. Protection mechanisms are also OPTIONAL, so an authentication mechanism MAY be implemented without any protection mechanism. If an AUTHENTICATE command fails with a NO response, the client MAY try a different mechanism by sending another AUTHENTICATE command, or MAY just try the LOGIN command. In other words, the client MAY request auth types in decreasing order of preference, with LOGIN as the last resort ๐.
S: * OK KerberosV4 IMAP4rev1 Server
C: A001 AUTHENTICATE KERBEROS_V4
S: + AmFYig==
C: BAcAQU5EUkVXLkNNVS5FRFUAOCAsho84kLN3/IJmrMG+25a4DT
+nZImJjnTNHJUtxAA+o0KPKfHEcAFs9a3CL5Oebe/ydHJUwYFd
WwuQ1MWiy6IesKvjL5rL9WjXUb9MwT9bpObYLGOKi1Qh
S: + or//EoAADZI=
C: DiAF5A4gA+oOIALuBkAAmw==
S: A001 OK Kerberos V4 authentication successful
Note: the line breaks in the first client answer are for editorial clarity and are not in real authenticators. ๐
6.2.2. LOGIN Command โจ
Arguments: user name
password
Responses: no specific responses for this command
Result: OK - login completed, now in authenticated state
NO - login failure: user name or password rejected
BAD - command unknown or arguments invalid
the LOGIN command is how the client identifies itself to the server ๐ชช. It carries the plaintext password that authenticates this user, so yes, it's sending the password in plain text ๐ญ.
C: a001 LOGIN SMITH SESAME
S: a001 OK LOGIN completed
6.3. Client Commands - Authenticated State ๐
In authenticated state, commands that manipulate mailboxes as atomic entities are permitted. Of those, SELECT and EXAMINE are the ones that pick a mailbox for access and move you into selected state ๐ฆ.
In addition to the universal commands (CAPABILITY, NOOP, and LOGOUT), these are valid in authenticated state: SELECT, EXAMINE, CREATE, DELETE, RENAME, SUBSCRIBE, UNSUBSCRIBE, LIST, LSUB, STATUS, and APPEND ๐ .
6.3.1. SELECT Command โจ
Arguments: mailbox name
Responses: REQUIRED untagged responses: FLAGS, EXISTS, RECENT
OPTIONAL OK untagged responses: UNSEEN, PERMANENTFLAGS
Result: OK - select completed, now in selected state
NO - select failure, now in authenticated state: no
such mailbox, can't access mailbox
BAD - command unknown or arguments invalid
SELECT picks a mailbox so you can actually access the messages inside ๐ฌ. Before the server returns an OK, it MUST send this untagged data to the client:
FLAGS Defined flags in the mailbox. See the description
of the FLAGS response for more detail.
<n> EXISTS The number of messages in the mailbox. See the
description of the EXISTS response for more detail.
<n> RECENT The number of messages with the \Recent flag set.
See the description of the RECENT response for more
detail.
OK [UIDVALIDITY <n>]
The unique identifier validity value. See the
description of the UID command for more detail.
All of that is there to set up the initial state of the mailbox on the client's side ๐.
The server SHOULD also send an UNSEEN response code in an OK untagged response ๐. It points at the message sequence number of the first unseen message in the mailbox.
If the client can not change the permanent state of one or more of the flags in the FLAGS untagged response, the server SHOULD send a PERMANENTFLAGS response code in an OK untagged response ๐ฉ. That one lists the flags the client CAN change permanently.
Only one mailbox can be selected at a time per connection ๐ โโ๏ธ. Want to touch multiple mailboxes? You need multiple connections. SELECT automatically deselects whatever's selected before trying the new one, so if you select a mailbox and then a SELECT fails, no mailbox is selected anymore ๐ญ.
If the client is permitted to modify the mailbox, the server SHOULD prefix the text of the tagged OK response with the [READ-WRITE] response code ๐.
If the client isn't permitted to modify the mailbox but IS permitted read access, the mailbox gets selected as read-only, and the server MUST prefix the tagged OK response to SELECT with the [READ-ONLY] response code ๐. Read-only access through SELECT differs from EXAMINE in that certain read-only mailboxes MAY permit changing permanent state on a per-user (as opposed to global) basis. Netnews messages marked in a server-based .newsrc file are an example of that kind of per-user permanent state that can be changed with read-only mailboxes ๐๏ธ.
C: A142 SELECT INBOX
S: * 172 EXISTS
S: * 1 RECENT
S: * OK [UNSEEN 12] Message 12 is first unseen
S: * OK [UIDVALIDITY 3857529045] UIDs valid
S: * FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
S: * OK [PERMANENTFLAGS (\Deleted \Seen \*)] Limited
S: A142 OK [READ-WRITE] SELECT completed
6.3.2. EXAMINE Command โจ
Arguments: mailbox name
Responses: REQUIRED untagged responses: FLAGS, EXISTS, RECENT
OPTIONAL OK untagged responses: UNSEEN, PERMANENTFLAGS
Result: OK - examine completed, now in selected state
NO - examine failure, now in authenticated state: no
such mailbox, can't access mailbox
BAD - command unknown or arguments invalid
EXAMINE is basically SELECT's read-only twin ๐ฏ. It gives you the same output, but the mailbox is marked as read-only. No changes to the permanent state of the mailbox are allowed, including per-user state ๐ โโ๏ธ.
The text of the tagged OK response to EXAMINE MUST begin with the [READ-ONLY] response code ๐.
C: A932 EXAMINE blurdybloop
S: * 17 EXISTS
S: * 2 RECENT
S: * OK [UNSEEN 8] Message 8 is first unseen
S: * OK [UIDVALIDITY 3857529045] UIDs valid
S: * FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
S: * OK [PERMANENTFLAGS ()] No permanent flags permitted
S: A932 OK [READ-ONLY] EXAMINE completed
6.3.3. CREATE Command โจ
Arguments: mailbox name
Responses: no specific responses for this command
Result: OK - create completed
NO - create failure: can't create mailbox with that name
BAD - command unknown or arguments invalid
CREATE makes a brand new mailbox with the name you give it ๐. You only get an OK if a new mailbox with that name was actually created. It's an error to try creating INBOX, or a name that points at a mailbox that already exists ๐. Any creation error comes back as a tagged NO response.
If the mailbox name ends with the server's hierarchy separator character (the one the server returns from a LIST command), that's the client saying "I plan to make mailboxes under this name" ๐ณ. Server implementations that don't need that declaration MUST ignore it.
If the hierarchy separator character shows up anywhere else in the name, the server SHOULD create any superior hierarchical names needed for CREATE to succeed. So, say the server uses / as the separator and you try to create foo/bar/zap. The server SHOULD create foo/ and foo/bar/ if they don't already exist ๐ง.
If a new mailbox is created with the same name as one that got deleted, its unique identifiers MUST be greater than any unique identifiers used in the previous incarnation of the mailbox, unless the new incarnation has a different unique identifier validity value. Check the description of the UID command for more detail ๐ข.
C: A003 CREATE owatagusiam/
S: A003 OK CREATE completed
C: A004 CREATE owatagusiam/blurdybloop
S: A004 OK CREATE completed
Note: how you read this example depends on whether / was returned as the hierarchy separator from LIST. If / is the separator, you get a new level of hierarchy called "owatagusiam" with a member named "blurdybloop" inside it ๐ท. Otherwise, you get two mailboxes sitting at the same hierarchy level ๐ฆ.
6.3.4. DELETE Command ๐๏ธโจ
Arguments: mailbox name
Responses: no specific responses for this command
Result: OK - delete completed
NO - delete failure: can't delete mailbox with that name
BAD - command unknown or arguments invalid
okay so DELETE is the command that permanently removes a mailbox by its name ๐ A tagged OK only comes back if the mailbox was actually deleted. And you can't delete INBOX, and you can't delete a mailbox name that doesn't exist. no cap, INBOX is untouchable ๐
The DELETE command MUST NOT remove inferior hierarchical names ๐
โโ๏ธ Say a mailbox "foo" has an inferior "foo.bar" (with "." as the hierarchy delimiter). Deleting "foo" MUST NOT delete "foo.bar". It's an error to delete a name that has inferior hierarchical names and the \Noselect mailbox name attribute (go check the LIST response part for the full tea โ).
It's allowed to delete a name that has inferior hierarchical names but doesn't have \Noselect. In that case, all the messages in that mailbox get removed, and the name picks up the \Noselect attribute. iykyk ๐ฆ
Also, the highest-used unique identifier of the deleted mailbox MUST be preserved ๐ That way, a new mailbox made with the same name won't reuse the IDs of the old one, UNLESS the new one has a different unique identifier validity value. Check the UID command section if you want the deep dive ๐ง
C: A682 LIST "" *
S: * LIST () "/" blurdybloop
S: * LIST (\Noselect) "/" foo
S: * LIST () "/" foo/bar
S: A682 OK LIST completed
C: A683 DELETE blurdybloop
S: A683 OK DELETE completed
C: A684 DELETE foo
S: A684 NO Name "foo" has inferior hierarchical names
C: A685 DELETE foo/bar
S: A685 OK DELETE Completed
C: A686 LIST "" *
S: * LIST (\Noselect) "/" foo
S: A686 OK LIST completed
C: A687 DELETE foo
S: A687 OK DELETE Completed
C: A82 LIST "" *
S: * LIST () "." blurdybloop
S: * LIST () "." foo
S: * LIST () "." foo.bar
S: A82 OK LIST completed
C: A83 DELETE blurdybloop
S: A83 OK DELETE completed
C: A84 DELETE foo
S: A84 OK DELETE Completed
C: A85 LIST "" *
S: * LIST () "." foo.bar
S: A85 OK LIST completed
C: A86 LIST "" %
S: * LIST (\Noselect) "." foo
S: A86 OK LIST completed
6.3.5. RENAME Command ๐
Arguments: existing mailbox name
new mailbox name
Responses: no specific responses for this command
Result: OK - rename completed
NO - rename failure: can't rename mailbox with that name,
can't rename to mailbox with that name
BAD - command unknown or arguments invalid
RENAME changes the name of a mailbox, and it's giving glow-up ๐ธ A tagged OK only shows up if the mailbox actually got renamed. It's an error to rename from a name that doesn't exist, or to a name that already exists. Any rename error gets a tagged NO back ๐
If the name has inferior hierarchical names, those inferior names MUST also be renamed ๐ซถ For example, renaming "foo" to "zap" will rename "foo/bar" (with "/" as the hierarchy delimiter) to "zap/bar". The sibling gets dragged along, no exceptions ๐
The highest-used unique identifier of the old mailbox name MUST be preserved ๐ So a new mailbox created with the same name won't reuse the old IDs, UNLESS the new incarnation has a different unique identifier validity value. Again, the UID command section has the full story โจ
Renaming INBOX is allowed, and it has its own special behavior ๐ฆ It moves every message in INBOX into a new mailbox with the given name, and INBOX gets left empty. If the server supports inferior hierarchical names of INBOX, those stay exactly where they are. Main character energy for INBOX ๐
C: A682 LIST "" *
S: * LIST () "/" blurdybloop
S: * LIST (\Noselect) "/" foo
S: * LIST () "/" foo/bar
S: A682 OK LIST completed
C: A683 RENAME blurdybloop sarasoop
S: A683 OK RENAME completed
C: A684 RENAME foo zowie
S: A684 OK RENAME Completed
C: A685 LIST "" *
S: * LIST () "/" sarasoop
S: * LIST (\Noselect) "/" zowie
S: * LIST () "/" zowie/bar
S: A685 OK LIST completed
C: Z432 LIST "" *
S: * LIST () "." INBOX
S: * LIST () "." INBOX.bar
S: Z432 OK LIST completed
C: Z433 RENAME INBOX old-mail
S: Z433 OK RENAME completed
C: Z434 LIST "" *
S: * LIST () "." INBOX
S: * LIST () "." INBOX.bar
S: * LIST () "." old-mail
S: Z434 OK LIST completed
6.3.6. SUBSCRIBE Command ๐
Arguments: mailbox
Responses: no specific responses for this command
Result: OK - subscribe completed
NO - subscribe failure: can't subscribe to that name
BAD - command unknown or arguments invalid
SUBSCRIBE adds the mailbox name to the server's set of "active" or "subscribed" mailboxes, the ones LSUB shows you ๐ A tagged OK only comes back if the subscription worked โจ
A server MAY validate the mailbox argument to SUBSCRIBE to check that it exists ๐ But here's the vibe check: it MUST NOT unilaterally remove an existing mailbox name from the subscription list, even if that mailbox doesn't exist anymore ๐ซถ
Note: this requirement is because some server sites may routinely remove a mailbox with a well-known name (e.g. "system-alerts") after its contents expire, with the intention of recreating it when new contents are appropriate. So the server can't just yank the subscription away ๐ฅบ
C: A002 SUBSCRIBE #news.comp.mail.mime
S: A002 OK SUBSCRIBE completed
6.3.7. UNSUBSCRIBE Command ๐
Arguments: mailbox name
Responses: no specific responses for this command
Result: OK - unsubscribe completed
NO - unsubscribe failure: can't unsubscribe that name
BAD - command unknown or arguments invalid
UNSUBSCRIBE is the opposite of SUBSCRIBE ๐ It removes the mailbox name from the server's set of "active" or "subscribed" mailboxes (the same set LSUB returns). A tagged OK only shows up if the unsubscription actually went through ๐ท
C: A002 UNSUBSCRIBE #news.comp.mail.mime
S: A002 OK UNSUBSCRIBE completed
6.3..8. LIST Command โจ
bestie, the LIST command is basically the "show me the folders" move ๐๐ซถ Here's how the arguments, responses, and results go:
- Arguments: a reference name, and a mailbox name with possible wildcards
- Responses: untagged LIST responses
- Result:
- OK: list completed
- NO: list failure, can't list that reference or name
- BAD: command unknown or arguments invalid
okay so LIST returns a subset of the names the client can see ๐ You get zero or more untagged LIST replies, and each one carries the name attributes, the hierarchy delimiter, and the name itself. Check the LIST reply description for the full tea โ
LIST SHOULD return its data quickly, without undue delay ๐โโ๏ธ๐จ It SHOULD NOT go to excess trouble to work out \Marked or \Unmarked status or do other extra processing. Imagine if each name took 1 second to process: a list of 1200 names would take 20 minutes!! ๐ญ nobody has time for that bestie ๐
An empty ("" string) reference name means the mailbox name gets interpreted the same way SELECT would do it ๐ The mailbox names that come back MUST match the mailbox name pattern you sent. A non-empty reference name is the name of a mailbox or a level of mailbox hierarchy, and it sets a context where the mailbox name is interpreted in an implementation-defined way ๐ฆ
An empty ("" string) mailbox name is a special request that gets you the hierarchy delimiter and the root name of the reference name ๐ธ The root MAY be null if the reference is non-rooted or is null. Either way the hierarchy delimiter always comes back, which is so useful because the client can grab it even when no mailboxes with that name exist yet ๐ง
The reference and mailbox name arguments get interpreted, in an implementation-dependent way, into a canonical form that represents an unambiguous left-to-right hierarchy โจ The returned mailbox names will be in that interpreted form.
Any part of the reference argument that gets included in the interpreted form SHOULD prefix the interpreted form ๐ It SHOULD also be in the same form as the reference name argument. This is the rule that lets the client tell whether a returned mailbox name lives in the context of the reference argument, or whether something in the mailbox argument overrode it ๐ Without this rule the client would need to know the server's naming semantics, including which characters are "breakouts" that override a naming context. no thank you ๐ โโ๏ธ
Here are some examples of how references and mailbox names might get interpreted on a UNIX-based server ๐ง
Reference Mailbox Name Interpretation
------------ ------------ --------------
~smith/Mail/ foo.* ~smith/Mail/foo.*
archive/ % archive/%
#news. comp.mail.* #news.comp.mail.*
~smith/Mail/ /usr/doc/foo /usr/doc/foo
archive/ ~fred/Mail/* ~fred/Mail/*
The first three examples show interpretations in the context of the reference argument ๐ฅฐ Note that ~smith/Mail SHOULD NOT get transformed into something like /u2/users/smith/Mail, or the client would have no way to tell the interpretation was in the context of the reference ๐ฉ
The * is a wildcard that matches zero or more characters at that position ๐ The % is similar to *, but it does NOT match a hierarchy delimiter. If % is the last character of a mailbox name argument, the matching levels of hierarchy get returned too. If those levels aren't also selectable mailboxes, they come back with the \Noselect mailbox name attribute (check the LIST response description for more details) ๐ซง
Server implementations are allowed to "hide" otherwise accessible mailboxes from the wildcards. They can stop certain characters or names from matching a wildcard in certain situations ๐ For example, a UNIX-based server might restrict * so that an initial / character doesn't match.
The special name INBOX is included in the LIST output if INBOX is supported by this server for this user, AND if the uppercase string "INBOX" matches the interpreted reference and mailbox name arguments with wildcards, the way we just described ๐ The criteria for omitting INBOX is whether SELECT INBOX would return failure. It doesn't matter whether the user's real INBOX lives on this server or some other one ๐ซถ
Example:
C: A101 LIST "" ""
S: * LIST (\Noselect) "/" ""
S: A101 OK LIST Completed
C: A102 LIST #news.comp.mail.misc ""
S: * LIST (\Noselect) "." #news.
S: A102 OK LIST Completed
C: A103 LIST /usr/staff/jones ""
S: * LIST (\Noselect) "/" /
S: A103 OK LIST Completed
C: A202 LIST ~/Mail/ %
S: * LIST (\Noselect) "/" ~/Mail/foo
S: * LIST () "/" ~/Mail/meetings
S: A202 OK LIST completed
6.3.9. LSUB Command ๐ฆ
LSUB is the "show me my subscribed folders" command ๐ Here's the rundown:
- Arguments: a reference name, and a mailbox name with possible wildcards
- Responses: untagged LSUB responses
- Result:
- OK: lsub completed
- NO: lsub failure, can't list that reference or name
- BAD: command unknown or arguments invalid
LSUB returns a subset of names from the set the user has declared as "active" or "subscribed" ๐ Zero or more untagged LSUB replies come back. The arguments to LSUB take the same form as the ones for LIST, so if you know LIST, you already know LSUB ๐
A server MAY validate the subscribed names to see if they still exist ๐ If a name doesn't exist, it SHOULD get flagged with the \Noselect attribute in the LSUB response. A server MUST NOT unilaterally remove an existing mailbox name from the subscription list, even if a mailbox by that name no longer exists. bestie, the server is NOT allowed to just delete your subscriptions on its own ๐ค๐
Example:
C: A002 LSUB "#news." "comp.mail.*"
S: * LSUB () "." #news.comp.mail.mime
S: * LSUB () "." #news.comp.mail.misc
S: A002 OK LSUB completed
6.3.10. STATUS Command ๐
the STATUS command asks for the status of a mailbox, and it's giving very efficient energy โจ Here's the setup:
- Arguments: a mailbox name, and status data item names
- Responses: untagged STATUS responses
- Result:
- OK: status completed
- NO: status failure, no status for that name
- BAD: command unknown or arguments invalid
STATUS requests the status of the mailbox you name ๐ It does NOT change the currently selected mailbox, and it doesn't touch the state of any messages in the mailbox you're asking about. In particular, STATUS MUST NOT cause messages to lose the \Recent flag. protect the \Recent flag at all costs ๐ก๏ธ
STATUS is a handy alternative to opening a second IMAP4rev1 connection and running EXAMINE on a mailbox just to check its status. That way you don't have to deselect the mailbox you already have open in your first IMAP4rev1 connection ๐ง
Unlike LIST, STATUS is NOT guaranteed to respond fast ๐ On some implementations the server has to open the mailbox read-only internally to get certain status info. Also unlike LIST, STATUS does NOT accept wildcards. no * here, babe ๐
โโ๏ธ
The currently defined status data items you can request are:
MESSAGES The number of messages in the mailbox.
RECENT The number of messages with the \Recent flag set.
UIDNEXT The next UID value that will be assigned to a new
message in the mailbox. It is guaranteed that this
value will not change unless new messages are added
to the mailbox; and that it will change when new
messages are added even if those new messages are
subsequently expunged.
UIDVALIDITY The unique identifier validity value of the
mailbox.
UNSEEN The number of messages which do not have the \Seen
flag set.
Example:
C: A042 STATUS blurdybloop (UIDNEXT MESSAGES)
S: * STATUS blurdybloop (MESSAGES 231 UIDNEXT 44292)
S: A042 OK STATUS completed
6.3.11. APPEND Command โจ
okay so APPEND is the command that tacks a brand new message onto the very end of a mailbox, bestie ๐ here's the lineup:
Arguments: mailbox name
OPTIONAL flag parenthesized list
OPTIONAL date/time string
message literal
Responses: no specific responses for this command
Result: OK - append completed
NO - append error: can't append to that mailbox, error
in flags or date/time or message text
BAD - command unknown or arguments invalid
So the literal argument is the message you're appending ๐ฉ and it SHOULD look like an [RFC-822] message. 8-bit characters are totally allowed in there ๐ BUT if your server can't keep 8-bit data intact, it MUST be able to reversibly convert that 8-bit APPEND data to 7-bit using a [MIME-IMB] content transfer encoding. no cap, that's the safety net ๐ซถ
There MAY be exceptions, like draft messages, where the required [RFC-822] header lines are left out of the message literal. But the full implications of doing that MUST be understood and carefully weighed ๐ง don't just vibe with it!
Now the flags. If you send a flag parenthesized list, those flags SHOULD be set on the new message ๐. If you don't, the flag list just defaults to empty ๐ซง
Same energy for dates. If a date_time is given, the internal date SHOULD be set on the resulting message ๐๏ธ otherwise it defaults to the current date and time โฐ
Here's the big drama moment ๐ญ If the append fails for any reason, the mailbox MUST be restored to how it was before the APPEND attempt. No partial appending is permitted. it's all or nothing, babe ๐
And if the destination mailbox doesn't exist, the server MUST return an error and MUST NOT auto-create it ๐
โโ๏ธ unless it's certain that the mailbox can't be created, the server MUST send the response code [TRYCREATE] as the prefix of the text in the tagged NO response. This is basically a hint saying "hey, try a CREATE and then retry the APPEND if that works" ๐ง
If the mailbox is currently selected, the normal new mail actions SHOULD happen โจ specifically, the server SHOULD tell the client right away with an untagged EXISTS response. If it doesn't, the client MAY send a NOOP command (or, failing that, a CHECK command) after one or more APPEND commands ๐
Example:
C: A003 APPEND saved-messages (\Seen) {310}
C: Date: Mon, 7 Feb 1994 21:52:25 -0800 (PST)
C: From: Fred Foobar <foobar@Blurdybloop.COM>
C: Subject: afternoon meeting
C: To: mooch@owatagu.siam.edu
C: Message-Id: <B27397-0100000@Blurdybloop.COM>
C: MIME-Version: 1.0
C: Content-Type: TEXT/PLAIN; CHARSET=US-ASCII
C:
C: Hello Joe, do you think we can meet at 3:30 tomorrow?
C:
S: A003 OK APPEND completed
Note: the APPEND command is not used for message delivery ๐ซ๐ฌ, because it does not provide a mechanism to transfer [SMTP] envelope information. so don't use it as your mail delivery truck, bestie!
6.4. Client Commands - Selected State ๐
in selected state, you get to play with the messages inside a mailbox ๐ commands that manipulate messages are permitted here.
On top of the universal commands (CAPABILITY, NOOP, and LOGOUT) and the authenticated state commands (SELECT, EXAMINE, CREATE, DELETE, RENAME, SUBSCRIBE, UNSUBSCRIBE, LIST, LSUB, STATUS, and APPEND), the following commands are valid in the selected state: CHECK, CLOSE, EXPUNGE, SEARCH, FETCH, STORE, COPY, and UID ๐
6.4.1. CHECK Command
Arguments: none
Responses: no specific responses for this command
Result: OK - check completed
BAD - command unknown or arguments invalid
CHECK requests a checkpoint of the currently selected mailbox ๐งน a checkpoint is any implementation-dependent housekeeping for the mailbox (like syncing the server's in-memory state of the mailbox with what's on its disk) that doesn't normally run with every command. A checkpoint MAY take a non-instantaneous amount of real time to finish โณ and if a server has no housekeeping to do, CHECK is equivalent to NOOP ๐คทโโ๏ธ
There is no guarantee that an EXISTS untagged response will happen because of CHECK ๐ so NOOP, not CHECK, SHOULD be used for new mail polling. the vibe check says NOOP ๐ฎ
Example:
C: FXXZ CHECK
S: FXXZ OK CHECK Completed
6.4.2. CLOSE Command
Arguments: none
Responses: no specific responses for this command
Result: OK - close completed, now in authenticated state
NO - close failure: no mailbox selected
BAD - command unknown or arguments invalid
CLOSE permanently removes every message with the \Deleted flag set from the currently selected mailbox ๐๏ธ and takes you from selected state back to authenticated state ๐ No untagged EXPUNGE responses are sent, so it's quiet and clean โจ
No messages are removed and no error is given if the mailbox was selected by an EXAMINE command or is otherwise selected read-only ๐ it's a no-drama zone.
Even if a mailbox is selected, a SELECT, EXAMINE, or LOGOUT command MAY be issued without issuing a CLOSE first ๐ซถ those three implicitly close the selected mailbox without doing an expunge. BUT when a bunch of messages get deleted, a CLOSE-LOGOUT or CLOSE-SELECT sequence is way faster than EXPUNGE-LOGOUT or EXPUNGE-SELECT ๐๏ธ๐จ because no untagged EXPUNGE responses (which the client would probably ignore anyway) get sent. efficiency is iconic ๐
Example:
C: A341 CLOSE
S: A341 OK CLOSE completed
6.4.3. EXPUNGE Command
Arguments: none
Responses: untagged responses: EXPUNGE
Result: OK - expunge completed
NO - expunge failure: can't expunge (e.g. permission
denied)
BAD - command unknown or arguments invalid
EXPUNGE permanently removes every message with the \Deleted flag set from the currently selected mailbox ๐ and before the server sends its OK, it sends an untagged EXPUNGE response for each message it removes. That's the receipts ๐งพ
Example:
C: A202 EXPUNGE
S: * 3 EXPUNGE
S: * 3 EXPUNGE
S: * 5 EXPUNGE
S: * 8 EXPUNGE
S: A202 OK EXPUNGE completed
Note: in this example, messages 3, 4, 7, and 11 had the \Deleted flag set. see the description of the EXPUNGE response for further explanation ๐ฆ
6.4.4. SEARCH Command ๐โจ
Arguments: OPTIONAL [CHARSET] specification
searching criteria (one or more)
Responses: REQUIRED untagged response: SEARCH
Result: OK - search completed
NO - search error: can't search that [CHARSET] or
criteria
BAD - command unknown or arguments invalid
okay bestie, SEARCH is the command that goes digging through the mailbox ๐ต๏ธโโ๏ธ for messages that match your searching criteria. The criteria are made of one or more search keys, and the server's untagged SEARCH response is basically a little list of message sequence numbers for everything that matched ๐
When you stack multiple keys, it's an AND situation. Only the messages that match all of them make the cut ๐ So DELETED FROM "SMITH" SINCE 1-Feb-1994 is asking for deleted messages from Smith that were placed in the mailbox since February 1, 1994. A search key can also be a parenthesized list of one or more search keys, which is how you use the OR and NOT keys together ๐ง
Server implementations MAY leave out [MIME-IMB] body parts with terminal content media types other than TEXT and MESSAGE when they're doing SEARCH matching ๐
The OPTIONAL [CHARSET] specification is the word CHARSET followed by a registered [CHARSET] ๐ It tells the server which [CHARSET] the strings in your search criteria are using. [MIME-IMB] content transfer encodings, and [MIME-HDRS] strings in [RFC-822]/[MIME-IMB] headers, MUST be decoded before comparing text in a [CHARSET] other than US-ASCII. US-ASCII MUST be supported, and other [CHARSET]s MAY be supported too. If the server doesn't support the [CHARSET] you specified, it MUST return a tagged NO response (not a BAD) ๐
In all search keys that use strings, a message matches if the string is a substring of the field. The matching is case-insensitive ๐ฆ
The defined search keys are below. For the exact syntax of the arguments, check out the Formal Syntax section ๐ซถ
<message set>: messages with message sequence numbers corresponding to the specified message sequence number setALL: all messages in the mailbox. This is the default initial key for ANDing ๐ANSWERED: messages with the\Answeredflag setBCC <string>: messages that contain the specified string in the envelope structure's BCC fieldBEFORE <date>: messages whose internal date is earlier than the specified dateBODY <string>: messages that contain the specified string in the body of the messageCC <string>: messages that contain the specified string in the envelope structure's CC fieldDELETED: messages with the\Deletedflag setDRAFT: messages with the\Draftflag setFLAGGED: messages with the\Flaggedflag setFROM <string>: messages that contain the specified string in the envelope structure's FROM fieldHEADER <field-name> <string>: messages that have a header with the specified field-name (as defined in [RFC-822]) and that contain the specified string in the [RFC-822] field-bodyKEYWORD <flag>: messages with the specified keyword setLARGER <n>: messages with an [RFC-822] size larger than the specified number of octetsNEW: messages that have the\Recentflag set but not the\Seenflag. This is functionally equivalent to"(RECENT UNSEEN)"๐ธNOT <search-key>: messages that do not match the specified search keyOLD: messages that do not have the\Recentflag set. This is functionally equivalent to"NOT RECENT"(as opposed to"NOT NEW") ๐ON <date>: messages whose internal date is within the specified dateOR <search-key1> <search-key2>: messages that match either search keyRECENT: messages that have the\Recentflag setSEEN: messages that have the\Seenflag setSENTBEFORE <date>: messages whose [RFC-822] Date: header is earlier than the specified dateSENTON <date>: messages whose [RFC-822] Date: header is within the specified dateSENTSINCE <date>: messages whose [RFC-822] Date: header is within or later than the specified dateSINCE <date>: messages whose internal date is within or later than the specified dateSMALLER <n>: messages with an [RFC-822] size smaller than the specified number of octetsSUBJECT <string>: messages that contain the specified string in the envelope structure's SUBJECT fieldTEXT <string>: messages that contain the specified string in the header or body of the messageTO <string>: messages that contain the specified string in the envelope structure's TO fieldUID <message set>: messages with unique identifiers corresponding to the specified unique identifier set ๐ฅUNANSWERED: messages that do not have the\Answeredflag setUNDELETED: messages that do not have the\Deletedflag setUNDRAFT: messages that do not have the\Draftflag setUNFLAGGED: messages that do not have the\Flaggedflag setUNKEYWORD <flag>: messages that do not have the specified keyword setUNSEEN: messages that do not have the\Seenflag set
Here's the example, bestie ๐
C: A282 SEARCH FLAGGED SINCE 1-Feb-1994 NOT FROM "Smith"
S: * SEARCH 2 84 882
S: A282 OK SEARCH completed
6.4.5. FETCH Command โจ
Arguments: message set
message data item names
Responses: untagged responses: FETCH
Result: OK - fetch completed
NO - fetch error: can't fetch that data
BAD - command unknown or arguments invalid
okay so FETCH is how you grab data about a message in the mailbox ๐ฌ๐. The data items you want can be a single atom or a parenthesized list, so you can ask for one thing or a whole bundle ๐.
These are the data items you can currently fetch:
ALL๐ is a macro that means(FLAGS INTERNALDATE RFC822.SIZE ENVELOPE).BODYis the non-extensible form of BODYSTRUCTURE ๐ง.BODY[<section>]<<partial>>gives you the text of one particular body section ๐. The section is zero or more part specifiers separated by periods. A part specifier is either a part number or one ofHEADER,HEADER.FIELDS,HEADER.FIELDS.NOT,MIME, orTEXT. An empty section means the whole message, header included ๐.- Every message has at least one part number. Messages that aren't [MIME-IMB] messages, and multipart [MIME-IMB] messages with no encapsulated message, only have part 1 ๐ธ.
- Multipart messages get consecutive part numbers in the order they show up in the message. If a part is type message or multipart, its parts MUST be indicated by a period followed by the part number within that nested multipart part ๐ฆ.
- A part of type MESSAGE/RFC822 has nested part numbers too, pointing at the parts of that MESSAGE part's body ๐.
HEADER,HEADER.FIELDS,HEADER.FIELDS.NOT, andTEXTcan stand alone, or they can be prefixed by one or more numeric part specifiers, as long as that numeric part specifier points at a part of type MESSAGE/RFC822 ๐ซถ. TheMIMEpart specifier MUST be prefixed by one or more numeric part specifiers ๐.HEADER,HEADER.FIELDS, andHEADER.FIELDS.NOTrefer to the [RFC-822] header of the message, or of an encapsulated [MIME-IMT] MESSAGE/RFC822 message โจ.HEADER.FIELDSandHEADER.FIELDS.NOTare followed by a list of field-name names (as defined in [RFC-822]) and give back a subset of the header ๐ฅ.HEADER.FIELDSreturns only the fields whose field-name matches one of the names in the list.HEADER.FIELDS.NOTreturns only the fields whose field-name does not match ๐ . Field matching is case-insensitive but otherwise exact ๐. In every case, the blank line that separates the header from the body is always included ๐.- The
MIMEpart specifier refers to the [MIME-IMB] header for this part ๐. - The
TEXTpart specifier refers to the text body of the message, leaving out the [RFC-822] header ๐ฆ.
Here's a complex message with some of its part specifiers, so you can see how the numbering works:
HEADER ([RFC-822] header of the message)
TEXT MULTIPART/MIXED
1 TEXT/PLAIN
2 APPLICATION/OCTET-STREAM
3 MESSAGE/RFC822
3.HEADER ([RFC-822] header of the message)
3.TEXT ([RFC-822] text body of the message)
3.1 TEXT/PLAIN
3.2 APPLICATION/OCTET-STREAM
4 MULTIPART/MIXED
4.1 IMAGE/GIF
4.1.MIME ([MIME-IMB] header for the IMAGE/GIF)
4.2 MESSAGE/RFC822
4.2.HEADER ([RFC-822] header of the message)
4.2.TEXT ([RFC-822] text body of the message)
4.2.1 TEXT/PLAIN
4.2.2 MULTIPART/ALTERNATIVE
4.2.2.1 TEXT/PLAIN
4.2.2.2 TEXT/RICHTEXT
You can also fetch a substring of the designated text ๐ท. To do that, add an open angle bracket (<), the octet position of the first octet you want, a period, the maximum number of octets you want, and a close angle bracket (>) to the part specifier. If the starting octet is beyond the end of the text, you get back an empty string ๐ซง.
Any partial fetch that tries to read past the end of the text gets truncated as needed ๐. A partial fetch that starts at octet 0 comes back as a partial fetch, even if that truncation happened ๐ญ.
Note: this means thatBODY[]<0.2048>of a 1500-octet message will returnBODY[]<0>with a literal of size 1500, notBODY[].
Note: a substring fetch of aHEADER.FIELDSorHEADER.FIELDS.NOTpart specifier is calculated after the header has been subset ๐ง.
The \Seen flag gets set implicitly ๐. If that changes the flags, they SHOULD be included as part of the FETCH responses โจ.
BODY.PEEK[<section>]<<partial>>is an alternate form ofBODY[<section>]that does not set the\Seenflag ๐.BODYSTRUCTUREis the [MIME-IMB] body structure of the message ๐ฆ. The server works it out by parsing the [MIME-IMB] header fields in the [RFC-822] header and the [MIME-IMB] headers ๐ธ.ENVELOPEis the envelope structure of the message ๐. The server builds it by parsing the [RFC-822] header into its component parts, filling in default values for various fields where needed ๐.FASTis a macro that means(FLAGS INTERNALDATE RFC822.SIZE)โก.FLAGSgives you the flags that are set for this message ๐ฉ.FULLis a macro that means(FLAGS INTERNALDATE RFC822.SIZE ENVELOPE BODY)๐.INTERNALDATEis the internal date of the message ๐๏ธ.RFC822is functionally equivalent toBODY[], but the untagged FETCH data comes back in theRFC822syntax ๐.RFC822.HEADERis functionally equivalent toBODY.PEEK[HEADER], but the untagged FETCH data comes back asRFC822.HEADER๐ง.RFC822.SIZEis the [RFC-822] size of the message ๐.RFC822.TEXTis functionally equivalent toBODY[TEXT], but the untagged FETCH data comes back asRFC822.TEXT๐.UIDis the unique identifier for the message ๐.
Here's an example ๐:
C: A654 FETCH 2:4 (FLAGS BODY[HEADER.FIELDS (DATE FROM)])
S: * 2 FETCH ....
S: * 3 FETCH ....
S: * 4 FETCH ....
S: A654 OK FETCH completed
6.4.6. STORE Command โจ
Arguments: message set
message data item name
value for message data item
Responses: untagged responses: FETCH
Result: OK - store completed
NO - store error: can't store that data
BAD - command unknown or arguments invalid
the STORE command changes data associated with a message in the mailbox ๐ ๏ธ. Normally, STORE sends back the updated value of the data in an untagged FETCH response ๐. Add a .SILENT suffix to the data item name and the untagged FETCH gets skipped ๐คซ. In that case the server SHOULD assume that the client has worked out the updated value itself, or doesn't care about it ๐ซถ.
Note: whether or not you use the .SILENT suffix, the server SHOULD send an untagged FETCH response if it notices a change to a message's flags from an external source ๐. The point is that the flag status is always clear, with no race condition ๐ฅ.
The data items you can currently store are:
FLAGS <flag list>replaces the flags for the message with the argument ๐ . The new value of the flags comes back as if you had done a FETCH of those flags ๐.FLAGS.SILENT <flag list>is the same asFLAGS, but it doesn't return a new value ๐คซ.+FLAGS <flag list>adds the argument to the flags for the message โ. The new value comes back as if you had done a FETCH of those flags ๐ธ.+FLAGS.SILENT <flag list>is the same as+FLAGS, but without a new value returned ๐ฆ.-FLAGS <flag list>removes the argument from the flags for the message โ. The new value comes back as if you had done a FETCH of those flags ๐ง.-FLAGS.SILENT <flag list>is the same as-FLAGS, but without a new value returned ๐.
Here's an example ๐:
C: A003 STORE 2:4 +FLAGS (\Deleted)
S: * 2 FETCH FLAGS (\Deleted \Seen)
S: * 3 FETCH FLAGS (\Deleted)
S: * 4 FETCH FLAGS (\Deleted \Flagged \Seen)
S: A003 OK STORE completed
6.4.7. COPY Command โจ
Arguments: message set
mailbox name
Responses: no specific responses for this command
Result: OK - copy completed
NO - copy error: can't copy those messages or to that
name
BAD - command unknown or arguments invalid
the COPY command copies the specified message(s) to the end of the specified destination mailbox ๐ฆโจ. The flags and internal date of the message(s) SHOULD be preserved in the copy ๐.
If the destination mailbox doesn't exist, a server SHOULD return an error ๐
โโ๏ธ. It SHOULD NOT create the mailbox automatically ๐ซ. Unless it's certain the destination mailbox can't be created, the server MUST send the response code [TRYCREATE] as the prefix of the text of the tagged NO response ๐. That's a hint for the client that it can try a CREATE command and then retry the COPY if the CREATE works ๐ง.
If the COPY command fails for any reason, server implementations MUST restore the destination mailbox to its state from before the COPY attempt ๐๐.
Here's an example ๐:
C: A003 COPY 2:4 MEETING
S: A003 OK COPY completed
6.4.8. UID Command โจ
- Arguments:
command name,command arguments - Responses: untagged responses:
FETCH,SEARCH - Result:
OK - UID command completed,NO - UID command error,BAD - command unknown or arguments invalid
okay so the UID command comes in two forms ๐ In the first one, you give it a COPY, FETCH, or STORE command with the arguments that command normally takes. The only difference is that the numbers in the message set are unique identifiers instead of message sequence numbers ๐ฆ
The second form takes a SEARCH command with SEARCH arguments. They're read the same way as a regular SEARCH, but the numbers in the SEARCH response are unique identifiers instead of message sequence numbers. For example, UID SEARCH 1:100 UID 443:557 gives you the unique identifiers for the intersection of the message sequence number set 1:100 and the UID set 443:557 ๐ง
Message set ranges are allowed, but unique identifiers are not guaranteed to be contiguous, so don't expect them to line up neatly ๐ If a unique identifier in a range doesn't exist, it gets ignored and no error message is generated. Quietly skipped, no drama ๐
One thing to keep straight: the number after the "*" in an untagged FETCH response is always a message sequence number, not a unique identifier, even when it's a response to a UID command ๐ Still, server implementations MUST implicitly include the UID message data item in any FETCH response caused by a UID command, whether or not the client asked for a UID as a message data item in the FETCH. Iconic behaviour, no notes ๐
Example:
C: A999 UID FETCH 4827313:4828442 FLAGS
S: * 23 FETCH (FLAGS (\Seen) UID 4827313)
S: * 24 FETCH (FLAGS (\Seen) UID 4827943)
S: * 25 FETCH (FLAGS (\Seen) UID 4828442)
S: A999 UID FETCH completed
6.5. Client Commands - Experimental/Expansion ๐
6.5.1. X<atom> Command ๐งช
- Arguments: implementation defined
- Responses: implementation defined
- Result:
OK - command completed,NO - failure,BAD - command unknown or arguments invalid
so any command starting with an X is an experimental command ๐งช Anything that isn't part of this specification, a standard or standards-track revision of it, or an IESG-approved experimental protocol MUST use the X prefix. Main character energy for sure, lowkey the vibe is "label your experiments" ๐
Any untagged responses added by an experimental command MUST also be prefixed with an X. And server implementations MUST NOT send any of those untagged responses unless the client asked for them by issuing the matching experimental command. Consent is everything ๐ซถ
Example:
C: a441 CAPABILITY
S: * CAPABILITY IMAP4rev1 AUTH=KERBEROS_V4 XPIG-LATIN
S: a441 OK CAPABILITY completed
C: A442 XPIG-LATIN
S: * XPIG-LATIN ow-nay eaking-spay ig-pay atin-lay
S: A442 OK XPIG-LATIN ompleted-cay
7. Server Responses ๐
okay so server responses come in three forms: status responses, server data, and command continuation requests ๐ธ The info in a server response (the stuff labelled "Contents:" in the descriptions below) is explained by what it means, not by how it's written. The exact syntax lives in the Formal Syntax section, so look there if you want the nitty gritty ๐ค
The client MUST be prepared to accept any response at all times. Literally always, no exceptions ๐ญ
Status responses can be tagged or untagged. Tagged ones tell you the result (OK, NO, or BAD) of a client command, and they carry the same tag as that command ๐
Some status responses, and all server data, are untagged. Untagged responses start with the token * instead of a tag. They show the server greeting, or server status that doesn't finish a command (like an impending system shutdown alert) ๐จ Historically, untagged server data gets called "unsolicited data," though technically only unilateral server data is truly unsolicited ๐
Certain server data MUST be recorded by the client when it arrives, and the description of that data will say so. This stuff is critical, because it changes how every later command and response gets read, like updates about messages being created or destroyed ๐
Other server data SHOULD be recorded for later reference. If the client doesn't need to keep it, or there's no obvious reason to record it (like a SEARCH response when no SEARCH command is in progress), the data SHOULD be ignored ๐งน
Here's an example of unilateral untagged server data: when the IMAP connection is in the selected state, the server checks the mailbox for new messages as part of running a command ๐ฆ Usually that check happens with every command, so a NOOP command is enough to look for new messages. If it finds some, the server sends untagged EXISTS and RECENT responses showing the new mailbox size โจ Server implementations that let several agents access the same mailbox at once SHOULD also send the right unilateral untagged FETCH and EXPUNGE responses when another agent changes message flags or expunges messages. Group chat, but make it server edition ๐ฌ
Command continuation request responses use the token + instead of a tag. The server sends these to say it accepts an incomplete client command and is ready for the rest of it ๐ง
7.1. Server Responses - Status Responses ๐
Status responses are OK, NO, BAD, PREAUTH and BYE. OK, NO, and BAD can be tagged or untagged. PREAUTH and BYE are always untagged ๐
Status responses MAY include an OPTIONAL "response code." A response code is data in square brackets, made of an atom and maybe a space plus some arguments ๐ It carries extra info or status codes for client software beyond the OK/NO/BAD result, and it's only defined when there's a specific action a client can take based on that extra info ๐ง
The currently defined response codes are:
- ALERT: The human-readable text has a special alert that MUST be presented to the user in a way that grabs their attention ๐จ
- NEWNAME: Followed by a mailbox name and a new mailbox name. A SELECT or EXAMINE is failing because the target mailbox name doesn't exist anymore, since it was renamed to the new mailbox name. It's a hint that the operation can work if you reissue the SELECT or EXAMINE with the new name ๐
- PARSE: The human-readable text is an error in parsing the [RFC-822] header or [MIME-IMB] headers of a message in the mailbox ๐จ
- PERMANENTFLAGS: Followed by a parenthesized list of flags, showing which of the known flags the client can change permanently. Any flag that's in the FLAGS untagged response but not in the PERMANENTFLAGS list can not be set permanently. If the client tries to STORE a flag that isn't in the PERMANENTFLAGS list, the server will either reject it with a NO reply or store the state for the rest of the current session only ๐
โโ๏ธ The PERMANENTFLAGS list can also include the special flag
\*, which means you can create new keywords by trying to store those flags in the mailbox โจ - READ-ONLY: The mailbox is selected read-only, or its access changed from read-write to read-only ๐
- READ-WRITE: The mailbox is selected read-write, or its access changed from read-only to read-write โ๏ธ
- TRYCREATE: An APPEND or COPY is failing because the target mailbox doesn't exist (as opposed to some other reason). It's a hint that the operation can work if you CREATE the mailbox first ๐ ๏ธ
- UIDVALIDITY: Followed by a decimal number, showing the unique identifier validity value ๐ข
- UNSEEN: Followed by a decimal number, showing the number of the first message without the
\Seenflag set ๐๏ธ
Additional response codes defined by particular client or server implementations SHOULD be prefixed with an "X" until they're added to a revision of this protocol. Client implementations SHOULD ignore response codes they don't recognize ๐ซถ
7.1.1. OK Response ๐
- Contents: OPTIONAL response code, human-readable text
the OK response is an information message from the server ๐ When it's tagged, it means the associated command finished successfully. The human-readable text MAY be shown to the user as an information message. The untagged form is info only, and the nature of the info MAY be shown with a response code ๐ธ
The untagged form also shows up as one of three possible greetings at connection startup. It tells you the connection isn't authenticated yet and a LOGIN command is needed ๐
Example:
S: * OK IMAP4rev1 server ready
C: A001 LOGIN fred blurdybloop
S: * OK [ALERT] System shutdown in 10 minutes
S: A001 OK LOGIN Completed
7.1.2. NO Response ๐ โโ๏ธ
- Contents: OPTIONAL response code, human-readable text
the NO response is an operational error message from the server ๐ฌ When it's tagged, the associated command did not finish successfully. The untagged form is a warning, and the command can still complete successfully anyway ๐ค The human-readable text describes what's going on ๐
Example:
C: A222 COPY 1:2 owatagusiam
S: * NO Disk is 98% full, please delete unnecessary data
S: A222 OK COPY completed
C: A223 COPY 3:200 blurdybloop
S: * NO Disk is 98% full, please delete unnecessary data
S: * NO Disk is 99% full, please delete unnecessary data
S: A223 NO COPY failed: disk is full
7.1.3. BAD Response ๐
- Contents: OPTIONAL response code, human-readable text
the BAD response is an error message from the server ๐ซ When it's tagged, it reports a protocol-level error in the client's command, and the tag tells you which command caused it. The untagged form is a protocol-level error where the command can't be figured out, and it can also mean an internal server failure ๐ง The human-readable text describes the condition ๐
Example:
C: ...very long command line...
S: * BAD Command line too long
C: ...empty line...
S: * BAD Empty command line
C: A443 EXPUNGE
S: * BAD Disk crash, attempting salvage to a new disk!
S: * OK Salvage successful, no data lost
S: A443 OK Expunge completed
7.1.4. PREAUTH Response
Contents: OPTIONAL response code, human-readable text
okay so the PREAUTH response is ALWAYS untagged ๐ and it's one of three possible greetings when you first connect ๐ง it basically says "hey, this connection is already authenticated by some outside method," so no LOGIN command is needed. main character energy, no login screen ๐
Example: S: * PREAUTH IMAP4rev1 server logged in as Smith โจ
7.1.5. BYE Response
Contents: OPTIONAL response code, human-readable text
bestie, the BYE response is always untagged, and it means the server is about to close the connection ๐ฅ the human-readable text MAY be shown to the user in a status report by the client ๐ there are four situations where you'll get a BYE:
- as part of a normal logout sequence. the server will close the connection after sending the tagged OK response to the LOGOUT command ๐ซถ
- as a panic shutdown announcement. the server closes the connection immediately ๐ญ
- as an announcement of an inactivity autologout. the server closes the connection immediately ๐
- as one of three possible greetings at connection startup, saying the server is not willing to accept a connection from this client. the server closes the connection immediately ๐
the tea is that the difference between a BYE from a normal LOGOUT (case 1) and a BYE from a failure (cases 2, 3 and 4) is just that in the failure cases the connection closes right away ๐ฅ
Example: S: * BYE Autologout; idle for too long ๐ธ
7.2. Server Responses - Server and Mailbox Status
these responses are always untagged ๐ฆ this is how server and mailbox status data gets sent from the server to the client ๐ง a lot of them usually come back from a command with the same name, so it's giving dรฉjร vu ๐
7.2.1. CAPABILITY Response
Contents: capability listing
the CAPABILITY response shows up as a result of a CAPABILITY command ๐ the capability listing is a space-separated list of capability names the server supports. the capability listing MUST include the atom "IMAP4rev1" ๐
a capability name that begins with "AUTH=" tells you the server supports that particular authentication mechanism ๐
other capability names mean the server supports an extension, revision, or amendment to the IMAP4rev1 protocol ๐ server responses MUST conform to this document until the client issues a command that uses the associated capability โจ
capability names MUST either begin with "X" or be standard or standards-track IMAP4rev1 extensions, revisions, or amendments registered with IANA ๐ซถ a server MUST NOT offer unregistered or non-standard capability names, unless those names are prefixed with an "X" ๐ โโ๏ธ
client implementations SHOULD NOT require any capability name other than "IMAP4rev1", and they MUST ignore any unknown capability names ๐
Example: S: * CAPABILITY IMAP4rev1 AUTH=KERBEROS_V4 XPIG-LATIN ๐ท
7.2.2. LIST Response
Contents: name attributes, hierarchy delimiter, name
the LIST response occurs as a result of a LIST command ๐ธ it returns a single name that matches the LIST specification. there can be MULTIPLE LIST responses for one LIST command ๐
okay, four name attributes are defined:
\Noinferiors: it is not possible for any child levels of hierarchy to exist under this name. no child levels exist now and none can be created in the future ๐ซ
\Noselect: it is not possible to use this name as a selectable mailbox ๐
\Marked: the server has marked the mailbox as "interesting". it probably has messages added since the last time it was selected ๐
\Unmarked: the mailbox doesn't have any additional messages since the last time it was selected โจ
if it isn't feasible for the server to figure out whether the mailbox is "interesting" or not, or if the name is a \Noselect name, the server SHOULD NOT send either \Marked or \Unmarked ๐ซ
the hierarchy delimiter is the character used to separate levels of hierarchy in a mailbox name ๐๏ธ clients use it to create child mailboxes and to search higher or lower levels of the naming hierarchy ๐ all children of a top-level hierarchy node MUST use the same separator character ๐ a NIL hierarchy delimiter means there's no hierarchy at all, and the name is a "flat" name ๐ฅ
the name represents an unambiguous left-to-right hierarchy, and it MUST be valid for use as a reference in LIST and LSUB commands ๐งญ unless \Noselect is indicated, the name MUST also be valid as an argument for commands, such as SELECT, that accept mailbox names ๐
Example: S: * LIST (\Noselect) "/" ~/Mail/foo ๐ฌ
7.2.3. LSUB Response
Contents: name attributes, hierarchy delimiter, name
the LSUB response occurs as a result of an LSUB command ๐ฆ it returns a single name that matches the LSUB specification. there can be multiple LSUB responses for a single LSUB command ๐ the data is identical in format to the LIST response, so you already know how to read it ๐
Example: S: * LSUB () "." #news.comp.mail.misc ๐ฐ
7.2.4 STATUS Response
Contents: name, status parenthesized list
the STATUS response occurs as a result of a STATUS command ๐ท it returns the mailbox name that matches the STATUS specification, plus the requested mailbox status information ๐
Example: S: * STATUS blurdybloop (MESSAGES 231 UIDNEXT 44292) ๐ง
7.2.5. SEARCH Response
Contents: zero or more numbers
the SEARCH response occurs as a result of a SEARCH or UID SEARCH command ๐ the numbers refer to the messages that match your search criteria. for SEARCH these are message sequence numbers, and for UID SEARCH these are unique identifiers ๐ each number is delimited by a space ๐ซง
Example: S: * SEARCH 2 3 6 ๐
7.2.6. FLAGS Response
Contents: flag parenthesized list
the FLAGS response occurs as a result of a SELECT or EXAMINE command ๐ฉ the flag parenthesized list tells you which flags apply to this mailbox (at a minimum, the system-defined flags). other flags can exist too, depending on the server implementation ๐
the update from the FLAGS response MUST be recorded by the client ๐
Example: S: * FLAGS (\Answered \Flagged \Deleted \Seen \Draft) ๐
7.3. Server Responses - Mailbox Size
these responses are always untagged ๐ธ this is how changes in the size of the mailbox get sent from the server to the client ๐ right after the "*" token there's a number that represents a message count ๐ข
7.3.1. EXISTS Response
Contents: none
the EXISTS response reports how many messages are in the mailbox ๐ it occurs as a result of a SELECT or EXAMINE command, and also whenever the size of the mailbox changes (e.g. new mail) ๐ฌ
the update from the EXISTS response MUST be recorded by the client ๐
Example: S: * 23 EXISTS โจ
7.3.2. RECENT Response
Contents: none
the RECENT response reports how many messages have the \Recent flag set ๐ it occurs as a result of a SELECT or EXAMINE command, and whenever the size of the mailbox changes (e.g. new mail) ๐จ
Note: it is NOT guaranteed that the message sequence numbers of recent messages form a contiguous range of the highest n messages in the mailbox (where n is the value reported by the RECENT response). situations where this isn't the case include multiple clients having the same mailbox open (the first session to be notified will see it as recent, while the others will probably see it as non-recent), and when the mailbox is re-ordered by a non-IMAP agent ๐ณ
the only reliable way to find recent messages is to look at the message flags and see which ones have the \Recent flag set, or to do a SEARCH RECENT ๐
the update from the RECENT response MUST be recorded by the client ๐ซถ
Example: S: * 5 RECENT ๐
7.4. Server Responses - Message Status
these responses are always untagged ๐ฆ this is how message data gets sent from the server to the client, often as a result of a command with the same name ๐ right after the "*" token there's a number that represents a message sequence number ๐ข
7.4.1. EXPUNGE Response
Contents: none
the EXPUNGE response reports that the specified message sequence number has been permanently removed from the mailbox ๐๏ธ the message sequence number for each message after it is immediately decremented by 1, and that decrement shows up in message sequence numbers in later responses (including other untagged EXPUNGE responses) ๐งฎ
because of that immediate decrement rule, the message sequence numbers in a bunch of successive EXPUNGE responses depend on whether messages get removed from lower numbers to higher numbers, or from higher numbers to lower numbers ๐ for example, if the last 5 messages in a 9-message mailbox get expunged, a "lower to higher" server will send five untagged EXPUNGE responses for message sequence number 5, while a "higher to lower server" will send successive untagged EXPUNGE responses for message sequence numbers 9, 8, 7, 6, and 5 ๐ข
an EXPUNGE response MUST NOT be sent when no command is in progress, and it MUST NOT be sent while responding to a FETCH, STORE, or SEARCH command ๐ซ this rule is necessary to prevent the message sequence numbers between client and server from falling out of sync ๐ญ
the update from the EXPUNGE response MUST be recorded by the client ๐
Example: S: * 44 EXPUNGE ๐
7.4.2. FETCH Response
Contents: message data
the FETCH response returns data about a message to the client ๐ฅ the data comes as pairs of data item names and their values, in parentheses ๐ง this response happens as the result of a FETCH or STORE command, and also when the server decides to send it on its own (e.g. flag updates) ๐
the current data items are:
BODY: a form of BODYSTRUCTURE without extension data ๐งฑ
BODY[<section>]<<origin_octet>>: a string expressing the body contents of the specified section. the string SHOULD be interpreted by the client according to the content transfer encoding, body type, and subtype ๐ค
if the origin octet is specified, this string is a substring of the entire body contents, starting at that origin octet. this means that BODY[]<0> MAY be truncated, but BODY[] is NEVER truncated ๐ซฃ
8-bit textual data is permitted if a [CHARSET] identifier is part of the body parameter parenthesized list for this section. Heads up though: headers (the part specifiers HEADER or MIME, or the header portion of a MESSAGE/RFC822 part) MUST be 7-bit, so 8-bit characters are not allowed in headers. Also, the blank line at the end of the header is always included in header data. ๐
Non-textual data like binary data MUST be transfer encoded into a textual form such as BASE64 before it gets sent to the client. To get the original binary back, the client MUST decode the transfer encoded string. ๐ซถ
- BODYSTRUCTURE ๐ฆ A parenthesized list that describes the [MIME-IMB] body structure of a message. The server computes it by parsing the [MIME-IMB] header fields and filling in defaults for various fields as needed.
For example, a simple text message of 48 lines and 2279 octets can have a body structure of:
("TEXT" "PLAIN" ("CHARSET" "US-ASCII") NIL NIL "7BIT" 2279 48)
Multiple parts are shown by parenthesis nesting. Instead of a body type as the first element of the parenthesized list, there's a nested body. The second element of the parenthesized list is the multipart subtype (mixed, digest, parallel, alternative, etc.). Iconic. ๐
For example, a two part message made up of a text part and a BASE645-encoded text attachment can have a body structure of:
(("TEXT" "PLAIN" ("CHARSET" "US-ASCII") NIL NIL "7BIT" 1152 23)("TEXT" "PLAIN"
("CHARSET" "US-ASCII" "NAME" "cc.diff")
"<960723163407.20117h@cac.washington.edu>"
"Compiler diff" "BASE64" 4554 73) "MIXED"))
Extension data follows the multipart subtype. Extension data is never returned with the BODY fetch, but it can be returned with a BODYSTRUCTURE fetch. Extension data, if present, MUST be in the defined order. ๐
The extension data of a multipart body part comes in the following order:
- body parameter parenthesized list A parenthesized list of attribute/value pairs, like
("foo" "bar" "baz" "rag")where "bar" is the value of "foo" and "rag" is the value of "baz", as defined in [MIME-IMB]. - body disposition A parenthesized list made of a disposition type string followed by a parenthesized list of disposition attribute/value pairs. The disposition type and attribute names will be defined in a future standards-track revision to [DISPOSITION]. ๐ธ
- body language A string or parenthesized list giving the body language value as defined in [LANGUAGE-TAGS].
Any following extension data isn't defined yet in this version of the protocol. That extension data can be zero or more NILs, strings, numbers, or potentially nested parenthesized lists of that stuff. Client implementations that do a BODYSTRUCTURE fetch MUST be prepared to accept such extension data. Server implementations MUST NOT send such extension data until it has been defined by a revision of this protocol. ๐
The basic fields of a non-multipart body part come in the following order:
- body type A string giving the content media type name as defined in [MIME-IMB].
- body subtype A string giving the content subtype name as defined in [MIME-IMB].
- body parameter parenthesized list A parenthesized list of attribute/value pairs, like
("foo" "bar" "baz" "rag")where "bar" is the value of "foo" and "rag" is the value of "baz", as defined in [MIME-IMB]. - body id A string giving the content id as defined in [MIME-IMB].
- body description A string giving the content description as defined in [MIME-IMB].
- body encoding A string giving the content transfer encoding as defined in [MIME-IMB].
- body size A number giving the size of the body in octets. This size is the size in its transfer encoding, not the resulting size after any decoding. ๐
A body type of type MESSAGE and subtype RFC822 contains, right after the basic fields, the envelope structure, body structure, and size in text lines of the encapsulated message.
A body type of type TEXT contains, right after the basic fields, the size of the body in text lines. This size is the size in its content transfer encoding, not the resulting size after any decoding. โจ
Extension data follows the basic fields and the type-specific fields listed above. Extension data is never returned with the BODY fetch, but it can be returned with a BODYSTRUCTURE fetch. Extension data, if present, MUST be in the defined order.
The extension data of a non-multipart body part comes in the following order:
- body MD5 A string giving the body MD5 value as defined in [MD5].
- body disposition A parenthesized list with the same content and function as the body disposition for a multipart body part.
- body language A string or parenthesized list giving the body language value as defined in [LANGUAGE-TAGS].
Any following extension data isn't defined yet in this version of the protocol, and it works the same way as the multipart extension data described above. ๐
- ENVELOPE ๐ A parenthesized list that describes the envelope structure of a message. The server computes it by parsing the [RFC-822] header into its component parts, filling in defaults for various fields as needed.
The fields of the envelope structure come in the following order: date, subject, from, sender, reply-to, to, cc, bcc, in-reply-to, and message-id. The date, subject, in-reply-to, and message-id fields are strings. The from, sender, reply-to, to, cc, and bcc fields are parenthesized lists of address structures.
An address structure is a parenthesized list that describes an electronic mail address. Its fields come in the following order: personal name, [SMTP] at-domain-list (source route), mailbox name, and host name. ๐ฎ
[RFC-822] group syntax is shown by a special form of address structure where the host name field is NIL. If the mailbox name field is also NIL, that's an end of group marker (semi-colon in RFC 822 syntax). If the mailbox name field is non-NIL, that's a start of group marker, and the mailbox name field holds the group name phrase. ๐ง
Any field of an envelope or address structure that doesn't apply is presented as NIL. The server MUST default the reply-to and sender fields from the from field; a client isn't expected to know to do this. Main character energy from the server. ๐ฅ
- FLAGS ๐ A parenthesized list of flags that are set for this message.
- INTERNALDATE A string representing the internal date of the message.
- RFC822 Equivalent to BODY[].
- RFC822.HEADER Equivalent to BODY.PEEK[HEADER].
- RFC822.SIZE A number expressing the [RFC-822] size of the message.
- RFC822.TEXT Equivalent to BODY[TEXT].
- UID A number expressing the unique identifier of the message.
Example:
S: * 23 FETCH (FLAGS (\Seen) RFC822.SIZE 44827)
7.5. Server Responses - Command Continuation Request ๐ฆ
The command continuation request response is shown by a "+" token instead of a tag. This response means the server is ready to accept the client's continuation of a command. The rest of this response is a line of text. ๐ธ
This response is used in the AUTHORIZATION command to send server data to the client and ask for more client data. It's also used when any command argument is a literal. ๐
The client is not permitted to send the octets of the literal unless the server says it expects them. This lets the server process commands and reject errors on a line-by-line basis. The rest of the command, including the CRLF that ends a command, follows the octets of the literal. If there are any more command arguments, the literal octets are followed by a space and those arguments. ๐
Example:
C: A001 LOGIN {11}
S: + Ready for additional command text
C: FRED FOOBAR {7}
S: + Ready for additional command text
C: fat man
S: A001 OK LOGIN completed
C: A044 BLURDYBLOOP {102856}
S: A044 BAD No such command as "BLURDYBLOOP"
8. Sample IMAP4rev1 connection ๐
The following is a transcript of an IMAP4rev1 connection. A long line in this sample is broken up for editorial clarity. ๐
8. Sample IMAP4rev1 connection โจ
okay so here's a whole conversation from start to finish ๐ the C: lines are the client talking and the S: lines are the server answering. every command gets a tag like a001, and the server's reply uses the same tag so you can match them up ๐
S: * OK IMAP4rev1 Service Ready
C: a001 login mrc secret
S: a001 OK LOGIN completed
C: a002 select inbox
S: * 18 EXISTS
S: * FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
S: * 2 RECENT
S: * OK [UNSEEN 17] Message 17 is the first unseen message
S: * OK [UIDVALIDITY 3857529045] UIDs valid
S: a002 OK [READ-WRITE] SELECT completed
C: a003 fetch 12 full
S: * 12 FETCH (FLAGS (\Seen) INTERNALDATE "17-Jul-1996 02:44:25 -0700"
RFC822.SIZE 4286 ENVELOPE ("Wed, 17 Jul 1996 02:23:25 -0700 (PDT)"
"IMAP4rev1 WG mtg summary and minutes"
(("Terry Gray" NIL "gray" "cac.washington.edu"))
(("Terry Gray" NIL "gray" "cac.washington.edu"))
(("Terry Gray" NIL "gray" "cac.washington.edu"))
((NIL NIL "imap" "cac.washington.edu"))
((NIL NIL "minutes" "CNRI.Reston.VA.US")
("John Klensin" NIL "KLENSIN" "INFOODS.MIT.EDU")) NIL NIL
"<B27397-0100000@cac.washington.edu>")
BODY ("TEXT" "PLAIN" ("CHARSET" "US-ASCII") NIL NIL "7BIT" 3028 92))
S: a003 OK FETCH completed
C: a004 fetch 12 body[header]
S: * 12 FETCH (BODY[HEADER] {350}
S: Date: Wed, 17 Jul 1996 02:23:25 -0700 (PDT)
S: From: Terry Gray <gray@cac.washington.edu>
S: Subject: IMAP4rev1 WG mtg summary and minutes
S: To: imap@cac.washington.edu
S: cc: minutes@CNRI.Reston.VA.US, John Klensin <KLENSIN@INFOODS.MIT.EDU>
S: Message-Id: <B27397-0100000@cac.washington.edu>
S: MIME-Version: 1.0
S: Content-Type: TEXT/PLAIN; CHARSET=US-ASCII
S:
S: )
S: a004 OK FETCH completed
C: a005 store 12 +flags \deleted
S: * 12 FETCH (FLAGS (\Seen \Deleted))
S: a005 OK +FLAGS completed
C: a006 logout
S: * BYE IMAP4rev1 server terminating connection
S: a006 OK LOGOUT completed
9. Formal Syntax โจ
okay bestie, the grammar is written in augmented BNF from [RFC-822], with ONE twist: the # construct uses a single space (SPACE) as its delimiter instead of one or more commas ๐ง
when two rules overlap and a later one could match the same text as an earlier one, the rule that's listed earlier MUST take priority ๐ for example, "\Seen" parsed as a flag is the \Seen flag name and not a flag_extension, even though it could be parsed as a flag_extension. not every overlap is called out below, so keep this in mind ๐
alphabetic characters are case-insensitive unless the grammar says otherwise, and using upper or lower case to write token strings is just for editorial clarity ๐ implementations MUST accept these strings in a case-insensitive fashion ๐ซถ
address ::= "(" addr_name SPACE addr_adl SPACE addr_mailbox
SPACE addr_host ")"
addr_adl ::= nstring
;; Holds route from [RFC-822] route-addr if
;; non-NIL
addr_host ::= nstring
;; NIL indicates [RFC-822] group syntax.
;; Otherwise, holds [RFC-822] domain name
addr_mailbox ::= nstring
;; NIL indicates end of [RFC-822] group; if
;; non-NIL and addr_host is NIL, holds
;; [RFC-822] group name.
;; Otherwise, holds [RFC-822] local-part
addr_name ::= nstring
;; Holds phrase from [RFC-822] mailbox if
;; non-NIL
alpha ::= "A" / "B" / "C" / "D" / "E" / "F" / "G" / "H" /
"I" / "J" / "K" / "L" / "M" / "N" / "O" / "P" /
"Q" / "R" / "S" / "T" / "U" / "V" / "W" / "X" /
"Y" / "Z" /
"a" / "b" / "c" / "d" / "e" / "f" / "g" / "h" /
"i" / "j" / "k" / "l" / "m" / "n" / "o" / "p" /
"q" / "r" / "s" / "t" / "u" / "v" / "w" / "x" /
"y" / "z"
;; Case-sensitive
append ::= "APPEND" SPACE mailbox [SPACE flag_list]
[SPACE date_time] SPACE literal
astring ::= atom / string
atom ::= 1*ATOM_CHAR
ATOM_CHAR ::= <any CHAR except atom_specials>
atom_specials ::= "(" / ")" / "{" / SPACE / CTL / list_wildcards /
quoted_specials
authenticate ::= "AUTHENTICATE" SPACE auth_type *(CRLF base64)
auth_type ::= atom
;; Defined by [IMAP-AUTH]
base64 ::= *(4base64_char) [base64_terminal]
base64_char ::= alpha / digit / "+" / "/"
base64_terminal ::= (2base64_char "==") / (3base64_char "=")
body ::= "(" body_type_1part / body_type_mpart ")"
body_extension ::= nstring / number / "(" 1#body_extension ")"
;; Future expansion. Client implementations
;; MUST accept body_extension fields. Server
;; implementations MUST NOT generate
;; body_extension fields except as defined by
;; future standard or standards-track
;; revisions of this specification.
body_ext_1part ::= body_fld_md5 [SPACE body_fld_dsp
[SPACE body_fld_lang
[SPACE 1#body_extension]]]
;; MUST NOT be returned on non-extensible
;; "BODY" fetch
body_ext_mpart ::= body_fld_param
[SPACE body_fld_dsp SPACE body_fld_lang
[SPACE 1#body_extension]]
;; MUST NOT be returned on non-extensible
;; "BODY" fetch
body_fields ::= body_fld_param SPACE body_fld_id SPACE
body_fld_desc SPACE body_fld_enc SPACE
body_fld_octets
body_fld_desc ::= nstring
body_fld_dsp ::= "(" string SPACE body_fld_param ")" / nil
body_fld_enc ::= (<"> ("7BIT" / "8BIT" / "BINARY" / "BASE64"/
"QUOTED-PRINTABLE") <">) / string
body_fld_id ::= nstring
body_fld_lang ::= nstring / "(" 1#string ")"
body_fld_lines ::= number
body_fld_md5 ::= nstring
body_fld_octets ::= number
body_fld_param ::= "(" 1#(string SPACE string) ")" / nil
body_type_1part ::= (body_type_basic / body_type_msg / body_type_text)
[SPACE body_ext_1part]
body_type_basic ::= media_basic SPACE body_fields
;; MESSAGE subtype MUST NOT be "RFC822"
body_type_mpart ::= 1*body SPACE media_subtype
[SPACE body_ext_mpart]
body_type_msg ::= media_message SPACE body_fields SPACE envelope
SPACE body SPACE body_fld_lines
body_type_text ::= media_text SPACE body_fields SPACE body_fld_lines
capability ::= "AUTH=" auth_type / atom
;; New capabilities MUST begin with "X" or be
;; registered with IANA as standard or
;; standards-track
capability_data ::= "CAPABILITY" SPACE [1#capability SPACE] "IMAP4rev1"
[SPACE 1#capability]
;; IMAP4rev1 servers which offer RFC 1730
;; compatibility MUST list "IMAP4" as the first
;; capability.
CHAR ::= <any 7-bit US-ASCII character except NUL,
0x01 - 0x7f>
CHAR8 ::= <any 8-bit octet except NUL, 0x01 - 0xff>
command ::= tag SPACE (command_any / command_auth /
command_nonauth / command_select) CRLF
;; Modal based on state
command_any ::= "CAPABILITY" / "LOGOUT" / "NOOP" / x_command
;; Valid in all states
command_auth ::= append / create / delete / examine / list / lsub /
rename / select / status / subscribe / unsubscribe
;; Valid only in Authenticated or Selected state
command_nonauth ::= login / authenticate
;; Valid only when in Non-Authenticated state
command_select ::= "CHECK" / "CLOSE" / "EXPUNGE" /
copy / fetch / store / uid / search
;; Valid only when in Selected state
continue_req ::= "+" SPACE (resp_text / base64)
copy ::= "COPY" SPACE set SPACE mailbox
CR ::= <ASCII CR, carriage return, 0x0D>
create ::= "CREATE" SPACE mailbox
;; Use of INBOX gives a NO error
CRLF ::= CR LF
CTL ::= <any ASCII control character and DEL,
0x00 - 0x1f, 0x7f>
date ::= date_text / <"> date_text <">
date_day ::= 1*2digit
;; Day of month
date_day_fixed ::= (SPACE digit) / 2digit
;; Fixed-format version of date_day
date_month ::= "Jan" / "Feb" / "Mar" / "Apr" / "May" / "Jun" /
"Jul" / "Aug" / "Sep" / "Oct" / "Nov" / "Dec"
date_text ::= date_day "-" date_month "-" date_year
date_year ::= 4digit
date_time ::= <"> date_day_fixed "-" date_month "-" date_year
SPACE time SPACE zone <">
delete ::= "DELETE" SPACE mailbox
;; Use of INBOX gives a NO error
digit ::= "0" / digit_nz
digit_nz ::= "1" / "2" / "3" / "4" / "5" / "6" / "7" / "8" /
"9"
envelope ::= "(" env_date SPACE env_subject SPACE env_from
SPACE env_sender SPACE env_reply_to SPACE env_to
SPACE env_cc SPACE env_bcc SPACE env_in_reply_to
SPACE env_message_id ")"
env_bcc ::= "(" 1*address ")" / nil
env_cc ::= "(" 1*address ")" / nil
env_date ::= nstring
env_from ::= "(" 1*address ")" / nil
env_in_reply_to ::= nstring
env_message_id ::= nstring
env_reply_to ::= "(" 1*address ")" / nil
env_sender ::= "(" 1*address ")" / nil
env_subject ::= nstring
env_to ::= "(" 1*address ")" / nil
examine ::= "EXAMINE" SPACE mailbox
fetch ::= "FETCH" SPACE set SPACE ("ALL" / "FULL" /
"FAST" / fetch_att / "(" 1#fetch_att ")")
fetch_att ::= "ENVELOPE" / "FLAGS" / "INTERNALDATE" /
"RFC822" [".HEADER" / ".SIZE" / ".TEXT"] /
"BODY" ["STRUCTURE"] / "UID" /
"BODY" [".PEEK"] section
["<" number "." nz_number ">"]
flag ::= "\Answered" / "\Flagged" / "\Deleted" /
"\Seen" / "\Draft" / flag_keyword / flag_extension
flag_extension ::= "\" atom
;; Future expansion. Client implementations
;; MUST accept flag_extension flags. Server
;; implementations MUST NOT generate
;; flag_extension flags except as defined by
;; future standard or standards-track
;; revisions of this specification.
flag_keyword ::= atom
flag_list ::= "(" #flag ")"
greeting ::= "*" SPACE (resp_cond_auth / resp_cond_bye) CRLF
header_fld_name ::= astring
header_list ::= "(" 1#header_fld_name ")"
LF ::= <ASCII LF, line feed, 0x0A>
list ::= "LIST" SPACE mailbox SPACE list_mailbox
list_mailbox ::= 1*(ATOM_CHAR / list_wildcards) / string
list_wildcards ::= "%" / "*"
literal ::= "{" number "}" CRLF *CHAR8
;; Number represents the number of CHAR8 octets
login ::= "LOGIN" SPACE userid SPACE password
lsub ::= "LSUB" SPACE mailbox SPACE list_mailbox
mailbox ::= "INBOX" / astring
;; INBOX is case-insensitive. All case variants of
;; INBOX (e.g. "iNbOx") MUST be interpreted as INBOX
;; not as an astring. Refer to section 5.1 for
;; further semantic details of mailbox names.
mailbox_data ::= "FLAGS" SPACE flag_list /
"LIST" SPACE mailbox_list /
"LSUB" SPACE mailbox_list /
"MAILBOX" SPACE text /
"SEARCH" [SPACE 1#nz_number] /
"STATUS" SPACE mailbox SPACE
"(" #<status_att number ")" /
number SPACE "EXISTS" / number SPACE "RECENT"
mailbox_list ::= "(" #("\Marked" / "\Noinferiors" /
"\Noselect" / "\Unmarked" / flag_extension) ")"
SPACE (<"> QUOTED_CHAR <"> / nil) SPACE mailbox
media_basic ::= (<"> ("APPLICATION" / "AUDIO" / "IMAGE" /
"MESSAGE" / "VIDEO") <">) / string)
SPACE media_subtype
;; Defined in [MIME-IMT]
media_message ::= <"> "MESSAGE" <"> SPACE <"> "RFC822" <">
;; Defined in [MIME-IMT]
media_subtype ::= string
;; Defined in [MIME-IMT]
media_text ::= <"> "TEXT" <"> SPACE media_subtype
;; Defined in [MIME-IMT]
message_data ::= nz_number SPACE ("EXPUNGE" /
("FETCH" SPACE msg_att))
msg_att ::= "(" 1#("ENVELOPE" SPACE envelope /
"FLAGS" SPACE "(" #(flag / "\Recent") ")" /
"INTERNALDATE" SPACE date_time /
"RFC822" [".HEADER" / ".TEXT"] SPACE nstring /
"RFC822.SIZE" SPACE number /
"BODY" ["STRUCTURE"] SPACE body /
"BODY" section ["<" number ">"] SPACE nstring /
"UID" SPACE uniqueid) ")"
nil ::= "NIL"
nstring ::= string / nil
number ::= 1*digit
;; Unsigned 32-bit integer
;; (0 <= n < 4,294,967,296)
nz_number ::= digit_nz *digit
;; Non-zero unsigned 32-bit integer
;; (0 < n < 4,294,967,296)
password ::= astring
quoted ::= <"> *QUOTED_CHAR <">
QUOTED_CHAR ::= <any TEXT_CHAR except quoted_specials> /
"\" quoted_specials
quoted_specials ::= <"> / "\"
rename ::= "RENAME" SPACE mailbox SPACE mailbox
;; Use of INBOX as a destination gives a NO error
response ::= *(continue_req / response_data) response_done
response_data ::= "*" SPACE (resp_cond_state / resp_cond_bye /
mailbox_data / message_data / capability_data)
CRLF
response_done ::= response_tagged / response_fatal
response_fatal ::= "*" SPACE resp_cond_bye CRLF
;; Server closes connection immediately
response_tagged ::= tag SPACE resp_cond_state CRLF
resp_cond_auth ::= ("OK" / "PREAUTH") SPACE resp_text
;; Authentication condition
resp_cond_bye ::= "BYE" SPACE resp_text
resp_cond_state ::= ("OK" / "NO" / "BAD") SPACE resp_text
;; Status condition
resp_text ::= ["[" resp_text_code "]" SPACE] (text_mime2 / text)
;; text SHOULD NOT begin with "[" or "="
resp_text_code ::= "ALERT" / "PARSE" /
"PERMANENTFLAGS" SPACE "(" #(flag / "\*") ")" /
"READ-ONLY" / "READ-WRITE" / "TRYCREATE" /
"UIDVALIDITY" SPACE nz_number /
"UNSEEN" SPACE nz_number /
atom [SPACE 1*<any TEXT_CHAR except "]">]
search ::= "SEARCH" SPACE ["CHARSET" SPACE astring SPACE]
1#search_key
;; [CHARSET] MUST be registered with IANA
search_key ::= "ALL" / "ANSWERED" / "BCC" SPACE astring /
"BEFORE" SPACE date / "BODY" SPACE astring /
"CC" SPACE astring / "DELETED" / "FLAGGED" /
"FROM" SPACE astring /
"KEYWORD" SPACE flag_keyword / "NEW" / "OLD" /
"ON" SPACE date / "RECENT" / "SEEN" /
"SINCE" SPACE date / "SUBJECT" SPACE astring /
"TEXT" SPACE astring / "TO" SPACE astring /
"UNANSWERED" / "UNDELETED" / "UNFLAGGED" /
"UNKEYWORD" SPACE flag_keyword / "UNSEEN" /
;; Above this line were in [IMAP2]
"DRAFT" /
"HEADER" SPACE header_fld_name SPACE astring /
"LARGER" SPACE number / "NOT" SPACE search_key /
"OR" SPACE search_key SPACE search_key /
"SENTBEFORE" SPACE date / "SENTON" SPACE date /
"SENTSINCE" SPACE date / "SMALLER" SPACE number /
"UID" SPACE set / "UNDRAFT" / set /
"(" 1#search_key ")"
section ::= "[" [section_text / (nz_number *["." nz_number]
["." (section_text / "MIME")])] "]"
section_text ::= "HEADER" / "HEADER.FIELDS" [".NOT"]
SPACE header_list / "TEXT"
select ::= "SELECT" SPACE mailbox
sequence_num ::= nz_number / "*"
;; * is the largest number in use. For message
;; sequence numbers, it is the number of messages
;; in the mailbox. For unique identifiers, it is
;; the unique identifier of the last message in
;; the mailbox.
set ::= sequence_num / (sequence_num ":" sequence_num) /
(set "," set)
;; Identifies a set of messages. For message
;; sequence numbers, these are consecutive
;; numbers from 1 to the number of messages in
;; the mailbox
;; Comma delimits individual numbers, colon
;; delimits between two numbers inclusive.
;; Example: 2,4:7,9,12:* is 2,4,5,6,7,9,12,13,
;; 14,15 for a mailbox with 15 messages.
SPACE ::= <ASCII SP, space, 0x20>
status ::= "STATUS" SPACE mailbox SPACE "(" 1#status_att ")"
status_att ::= "MESSAGES" / "RECENT" / "UIDNEXT" / "UIDVALIDITY" /
"UNSEEN"
store ::= "STORE" SPACE set SPACE store_att_flags
store_att_flags ::= (["+" / "-"] "FLAGS" [".SILENT"]) SPACE
(flag_list / #flag)
string ::= quoted / literal
subscribe ::= "SUBSCRIBE" SPACE mailbox
tag ::= 1*<any ATOM_CHAR except "+">
text ::= 1*TEXT_CHAR
text_mime2 ::= "=?" <charset> "?" <encoding> "?"
<encoded-text> "?="
;; Syntax defined in [MIME-HDRS]
TEXT_CHAR ::= <any CHAR except CR and LF>
time ::= 2digit ":" 2digit ":" 2digit
;; Hours minutes seconds
uid ::= "UID" SPACE (copy / fetch / search / store)
;; Unique identifiers used instead of message
;; sequence numbers
uniqueid ::= nz_number
;; Strictly ascending
unsubscribe ::= "UNSUBSCRIBE" SPACE mailbox
userid ::= astring
x_command ::= "X" atom <experimental command arguments>
zone ::= ("+" / "-") 4digit
;; Signed four-digit value of hhmm representing
;; hours and minutes west of Greenwich (that is,
;; (the amount that the given time differs from
;; Universal Time). Subtracting the timezone
;; from the given time will give the UT form.
;; The Universal Time zone is "+0000".
10. Author's Note ๐
okay so this whole document is a glow-up of older specs, and it literally supersedes them all ๐ โจ the ones it replaces are RFC 1730, the unpublished IMAP2bis.TXT document, RFC 1176, and RFC 1064. bye bye, old drafts ๐ซถ
11. Security Considerations ๐ฅ
bestie, this part is SERIOUS and i need you to hear me ๐ญ๐
IMAP4rev1 protocol transactions, including electronic mail data, are sent in the clear over the network unless privacy protection is negotiated in the AUTHENTICATE command. so yeah, your emails are basically postcards unless you negotiate privacy ๐๐ฎ
a server error message for an AUTHENTICATE command that fails because of invalid credentials SHOULD NOT detail why the credentials are invalid. don't give the attacker a hint, periodt ๐
using the LOGIN command sends passwords in the clear ๐ฌ you can avoid that by using the AUTHENTICATE command instead. main character move ๐
a server error message for a failing LOGIN command SHOULD NOT specify that the user name, as opposed to the password, is invalid. again, no hints for the bad guys ๐ฆ
there are additional security considerations discussed in the section about the AUTHENTICATE and LOGIN commands, so go read those too ๐ง
12. Author's Address ๐
here's who to find if you need the author, fr fr ๐ธ
Mark R. Crispin
Networks and Distributed Computing
University of Washington
4545 15th Aveneue NE
Seattle, WA 98105-4527
Phone: (206) 543-5762
EMail: MRC@CAC.Washington.EDU
Appendices ๐
A. References โจ
these are the docs this spec is built on, and yes, they're all worth a read ๐๐
- [ACAP] Myers, J. "ACAP -- Application Configuration Access Protocol", Work in Progress.
- [CHARSET] Reynolds, J., and J. Postel, "Assigned Numbers", STD 2, RFC 1700, USC/Information Sciences Institute, October 1994.
- [DISPOSITION] Troost, R., and Dorner, S., "Communicating Presentation Information in Internet Messages: The Content-Disposition Header", RFC 1806, June 1995.
- [IMAP-AUTH] Myers, J., "IMAP4 Authentication Mechanism", RFC 1731. Carnegie-Mellon University, December 1994.
- [IMAP-COMPAT] Crispin, M., "IMAP4 Compatibility with IMAP2bis", RFC 2061, University of Washington, November 1996.
- [IMAP-DISC] Austein, R., "Synchronization Operations for Disconnected IMAP4 Clients", Work in Progress.
- [IMAP-HISTORICAL] Crispin, M. "IMAP4 Compatibility with IMAP2 and IMAP2bis", RFC 1732, University of Washington, December 1994.
- [IMAP-MODEL] Crispin, M., "Distributed Electronic Mail Models in IMAP4", RFC 1733, University of Washington, December 1994.
- [IMAP-OBSOLETE] Crispin, M., "Internet Message Access Protocol - Obsolete Syntax", RFC 2062, University of Washington, November 1996.
- [IMAP2] Crispin, M., "Interactive Mail Access Protocol - Version 2", RFC 1176, University of Washington, August 1990.
- [LANGUAGE-TAGS] Alvestrand, H., "Tags for the Identification of Languages", RFC 1766, March 1995.
- [MD5] Myers, J., and M. Rose, "The Content-MD5 Header Field", RFC 1864, October 1995.
- [MIME-IMB] Freed, N., and N. Borenstein, "MIME (Multipurpose Internet Mail Extensions) Part One: Format of Internet Message Bodies", RFC 2045, November 1996.
- [MIME-IMT] Freed, N., and N. Borenstein, "MIME (Multipurpose Internet Mail Extensions) Part Two: Media Types", RFC 2046, November 1996.
- [MIME-HDRS] Moore, K., "MIME (Multipurpose Internet Mail Extensions) Part Three: Message Header Extensions for Non-ASCII Text", RFC 2047, November 1996.
- [RFC-822] Crocker, D., "Standard for the Format of ARPA Internet Text Messages", STD 11, RFC 822, University of Delaware, August 1982.
- [SMTP] Postel, J., "Simple Mail Transfer Protocol", STD 10, RFC 821, USC/Information Sciences Institute, August 1982.
- [UTF-7] Goldsmith, D., and Davis, M., "UTF-7: A Mail-Safe Transformation Format of Unicode", RFC 1642, July 1994.
B. Changes from RFC 1730 ๐ฆ
here's what changed since RFC 1730, bestie ๐
- The
STATUScommand has been added. ๐ - Clarify in the formal syntax that the "#" construct can never refer to multiple spaces. ๐ซถ
- Obsolete syntax has been moved to a separate document. ๐ง
- The
PARTIALcommand has been obsoleted. ๐ญ - okay bestie, the
RFC822.HEADER.LINES,RFC822.HEADER.LINES.NOT,RFC822.PEEK, andRFC822.TEXT.PEEKfetch attributes have been obsoleted ๐ฅ they're officially retired from the group chat ๐ - the
"<" origin "." size ">"suffix for BODY text attributes has been added โจ so cute, origin and size all in one little suffix ๐ - the HEADER, HEADER.FIELDS, HEADER.FIELDS.NOT, MIME, and TEXT part specifiers have been added ๐ง
- support for Content-Disposition and Content-Language has been added ๐
- the restriction on fetching nested MULTIPART parts has been removed ๐ no more gatekeeping, periodt
- body part number 0 has been obsoleted ๐ฅ
- server-supported authenticators are now identified by capabilities ๐
- the capability that identifies this protocol is now called "IMAP4rev1" ๐ A server that provides backwards support for RFC 1730 SHOULD emit the "IMAP4" capability in addition to "IMAP4rev1" in its CAPABILITY response. Because RFC-1730 required "IMAP4" to appear as the first capability, it MUST be listed first in the response ๐ซถ
- a description of the mailbox name namespace convention has been added ๐
- a description of the international mailbox name convention has been added ๐
- the UID-NEXT and UID-VALIDITY status items are now called UIDNEXT and UIDVALIDITY ๐ This is a change from the IMAP STATUS Work in Progress and not from RFC-1730, so it's not a RFC-1730 thing, it's a STATUS draft thing ๐ฆ
- add a clarification that a null mailbox name argument to the LIST command returns an untagged LIST response with the hierarchy delimiter and root of the reference argument ๐
- define terms such as "MUST", "SHOULD", and "MUST NOT" ๐ the key words finally get their own definitions, iconic โจ
- add a section which defines message attributes and more thoroughly details the semantics of message sequence numbers, UIDs, and flags ๐ฅ main character energy for this section ๐
- add a clarification detailing the circumstances when a client may send multiple commands without waiting for a response, and the circumstances in which ambiguities may result ๐ธ
- add a recommendation on server behavior for DELETE and RENAME when inferior hierarchical names of the given name exist ๐
- add a clarification that a mailbox name may not be unilaterally unsubscribed by the server, even if that mailbox name no longer exists ๐ซถ the server can't just unsubscribe you on its own, no cap ๐ โโ๏ธ
- add a clarification that LIST should return its results quickly without undue delay ๐งโโ๏ธ
- add a clarification that the date_time argument to APPEND sets the internal date of the message ๐ฐ๏ธ
- add a clarification on APPEND behavior when the target mailbox is the currently selected mailbox ๐
- add a clarification that external changes to flags should be always announced via an untagged FETCH even if the current command is a STORE with the ".SILENT" suffix ๐ even with .SILENT, the flag changes still get announced, bestie ๐ฃ
- add a clarification that COPY appends to the target mailbox โจ
- add the NEWNAME response code ๐ง
- rewrite the description of the untagged BYE response to clarify its semantics ๐
- change the reference for the body MD5 to refer to the proper RFC ๐
- clarify that the formal syntax contains rules which may overlap, and that in the event of such an overlap the rule which occurs first takes precedence ๐
- correct the definition of body_fld_param ๐ง
- more formal syntax for capability_data ๐
- clarify that any case variant of "INBOX" must be interpreted as INBOX ๐
- clarify that the human-readable text in resp_text should not begin with "[" or "=" ๐
- change MIME references to Draft Standard documents ๐
- clarify \Recent semantics ๐ and that's the whole changelog, iykyk ๐ฆ
- Additional examples. ๐ And that's the very last change on the list, bestie ๐ญโจ
C. Key Word Index ๐๐
Okay so this is the cheat sheet, the place where every command, response, flag, search key and fetch item is listed next to the page it lives on ๐ง Use it like a lookup table and you'll never get lost again ๐ฆ
+FLAGS <flag list> (store command data item) ............... 45
+FLAGS.SILENT <flag list> (store command data item) ........ 46
-FLAGS <flag list> (store command data item) ............... 46
-FLAGS.SILENT <flag list> (store command data item) ........ 46
ALERT (response code) ...................................... 50
ALL (fetch item) ........................................... 41
ALL (search key) ........................................... 38
ANSWERED (search key) ...................................... 38
APPEND (command) ........................................... 34
AUTHENTICATE (command) ..................................... 20
BAD (response) ............................................. 52
BCC <string> (search key) .................................. 38
BEFORE <date> (search key) ................................. 39
BODY (fetch item) .......................................... 41
BODY (fetch result) ........................................ 58
BODY <string> (search key) ................................. 39
BODY.PEEK[<section>]<<partial>> (fetch item) ............... 44
BODYSTRUCTURE (fetch item) ................................. 44
BODYSTRUCTURE (fetch result) ............................... 59
BODY[<section>]<<origin_octet>> (fetch result) ............. 58
BODY[<section>]<<partial>> (fetch item) .................... 41
BYE (response) ............................................. 52
Body Structure (message attribute) ......................... 11
CAPABILITY (command) ....................................... 18
CAPABILITY (response) ...................................... 53
CC <string> (search key) .................................. 39
CHECK (command) ............................................ 36
CLOSE (command) ............................................ 36
COPY (command) ............................................. 46
CREATE (command) ........................................... 25
DELETE (command) ........................................... 26
DELETED (search key) ....................................... 39
DRAFT (search key) ......................................... 39
ENVELOPE (fetch item) ...................................... 44
ENVELOPE (fetch result) .................................... 62
EXAMINE (command) .......................................... 24
EXISTS (response) .......................................... 56
EXPUNGE (command) .......................................... 37
EXPUNGE (response) ......................................... 57
Envelope Structure (message attribute) ..................... 11
FAST (fetch item) .......................................... 44
FETCH (command) ............................................ 41
FETCH (response) ........................................... 58
FLAGGED (search key) ....................................... 39
FLAGS (fetch item) ......................................... 44
FLAGS (fetch result) ....................................... 62
FLAGS (response) ........................................... 56
FLAGS <flag list> (store command data item) ................ 45
FLAGS.SILENT <flag list> (store command data item) ......... 45
FROM <string> (search key) ................................. 39
FULL (fetch item) .......................................... 44
Flags (message attribute) .................................. 9
HEADER (part specifier) .................................... 41
HEADER <field-name> <string> (search key) .................. 39
HEADER.FIELDS <header_list> (part specifier) ............... 41
HEADER.FIELDS.NOT <header_list> (part specifier) ........... 41
INTERNALDATE (fetch item) .................................. 44
INTERNALDATE (fetch result) ................................ 62
Internal Date (message attribute) .......................... 10
KEYWORD <flag> (search key) ................................ 39
Keyword (type of flag) ..................................... 10
LARGER <n> (search key) .................................... 39
LIST (command) ............................................. 30
LIST (response) ............................................ 54
LOGIN (command) ............................................ 22
LOGOUT (command) ........................................... 20
LSUB (command) ............................................. 32
LSUB (response) ............................................ 55
MAY (specification requirement term) ....................... 5
MESSAGES (status item) ..................................... 33
MIME (part specifier) ...................................... 42
MUST (specification requirement term) ...................... 4
MUST NOT (specification requirement term) .................. 4
Message Sequence Number (message attribute) ................ 9
NEW (search key) ........................................... 39
NEWNAME (response code) .................................... 50
NO (response) .............................................. 51
NOOP (command) ............................................. 19
NOT <search-key> (search key) .............................. 39
OK (response) .............................................. 51
OLD (search key) ........................................... 39
ON <date> (search key) ..................................... 39
OPTIONAL (specification requirement term) .................. 5
OR <search-key1> <search-key2> (search key) ................ 39
PARSE (response code) ...................................... 50
PERMANENTFLAGS (response code) ............................. 50
PREAUTH (response) ......................................... 52
Permanent Flag (class of flag) ............................. 10
READ-ONLY (response code) .................................. 50
READ-WRITE (response code) ................................. 50
RECENT (response) .......................................... 57
RECENT (search key) ........................................ 39
RECENT (status item) ....................................... 33
RENAME (command) ........................................... 27
REQUIRED (specification requirement term) .................. 4
RFC822 (fetch item) ........................................ 44
RFC822 (fetch result) ...................................... 63
RFC822.HEADER (fetch item) ................................. 44
RFC822.HEADER (fetch result) ............................... 62
RFC822.SIZE (fetch item) ................................... 44
RFC822.SIZE (fetch result) ................................. 62
RFC822.TEXT (fetch item) ................................... 44
RFC822.TEXT (fetch result) ................................. 62
SEARCH (command) ........................................... 37
SEARCH (response) .......................................... 55
SEEN (search key) .......................................... 40
SELECT (command) ........................................... 23
SENTBEFORE <date> (search key) ............................. 40
SENTON <date> (search key) ................................. 40
SENTSINCE <date> (search key) .............................. 40
SHOULD (specification requirement term) .................... 5
SHOULD NOT (specification requirement term) ................ 5
SINCE <date> (search key) .................................. 40
SMALLER <n> (search key) ................................... 40
STATUS (command) ........................................... 33
STATUS (response) .......................................... 55
STORE (command) ............................................ 45
SUBJECT <string> (search key) .............................. 40
SUBSCRIBE (command) ........................................ 29
Session Flag (class of flag) ............................... 10
System Flag (type of flag) ................................. 9
TEXT (part specifier) ...................................... 42
TEXT <string> (search key) ................................. 40
TO <string> (search key) ................................... 40
TRYCREATE (response code) .................................. 51
UID (command) .............................................. 47
UID (fetch item) ........................................... 44
UID (fetch result) ......................................... 63
UID <message set> (search key) ............................. 40
UIDNEXT (status item) ...................................... 33
UIDVALIDITY (response code) ................................ 51
UIDVALIDITY (status item) .................................. 34
UNANSWERED (search key) .................................... 40
UNDELETED (search key) ..................................... 40
UNDRAFT (search key) ....................................... 40
UNFLAGGED (search key) ..................................... 40
UNKEYWORD <flag> (search key) .............................. 40
UNSEEN (response code) ..................................... 51
UNSEEN (search key) ........................................ 40
UNSEEN (status item) ....................................... 34
UNSUBSCRIBE (command) ...................................... 30
Unique Identifier (UID) (message attribute) ................ 7
X<atom> (command) .......................................... 48
[RFC-822] Size (message attribute) ......................... 11
\Answered (system flag) .................................... 9
\Deleted (system flag) ..................................... 9
\Draft (system flag) ....................................... 9
\Flagged (system flag) ..................................... 9
\Marked (mailbox name attribute) ........................... 54
\Noinferiors (mailbox name attribute) ...................... 54
\Noselect (mailbox name attribute) ......................... 54
\Recent (system flag) ...................................... 10
\Seen (system flag) ........................................ 9
\Unmarked (mailbox name attribute) ......................... 54
That's the whole thing, bestie! ๐๐ Every single entry, every page number, all tucked into the index โจ๐
๐ฆ where this page comes from
- ietf: rfc2060 1996-12
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms