
IMAP Commands
Following on from our IMAP 101 and Advanced IMAP posts, we’ve received a few queries on what other IMAP commands can be used, and requests for some examples of using the client commands.
So, this post we will provide an overview of all the main IMAP commands that a client can send under RFC 3501 (and others), explain what the command does, and provide a small example snippet of usage.
Disclaimer: We are only giving a high level overview. RFC 3501 defines all these commands in far greater detail than what we show here, and should be considered the authoritative source.
Client Commands: Not Authenticated State
The following IMAP commands can be issued to a server before authentication has taken place:
STARTTLS
This command instructs the server that the client wishes to encrypt the session now. This command may only be issued if the server advertised that STARTTLS is available and supported. If a successful key negotiation results after this command is issued, then the session is encrypted and IMAP commands continue.
Here is an example of connecting to an IMAP server (with netcat) and issuing the STARTTLS command:
$ nc zeus.p 143 * OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE STARTTLS AUTH=PLAIN AUTH=LOGIN] IMAP/POP3 ready - zeus c1 STARTTLS c1 OK Begin TLS negotiation now.
Here is openssl’s s_client utility performing a successful TLS connection:
$ openssl s_client -connect zeus.p:143 -starttls imap -crlf -quiet depth=0 OU = IMAP server, CN = imap.example.com, emailAddress = [email protected] verify error:num=18:self signed certificate verify return:1 depth=0 OU = IMAP server, CN = imap.example.com, emailAddress = [email protected] verify return:1 . OK Pre-login capabilities listed, post-login capabilities have more.
AUTHENTICATE
This command advises the server that the client wants to initiate a SASL authentication mechanism to prove its identity. The client may only select a SASL method advertised by the server – which is shown in the response to the command CAPABILITY.
This is an example from our IMAP 101 post:
$ telnet imap-us.atmailcloud.com 143 Trying 204.145.97.25... Connected to imap-us.atmailcloud.com. Escape character is '^]'. * OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE AUTH=PLAIN AUTH=LOGIN] IMAP/POP3 ready - us11-012mip a authenticate login + VXNlcm5hbWU6 c29tZXVzZXJAZXhhbXBsZS5hdG1haWxjbG91ZC5jb20= + UGFzc3dvcmQ6 TXlfUEBzc3dvcmQx a OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS THREAD=ORDEREDSUBJECT MULTIAPPEND URL-PARTIAL CATENATE UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS BINARY MOVE NOTIFY SPECIAL-USE QUOTA] Logged in
LOGIN
This command advises the server that the client wants to login with a username and password to prove its identity.
Here is the example from our IMAP 101 post:
$ telnet imap-us.atmailcloud.com 143 Trying 204.145.97.26... Connected to imap-us.atmailcloud.com. Escape character is '^]'. * OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE AUTH=PLAIN AUTH=LOGIN] IMAP/POP3 ready - us11-011mip A1 login [email protected] My_P@ssword1 A1 OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS THREAD=ORDEREDSUBJECT MULTIAPPEND URL-PARTIAL CATENATE UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS BINARY MOVE NOTIFY SPECIAL-USE QUOTA] Logged in
Client Commands: Authenticated State
Once a client is authenticated to the server, the following set of commands become accessible.
SELECT
This command instructs the server that the client now wishes to select a particular mailbox or folder, and any commands that relate to a folder should assume this folder as the target of that command. For example, an INBOX or a subfolder such as, “To Do.This Weekend”. Once a mailbox is selected, the state of the connection becomes “Selected”.
This is an example from our IMAP 101 post:
g21 SELECT "INBOX" * FLAGS (Answered Flagged Deleted Seen Draft) * OK [PERMANENTFLAGS (Answered Flagged Deleted Seen Draft *)] Flags permitted. * 4 EXISTS * 0 RECENT * OK [UNSEEN 2] First unseen. * OK [UIDVALIDITY 1536750617] UIDs valid * OK [UIDNEXT 9] Predicted next UID * OK [HIGHESTMODSEQ 11] Highest g21 OK [READ-WRITE] Select completed (0.000 + 0.000 secs).
EXAMINE
This command does the exact same thing as SELECT, except that it selects the folder in read-only mode, meaning that no changes can be effected on the folder.
Here is an example from RFC 3501:
A932 EXAMINE blurdybloop * 17 EXISTS * 2 RECENT * OK [UNSEEN 8] Message 8 is first unseen * OK [UIDVALIDITY 3857529045] UIDs valid * OK [UIDNEXT 4392] Predicted next UID * FLAGS (\Answered \Flagged \Deleted \Seen \Draft) * OK [PERMANENTFLAGS ()] No permanent flags permitted A932 OK [READ-ONLY] EXAMINE completed
CREATE
This command created a new folder.
This example is from our Advanced IMAP post:
c CREATE work c OK Create completed (0.002 + 0.000 + 0.001 secs). k2 LIST "" "*" * LIST (\HasNoChildren \Trash) "." Trash * LIST (\HasNoChildren) "." folder1 * LIST (\HasNoChildren) "." work * LIST (\HasNoChildren) "." INBOX k2 OK List completed (0.001 + 0.000 secs).
DELETE
This command deletes the named mailbox or folder.
We haven’t covered this command in either our IMAP 101 or Advanced IMAP posts, so here is an example from RFC 3501:
A682 LIST "" * * LIST () "/" blurdybloop * LIST (\Noselect) "/" foo * LIST () "/" foo/bar A682 OK LIST completed A683 DELETE blurdybloop A683 OK DELETE completed A684 DELETE foo A684 NO Name "foo" has inferior hierarchical names A685 DELETE foo/bar A685 OK DELETE Completed A686 LIST "" * * LIST (\Noselect) "/" foo A686 OK LIST completed A687 DELETE foo A687 OK DELETE Completed
RENAME
This command renames a mailbox or folder from one name to a new name.
Again, another command we haven’t covered in our previous posts.
An example from RFC 3501:
A682 LIST "" * * LIST () "/" blurdybloop * LIST (\Noselect) "/" foo * LIST () "/" foo/bar A682 OK LIST completed A683 RENAME blurdybloop sarasoop A683 OK RENAME completed A684 RENAME foo zowie A684 OK RENAME Completed A685 LIST "" * * LIST () "/" sarasoop * LIST (\Noselect) "/" zowie * LIST () "/" zowie/bar A685 OK LIST completed
SUBSCRIBE
OK, this command needs a little explanation. In IMAP you have a list of folders (also called mailboxes), and these mailboxes may be: yours, the logged in user; or they might be other users who have given you access; or they might be publicly accessible folders, for anyone to access.
However, you may find that a subset of these folders are more interesting to you than others and therefore you wish to “subscribe” to them and only be notified of updates and changes to those folders.
When you SUBSCRIBE to a folder, that folder will be returned when the client issues an LSUB command (i.e. list subscribed folders only) – this means the client then only needs to poll for changes in the folders that you are interested in, rather than all of the folders you might be able to access.
Here is an example of the subscribe command in action from RFC 3501. In this case, a publicly available folder is being subscribed to:
A002 SUBSCRIBE #news.comp.mail.mime A002 OK SUBSCRIBE completed
UNSUBSCRIBE
No prizes for guessing what this command does. Yep, it’s the opposite of SUBSCRIBE above. You are telling the server that you are no longer interested in this folder, and please do not return this folder in response to the LSUB command.
The example from RFC 3501:
A002 UNSUBSCRIBE #news.comp.mail.mime 002 OK UNSUBSCRIBE completed
LIST
This command will list all folders/mailboxes that you are entitled to list on the server, whether it be your own folders, another user’s, or publicly available folders.
This command does take two possible arguments. The first (known as the “reference name”) indicates under what folder hierarchy you’d like to limit the list to. The second argument (known as the “mailbox name”) can contain wildcards to match names under the provided hierarchy.
Here is an example from our IMAP 101 post that lists all the folders under the users INBOX:
A1 list "INBOX/" "*" * LIST (HasNoChildren) "/" INBOX/some_other_folder * LIST (HasNoChildren UnMarked Archive) "/" INBOX/Archive * LIST (HasNoChildren UnMarked Sent) "/" INBOX/Sent * LIST (HasNoChildren Marked Trash) "/" INBOX/Trash * LIST (HasNoChildren Marked Junk) "/" INBOX/Spam * LIST (HasNoChildren UnMarked Drafts) "/" INBOX/Drafts A1 OK List completed (0.000 + 0.000 secs).
Compare that to this example taken from RFC 3501, which lists all folders under ~/Mail but not subfolders of those folders (the % characters causes this behaviour):
A202 LIST ~/Mail/ % * LIST (\Noselect) "/" ~/Mail/foo * LIST () "/" ~/Mail/meetings A202 OK LIST completed
LSUB
As discussed above under the SUBSCRIBE command, the LSUB command will act the same as LIST but only return folders that have been subscribed to by the user.
Here is the example from RFC 3501, that uses both reference names and mailbox names/patterns (as discussed above under the LIST command):
A002 LSUB "#news." "comp.mail.*" * LSUB () "." #news.comp.mail.mime * LSUB () "." #news.comp.mail.misc A002 OK LSUB completed A003 LSUB "#news." "comp.%" * LSUB (\NoSelect) "." #news.comp.mail A003 OK LSUB completed
STATUS
This command requests the status of the folder provided. This allows the status of a folder not currently selected to be updated in the client. The client must advise the server what attributes of the folder that it is interested in, with possible values being:
- MESSAGES: The number of messages in the mailbox.
- RECENT: The number of messages with the \Recent flag set.
- UIDNEXT: The next unique identifier value of the mailbox.
- UIDVALIDITY: The unique identifier validity value of the mailbox.
- UNSEEN: The number of messages which do not have the \Seen flag set.
We have not covered this command in any of our previous posts, so here is the example from RFC 3501:
A042 STATUS blurdybloop (UIDNEXT MESSAGES) * STATUS blurdybloop (MESSAGES 231 UIDNEXT 44292) A042 OK STATUS completed
APPEND
This command allows a message to be appended to a specified mailbox. This isn’t a copy/move command, you must supply a full message body to append.
Here is the example from our Advanced IMAP post – to be clear the number inside the curly brackets (i.e. {89} below) is the number of octets to expect for the message:
a1 APPEND "work.due today" {89} + OK Subject: Send the weekly report Remember to send the weekly report to THE BOSS TODAY!! a1 OK [APPENDUID 1548379804 2] Append completed (0.007 + 4.391 + 0.005 secs).
Client Commands: Authenticated State
Once a client selects (or EXAMINE’s) a folder, the following command becomes available to the client, in addition to the authenticated commands.
CHECK
This is a seldom used command. It requests a “checkpoint” on the server. Which means that the server is instructed to complete some housekeeping on the mailbox – very weird for a client to request this, and we’ve never seen a client call it, but it exists… for some reason, which can only possibly be implementation dependant.
An exciting example from RFC 3501:
FXXZ CHECK FXXZ OK CHECK Completed
CLOSE
This closes the currently selected mailbox, and as a side-effect, an expunge is run on the mailbox (i.e. all messages marked as \Deleted are deleted properly). After this command returns, the client is no longer in the “selected” state and returns to the “authenticated” state.
Here is the example from RFC 3501:
A341 CLOSE A341 OK CLOSE completed
EXPUNGE
This command instructs the server to permanently delete messages that have the \Deleted flag set on them from the currently selected folder.
Note: This does not mean “move to trash”. It means to really, properly, and finally delete.
Here is an example from our IMAP 101 post:
d store 2 +FLAGS (Deleted) * 2 FETCH (FLAGS (Deleted Seen)) d OK Store completed (0.001 + 0.000 secs). e expunge * 2 EXPUNGE e OK Expunge completed.
SEARCH
The search command is a powerful command that probably warrants an entire future post to itself. With the rise of mobile clients, it is a command that is being leveraged more than ever. Mobile clients don’t have the capacity to store and process mail on the device itself, and offloading this work onto a server saves precious battery life.
In a nutshell, you can provide various search terms to the server and any messages that match, in the currently selected folder, will be returned. One limitation of the command is that when multiple search terms are specified, they are considered “AND” terms by default, but you can select only two terms to “OR”, and there is no complex logic grouping (i.e. bracketing of terms) – so it’s rather simple in that regard.
Here is a rundown of all the possible criteria that can be specified:
- ALL: All messages in the mailbox.
- 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 (disregarding time and timezone) 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 and which contain the specified string in the text of the header (i.e. what comes after the colon). If the string to search is zero-length, this matches all messages that have a header line with the specified field-name, regardless of the contents.
- KEYWORD <flag>: Messages with the specified keyword flag set.
- LARGER <n>: Messages with a size larger than the specified number of octets.
- NEW: Messages that have the \Recent flag set but not the \Seen flag.
- NOT <search-key>: Messages that do not match the specified search key.
- OLD: Messages that do not have the \Recent flag set.
- ON <date>: Messages whose internal date (disregarding time and timezone) 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 Date: header (disregarding time and timezone) is earlier than the specified date.
- SENTON <date>: Messages whose Date: header (disregarding time and timezone) is within the specified date.
- SENTSINCE <date>: Messages whose Date: header (disregarding time and timezone) is within or later than the specified date.
- SINCE <date>: Messages whose internal date (disregarding time and timezone) is within or later than the specified date.
- SMALLER <n>: Messages with a 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 <sequence set>: Messages with unique identifiers corresponding to the specified unique identifier set. Sequence set ranges are permitted.
- 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 flag set.
- UNSEEN: Messages that do not have the \Seen flag set.
Here is the example we used in our Advanced IMAP post, where we search for unseen messages with “crash” in the subject. Then we “see” one of the messages and then perform the search again and notice that it no longer appears in the search result list:
s2 SEARCH UNSEEN HEADER SUBJECT "crash" * SEARCH 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 s2 OK Search completed (0.001 + 0.000 secs). f FETCH 15 BODY[HEADER.FIELDS (SUBJECT)] * 15 FETCH (FLAGS (\Seen) BODY[HEADER.FIELDS (SUBJECT)] {18} Subject: crash ) f OK Fetch completed (0.001 + 0.000 secs). s3 SEARCH UNSEEN HEADER SUBJECT "crash" * SEARCH 14 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 s3 OK Search completed (0.002 + 0.000 + 0.001 secs).
FETCH
This command allows a client to fetch messages from a folder, and it is one of the most widely used IMAP commands.
You may specify which messages you wish to fetch, and even which messages parts; you do not have to fetch the entire message. This one command is probably the “killer feature” of IMAP, one of the main reasons it exists; it allows clients to interact in a sophisticated way with the IMAP server.
Here is a list of all the message parts (and defined macros representing pre-defined messages parts) you can fetch:
- ALL: Macro equivalent to: (FLAGS INTERNALDATE RFC822.SIZE ENVELOPE)
- FAST: Macro equivalent to: (FLAGS INTERNALDATE RFC822.SIZE)
- FULL: Macro equivalent to: (FLAGS INTERNALDATE RFC822.SIZE ENVELOPE BODY)
- BODY: Non-extensible form of BODYSTRUCTURE.
- BODY[<section>]<<partial>>: The text of a particular body section. The section specification is a set of zero or more part specifiers delimited by periods. A part specifier is either a part number or one of the following: HEADER, HEADER.FIELDS, HEADER.FIELDS.NOT, MIME, and TEXT. An empty section specification refers to the entire message, including the header. You may even select only parts of a multipart MIME message and even specific octets within that part, see RFC 3501#section-6.4.5 for more details.
- BODY.PEEK[<section>]<<partial>>: An alternate form of BODY[<section>] that does not implicitly set the \Seen flag.
- BODYSTRUCTURE: The MIME body structure of the message. This is computed by the server by parsing the MIME header fields in the header and body MIME headers.
- ENVELOPE: The envelope structure of the message. This is computed by the server by parsing the message header into the component parts, defaulting various fields as necessary.
- FLAGS: The flags that are set for this message.
- INTERNALDATE: The internal date of the message.
- RFC822: Functionally equivalent to BODY[], differing in the syntax of the resulting untagged FETCH data in that the full RFC822 message is returned.
- RFC822.HEADER: Functionally equivalent to BODY.PEEK[HEADER], with RFC822 header syntax returned.
- RFC822.SIZE: The size of the message.
- RFC822.TEXT: Functionally equivalent to BODY[TEXT], differing in the syntax of the resulting untagged FETCH data as RFC822.TEXT is returned.
- UID: The unique identifier for the message.
Here is an example from our IMAP 101 post where we only fetch the Subject from the first four messages in a folder:
f fetch 1:4 (BODY[HEADER.FIELDS (Subject)]) * 1 FETCH (BODY[HEADER.FIELDS (SUBJECT)] {27} Subject: Test message 1 ) * 2 FETCH (FLAGS (Seen) BODY[HEADER.FIELDS (SUBJECT)] {27} Subject: Test message 3 ) * 3 FETCH (FLAGS (Seen) BODY[HEADER.FIELDS (SUBJECT)] {27} Subject: Test message 5 ) * 4 FETCH (FLAGS (Seen) BODY[HEADER.FIELDS (SUBJECT)] {27} Subject: Test Message 6 ) f OK Fetch completed (0.002 + 0.000 secs).
COPY
This message copies a message from the currently selected folder to a different folder, and preserves all flags and date information about the message.
Here is the example from our Advanced IMAP post – that post provides a more complete example:
c1 COPY 10 "work.due today" c1 OK [COPYUID 1548379804 17 1] Copy completed (0.007 + 0.000 + 0.006 secs).
UID
This is an interesting command, in that it is a modifier to other commands (namely COPY, FETCH, STORE and SEARCH). It instructs the server to use UIDs as arguments or results, rather than message sequence numbers (as is the default).
A sequence number references a message in that specific IMAP session, and the sequence numbers of messages may change between sessions, whereas UIDs remain constant for every message whilst the UIDVALIDITY flag for a folder remains unchanged.
We detail this further in our Advanced IMAP post. Here is an example from that post:
w UID STORE 10 +FLAGS (a-funny-flag) * FLAGS (\Answered \Flagged \Deleted \Seen \Draft some-flag a-different-flag a-funny-flag) * OK [PERMANENTFLAGS (\Answered \Flagged \Deleted \Seen \Draft some-flag a-different-flag a-funny-flag \*)] Flags permitted. * 3 FETCH (UID 10 FLAGS (a-funny-flag)) w OK Store completed (0.004 + 0.000 + 0.003 secs).
This wraps up all of the IMAP client commands defined in RFC 3501, however a number of extensions have been defined by errata RFC’s, which I will detail below.
Errata RFC IMAP Commands
A number of additions to the standard IMAP client commands have been defined, so we will give a quick overview of these too:
RFC 4314
RFC 4314 here as it is a commonly implemented extension to IMAP, as it enables administering rights to folders to other users (i.e. if you wanted to give permission to the same folder to a collection of people, and each of those people to have a different set of permissions).
It is important to understand the permission characters and their meaning, so I detail these here (as found in the RFC):
- l: Lookup (mailbox is visible to LIST/LSUB commands, and you may SUBSCRIBE to the mailbox)
- r: Read (SELECT the mailbox, perform STATUS)
- s: Keep seen/unseen information across sessions (set or clear \SEEN flag via STORE, also set \SEEN during APPEND/COPY/FETCH BODY[…])
- w: Write (set or clear flags other than \SEEN and \DELETED via STORE, also set them during APPEND/COPY)
- i: Insert (perform APPEND, COPY into mailbox)
- p: Post (send mail to submission address for mailbox, not enforced by IMAP4 itself but rather the implementation)
- c: Create/write (create and in some cases delete folders and subfolders and messages in the folders; this is obsoleted and is replaced by ‘k’ and ‘x’ and ‘t’)
- k: Create mailboxes (CREATE new sub-mailboxes in any implementation-defined hierarchy, parent mailbox for the new mailbox name in RENAME)
- d: Delete (delete mailboxes and subfolders, and messages; this is obsoleted and is replaced by ‘k’ and ‘x’ and ‘t’)
- x: Delete mailbox (DELETE mailbox, old mailbox name in RENAME)
- t: Delete messages (set or clear \DELETED flag via STORE, set \DELETED flag during APPEND/COPY)
- e: Perform EXPUNGE and expunge as a part of CLOSE
- a: Administer (perform SETACL/DELETEACL/GETACL/LISTRIGHTS)
Here are the associated IMAP commands:
SETACL
The SETACL command changes the access control list on the specified mailbox, so that the specified user is granted permissions as specified.
Here is an example from the RFC:
A001 GETACL INBOX/Drafts * ACL INBOX/Drafts Fred rwipslxetad Chris lrswi A001 OK Getacl complete A002 SETACL INBOX/Drafts Chris +cda A002 OK Setacl complete A003 GETACL INBOX/Drafts * ACL INBOX/Drafts Fred rwipslxetad Chris lrswicdakxet A003 OK Getacl complete
DELETEACL
The DELETEACL command removes any <identifier/user,rights> pair for the specified identifier/username from the access control list for the specified mailbox.
An example from the RFC:
B001 getacl INBOX * ACL INBOX Fred rwipslxetad -Fred wetd $team w B001 OK Getacl complete B002 DeleteAcl INBOX Fred B002 OK Deleteacl complete B003 GETACL INBOX * ACL INBOX -Fred wetd $team w B003 OK Getacl complete
GETACL
The GETACL command returns the access control list for the mailbox.
There are examples of this IMAP command in the previous two commands.
LISTRIGHTS
The LISTRIGHTS command takes a mailbox name and a username, and returns information about what rights can be granted to the user in the ACL for the mailbox.
Here is an example from the RFC:
a001 LISTRIGHTS ~/Mail/saved smith * LISTRIGHTS ~/Mail/saved smith la r swicdkxte a001 OK Listrights completed
MYRIGHTS
The MYRIGHTS command returns the set of rights that the logged in user has to a mailbox.
An example from the RFC:
A003 MYRIGHTS INBOX * MYRIGHTS INBOX rwiptsldaex A003 OK Myrights complete
RFC 4466
RFC 4466 outlines some extensions to the standard IMAP commands. Specifically, extensions to the commands SELECT/EXAMINE, CREATE, RENAME, FETCH, STORE, APPEND and SEARCH commands. This blog post is not going to detail these command extensions, but I invite you to read RFC 4466 if you think that these might be interesting to you.
RFC 4469
RFC 4469 introduces an extension to the APPEND command that allows the client to create a message on the server that can include the text of messages (or parts of messages) that already exist on the server, without having to FETCH them and APPEND them back to the server.
Here is an example from that RFC, which demonstrates how a CATENATE client can replace an attachment in a draft message, without the need to download it to the client and upload it back:
A003 APPEND Drafts (\Seen \Draft $MDNSent) CATENATE (URL "/Drafts;UIDVALIDITY=385759045/;UID=20/;section=HEADER" TEXT {42} + Ready for literal data --------------030308070208000400050907 URL "/Drafts;UIDVALIDITY=385759045/;UID=20/;section=1.MIME" URL "/Drafts;UIDVALIDITY=385759045/;UID=20/;section=1" TEXT {42} + Ready for literal data --------------030308070208000400050907 URL "/Drafts;UIDVALIDITY=385759045/;UID=30" TEXT {44} + Ready for literal data --------------030308070208000400050907-- ) A003 OK catenate append completed
RFC 5032
RFC 5032 exposes two new search keys for the IMAP search command, OLDER and YOUNGER, each of which takes a non-zero integer argument corresponding to a time interval in seconds. The server calculates the time of interest by subtracting the time interval that the client presents, from the current date and time of the server. The server then either returns messages older or younger than the resultant time and date, depending on the search key used.
Here is an example from that RFC:
a1 SEARCH UNSEEN YOUNGER 259200 a1 * SEARCH 4 8 15 16 23 42
RFC 5182
RFC 5182 introduces the ability to reference messages that were a result of a search operation in other commands. As the RFC itself states, “many IMAP clients use the result of a SEARCH command as the input to perform another operation, for example, fetching the found messages, deleting them, or copying them to another mailbox. This can be achieved using standard IMAP operations described in RFC 3501; however, this would be suboptimal”.
Allowing commands to reference return results from a search command particularly lends itself to command pipelining, as demonstrated in this example from the RFC, where the client is pipelining the search and fetch commands that only act on interesting messages. The “$” symbol means “the results of the last saved search command”:
A282 SEARCH RETURN (SAVE) FLAGGED SINCE 1-Feb-1994 NOT FROM "Smith" A283 FETCH $ (UID INTERNALDATE FLAGS RFC822.HEADER) A282 OK SEARCH completed * 2 FETCH (UID 14 ... * 84 FETCH (UID 100 ... * 882 FETCH (UID 1115 ... A283 OK completed
RFC 8437
RFC 8437 introduces a new command, UNAUTHENTICATE, which serves to return the connection back to the “unauthenticated” state. Under the basic IMAP standard, a client is required to drop a connect and reconnect, but using this extension, a connection may be maintained and be reauthenticated, perhaps as a completely different user.
A small example of what the syntax probably looks like (I say ‘probably’ because I have never seen this command in the wild, nor could I find a server that implements it) might be:
g456 unauthenticate g456 OK unauthenticated * OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE AUTH=PLAIN AUTH=LOGIN] IMAP/POP3 ready - my server
Find this IMAP Commands post useful?
We’re taking ideas for future how-to posts about the behind-the-scenes workings of email services. If you’d like to make a request, we invite you to drop us a line here.
Meanwhile, we invite you to check out some of our other how-to posts:
- IMAP 101: Manual IMAP Sessions
- Advanced IMAP
- POP 101: Manual POP Sessions
- SMTP 101: Manual SMTP Sessions
- SMTP Reply, Status and Error Codes
- CalDAV and CardDAV