RFC 1730
Internet Message Access Protocol - Version 4
RFC 1730 ๐ Title Block Tea
- Network Working Group ๐ธ (this is the group that put it out)
- RFC number: 1730
- Title: INTERNET MESSAGE ACCESS PROTOCOL - VERSION 4 ๐ฌ
- Author: M. Crispin, University of Washington
- Category: Standards Track โจ
- Date: December 1994
- It doesn't say it obsoletes or updates anything, so there's no drama there ๐ซถ
Status of this Memo ๐
Okay so this one is an Internet standards track protocol for the Internet community, and the authors are literally asking for discussion and suggestions for improvements ๐ฃ๏ธ If you want the current standardization state and status of this protocol, check the current edition of the "Internet Official Protocol Standards" (STD 1) ๐ Distribution of this memo is unlimited, so share it with your whole group chat ๐
Abstract ๐ฆ
IMAP4 (that's Internet Message Access Protocol, Version 4) lets a client access and manage email messages sitting on a server ๐ It treats remote folders, called "mailboxes", in a way that's functionally equivalent to local mailboxes, which is honestly so iconic ๐ IMAP4 also gives an offline client a way to resynchronize with the server (see also [IMAP-DISC]) ๐
It covers a whole list of moves: creating, deleting, and renaming mailboxes โจ checking for new messages ๐ฉ permanently removing messages ๐๏ธ setting and clearing flags ๐ฉ RFC 822 and MIME parsing ๐งฉ searching ๐ and selectively fetching message attributes, texts, and portions of them ๐ Messages are accessed by numbers, and those numbers come in two flavors. Message sequence numbers are relative positions running from 1 up to the number of messages in the mailbox ๐ Unique identifiers are immutable, strictly ascending values given to each message, though they aren't necessarily contiguous ๐ง
IMAP4 supports a single server ๐ A mechanism for supporting multiple IMAP4 servers is discussed in [IMSP]. IMAP4 doesn't cover posting mail, since that's handled by a mail transfer protocol like [SMTP] ๐ฎ Last but not least, IMAP4 is designed to be upwards compatible from the [IMAP2] protocol, and the compatibility issues are discussed in [IMAP-COMPAT] ๐ซถ
Table of Contents ๐
IMAP4 Protocol Specification ...................................... 1
1. Organization of this Document ............................. 1
1.1. How to Read This Document ................................. 1
1.2. Conventions Used in this Document ......................... 1
2. Protocol Overview ......................................... 1
2.1. Link Level ................................................ 1
2.2. Commands and Responses .................................... 1
2.2.1. Client Protocol Sender and Server Protocol Receiver ....... 2
2.2.2. Server Protocol Sender and Client Protocol Receiver ....... 2
3. State and Flow Diagram .................................... 4
3.1. Non-Authenticated State ................................... 4
3.2. Authenticated State ....................................... 4
3.3. Selected State ............................................ 4
3.4. Logout State .............................................. 4
4. Data Formats .............................................. 6
4.1. Atom ...................................................... 6
4.2. Number .................................................... 6
4.3. String .................................................... 6
4.3.1. 8-bit and Binary Strings .................................. 7
4.4. Parenthesized List ........................................ 7
4.5. NIL ....................................................... 7
5. Operational Considerations ................................ 8
5.1. Mailbox Naming ............................................ 8
5.2. Mailbox Size and Message Status Updates ................... 8
5.3. Response when no Command in Progress ...................... 8
5.4. Autologout Timer .......................................... 9
5.5. Multiple Commands in Progress ............................. 9
6. Client Commands ........................................... 10
6.1. Client Commands - Any State ............................... 10
6.1.1. CAPABILITY Command ........................................ 10
6.1.2. NOOP Command .............................................. 11
6.1.3. LOGOUT Command ............................................ 11
6.2. Client Commands - Non-Authenticated State ................. 12
6.2.1. AUTHENTICATE Command ...................................... 12
6.2.2. LOGIN Command ............................................. 14
6.3. Client Commands - Authenticated State ..................... 14
6.3.1. SELECT Command ............................................ 15
6.3.2. EXAMINE Command ........................................... 16
6.3.3. CREATE Command ............................................ 17
6.3.4. DELETE Command ............................................ 18
6.3.5. RENAME Command ............................................ 18
6.3.6. SUBSCRIBE Command ......................................... 19
6.3.7. UNSUBSCRIBE Command ....................................... 19
6.3.8. LIST Command .............................................. 20
6.3.9. LSUB Command .............................................. 22
6.3.10. APPEND Command ............................................ 22
6.4. Client Commands - Selected State .......................... 23
6.4.1. CHECK Command ............................................. 23
6.4.2. CLOSE Command ............................................. 24
6.4.3. EXPUNGE Command ........................................... 25
6.4.4. SEARCH Command ............................................ 25
6.4.5. FETCH Command ............................................. 29
6.4.6. PARTIAL Command ........................................... 32
6.4.7. STORE Command ............................................. 33
6.4.8. COPY Command .............................................. 34
6.4.9. UID Command ............................................... 35
6.5. Client Commands - Experimental/Expansion .................. 37
6.5.1. X<atom> Command ........................................... 37
7. Server Responses .......................................... 38
7.1. Server Responses - Status Responses ....................... 39
7.1.1. OK Response ............................................... 40
7.1.2. NO Response ............................................... 40
7.1.3. BAD Response .............................................. 41
7.1.4. PREAUTH Response .......................................... 41
7.1.5. BYE Response .............................................. 41
7.2. Server Responses - Server and Mailbox Status .............. 42
7.2.1. CAPABILITY Response ....................................... 42
7.2.2. LIST Response ............................................. 43
7.2.3. LSUB Response ............................................. 44
7.2.4. SEARCH Response ........................................... 44
7.2.5. FLAGS Response ............................................ 44
7.3. Server Responses - Message Status ......................... 45
7.3.1. EXISTS Response ........................................... 45
7.3.2. RECENT Response ........................................... 45
7.3.3. EXPUNGE Response .......................................... 45
7.3.4. FETCH Response ............................................ 46
7.3.5. Obsolete Responses ........................................ 51
7.4. Server Responses - Command Continuation Request ........... 51
8. Sample IMAP4 session ...................................... 52
9. Formal Syntax ............................................. 53
10. Author's Note ............................................. 64
11. Security Considerations ................................... 64
12. Author's Address .......................................... 64
Appendices ........................................................ 65
A. Obsolete Commands ......................................... 65
A.6.3.OBS.1. FIND ALL.MAILBOXES Command ........................ 65
A.6.3.OBS.2. FIND MAILBOXES Command ............................ 65
A.6.3.OBS.3. SUBSCRIBE MAILBOX Command ......................... 66
A.6.3.OBS.4. UNSUBSCRIBE MAILBOX Command ....................... 66
B. Obsolete Responses ........................................ 68
B.7.2.OBS.1. MAILBOX Response .................................. 68
B.7.3.OBS.1. COPY Response ..................................... 68
B.7.3.OBS.2. STORE Response .................................... 69
C. References ................................................ 70
E. IMAP4 Keyword Index ....................................... 71
IMAP4 Protocol Specification ๐ง
1. Organization of this Document โจ
1.1. How to Read This Document ๐
This doc is written for the implementor of an IMAP4 client or server, so it's not really optimized for someone trying to understand how the protocol works. Beyond the protocol overview in section 2, the stuff in sections 3 through 5 gives you the general context and definitions IMAP4 runs on ๐ง
Sections 6, 7, and 9 cover the IMAP commands, responses, and syntax. They're so intertwined that it's almost impossible to understand any one of them on its own ๐ญ 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 server, respectively ๐ฌ
2. Protocol Overview ๐
2.1. Link Level ๐
IMAP4 assumes a reliable data stream, like the one TCP gives you. When TCP is used, an IMAP4 server listens on port 143 ๐ฆ
2.2. Commands and Responses ๐
An IMAP4 session is made up of three things: setting up a client/server connection, an initial greeting from the server, and then client/server interactions ๐ฏ Each interaction has a client command, server data, and a server completion result response โจ
Everything the client and server send is a line, meaning a string that ends with a CRLF ๐ The protocol receiver on an IMAP4 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
okay so the client kicks off every operation with a command ๐ each command gets a tag ๐, which is a short alphanumeric label the client makes up (like A0001, A0002, and so on). the client uses a different tag for every command.
there are two situations where a line from the client isn't a full command yet ๐. one is when a command argument is quoted with an octet count (check out literal under String in Data Formats). the other is when the command arguments need server feedback (see the AUTHENTICATE command). either way, if the server is ready for the octets (when that applies) and for the rest of the command, it sends a command continuation request response, which starts with the token + โจ
Note: if the server spots an error in the command instead, it sends a BAD completion response with the matching tag (more on that below) to reject the command and stop 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 several are in progress), or untagged data ๐ฆ in either case, the command continuation request is still pending. the client deals with whatever came in and reads the next response from the server.
the protocol receiver of an IMAP4 server reads a command line from the client, parses the command and its arguments, and sends back server data and a server command completion result response ๐ง
2.2.2. Server Protocol Sender and Client Protocol Receiver
anything the server sends to the client as data, or any status response that doesn't mark a command as finished, starts with the token * ๐ธ these are called untagged responses.
server data can show up because of a client command, or the server can send it unilaterally ๐ there's no syntactic difference between server data that came from a specific command and server data that was sent on its own.
the server completion result response tells you if the operation worked or not ๐ it carries the same tag as the client command that started the operation. so if more than one command is in progress, the tag tells you which command the response belongs to. there are three possible ones: OK (success), NO (failure), or BAD (protocol error, like an unrecognized command or a command syntax error) ๐ฅ
the protocol receiver of an IMAP4 client reads a response line from the server, then acts on it based on its first token, which might be a tag, a *, or a +, as described above ๐ซถ
A client MUST be prepared to accept any server response at all times ๐ค that includes server data it never asked for. server data SHOULD be recorded, so the client can reference its saved copy instead of sending a command to request the data again ๐ง for certain server data, recording it is mandatory ๐
this topic gets a deeper dive in the Server Responses section ๐
3. State and Flow Diagram โจ
an IMAP4 server is in one of four states ๐ most commands only work in certain states. if the client tries a command while the server is in a state where it doesn't belong, that's a protocol error ๐ in that case, the server responds with a BAD or NO completion result, depending on the server implementation.
3.1. Non-Authenticated State
in non-authenticated state, the user has to supply authentication credentials before most commands are allowed ๐ this state is entered when a connection starts, unless the connection has been pre-authenticated.
3.2. Authenticated State
in authenticated state, the user is authenticated and has to select a mailbox before commands that affect messages are allowed ๐ this state is entered when a pre-authenticated connection starts, when acceptable authentication credentials have been provided, or after an error in selecting a mailbox.
3.3. Selected State
in selected state, a mailbox has been selected to access ๐ฌ this state is entered when a mailbox has been successfully selected.
3.4. Logout State
in logout state, the session is being wrapped up and the server will close the connection ๐ this can happen because the client asked for it, or because the server decided on its own. this state can be entered as a result of a client request or by unilateral server decision.
+--------------------------------------+
|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 ๐
IMAP4 uses textual commands and responses ๐ฌ data in IMAP4 can take one of several 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 form is an alternative that skips the overhead of processing a literal, but it comes with restrictions on what can go inside it.
a literal is zero or more octets (CR and LF included), prefixed 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 it sends the octet data and the remainder of the command โณ
a quoted string is zero or more 7-bit characters, excluding CR and LF, with double quote (<">) characters at each end ๐
the empty string is represented as either "" (a quoted string with zero characters between 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 โจ
okay so 8-bit textual and binary mail is totally supported, as long as it goes through [MIME-1] encoding ๐. IMAP4 implementations MAY transmit 8-bit or multi-octet characters in literals, but they should do so only when the character set is identified ๐ธ.
now the binary part is where it gets serious ๐ฅบ. Even though 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, although this is not required ๐ค.
4.4. Parenthesized List ๐
data structures are represented as a "parenthesized list" ๐ง: a sequence of data items, delimited by space, and bounded at each end by parentheses. A parenthesized list can contain other parenthesized lists too, using multiple levels of parentheses to show nesting. It's giving Russian doll energy ๐ช.
the empty list is written as (), a parenthesized list with no members ๐ซง.
4.5. NIL ๐
the special atom "NIL" means the non-existence of a particular data item that's represented as a string or parenthesized list. This is different from the empty string "" or the empty parenthesized list () ๐. Don't mix them up, bestie!
5. Operational Considerations ๐
5.1. Mailbox Naming ๐ซ
the interpretation of mailbox names is implementation-dependent ๐คทโโ๏ธ. BUT the mailbox name INBOX is special and reserved to mean "the primary mailbox for this user on this server" ๐. If you want to export hierarchical mailbox names, they must be left-to-right hierarchical, using a single character to separate levels of hierarchy ๐ณ. The same hierarchy separator character gets used for all levels within a single name, so no mixing it up ๐
โโ๏ธ.
5.2. Mailbox Size and Message Status Updates ๐ฌ
at any time, a server can send data the client didn't request ๐. Sometimes that's required! For example, other agents besides the server might add messages to the mailbox (like new mail delivery), change the flags of messages (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 too, without the client needing to ask for them explicitly โจ. There are special rules for telling the client about removed messages so nothing gets out of sync, so check the description of the EXPUNGE response for the full scoop ๐ง.
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. Don't be that client ๐.
5.3. Response when no Command in Progress โธ๏ธ
server implementations are permitted to send an untagged response (except for EXPUNGE) while there's no command in progress ๐ซถ. Server implementations that send such responses MUST deal with flow control considerations. Specifically, they must either (1) verify that the size of the data doesn't exceed the underlying transport's available window size, or (2) use non-blocking writes ๐.
5.4. Autologout Timer โฐ
if a server has an inactivity autologout timer, that timer MUST be of at least 30 minutes' duration โ. 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 doesn't have to wait for the completion result response of a command before sending another one, as long as it's within the flow control limits of the underlying data stream ๐. Likewise, a server doesn't have to finish processing one command before starting the next, UNLESS an ambiguity would result because a command would affect the results of other commands ๐. If there's an ambiguity like that, the server executes commands to completion in the order the client gave them ๐ง .
6. Client Commands ๐ฆ
IMAP4 commands are described in this section, organized by the state in which they're permitted ๐๏ธ. Commands permitted in multiple states are listed in the minimum permitted state (for example, commands valid in authenticated and selected state are listed in the authenticated state commands) โจ.
Command arguments, marked "Arguments:" in the command descriptions below, are described by function, not by syntax. The precise syntax of command arguments is in the Formal Syntax section ๐.
Some commands cause specific server data to be returned. These are marked "Data:" below. See the response descriptions in the Responses section for info on them, and the Formal Syntax section for their exact syntax. Server data can be transmitted as a result of any command, which is why commands that don't specifically require server data say "no specific data 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 interpretation of those status responses ๐ท๏ธ.
6.1. Client Commands - Any State ๐ธ
the following commands are valid in any state: CAPABILITY, NOOP, and LOGOUT ๐.
6.1.1. CAPABILITY Command ๐งฉ
Arguments: none
Data: mandatory untagged response: CAPABILITY
Result: OK - capability completed
BAD - command unknown or arguments invalid
the CAPABILITY command requests a listing of the capabilities the server supports ๐. The server MUST send a single untagged CAPABILITY response with "IMAP4" as the first listed capability before the (tagged) OK response ๐ฅ. This listing isn't dependent on connection state or user, so there's no need to issue a CAPABILITY command more than once in a session ๐.
Capability names other than "IMAP4" refer to extensions, revisions, or amendments to this specification. See the documentation of the CAPABILITY response for more info ๐. No capabilities are enabled without the client explicitly invoking them ๐. For info on the form of site or implementation-specific capabilities, see the section entitled "Client Commands - Experimental/Expansion" โจ.
Example:
C: abcd CAPABILITY
S: * CAPABILITY IMAP4
S: abcd OK CAPABILITY completed
6.1.2. NOOP Command ๐ด
Arguments: none
Data: no specific data for this command (but see below)
Result: OK - noop completed
BAD - command unknown or arguments invalid
the NOOP command always succeeds, and it does nothing ๐ซ . 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 period of inactivity ๐. 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
Data: mandatory 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 session ๐ซก. 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 IMAP4 Server logging out
S: A023 OK LOGOUT completed
(Server and client then close the connection)
6.2. Client Commands - Non-Authenticated State ๐
in non-authenticated state, the AUTHENTICATE or LOGIN command establishes authentication and enters authenticated state ๐ช. AUTHENTICATE is a general mechanism for a variety of authentication techniques, whereas LOGIN uses the traditional 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, go on the password, and what access restrictions apply to anonymous users, is implementation-dependent ๐ต๏ธโโ๏ธ.
Once authenticated (including as anonymous), it is not possible to re-enter non-authenticated state ๐ซ.
In addition to the universal commands (CAPABILITY, NOOP, and LOGOUT), the following commands are valid in non-authenticated state: AUTHENTICATE and LOGIN ๐.
6.2.1. AUTHENTICATE Command โจ
okay so AUTHENTICATE is how the client tells the server "bestie, I wanna log in with THIS mechanism" ๐ Here's the spec at a glance:
Arguments: authentication mechanism name
Data: continuation data may 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
So AUTHENTICATE is the client saying which auth mechanism it wants, like the ones described in [IMAP-AUTH] ๐
If the server knows that mechanism, it runs an auth exchange to figure out who you are ๐ชช It can optionally also negotiate a protection mechanism for everything after that ๐ก๏ธ If the mechanism isn't supported, the server should reject the command with a tagged NO response. hard pass ๐
The back-and-forth is a bunch of server challenges and client answers, and they're specific to whichever mechanism you picked ๐งฉ A server challenge is a command continuation request response that starts with the + token, followed by a BASE64 encoded string. Your answer is a line that's just a BASE64 encoded string. Wanna bail mid-exchange? The client should issue a line with a single * in it ๐
โโ๏ธ If the server gets that *, it must reject the AUTHENTICATE command with a tagged BAD response. no notes ๐
Now the protection mechanism, which is giving security main character energy ๐ It provides integrity and privacy protection to the protocol session. If one gets negotiated, it's applied to all subsequent data sent over the connection. It kicks in right after the CRLF that wraps up the authentication exchange for the client, and right after the CRLF of the tagged OK response for the server โจ From then on, the stream of command and response octets gets chopped into buffers of ciphertext ๐ง Each buffer goes over the connection as a stream of octets with a four octet field in front of it, in network byte order, that tells you how long the data after it is. The maximum ciphertext buffer length is defined by the protection mechanism ๐
Last but not least, the server is not required to support any particular authentication mechanism, and mechanisms aren't required to support any protection mechanisms either ๐ If an AUTHENTICATE command fails with a NO response, the client may try another authentication mechanism by sending another AUTHENTICATE command, or may just use the LOGIN command. In other words, the client can request auth types in decreasing order of preference, with LOGIN as a last resort ๐ซถ
S: * OK KerberosV4 IMAP4 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: those line breaks in the first client answer are just for editorial clarity ๐ Real authenticators don't have them.
6.2.2. LOGIN Command ๐
Here's the spec for LOGIN:
Arguments: user name
password
Data: no specific data 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
LOGIN identifies the user to the server and carries the plaintext password that authenticates them, as the name suggests ๐ฌ
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 ๐ฆ
Besides the universal commands (CAPABILITY, NOOP, and LOGOUT), these are valid in authenticated state: SELECT, EXAMINE, CREATE, DELETE, RENAME, SUBSCRIBE, UNSUBSCRIBE, LIST, LSUB, and APPEND ๐
6.3.1. SELECT Command ๐ฌ
Arguments: mailbox name
Data: mandatory 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 opens a mailbox so you can get at the messages inside it ๐จ Before the server returns an OK to the client, it MUST send these untagged bits of data:
FLAGS: defined flags in the mailbox<n> EXISTS: the number of messages in the mailbox<n> RECENT: the number of messages added to the mailbox since the previous time this mailbox was readOK [UIDVALIDITY <n>]: the unique identifier validity value. See the description of the UID command for more detail.
Together, those set the initial state of the mailbox at the client ๐ง If it's not possible to figure out which messages were added since the mailbox was last read, then all messages SHOULD be considered recent ๐ฐ๏ธ
The server SHOULD also send an UNSEEN response code in an OK untagged response, pointing 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 listed in the FLAGS untagged response, the server SHOULD send a PERMANENTFLAGS response code in an OK untagged response, listing the flags the client may change permanently ๐ท๏ธ
Only one mailbox can be selected at a time in a session. If you want to access multiple mailboxes at once, you need multiple sessions ๐ SELECT automatically deselects whatever mailbox is currently selected before it tries the new one. So if a mailbox is selected and a SELECT that fails gets attempted, no mailbox is selected anymore ๐
If the user 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 user can't modify the mailbox but is permitted read access, the mailbox is selected as read-only, and the server MUST prefix the text of the tagged OK response to SELECT with the [READ-ONLY] response code ๐ Read-only access through SELECT is different from EXAMINE because certain read-only mailboxes may permit changes to permanent state on a per-user (as opposed to global) basis. Netnews messages marked in a user's .newsrc file are an example of that per-user permanent state, and it can be modified 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
Data: mandatory 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 twin ๐ฏโโ๏ธ It returns the same output, but the selected mailbox is marked as read-only. No changes to the permanent state of the mailbox are permitted, including per-user state ๐ซโ๏ธ
The text of the tagged OK response to the EXAMINE command 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
Data: no specific data 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 mailbox with the given name ๐ฑ You only get an OK back if a brand-new mailbox with that name was actually created. It's an error to try creating INBOX, or a mailbox whose name refers to an existing mailbox ๐
โโ๏ธ Any error during creation gets a tagged NO response ๐
If the mailbox name ends with the server's hierarchy separator character (the one the server hands back from a LIST command), that's a heads-up that the client may create mailbox names under this one later on ๐ณ Server implementations that don't need that heads-up MUST ignore it ๐ซง
If a new mailbox gets the same name as a mailbox that was 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 ๐ See 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: what this example means depends on whether / was returned as the hierarchy separator from LIST ๐ฒ If / is the hierarchy 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
Data: no specific data for this command
Result:
OK - delete completedNO - delete failure: can't delete mailbox with that nameBAD - command unknown or arguments invalid
okay so DELETE is giving permanent ๐ It removes the mailbox with the given name for good. You only get a tagged OK back if the mailbox has actually been deleted. Trying to delete INBOX, or a name that doesn't exist, is an error, and any deletion error gets you a tagged NO response. no cap, read those carefully ๐ซถ
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 identifiers of the old one, unless the new mailbox has a different unique identifier validity value. Check out the UID command section if you want the full tea on that ๐
Example:
C: A683 DELETE blurdybloop
S: A683 OK DELETE completed
6.3.5. RENAME Command ๐ฆ
Arguments: existing mailbox name, new mailbox name
Data: no specific data for this command
Result:
OK - rename completedNO - rename failure: can't rename mailbox with that name, can't rename to mailbox with that nameBAD - command unknown or arguments invalid
RENAME lets you change the name of a mailbox, and it's lowkey so satisfying โจ A tagged OK comes back only if the rename actually happened. It's an error to rename from a name that doesn't exist, or to a name that already exists. Any renaming error returns a tagged NO response.
Renaming INBOX is permitted, and here's the iconic part: a brand new, empty INBOX gets created right in its place ๐ธ
Example:
C: Z4S9 RENAME blurdybloop owatagusiam
S: Z4S9 OK RENAME completed
6.3.6. SUBSCRIBE Command ๐
Arguments: mailbox
Data: no specific data for this command
Result:
OK - subscribe completedNO - subscribe failure: can't subscribe to that nameBAD - command unknown or arguments invalid
SUBSCRIBE adds the mailbox name you give it to the server's set of "active" or "subscribed" mailboxes, the same ones LSUB returns ๐ฌ You only get a tagged OK back if the subscription worked.
Example:
C: A002 SUBSCRIBE #news.comp.mail.mime
S: A002 OK SUBSCRIBE completed
6.3.7. UNSUBSCRIBE Command ๐
Arguments: mailbox name
Data: no specific data for this command
Result:
OK - unsubscribe completedNO - unsubscribe failure: can't unsubscribe that nameBAD - command unknown or arguments invalid
UNSUBSCRIBE is the undo button for SUBSCRIBE ๐ It removes the mailbox name from that same "active" or "subscribed" set that LSUB reports on. A tagged OK only comes back if the unsubscription went through.
Example:
C: A002 UNSUBSCRIBE #news.comp.mail.mime
S: A002 OK UNSUBSCRIBE completed
6.3.8. LIST Command ๐โจ
Arguments: reference name, mailbox name with possible wildcards
Data: untagged responses: LIST
Result:
OK - list completedNO - list failure: can't list that reference or nameBAD - command unknown or arguments invalid
LIST gives you a subset of the names the user can see, out of the full set of everything available ๐ You get zero or more untagged LIST replies back. Each one has the name attributes, the hierarchy delimiter, and the name. Check the LIST reply section for the deep dive.
An empty "" reference name means the mailbox name gets interpreted the same way SELECT would interpret it. The returned mailbox names MUST match the mailbox name pattern you supplied. A non-empty reference name is a mailbox, or a level of mailbox hierarchy, and it sets up a context where the mailbox name gets interpreted in an implementation-defined way. implementation-defined = the server decides, and it's not my place to spill that tea ๐คซ
The reference and mailbox name get interpreted, in an implementation-dependent way, into a canonical form that shows an unambiguous left-to-right hierarchy. The returned mailbox names come back 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 name is inside the reference's context, 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's 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. Notice that "~smith/Mail" should not get turned into something like "/u2/users/smith/Mail", because then the client would have no way to tell that the interpretation was in the context of the reference ๐ฅบ
The * is a wildcard that matches zero or more characters at its position. The % is kind of similar to *, but it does NOT match a hierarchy delimiter. If % is the last character of a mailbox name argument, matching levels of hierarchy get returned too. If those levels aren't also selectable mailboxes, they come back with the \Noselect mailbox name attribute (see the LIST response description for more detail).
Server implementations are allowed to "hide" mailboxes that are otherwise accessible from the wildcard characters, by stopping 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 it matches the input arguments and INBOX is supported by this server for this user. The only thing that decides whether INBOX gets omitted is whether SELECT INBOX would return failure. Whether the user's real INBOX lives on this server or somewhere else doesn't matter at all ๐ฅ
Example:
C: A002 LIST "~/Mail/" "%"
S: * LIST (\Noselect) "/" ~/Mail/foo
S: * LIST () "/" ~/Mail/meetings
S: A002 OK LIST completed
6.3.9. LSUB Command ๐
Arguments: reference name, mailbox name with possible wildcards
Data: untagged responses: LSUB
Result:
OK - lsub completedNO - lsub failure: can't list that reference or nameBAD - command unknown or arguments invalid
LSUB returns a subset of names from the set the user has declared as "active" or "subscribed" ๐ซง You get zero or more untagged LSUB replies back. The arguments to LSUB are in the same form as the ones for LIST, so if you know LIST, you already know LSUB.
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. APPEND Command ๐ฉโจ
Arguments: mailbox name, optional flag parenthesized list, optional date/time string, message literal
Data: no specific data for this command
Result:
OK - append completedNO - append error: can't append to that mailbox, error in flags or date/time or message textBAD - command unknown or arguments invalid
APPEND adds the literal argument as a new message in the mailbox you pick ๐ That literal has to be in the format of an [RFC-822] message. 8-bit characters are allowed in the message. A server that can't keep 8-bit data intact MUST be able to reversibly convert 8-bit APPEND data to 7-bit using [MIME-1] encoding. Very careful, very important ๐ฅ
If you specify a flag parenthesized list or a date_time, that data SHOULD be set on the resulting message. If you don't, the defaults are empty flags and the current date/time.
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. If the mailbox is currently selected, the normal new mail actions should occur ๐ฌ
If the destination mailbox doesn't exist, a server MUST return an error, and MUST NOT automatically create the mailbox. Unless it's certain that the destination mailbox cannot be created, the server MUST send the response code [TRYCREATE] as the prefix of the text in the tagged NO response. That's a little hint for the client that it can try a CREATE command and then retry the APPEND if the CREATE works ๐ง
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 doesn't give you a way to transfer [SMTP] envelope information. Don't use it as your mail delivery method, bestie ๐ โโ๏ธ
6.4. Client Commands - Selected State ๐ธ
In the selected state, commands that manipulate messages in a mailbox are permitted ๐งโโ๏ธ
On top of the universal commands (CAPABILITY, NOOP, and LOGOUT), and the authenticated state commands (SELECT, EXAMINE, CREATE, DELETE, RENAME, SUBSCRIBE, UNSUBSCRIBE, LIST, LSUB, FIND ALL.MAILBOXES, FIND MAILBOXES, and APPEND), the following commands are valid in the selected state: CHECK, CLOSE, EXPUNGE, SEARCH, FETCH, PARTIAL, STORE, COPY, and UID ๐
6.4.1. CHECK Command โจ
Arguments: none
Data: no specific data for this command
Result: OK - check completed
BAD - command unknown or arguments invalid
Okay so, CHECK is basically asking the server for a checkpoint on the mailbox you've got selected ๐ง. A checkpoint is any implementation-dependent housekeeping the server does for the mailbox (like syncing its in-memory picture of the mailbox with what's actually on disk) that doesn't normally happen with every single command. It can take a little real time to finish ๐ . If a server doesn't have any housekeeping like that, then CHECK is literally the same as NOOP. Main character energy for NOOP ๐ธ
Also, don't get it twisted: there's no promise you'll get an EXISTS untagged response back from CHECK ๐. If you're trying to poll for new mail, use NOOP, not CHECK. Trust me on this one, bestie ๐ซถ
C: FXXZ CHECK
S: FXXZ OK CHECK Completed
6.4.2. CLOSE Command ๐ฆ
Arguments: none
Data: no specific data for this command
Result: OK - close completed, now in authenticated state
NO - close failure: no mailbox selected
BAD - command unknown or arguments invalid
CLOSE is the one that permanently removes every message with the \Deleted flag set from the mailbox you've selected, and then drops you from selected state back to authenticated state ๐ฅ. The server doesn't send any untagged EXPUNGE responses for this, so it's super clean.
If the mailbox was selected with EXAMINE, or it's otherwise read-only, then nothing gets removed and you won't get an error either. Nothing happens, no drama ๐
You don't actually have to send CLOSE before you SELECT, EXAMINE, or LOGOUT ๐. Those three commands implicitly close whatever mailbox is currently selected, but they don't do an expunge when they do it. Here's the tea though: if you've deleted a whole bunch of messages, CLOSE-LOGOUT or CLOSE-SELECT is way faster than EXPUNGE-LOGOUT or EXPUNGE-SELECT. Why? Because no untagged EXPUNGE responses get sent, and the client would probably just ignore those anyway ๐ญโจ
C: A341 CLOSE
S: A341 OK CLOSE completed
6.4.3. EXPUNGE Command ๐
Arguments: none
Data: 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 ๐๏ธ. Before the server says OK, it sends one untagged EXPUNGE response for each message that gets removed. So it's very much a "watch it happen" kind of command ๐
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 character set specification
searching criteria (one or more)
Data: mandatory untagged response: SEARCH
Result: OK - search completed
NO - search error: can't search that character set or
criteria
BAD - command unknown or arguments invalid
SEARCH digs through the mailbox for messages that match your searching criteria ๐ต๏ธโโ๏ธ. Criteria are made of one or more search keys. The server answers with an untagged SEARCH response that lists the message sequence numbers of everything that matched, so you get a little list of wins ๐
When you use more than one key, the result is the intersection (an AND of all of them). So DELETED FROM "SMITH" SINCE 1-Feb-1994 means all the deleted messages from Smith that showed up in the mailbox since February 1, 1994. Iconic. You can also wrap search keys in parentheses, which is handy when you're using OR and NOT ๐ง
Server implementations MAY exclude [MIME-1] body parts with terminal content types other than TEXT and MESSAGE from SEARCH matching. That's a choice the server gets to make, so it's giving flexibility ๐
The optional character set specification is the word "CHARSET" followed by a registered MIME character set. It tells the server what character set the strings in your search criteria are using ๐. [MIME-2] strings that show up in RFC 822/MIME message headers, and [MIME-1] content transfer encodings, MUST be decoded before matching, no exceptions ๐ โโ๏ธ. Except for US-ASCII, you don't get any guarantee that a particular character set is supported. And if the server doesn't support the character set you asked for, it MUST return a tagged NO response (not a BAD). Don't freak out, it's just a NO ๐
For every search key that takes a string, a message matches if that string is a substring of the field. Matching is case-insensitive, so "smith" and "SMITH" are the same to the server ๐ธ
Here are the defined search keys. Check the Formal Syntax section for the exact syntax of each argument ๐
<message set> Messages with message sequence numbers
corresponding to the specified message sequence
number set
ALL All messages in the mailbox; the default initial
key for ANDing.
ANSWERED Messages with the \Answered flag set.
BCC <string> Messages that contain the specified string in the
envelope structure's BCC field.
BEFORE <date> Messages whose internal date is earlier than the
specified date.
BODY <string> Messages that contain the specified string in the
body of the message.
CC <string> Messages that contain the specified string in the
envelope structure's CC field.
DELETED Messages with the \Deleted flag set.
DRAFT Messages with the \Draft flag set.
FLAGGED Messages with the \Flagged flag set.
FROM <string> Messages that contain the specified string in the
envelope structure's FROM field.
HEADER <field-name> <string>
Messages that have a header with the specified
field-name (as defined in [RFC-822]) and that
contains the specified string in the [RFC-822]
field-body.
KEYWORD <flag> Messages with the specified keyword set.
LARGER <n> Messages with an RFC822.SIZE larger than the
specified number of octets.
NEW Messages that have the \Recent flag set but not the
\Seen flag. This is functionally equivalent to
"(RECENT UNSEEN)".
NOT <search-key>
Messages that do not match the specified search
key.
OLD Messages that do not have the \Recent flag set.
This is functionally equivalent to "NOT RECENT" (as
opposed to "NOT NEW").
ON <date> Messages whose internal date is within the
specified date.
OR <search-key1> <search-key2>
Messages that match either search key.
RECENT Messages that have the \Recent flag set.
SEEN Messages that have the \Seen flag set.
SENTBEFORE <date>
Messages whose [RFC-822] Date: header is earlier
than the specified date.
SENTON <date> Messages whose [RFC-822] Date: header is within the
specified date.
SENTSINCE <date>
Messages whose [RFC-822] Date: header is within or
later than the specified date.
SINCE <date> Messages whose internal date is within or later
than the specified date.
SMALLER <n> Messages with an RFC822.SIZE smaller than the
specified number of octets.
SUBJECT <string>
Messages that contain the specified string in the
envelope structure's SUBJECT field.
TEXT <string> Messages that contain the specified string in the
header or body of the message.
TO <string> Messages that contain the specified string in the
envelope structure's TO field.
UID <message set>
Messages with unique identifiers corresponding to
the specified unique identifier set.
UNANSWERED Messages that do not have the \Answered flag set.
UNDELETED Messages that do not have the \Deleted flag set.
UNDRAFT Messages that do not have the \Draft flag set.
UNFLAGGED Messages that do not have the \Flagged flag set.
UNKEYWORD <flag>
Messages that do not have the specified keyword
set.
UNSEEN Messages that do not have the \Seen flag set.
Here's a quick example to see it all click together ๐
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
Data: 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 the data for a message in the mailbox ๐ฌ the data items can be a single atom or a parenthesized list, and these are the ones you can ask for rn ๐
ALLis a macro, basically a shortcut for(FLAGS INTERNALDATE RFC822.SIZE ENVELOPE)๐ธBODYis the non-extensible form ofBODYSTRUCTURE๐BODY[<section>]is the text of one particular body section ๐ฆ the section spec is one or more part numbers, separated by periods- single-part messages only have a 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 have to be listed with a period and then the number inside that nested multipart part ๐ซถ
- you cannot fetch a multipart part by itself, only its individual members ๐
- a part of type MESSAGE and subtype RFC822 has nested parts too, which are the parts of the MESSAGE part's body โจ
- nested part 0 of a MESSAGE/RFC822 part is the [RFC-822] header of the message ๐
- every message has at least one part ๐
- the
\Seenflag gets implicitly set here, and if that changes the flags, they should be included as part of the fetch responses ๐
here's a super complex message with its section specs, it's giving multipart chaos ๐ญ
0 ([RFC-822] header of the message)
MULTIPART/MIXED
1 TEXT/PLAIN
2 APPLICATION/OCTET-STREAM
3 MESSAGE/RFC822
3.0 ([RFC-822] header of the message)
3.1 TEXT/PLAIN
3.2 APPLICATION/OCTET-STREAM
MULTIPART/MIXED
4.1 IMAGE/GIF
4.2 MESSAGE/RFC822
4.2.0 ([RFC-822] header of the message)
4.2.1 TEXT/PLAIN
MULTIPART/ALTERNATIVE
4.2.2.1 TEXT/PLAIN
4.2.2.2 TEXT/RICHTEXT
notice there's no section spec for the multipart parts themselves (no section 4 or 4.2.2) ๐
BODY.PEEK[<section>]is the alternate form ofBODY[section]that does NOT implicitly set\Seen๐ซฃBODYSTRUCTUREis the [MIME-1] body structure of the message, computed by the server by parsing the [MIME-1] header lines ๐งENVELOPEis the envelope structure of the message, computed by the server by parsing the [RFC-822] header into its component parts, defaulting various fields as necessary ๐FASTis another macro, equivalent to(FLAGS INTERNALDATE RFC822.SIZE)โกFLAGSgives the flags that are set for this message ๐ฉFULLis a macro equivalent to(FLAGS INTERNALDATE RFC822.SIZE ENVELOPE BODY)๐INTERNALDATEis the date and time of final delivery of the message, as defined by RFC 821 ๐RFC822is the message in [RFC-822] format ๐ it implicitly sets\Seen(and if that changes the flags, they should be included in the fetch responses), and it's the concatenation ofRFC822.HEADERandRFC822.TEXTRFC822.PEEKis the alternate form ofRFC822that does not implicitly set\Seen๐ฆRFC822.HEADERis the [RFC-822] format header as stored on the server, including the delimiting blank line between the header and the body ๐RFC822.HEADER.LINES <header_list>gives all the header lines (continuation lines too) whose field-name matches any string in header_list. the matching is case-insensitive but otherwise exact, and the delimiting blank line is always included ๐RFC822.HEADER.LINES.NOT <header_list>is the opposite vibe: all header lines (continuation lines included) whose field-name does NOT match any string in header_list. again case-insensitive but otherwise exact, and the blank line is always included ๐ โโ๏ธRFC822.SIZEis the number of octets in the message, expressed in [RFC-822] format ๐RFC822.TEXTis the text body of the message, minus the [RFC-822] header. it implicitly sets\Seentoo, so same deal with the flags ๐RFC822.TEXT.PEEKis the alternate form ofRFC822.TEXTthat doesn't implicitly set\Seen๐ทUIDis the unique identifier for the message ๐ชช
here's an example, the server replies per message ๐
C: A654 FETCH 2:4 (FLAGS RFC822.HEADER.LINES (DATE FROM))
S: * 2 FETCH ....
S: * 3 FETCH ....
S: * 4 FETCH ....
S: A003 OK FETCH completed
6.4.6. PARTIAL Command โจ
Arguments: message sequence number
message data item name
position of first octet
number of octets
Data: untagged responses: FETCH
Result: OK - partial completed
NO - partial error: can't fetch that data
BAD - command unknown or arguments invalid
PARTIAL is basically FETCH but with a slice ๐ฐ you get back only the number of octets you asked for, starting from the starting octet you named. you can only fetch one message at a time, and the first octet of a message is octet 1, so that's the lowest starting octet you can use ๐ง
these FETCH items work with PARTIAL: RFC822, RFC822.HEADER, RFC822.TEXT, BODY[section], plus any .PEEK forms of those ๐
if your partial fetch tries to read past the end of the text, it gets truncated as needed. and if your starting octet is already past the end, you get an empty string back ๐ซ
the data comes back in the FETCH response, but there's no indication of what range the partial data covers, so keep track of that yourself ๐ also, you can't stream multiple PARTIAL commands for the same data item without processing and synchronizing at each step, because streamed commands might run out of order ๐
there's no requirement that partial fetches follow any sequence. for example, if a partial fetch of octets 1 through 10000 breaks in an awkward spot for BASE64 decoding, it's allowed to continue with a partial fetch of 9987 through 19987, and so on ๐ฆ
the \Seen flag gets handled the same way as in the associated FETCH command ๐ธ
here's an example, very cute ๐ฅน
C: A005 PARTIAL 4 RFC822 1 1024
S: * 1 FETCH (RFC822 {1024}
S: Return-Path: <gray@cac.washington.edu>
S: ...
S: ......... FLAGS (\Seen))
S: A005 OK PARTIAL completed
6.4.7. STORE Command โจ
Arguments: message set
message data item name
value for message data item
Data: untagged responses: FETCH
Result: OK - store completed
NO - store error: can't store that data
BAD - command unknown or arguments invalid
STORE is the command that changes the data attached to a message ๐ง normally it sends back the updated value in an untagged FETCH response. but if you add .SILENT to the data item name, the untagged FETCH is skipped, and the server should assume the client already worked out the updated value itself or just doesn't care about it ๐คซ
these are the data items you can store rn ๐
FLAGS <flag list>replaces the flags for the message with the argument ๐ฉ the new values come back as if you did a FETCH of those flagsFLAGS.SILENT <flag list>is the same asFLAGSbut doesn't return a new value ๐ค+FLAGS <flag list>adds the argument to the message's flags โ the new values come back as if you did a FETCH of those flags+FLAGS.SILENT <flag list>is the same as+FLAGS, no new value returned ๐ซฅ-FLAGS <flag list>removes the argument from the message's flags โ the new values come back as if you did a FETCH of those flags-FLAGS.SILENT <flag list>is the same as-FLAGS, but no new value returned ๐
here's an example, watch the flags glow up ๐
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.8. COPY Command โจ
Arguments: message set
mailbox name
Data: no specific data 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
COPY copies the specified message(s) over to the specified destination mailbox ๐ฆ the flags and internal date of the messages SHOULD be preserved in the copy ๐ซถ
if the destination mailbox doesn't exist, a server SHOULD return an error ๐ซ it SHOULD NOT automatically create the mailbox, periodt ๐
unless it's certain the destination mailbox can not be created, the server MUST send the response code "[TRYCREATE]" as the prefix of the text of the tagged NO response. that's basically a hint for the client that it can try a CREATE command and then retry the COPY if the CREATE works ๐
if COPY fails for any reason at all, server implementations MUST restore the destination mailbox to its state from before the COPY attempt. no half-finished copies, bestie ๐ญ
here's the example ๐ฆ
C: A003 COPY 2:4 MEETING
S: A003 OK COPY completed
6.4.9. UID Command ๐โจ
Arguments: command name
command arguments
Data: 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 and it's giving main character energy ๐ In the first form, it takes a COPY, FETCH, or STORE command as its arguments, with arguments that fit whichever command it is. The twist is that the numbers in the message set argument are unique identifiers instead of message sequence numbers ๐ฆ
In the second form, the UID command takes a SEARCH command with SEARCH command arguments. The arguments are read the same way as with SEARCH, but the numbers returned in a SEARCH response to a UID SEARCH command are unique identifiers instead of message sequence numbers. For example, UID SEARCH 1:100 UID 443:557 returns the unique identifiers that match the intersection of the message sequence number set 1:100 and the UID set 443:557 ๐
A unique identifier is a number, and it's guaranteed not to point at any other message in the mailbox ๐ฅ Unique identifiers get assigned in strictly ascending order for each message added to the mailbox. Unlike message sequence numbers, they persist across sessions ๐ That lets a client resync its state from a previous session with the server (think disconnected or offline access clients), and [IMAP-DISC] goes deeper on this ๐ซถ
Every mailbox has a unique identifier validity value ๐ It gets sent in an UIDVALIDITY response code inside an OK untagged response when the mailbox is selected. If unique identifiers from an earlier session fail to persist into this session, the unique identifier validity value MUST be greater than it was in the earlier session. No cap, this is the rule that keeps everyone from getting confused ๐
Note: A good value for the unique identifier validity value is a 32-bit representation of the creation date/time of the mailbox. It's alright to use a constant such as 1, but only if it's guaranteed that unique identifiers will never be reused, even if a mailbox gets deleted and a new mailbox with the same name is created at some future time.
Message set ranges are allowed ๐ However, there's no guarantee that unique identifiers are contiguous. A non-existent unique identifier inside a message set range gets ignored, and no error message is generated for it ๐
The number after the "*" in an untagged FETCH response is always a message sequence number, not a unique identifier, even for a UID command response ๐ง Still, server implementations MUST implicitly include the UID message data item as part of any FETCH response caused by a UID command, whether or not UID was specified as a message data item in the FETCH โจ
Example:
C: A003 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
Data: implementation defined
Result: OK - command completed
NO - failure
BAD - command unknown or arguments invalid
Any command prefixed with an X is an experimental command ๐ฌ Commands that aren't part of this specification, or a standard or standards-track revision of it, MUST use the X prefix. Bestie, that's how everyone knows what's experimental and what's the real deal ๐
Any added untagged responses issued by an experimental command MUST also be prefixed with an X. Server implementations MUST NOT send any such untagged responses unless the client asked for them by issuing the associated experimental command ๐ โโ๏ธ
Example:
C: a441 CAPABILITY
S: * CAPABILITY IMAP4 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 ๐ซง
Server responses come in three forms: status responses, server data, and command continuation requests ๐
Server response data is marked "Data:" in the response descriptions below. It's described by what it does, not by how it's written. The exact syntax of server response data lives in the Formal Syntax section ๐
The client MUST be prepared to accept any response at all times ๐ซถ
Status responses that are tagged tell you the completion result of a client command, and they carry a tag that matches the command ๐
Some status responses, and all server data, are untagged. An untagged response uses the token * instead of a tag. Untagged status responses show the server greeting, or server status that doesn't mark a command as finished. For historical reasons, untagged server data responses are also called "unsolicited data," though strictly speaking only unilateral server data is truly "unsolicited" ๐
Certain server data MUST be recorded by the client when it's received, and that's called out in the description of that data. This stuff is critical because it affects how every later command and response gets interpreted (for example, updates about messages being created or destroyed) ๐ฅ
Other server data SHOULD be recorded for later reference. If the client doesn't need to record the data, or recording it has no obvious purpose (for example, a SEARCH response when no SEARCH command is in progress), the data SHOULD be ignored ๐๏ธ
Unilateral untagged responses happen in selected state. In selected state, the server checks the mailbox for new messages as part of running each command. If it finds new messages, it sends untagged EXISTS and RECENT responses that reflect the new size of the mailbox ๐ฌ Server implementations that allow multiple simultaneous access to the same mailbox should also send the right unilateral untagged FETCH and EXPUNGE responses when another agent changes message flags or expunges messages ๐
Command continuation request responses use the token + instead of a tag. The server sends these to say it accepted an incomplete client command and is ready for the rest of it โจ
7.1. Server Responses - Status Responses ๐
Status responses may include an optional response code. A response code is data inside square brackets, written as an atom and possibly followed by a space and arguments. It carries extra info or status codes for client software beyond the OK/NO/BAD condition, and it's only defined when there's a specific action the client can take based on that info ๐ง
The currently defined response codes are:
ALERT: the human-readable text contains a special alert that MUST be presented to the user in a way that grabs their attention ๐จPARSE: the human-readable text is an error in parsing the [RFC-822] or [MIME-1] headers of a message in the mailbox ๐งพPERMANENTFLAGS: followed by a parenthesized list of flags, this shows which of the known flags the client may change permanently ๐ Any flag that's in the FLAGS untagged response but not in the PERMANENTFLAGS list cannot 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 while selected changed from read-write to read-only ๐READ-WRITE: the mailbox is selected read-write, or its access while selected changed from read-only to read-write โ๏ธTRYCREATE: an APPEND or COPY attempt is failing because the target mailbox doesn't exist (and not for some other reason). It's a hint that the operation may succeed if the mailbox is created first with the CREATE command ๐ ๏ธUIDVALIDITY: followed by a decimal number, this shows the unique identifier validity value. Check the UID command description for more detail ๐ขUNSEEN: followed by a decimal number, this shows 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 any response codes they don't recognize ๐ซ
7.1.1. OK Response โ
Data: 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 completed 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 by a response code ๐โโ๏ธ
The untagged form is also one of three possible greetings at session startup. It means the session isn't authenticated yet and a LOGIN command is needed ๐
Example:
S: * OK IMAP4 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 โ ๏ธ
Data: optional response code
human-readable text
The NO response is an operational error message from the server ๐ฌ When it's tagged, it means the associated command did not complete successfully. The untagged form is a warning, and the command may still complete successfully. The human-readable text describes the condition ๐ซฃ
Example:
C: A222 COPY 1:2 owatagusiam
S: * NO Disk is 98% full, please delete unnecessary data
S: A222 OK COPY completed
C: A222 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: A222 NO COPY failed: disk is full
7.1.3. BAD Response
Data: optional response code
human-readable text
okay so the BAD response is the server basically going "ugh, that's an error" ๐ It's an error message from the server ๐จ. When it's tagged ๐ท๏ธ, it's calling out a protocol-level error in the client's command, and the tag tells you which command caused the drama. The untagged version is for protocol-level errors where the server can't figure out which command caused it, and it can also mean an internal server failure ๐ญ. Either way, the human-readable text explains what happened ๐.
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
This example is giving full disaster movie ๐ฌ. The server rejects the super long command line, then the empty line, then the EXPUNGE hits a disk crash, but the server is like "don't worry, salvage worked, nothing lost" ๐ฅน and then finally says the expunge is done โจ.
7.1.4. PREAUTH Response
Data: optional response code
human-readable text
the PREAUTH response is always untagged ๐ฆ, and it's one of three possible greetings when a session starts ๐ธ. It tells you the session is already authenticated by external means, so no LOGIN command is needed ๐. No password dance, bestie ๐ .
Example: S: * PREAUTH IMAP4 server ready and logged in as Smith
7.1.5. BYE Response
Data: optional response code
human-readable text
the BYE response is always untagged too ๐, and it means the server is about to close the connection ๐. The human-readable text can be shown to the user in a status report by the client ๐. A BYE can show up as part of a normal logout sequence, or as a panic shutdown announcement from the server ๐ฑ. Some server implementations also use it to announce an inactivity autologout ๐ค.
BYE is also one of the three possible greetings at session startup ๐ง. In that case it means the server is not willing to accept a session from this client ๐ โโ๏ธ. Rude, but honest ๐.
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 data gets sent to the client, often as the result of a command with the same name ๐.
7.2.1. CAPABILITY Response
Data: 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 first name in that list MUST be the atom "IMAP4" ๐. That's the rule, no exceptions, bestie.
A capability name other than IMAP4 means the server supports an extension, revision, or amendment to the IMAP4 protocol ๐งฉ. Server responses MUST conform to this document until the client issues a command that uses the associated capability ๐. So the old rules stay in place until you actually use the new stuff ๐.
Capability names MUST either begin with "X" or be standard or standards-track IMAP4 extensions, revisions, or amendments registered with IANA ๐๏ธ. A server MUST NOT offer unregistered or non-standard capability names, unless such names are prefixed with an "X" ๐ซ. Not me offering random names with no "X" ๐ .
Client implementations SHOULD NOT require any capability name other than "IMAP4" ๐ธ, and MUST ignore any unknown capability names ๐ซ . So clients should be chill about anything they don't recognise and just skip it ๐ฆ.
Example: S: * CAPABILITY IMAP4 XPIG-LATIN
Yes, XPIG-LATIN is the pig latin extension, and it's giving pure chaos ๐ทโจ.
7.2.2. LIST Response
Data: name attributes
hierarchy delimiter
name
the LIST response shows up as a result of a LIST command ๐. It returns a single name that matches the LIST specification ๐ฏ. There may be multiple LIST responses for a single LIST command ๐.
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. Dead end, no kids allowed ๐ โโ๏ธ.\Noselect: It is not possible to use this name as a selectable mailbox. Look, but don't touch ๐.\Marked: The mailbox has been marked "interesting" by the server; the mailbox probably contains messages that have been added since the last time the mailbox was selected. Ooh, something new in there ๐โจ.\Unmarked: The mailbox does not contain any additional messages since the last time the mailbox was selected. Nothing new, bestie ๐.
If it is not feasible for the server to determine whether the mailbox is "interesting" or not, or if the name is a \Noselect name, the server should not send either \Marked or \Unmarked ๐คทโโ๏ธ. Basically, if the server can't tell, it just skips both labels.
The hierarchy delimiter is a character used to delimit levels of hierarchy in a mailbox name ๐ช. A client may use it to create child mailboxes, and to search higher or lower levels of naming hierarchy ๐ณ. All children of a top-level hierarchy node must use the same separator character ๐งก. A NIL hierarchy delimiter means that no hierarchy exists, and the name is a "flat" name ๐ฅ.
The name represents an unambiguous left-to-right hierarchy, and 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
Data: name attributes
hierarchy delimiter
name
the LSUB response shows up as a result of an LSUB command ๐ซ. It returns a single name that matches the LSUB specification ๐ฏ. There may be multiple LSUB responses for a single LSUB command ๐ธ. The data is identical in format to the LIST response, so it's the same vibe ๐ค.
Example: S: * LSUB () "." #news.comp.mail.misc
7.2.4. SEARCH Response
Data: zero or more numbers
the SEARCH response shows up as a result of a SEARCH or UID SEARCH command ๐. The numbers point to the messages that match the search criteria ๐ฏ. For SEARCH, these are message sequence numbers; for UID SEARCH, these are unique identifiers ๐. Each number is delimited by a space โจ.
Example: S: * SEARCH 2 3 6
7.2.5. FLAGS Response
Data: flag parenthesized list
the FLAGS response shows up as a result of a SELECT or EXAMINE command ๐ณ๏ธโ๐. The flag parenthesized list tells you which flags apply to this mailbox ๐ฉ. At a minimum you get the system-defined flags, but the server might have other flags too, depending on how it's implemented ๐.
The update from the FLAGS response MUST be recorded by the client ๐. No skipping this one, bestie ๐ซถ.
Example: S: * FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
7.3. Server Responses - Message Status
these responses are always untagged ๐. This is how message data gets sent from the server to the client, often as the result of a command with the same name ๐. Right after the "*" token there's a number ๐ข, and it represents either a message sequence number or a message count. Main character number energy โจ.
7.3.1. EXISTS Response
Data: none
the EXISTS response reports how many messages are in the mailbox ๐ฆ. It shows up as a result of a SELECT or EXAMINE command, and also whenever the size of the mailbox changes, like when new mail arrives ๐ฌ.
The update from the EXISTS response MUST be recorded by the client ๐.
Example: S: * 23 EXISTS
7.3.2. RECENT Response
Data: none
the RECENT response reports how many messages have arrived since the last time a SELECT command was run on this mailbox ๐. It shows up as a result of a SELECT or EXAMINE command, and also whenever the size of the mailbox changes, like new mail ๐.
The update from the RECENT response MUST be recorded by the client ๐ซถ.
Example: S: * 5 RECENT
7.3.3. EXPUNGE Response
Data: none
the EXPUNGE response reports that the specified message sequence number has been permanently removed from the mailbox ๐๏ธ๐. After that, the message sequence number for each message after it in the mailbox is immediately decremented by 1 ๐. That decrement shows up in message sequence numbers in later responses too, including other untagged EXPUNGE responses ๐.
Because of that immediate decrement rule, the message sequence numbers in a bunch of EXPUNGE responses depend on the order the messages get removed in ๐ง . Lower to higher, or higher to lower, makes a difference. For example, say 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. A "higher to lower server" will send successive untagged EXPUNGE responses for message sequence numbers 9, 8, 7, 6, and 5. Same messages gone, totally different numbers, iykyk ๐.
An EXPUNGE response MUST NOT be sent when no command is in progress ๐ซ, nor while responding to a FETCH, STORE, or SEARCH command ๐ โโ๏ธ. This rule is necessary to prevent a loss of synchronization of message sequence numbers between client and server ๐. Without it, everyone's numbers get out of sync and it's chaos ๐ญ.
The update from the EXPUNGE response MUST be recorded by the client ๐.
Example: S: * 44 EXPUNGE
7.3.4. FETCH Response โจ
Data: message data
The FETCH response is how the server hands the client info about a message ๐ฌ It comes back as pairs of data item names and their values, all wrapped in parentheses. You'll see it when the client sends a FETCH or STORE command, and also when the server decides on its own to send something (like flag updates) ๐ฆ
The current data items are:
BODY: a form of BODYSTRUCTURE without extension data ๐BODY[section]: a string with the body contents of the specified section ๐- The client should interpret this string based on the content transfer encoding, body type, and body subtype.
- 8-bit textual data is allowed if a character set identifier is part of the body parameter parenthesized list for this section.
- Non-textual data, like binary, has to 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 has to decode the transfer encoded string ๐
BODYSTRUCTURE: a parenthesized list that describes the body structure of a message ๐งฉ The server works this out by parsing the [RFC-822] header and body into component parts, filling in defaults for various fields whenever needed.- Multiple parts are shown through parenthesis nesting. Where you'd normally expect a body type as the first element of the list, you get a nested body instead. The second element of the list is the multipart subtype (mixed, digest, parallel, alternative, etc.).
- Extension data comes right after the multipart subtype. It's never returned with the BODY fetch, but it may come back with a BODYSTRUCTURE fetch. If extension data is present, it must be in the defined order.
- The extension data of a multipart body part comes in this order:
- body parameter parenthesized list: a parenthesized list of attribute/value pairs [e.g.
(foo bar baz rag)where "bar" is the value of "foo" and "rag" is the value of "baz"] as defined in [MIME-1].
- body parameter parenthesized list: a parenthesized list of attribute/value pairs [e.g.
- Any extension data after that isn't defined yet in this version of the protocol. It may be made up of zero or more NILs, strings, numbers, or possibly nested parenthesized lists of that stuff. Client implementations that do a BODYSTRUCTURE fetch MUST be prepared to accept that extension data ๐ซถ Server implementations MUST NOT send that extension data until a revision of this protocol has defined it ๐ซ
- The basic fields of a non-multipart body part come in this order:
- body type: a string giving the content type name as defined in [MIME-1].
- body subtype: a string giving the content subtype name as defined in [MIME-1].
- body parameter parenthesized list: a parenthesized list of attribute/value pairs [e.g.
(foo bar baz rag)where "bar" is the value of "foo" and "rag" is the value of "baz"] as defined in [MIME-1]. - body id: a string giving the content id as defined in [MIME-1].
- body description: a string giving the content description as defined in [MIME-1].
- body encoding: a string giving the content transfer encoding as defined in [MIME-1].
- body size: a number giving the size of the body in octets. This size is the size in its transfer encoding, not the size after any decoding.
- A body type of type MESSAGE and subtype RFC822 has, 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 has, right after the basic fields, the size of the body in text lines. Again, this size is the size in its transfer encoding, not the size after any decoding.
- Extension data follows the basic fields and the type-specific fields listed above. It's never returned with the BODY fetch, but it may come back with a BODYSTRUCTURE fetch. If extension data is present, it must be in the defined order.
- The extension data of a non-multipart body part comes in this order:
- body MD5: a string giving the content MD5 value as defined in [MIME-1].
- Any extension data after that 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 gets this by parsing the [RFC-822] header into component parts, filling in defaults for various fields as needed.- The fields of the envelope structure come in this 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 email address. Its fields come in this order: personal name, [SMTP] at-domain-list (source route), mailbox name, and host name.
- [RFC-822] group syntax is shown with 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 (the semi-colon in RFC 822 syntax). If the mailbox name field is not 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 gets presented as NIL. Also, the server must default the reply-to and sender fields from the from field, because a client isn't expected to know to do that ๐
FLAGS: a parenthesized list of flags that are set for this message ๐ฉ This can include keywords plus these system flags:\Seen: the message has been read ๐\Answered: the message has been answered ๐ฌ\Flagged: the message is "flagged" for urgent or special attention โญ\Deleted: the message is "deleted" for removal by a later EXPUNGE ๐๏ธ\Draft: the message hasn't finished composition (it's marked as a draft) โ๏ธ- There's also one special flag that can be fetched but not stored:
\Recent: the message has arrived since the last time this mailbox was selected ๐
INTERNALDATE: a string with the date and time of final delivery of the message as defined by [SMTP] ๐RFC822: a string with the message in [RFC-822] format. The header portion of the message must be 7-bit. 8-bit characters are only allowed in the non-header portion, and only if there are [MIME-1] data in the message that identify the character set of the message ๐RFC822.HEADER: a string with the [RFC-822] format header of the message, including the blank line between the header and the body that delimits them. The entire string must be 7-bit, because 8-bit characters aren't allowed in headers. RFC822.HEADER is used to return data for the RFC822.HEADER, RFC822.HEADER.LINES, and RFC822.HEADER.LINES.NOT FETCH data items. Note that a blank line is always included, no matter what header line restrictions apply ๐RFC822.SIZE: a number with the count of octets in the message in [RFC-822] format ๐ขRFC822.TEXT: a string with the text body of the message, leaving out the [RFC-822] header. 8-bit characters are only allowed if there are [MIME-1] data in the message that identify the character set of the message ๐UID: a number that's the unique identifier of the message ๐
Example: S: * 23 FETCH (FLAGS (\Seen) RFC822.SIZE 44827)
S: * 23 FETCH (FLAGS (\Seen) RFC822.SIZE 44827)
7.3.5. Obsolete Responses
In addition to the responses listed here, client implementations MUST accept and implement the obsolete responses described in Appendix B ๐ฐ๏ธ Yes, even the old ones, bestie ๐ญ
7.4. Server Responses - Command Continuation Request
The command continuation request response is marked with a "+" token instead of a tag ๐ช That's the server saying "ready when you are." 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 whenever an argument to any command is a literal ๐ฆ
The client isn't allowed to send the octets of the literal unless the server says it expects them. This lets the server process commands and reject errors line by line, which is so smart ๐ง The rest of the command, including the CRLF that ends a command, comes after the octets of the literal. If there are more command arguments, the literal octets are followed by a space and then those arguments ๐
So here's how a literal looks when it's sent to the server, with the braces counting the bytes ๐
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 IMAP4 session โจ
Okay bestie, this is a full IMAP4 session transcript, basically a whole group chat between the client (C) and the server (S) ๐ฌ. One long line got split up so it's easier to read, and that's just for editorial clarity ๐ธ.
S: * OK IMAP4 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 "14-Jul-1993 02:44:25 -0700"
RFC822.SIZE 4282 ENVELOPE ("Wed, 14 Jul 1993 02:23:25 -0700 (PDT)"
"IMAP4 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 rfc822.header
S: * 12 FETCH (RFC822.HEADER {346}
S: Date: Wed, 14 Jul 1993 02:23:25 -0700 (PDT)
S: From: Terry Gray <gray@cac.washington.edu>
S: Subject: IMAP4 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 IMAP4 server terminating connection
S: a006 OK LOGOUT completed
9. Formal Syntax โจ
Time for the grammar ๐ง โจ. This spec uses the augmented Backus-Naur Form (BNF) notation from [RFC-822], with one twist: the delimiter for the "#" construct is a single space (SPACE), not a comma ๐.
Everything is case-insensitive, except where noted, and using upper or lower case for token strings is just for editorial clarity ๐ . Implementations MUST accept these strings in a case-insensitive fashion ๐ซถ.
Obsolete syntax might still show up if you're talking to implementations written for an earlier version of this protocol (like IMAP2) ๐ฆ. New implementations SHOULD accept obsolete syntax as input, but MUST NOT otherwise use such syntax ๐.
address ::= "(" addr_name SPACE addr_adl SPACE addr_mailbox
SPACE addr_host ")"
addr_adl ::= nstring
addr_host ::= nstring
;; NIL indicates [RFC-822] group syntax
addr_mailbox ::= nstring
;; NIL indicates end of [RFC-822] group; if
;; non-NIL and addr_host is NIL, holds
;; [RFC-822] group name
addr_name ::= nstring
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 / CTLs / list_wildcards /
quoted_specials
authenticate ::= "AUTHENTICATE" SPACE auth_type *(CRLF base64)
auth_type ::= atom
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 1#body_extension]
;; MUST NOT be returned on non-extensible
;; "BODY" fetch
body_ext_mpart ::= body_fld_param [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_enc ::= (<"> ("7BIT" / "8BIT" / "BINARY" / "BASE64"/
"QUOTED-PRINTABLE") <">) / string
body_fld_id ::= nstring
body_fld_lines ::= number
body_fld_md5 ::= nstring
body_fld_octets ::= number
body_fld_param ::= "(" 1#(string string) ")" / nil
body_fld_subtyp ::= string
body_type_1part ::= (body_type_basic / body_type_msg / body_type_text)
[SPACE body_ext_1part]
body_type_basic ::= (<"> ("APPLICATION" / "AUDIO" / "IMAGE" /
"MESSAGE" / "VIDEO") <">) / string) SPACE
body_fld_subtyp SPACE body_fields
;; MESSAGE subtype MUST NOT be "RFC822"
body_type_mpart ::= 1*body SPACE body_fld_subtyp
[SPACE body_ext_mpart]
body_type_msg ::= <"> "MESSAGE" <"> SPACE <"> "RFC822" <"> SPACE
body_fields SPACE envelope SPACE body SPACE
body_fld_lines
body_type_text ::= <"> "TEXT" <"> SPACE body_fld_subtyp SPACE
body_fields SPACE body_fld_lines
capability ::= atom
;; Must begin with "X" or be registered with
;; IANA as standard or standards-track
capability_data ::= "CAPABILITY" SPACE "IMAP4" [SPACE 1#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 / find / list /
lsub / rename / select / 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 / partial / 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, 0x0C>
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_old)
date_year ::= 4digit
date_year_old ::= 2digit
;; OBSOLETE, (year - 1900)
date_time ::= <"> (date_time_new / date_time_old) <">
date_time_new ::= date_day_fixed "-" date_month "-" date_year
SPACE time SPACE zone
date_time_old ::= date_day_fixed "-" date_month "-" date_year_old
SPACE time "-" zone_old
;; OBSOLETE
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 ::= "BODY" / "BODYSTRUCTURE" /
"BODY" [".PEEK"] "[" section "]" / "ENVELOPE" /
"FLAGS" / "INTERNALDATE" / "UID" /
"RFC822" (([".TEXT"] [".PEEK"]) / ".SIZE" /
(".HEADER" [".LINES" [".NOT"] SPACE header_list])
find ::= "FIND" SPACE ["ALL."] "MAILBOXES" SPACE
list_mailbox
;; OBSOLETE
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_line ::= astring
header_list ::= "(" 1#header_line ")"
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; other names may be
;; case-sensitive depending on implementation.
mailbox_data ::= "FLAGS" SPACE flag_list /
"LIST" SPACE mailbox_list /
"LSUB" SPACE mailbox_list /
"MAILBOX" SPACE text /
"SEARCH" [SPACE 1#nz_number] /
number SPACE "EXISTS" / number SPACE "RECENT"
mailbox_list ::= "(" #("\Marked" / "\Noinferiors" /
"\Noselect" / "\Unmarked" / flag_extension) ")"
SPACE (<"> QUOTED_CHAR <"> / nil) SPACE mailbox
message_data ::= nz_number SPACE ("EXPUNGE" /
("FETCH" SPACE msg_fetch) / msg_obsolete)
msg_fetch ::= "(" 1#("BODY" SPACE body /
"BODYSTRUCTURE" SPACE body /
"BODY[" section "]" SPACE nstring /
"ENVELOPE" SPACE envelope /
"FLAGS" SPACE "(" #(flag / "\Recent") ")" /
"INTERNALDATE" SPACE date_time /
"RFC822" [".HEADER" / ".TEXT"] SPACE nstring /
"RFC822.SIZE" SPACE number /
"UID" SPACE uniqueid) ")"
msg_obsolete ::= "COPY" / ("STORE" SPACE msg_fetch)
;; OBSOLETE untagged data responses
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)
partial ::= "PARTIAL" SPACE nz_number SPACE
("BODY" [".PEEK"] "[" section "]" /
"RFC822" (([".TEXT"] [".PEEK"]) / ".HEADER")
SPACE number SPACE number
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 ::= *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
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
;; Server will disconnect condition
resp_cond_state ::= ("OK" / "NO" / "BAD") SPACE resp_text
;; Status condition
resp_text ::= ["[" resp_text_code "]" SPACE] (text_mime2 / text)
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]
search_criteria
;; Character set must be registered with IANA
;; as a MIME character set
search_criteria ::= 1#search_key
search_key ::= search_new / search_old
search_new ::= "DRAFT" /
"HEADER" SPACE header_line 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 /
"(" search_criteria ")"
;; New in IMAP4
search_old ::= "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"
;; Defined in [IMAP2]
section ::= "0" / nz_number ["." section]
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>
store ::= "STORE" SPACE set SPACE store_att_flags
store_att_flags ::= (["+" / "-"] "FLAGS" [".SILENT"]) SPACE
(flag_list / #flag)
string ::= quoted / literal
subscribe ::= ("SUBSCRIBE" SPACE mailbox) / subscribe_obs
subscribe_obs ::= "SUBSCRIBE" SPACE "MAILBOX" SPACE mailbox
;;OBSOLETE
tag ::= 1*<any ATOM_CHAR except "+">
text ::= 1*TEXT_CHAR
text_mime2 ::= "=?" <charset> "?" <encoding> "?"
<encoded-text> "?="
;; Syntax defined in [MIME-2]
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) / unsubscribe_obs
unsubscribe_obs ::= "UNSUBSCRIBE" SPACE "MAILBOX" SPACE mailbox
;;OBSOLETE
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".
zone_old ::= "UT" / "GMT" / "Z" / ;; +0000
"AST" / "EDT" / ;; -0400
"EST" / "CDT" / ;; -0500
"CST" / "MDT" / ;; -0600
"MST" / "PDT" / ;; -0700
"PST" / "YDT" / ;; -0800
"YST" / "HDT" / ;; -0900
"HST" / "BDT" / ;; -1000
"BST" / ;; -1100
"A" / "B" / "C" / "D" / "E" / "F" / ;; +1 to +6
"G" / "H" / "I" / "K" / "L" / "M" / ;; +7 to +12
"N" / "O" / "P" / "Q" / "R" / "S" / ;; -1 to -6
"T" / "U" / "V" / "W" / "X" / "Y" ;; -7 to -12
;; OBSOLETE
10. Author's Note ๐
okay so this bit is the author being real about the history ๐ซถ this document is a revision or rewrite of earlier documents, and it supersedes the protocol specification in those older docs: the IMAP4 Internet drafts, the IMAP2bis Internet drafts, the unpublished IMAP2bis.TXT document, RFC 1176, and RFC 1064. so if you're hunting through old specs, this is the one that wins ๐
11. Security Considerations ๐
okay bestie, this one is SERIOUS so let's pay attention ๐ญ๐ฅ
IMAP4 protocol transactions, including electronic mail data, are sent in the clear over the network unless the optional privacy protection is negotiated in the AUTHENTICATE command. so by default everything is just floating around out there unencrypted unless that privacy protection gets negotiated ๐
A server error message for an AUTHENTICATE command which fails due to invalid credentials should not detail why the credentials are invalid. basically the server should keep its lips sealed about the exact reason ๐ค
Use of the LOGIN command sends passwords in the clear. This can be avoided by using the AUTHENTICATE command instead. so if you can, reach for AUTHENTICATE and keep those passwords off the open wire ๐ฆ
A server error message for a failing LOGIN command should not specify that the user name, as opposed to the password, is invalid. same energy here: don't tell people which part of the login was wrong ๐
Additional security considerations are discussed in the section discussing the AUTHENTICATE and LOGIN commands. so go check those sections too, they've got more tea โ
12. Author's Address ๐ฎ
Mark R. Crispin ๐ธ
Networks and Distributed Computing, JE-30
University of Washington
Seattle, WA 98195
Phone: (206) 543-5762
EMail: MRC@CAC.Washington.EDU
Appendices ๐
A. Obsolete Commands ๐ฐ๏ธ
okay so these commands are all OBSOLETE, which means it is NOT required to support any of them in new server implementations ๐ they're only documented here for the benefit of implementors who may want to support them so they can keep talking to old client implementations. the section headings below are meant to line up with where these commands would have lived in the main document if they hadn't been obsoleted ๐ง
A.6.3.OBS.1. FIND ALL.MAILBOXES Command ๐
- Arguments: mailbox name with possible wildcards
- Data: untagged responses: MAILBOX
- Result:
OK - find completed
NO - find failure: can't list that name
BAD - command unknown or arguments invalid
the FIND ALL.MAILBOXES command returns a subset of names from the complete set of all names available to the user ๐ซง it returns zero or more untagged MAILBOX replies. the mailbox argument is similar to the one for LIST with an empty reference, except that the characters "%" and "?" match a single character. it's giving LIST but make it a little different โจ
Example:
C: A002 FIND ALL.MAILBOXES *
S: * MAILBOX blurdybloop
S: * MAILBOX INBOX
S: A002 OK FIND ALL.MAILBOXES completed
A.6.3.OBS.2. FIND MAILBOXES Command ๐ฆ
- Arguments: mailbox name with possible wildcards
- Data: untagged responses: MAILBOX
- Result:
OK - find completed
NO - find failure: can't list that name
BAD - command unknown or arguments invalid
Okay so FIND MAILBOXES ๐
this one hands back a subset of names from the set the user has declared as "active" or "subscribed" ๐ฆ It sends back zero or more untagged MAILBOX replies. The mailbox argument works like LSUB with an empty reference, except that % and ? each match a single character ๐
C: A002 FIND MAILBOXES *
S: * MAILBOX blurdybloop
S: * MAILBOX INBOX
S: A002 OK FIND MAILBOXES completed
A.6.3.OBS.3. SUBSCRIBE MAILBOX Command โจ
Arguments: mailbox name
Data: no specific data for this command
Result:
OK- subscribe completedNO- subscribe failure: can't subscribe to that nameBAD- command unknown or arguments invalid
SUBSCRIBE MAILBOX is basically the same as SUBSCRIBE in effect ๐ซถ but a server that does this command must be able to tell apart a SUBSCRIBE MAILBOX command and a SUBSCRIBE command whose mailbox name is literally "MAILBOX" ๐
C: A002 SUBSCRIBE MAILBOX #news.comp.mail.mime
S: A002 OK SUBSCRIBE MAILBOX to #news.comp.mail.mime
completed
C: A003 SUBSCRIBE MAILBOX
S: A003 OK SUBSCRIBE to MAILBOX completed
A.6.3.OBS.4. UNSUBSCRIBE MAILBOX Command ๐ธ
Arguments: mailbox name
Data: no specific data for this command
Result:
OK- unsubscribe completedNO- unsubscribe failure: can't unsubscribe that nameBAD- command unknown or arguments invalid
UNSUBSCRIBE MAILBOX is identical in effect to UNSUBSCRIBE ๐ A server that implements it must be able to distinguish between an UNSUBSCRIBE MAILBOX command and an UNSUBSCRIBE command with a mailbox name argument of "MAILBOX" ๐
C: A002 UNSUBSCRIBE MAILBOX #news.comp.mail.mime
S: A002 OK UNSUBSCRIBE MAILBOX from #news.comp.mail.mime
completed
C: A003 UNSUBSCRIBE MAILBOX
S: A003 OK UNSUBSCRIBE from MAILBOX completed
B. Obsolete Responses ๐ง
The following responses are OBSOLETE ๐ฅ Except as noted below, these responses MUST NOT be transmitted by new server implementations. Fair warning, bestie.
The section headings here line up with where these responses would sit in the main document if they hadn't been obsoleted ๐
B.7.2.OBS.1. MAILBOX Response ๐ฆ
Data: name
The MAILBOX response MUST NOT be transmitted by server implementations except in response to the obsolete FIND MAILBOXES and FIND ALL.MAILBOXES commands. Client implementations that don't use these commands MAY ignore this response. It's documented here so implementors who want compatibility with old client implementations can support it ๐ซถ
This response shows up as a result of FIND MAILBOXES and FIND ALL.MAILBOXES. It returns a single name that matches the FIND specification. There are no attributes or hierarchy delimiter, so it's very minimal ๐
S: * MAILBOX blurdybloop
B.7.3.OBS.1. COPY Response ๐
Data: none
The COPY response MUST NOT be transmitted by new server implementations. Client implementations MUST ignore the COPY response. It's documented here for client implementors who might run into it from old server implementations ๐
In some experimental versions of this protocol, this response came back in reply to a COPY command, marking on a per-message basis that the message was copied successfully โจ
S: * 44 COPY
B.7.3.OBS.2. STORE Response ๐
Data: message data
The STORE response MUST NOT be transmitted by new server implementations. Client implementations MUST treat the STORE response as equivalent to the FETCH response. It's documented here for client implementors who might see it from old server implementations ๐ญ
In some experimental versions of this protocol, this response was returned instead of FETCH in reply to a STORE command, reporting the new value of the flags ๐ฅ
S: * 69 STORE (FLAGS (\Deleted))
C. References ๐
[IMAP-AUTH] Myers, J., "IMAP4 Authentication Mechanism", RFC 1731. Carnegie-Mellon University, December 1994.
[IMAP-COMPAT] Crispin, M. "IMAP4 Compatibility with IMAP2 and IMAP2bis", RFC 1732, University of Washington, December 1994.
[IMAP-DISC] Austein, R. "Synchronization Operations for Disconnected IMAP4 Clients", Work in Progress.
[IMAP-MODEL] Crispin, M. "Distributed Electronic Mail Models in IMAP4", RFC 1733, University of Washington, December 1994.
[IMAP-NAMING] Crispin, M. "Mailbox Naming Convention in IMAP4", Work in Progress.
[IMAP2] Crispin, M., "Interactive Mail Access Protocol - Version 2", RFC 1176, University of Washington, August 1990.
[IMSP] Myers, J. "IMSP -- Internet Message Support Protocol", Work in Progress.
[MIME-1] Borenstein, N., and Freed, N., "MIME (Multipurpose Internet Mail Extensions) Part One: Mechanisms for Specifying and Describing the Format of Internet Message Bodies", RFC 1521, Bellcore, Innosoft, September 1993.
[MIME-2] Moore, K., "MIME (Multipurpose Internet Mail Extensions) Part Two: Message Header Extensions for Non-ASCII Text", RFC 1522, University of Tennessee, September 1993.
[RFC-822] Crocker, D., "Standard for the Format of ARPA Internet Text Messages", STD 11, RFC 822, University of Delaware, August 1982.
[SMTP] Postel, Jonathan B. "Simple Mail Transfer Protocol", STD 10, RFC 821, USC/Information Sciences Institute, August 1982.
E. IMAP4 Keyword Index ๐
Index โจ
Okay bestie, this is the index, and it's giving full alphabetical organization. ๐๏ธ๐ Every command, response, search key, fetch item, and flag lives here with its page number, so you can jump straight to the good stuff. Lowkey the most useful part of the whole doc. ๐ซถ
+FLAGS <flag list> (store command data item) ............... 34
+FLAGS.SILENT <flag list> (store command data item) ........ 34
-FLAGS <flag list> (store command data item) ............... 34
-FLAGS.SILENT <flag list> (store command data item) ........ 34
ALERT (response code) ...................................... 39
ALL (fetch item) ........................................... 29
ALL (search key) ........................................... 27
ANSWERED (search key) ...................................... 27
APPEND (command) ........................................... 22
AUTHENTICATE (command) ..................................... 12
BAD (response) ............................................. 41
BCC <string> (search key) .................................. 27
BEFORE <date> (search key) ................................. 27
BODY (fetch item) .......................................... 29
BODY (fetch result) ........................................ 46
BODY <string> (search key) ................................. 27
BODY.PEEK[<section>] (fetch item) .......................... 30
BODYSTRUCTURE (fetch item) ................................. 31
BODYSTRUCTURE (fetch result) ............................... 47
BODY[<section>] (fetch item) ............................... 29
BODY[section] (fetch result) ............................... 46
BYE (response) ............................................. 41
CAPABILITY (command) ....................................... 10
CAPABILITY (response) ...................................... 42
CC <string> (search key) ................................... 27
CHECK (command) ............................................ 23
CLOSE (command) ............................................ 24
COPY (command) ............................................. 34
COPY (response) ............................................ 68
CREATE (command) ........................................... 17
DELETE (command) ........................................... 18
DELETED (search key) ....................................... 27
DRAFT (search key) ......................................... 27
ENVELOPE (fetch item) ...................................... 31
ENVELOPE (fetch result) .................................... 49
EXAMINE (command) .......................................... 16
EXISTS (response) .......................................... 45
EXPUNGE (command) .......................................... 25
EXPUNGE (response) ......................................... 45
FAST (fetch item) .......................................... 31
FETCH (command) ............................................ 29
FETCH (response) ........................................... 46
FIND ALL.MAILBOXES (command) ............................... 65
FIND MAILBOXES (command) ................................... 65
FLAGGED (search key) ....................................... 27
FLAGS (fetch item) ......................................... 31
FLAGS (fetch result) ....................................... 50
FLAGS (response) ........................................... 44
FLAGS <flag list> (store command data item) ................ 34
FLAGS.SILENT <flag list> (store command data item) ......... 34
FROM <string> (search key) ................................. 27
FULL (fetch item) .......................................... 31
HEADER <field-name> <string> (search key) .................. 27
INTERNALDATE (fetch item) .................................. 31
INTERNALDATE (fetch result) ................................ 50
KEYWORD <flag> (search key) ................................ 27
LARGER <n> (search key) .................................... 27
LIST (command) ............................................. 20
LIST (response) ............................................ 43
LOGIN (command) ............................................ 14
LOGOUT (command) ........................................... 11
LSUB (command) ............................................. 22
LSUB (response) ............................................ 44
MAILBOX (response) ......................................... 68
NEW (search key) ........................................... 27
NO (response) .............................................. 40
NOOP (command) ............................................. 11
NOT <search-key> (search key) .............................. 28
OK (response) .............................................. 40
OLD (search key) ........................................... 28
ON <date> (search key) ..................................... 28
OR <search-key1> <search-key2> (search key) ................ 28
PARSE (response code) ...................................... 39
PARTIAL (command) .......................................... 32
PERMANENTFLAGS (response code) ............................. 39
PREAUTH (response) ......................................... 41
READ-ONLY (response code) .................................. 39
READ-WRITE (response code) ................................. 39
RECENT (response) .......................................... 45
RECENT (search key) ........................................ 28
RENAME (command) ........................................... 18
RFC822 (fetch item) ........................................ 31
RFC822 (fetch result) ...................................... 50
RFC822.HEADER (fetch item) ................................. 31
RFC822.HEADER (fetch result) ............................... 50
RFC822.HEADER.LINES <header_list> (fetch item) ............. 31
RFC822.HEADER.LINES.NOT <header_list> (fetch item) ......... 32
RFC822.PEEK (fetch item) ................................... 31
RFC822.SIZE (fetch item) ................................... 32
RFC822.SIZE (fetch result) ................................. 50
RFC822.TEXT (fetch item) ................................... 32
RFC822.TEXT (fetch result) ................................. 51
RFC822.TEXT.PEEK (fetch item) .............................. 32
SEARCH (command) ........................................... 25
SEARCH (response) .......................................... 44
SEEN (search key) .......................................... 28
SELECT (command) ........................................... 15
SENTBEFORE <date> (search key) ............................. 28
SENTON <date> (search key) ................................. 28
SENTSINCE <date> (search key) .............................. 28
SINCE <date> (search key) .................................. 28
SMALLER <n> (search key) ................................... 28
STORE (command) ............................................ 33
STORE (response) ........................................... 69
SUBJECT <string> (search key) .............................. 28
SUBSCRIBE (command) ........................................ 19
SUBSCRIBE MAILBOX (command) ................................ 66
TEXT <string> (search key) ................................. 28
TO <string> (search key) ................................... 28
TRYCREATE (response code) .................................. 39
UID (command) .............................................. 35
UID (fetch item) ........................................... 32
UID (fetch result) ......................................... 51
UID <message set> (search key) ............................. 28
UIDVALIDITY (response code) ................................ 40
UNANSWERED (search key) .................................... 29
UNDELETED (search key) ..................................... 29
UNDRAFT (search key) ....................................... 29
UNFLAGGED (search key) ..................................... 29
UNKEYWORD <flag> (search key) .............................. 29
UNSEEN (response code) ..................................... 40
UNSEEN (search key) ........................................ 29
UNSUBSCRIBE (command) ...................................... 19
UNSUBSCRIBE MAILBOX (command) .............................. 66
X<atom> (command) .......................................... 37
\Answered (system flag) .................................... 50
\Deleted (system flag) ..................................... 50
\Draft (system flag) ....................................... 50
\Flagged (system flag) ..................................... 50
\Marked (mailbox name attribute) ........................... 43
\Noinferiors (mailbox name attribute) ...................... 43
\Noselect (mailbox name attribute) ......................... 43
\Recent (system flag) ...................................... 50
\Seen (system flag) ........................................ 50
\Unmarked (mailbox name attribute) ......................... 43
That's the whole index, babe! ๐โจ Every entry, every page number, all accounted for. Main character energy fr. ๐๐ฆ
๐ฆ where this page comes from
- ietf: rfc1730 1994-12
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms