Here some notes just to use as cut&modify&paste.
Related note:…
How to test with curl command :
$curl imap://username:password@in.example.com/INBOX?NEW (goto curl notes)
extra notes here
#0 IMAP PORT 143 / 993 (telnet / SSL )
Port 143 (plain / no SSL) telnet <IP> 143 .... Port 993 (SSL) openssl s_client -connect <IP>:993 CONNECTED(00000003) depth=2 /C=US/O=GeoTrust Inc./CN=GeoTrust Global CA verify error:num=20:unable to get local issuer certificate verify return:0 --- Certificate chain ...

$curl imap://username:password@in.example.com/INBOX?NEW (goto curl notes)
#1 Commands format
Command Input : <RandomStringID> command Answer : <RandomStringID> OK <ANSWER DETAIL> Examples : x1yz login test@dom.it p4ssw0rd x1yz OK login successful or a login test@dom.it p4ssw0rd a OK login successful
where <RandomStringID> is chars x1yz or simply char a or (that identifies the IMAP transaction).
~ giovanni$ telnet <IP> 143 Trying <IP>... Connected to <IP>. Escape character is '^]'. * OK IMAP4 PROXY server ready a LOGIN <local>@<domain> <password> a OK login successful a LIST "" "%" * LIST (\HasNoChildren) "/" Draft * LIST (\HasChildren) "/" INBOX * LIST (\HasNoChildren) "/" Notes * LIST (\HasNoChildren) "/" "Emails to check" * LIST (\HasNoChildren) "/" Sent * LIST (\HasNoChildren) "/" Spam * LIST (\HasNoChildren) "/" Test_2015 * LIST (\HasNoChildren) "/" Trash a OK LIST completed a SELECT INBOX * 208 EXISTS * 0 RECENT * FLAGS (\Answered \Flagged \Deleted \Seen \Draft $MDNSent) * OK [PERMANENTFLAGS (\Answered \Flagged \Deleted \Seen \Draft $MDNSent)] flags can be changed * OK [UIDVALIDITY 1365581562] mailbox UID validity * OK [UIDNEXT 505] predicted next UID a OK [READ-WRITE] SELECT complete a FETCH 1 (FLAGS BODY[HEADER.FIELDS (SUBJECT DATE FROM TO CC)]) * 1 FETCH (FLAGS (\Seen) BODY[HEADER.FIELDS (SUBJECT DATE FROM TO CC)] {112} Subject: testtest2 Date: Tue, 9 Oct 2007 11:34:26 +0200 From: "X Y Z" <X.Y.Z@XYZ.com> To: <A.B.C.@ABC.it> ) a OK FETCH complete a LOGOUT * BYE disconnecting a OK LOGOUT complete Connection closed by foreign host.
#2 Commands:
A command, usually, has to be executed in the proper sequence and only if IMAP status has the correct value for that command.

2.1 CAPABILITY (optional)
This command provides the options and capabilities that the server has. Can be executed in whichever status … generally in connected status before the LOGIN.
a capability
* CAPABILITY IMAP4rev1 UIDPLUS IDLE LOGIN-REFERRALS NAMESPACE QUOTA CHILDREN ...
a OK capabilities listed
2.2 LOGIN (authenticate)
LOGIN <username>@<domain> <password>
With domain or not (it depends on of provider) LOGIN allows to pass from Connected to Authenticated status. Generally connection, before to send user/password is promoted to secure with command STARTTLS. There are other Authentication mechanisms like CRAM-MD5 click-here.
telnet <SERVER-IP> 143 Trying <SERVER-IP>... Connected to <SERVER-IP> Escape character is '^]'. * OK IMAP4 server ready
a login <username>@<domain> <password> a OK login successful
2.3 LIST of folders/mailboxes
System defined mailbox is “INBOX” : INBOX is a special name reserved to the primary mailbox for user (where the new mails are usually placed).
LIST “<mailbox path>” “<search argument>”
- “<mailbox path>” if empty list shows all content from root
- “” is case-sensitive mailbox name with possible wildcards
- * is a wildcard, and matches zero or more characters at this position.
- % is similar to “*” but it does not match a hierarchy delimiter
Examples are based on this : folder-name-1 folder-name-1/folder-name-1.1 folder-name-2 folder-name-3 folder-name-3/folder-name-3.1 ... INBOX ... Trash
a LIST "" "*" * LIST (HasChildren) "/" folder-name-1 * LIST (HasNoChildren) "/" folder-name-1/folder-name-1.1
* LIST (HasNoChildren) "/" folder-name-2 * LIST (HasChildren) "/" folder-name-3 * LIST (HasNoChildren) "/" folder-name-3/folder-name-3.1 ... * LIST (HasNoChildren) "/" INBOX ... * LIST (HasNoChildren) "/" Trash a OK LIST completed
a LIST "" "%"
* LIST (HasNoChildren) "/" folder-name-1
* LIST (HasNoChildren) "/" folder-name-2
* LIST (HasChildren) "/" folder-name-3
...
* LIST (HasNoChildren) "/" INBOX
...
* LIST (HasNoChildren) "/" Trash
a OK LIST completed
a LIST "" "%/%" * LIST (HasNoChildren) "/" folder-name-1/folder-name-1.1 * LIST (HasNoChildren) "/" folder-name-3/folder-name-3.1 a OK LIST completed
a LIST "folder-name-3" "*"
* LIST (HasNoChildren) "/" folder-name-3/folder-name-3.1
a OK LIST completed
a LIST "" "fol*1"
* LIST (HasNoChildren) "/" folder-name-1
* LIST (HasNoChildren) "/" folder-name-1/folder-name-1.1
* LIST (HasNoChildren) "/" folder-name-3/folder-name-3.1
a OK LIST completed
2.4 STATUS of a mailbox
STATUS <mailbox name> <status data>
where <status data> :
- 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.
a STATUS INBOX (MESSAGES)
* STATUS INBOX (MESSAGES 22)
a OK STATUS complete
2.5 SELECT a mailbox on which work
SELECT <mailbox path>
SELECT allows to pass fromAuthenticated to Selected status…
a SELECT INBOX
* 22 EXISTS
* 0 RECENT
* FLAGS (Answered Flagged Deleted Seen Draft )
* OK [PERMANENTFLAGS (Answered Flagged Deleted Seen Draft)] flags can be changed
* OK [UIDVALIDITY 1339682095] mailbox UID validity
* OK [UIDNEXT 745] predicted next UID
a OK [READ-WRITE] SELECT complete
a SELECT folder-name-1/folder-name-1.1 * 0 EXISTS * 0 RECENT * FLAGS (\Answered \Flagged \Deleted \Seen \Draft $MDNSent) * OK [PERMANENTFLAGS (\Answered \Flagged \Deleted \Seen \Draft $MDNSent)] flags can be changed * OK [UIDVALIDITY 1368699799] mailbox UID validity * OK [UIDNEXT 1] predicted next UID a OK [READ-WRITE] SELECT complete
2.6 SARCH emails
SEARCH <criteria>
SEARCH searches the mailbox for messages that match the given searching criteria.
Common criteria : FROM, BEFORE, KEYWORD, RECENT, DELETED…
a UID SEARCH FROM "giovanni" * SEARCH 127 128 222 223 224 234 251 252 389 441 450 461 470 471 472 482 483 484 490 492 496 499 505 a OK SEARCH complete
a UID SEARCH OR FROM "giovanni" FROM "staff" * SEARCH 127 128 222 223 224 234 251 252 389 441 450 461 468 470 471 472 475 482 483 484 490 492 496 499 500 505 a OK SEARCH complete
a SEARCH NEW * SEARCH * 206 EXISTS * 0 RECENT a OK SEARCH complete
a SEARCH ON "6-dec-2012" * SEARCH 35 36 37 a OK SEARCH complete
a SEARCH SINCE "01-jan-2013" BEFORE "31-dec-2013" * SEARCH 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 a OK SEARCH complete a UID SEARCH SINCE "01-jan-2012" BEFORE "01-jan-2013" * SEARCH 238 239 240 241 244 245 246 247 249 250 251 252 253 254 255 256 257 258 259 262 265 266 267 269 a OK SEARCH complete
a SEARCH BODY "test" * SEARCH 1 2 4 5 6 8 14 15 198 199 200 202 203 204 205 206 a OK SEARCH complete
2.7 FETCH the contents of emails
FETCH <sequence set> <data items name>
FETCH reads content/parts of an email. Using the range (#4 click-here) this command is applied to a set of emails (like email listing). <sequence set> can be “Message Sequence Numeber” or “UID” (#4.1 click-here). About FLAGS at end of this post #3 and #4 below.
a FETCH 10588 (BODY.PEEK[HEADER]) * 10588 FETCH (BODY[HEADER] {1344} Return-Path: <test_nospam@test.priv> Received: from ms1.busylog.priv (192.168.2.1) by ms2.busylog.priv id ADR9398458A00a for giovanni_nospam@busylog.net; Fri, 8 Jul 2016 19:37:33 +0200 Received: from be02.busylog.net.priv (192.168.2.2) by ms1.busylog.priv id ADR9398458d838 for giovanni_nospam@busylog.net; Fri, 8 Jul 2016 19:37:33 +0200 Message-ID: <344775Q_d932858_212AT34@be02.busylog.net.priv> Date: Fri, 8 Jul 2016 19:37:28 +0200 (CEST) From: test_nospam <test_nospam@test.priv> Reply-To: test_nospam <test_nospam@test.priv> To: giovanni_nospam@busylog.net Subject: Test 28/07/2016 - 2 Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Sender: test_nospam@test.priv Content-Language: it X-Busy-Expiry: 2016-07-09T13:37:23.533Z X-Busy-Type: Protected ) a OK FETCH complete
a FETCH 1 (FLAGS BODY[HEADER.FIELDS (DATE FROM SUBJECT)])
* 1 FETCH (FLAGS (\Seen) BODY[HEADER.FIELDS (DATE FROM SUBJECT)] {145}
from: Staff_Community <help.community@staff.virgilio.it>
date: 27 Jul 2009 15:36:33 +0200
subject: Il tuo profilo entra in Virgilio People!
)
a OK FETCH complete
a FETCH 1:* FLAGS
* 1 FETCH (FLAGS (Seen))
* 2 FETCH (FLAGS (Seen))
a OK FETCH complete
a FETCH 1:* INTERNALDATE
* 1 FETCH (INTERNALDATE "13-Jun-2012 11:04:18 +0200")
* 2 FETCH (INTERNALDATE "20-Aug-2012 16:29:21 +0200")
...
* 22 FETCH (INTERNALDATE "23-Oct-2012 15:31:05 +0200")
a OK FETCH complete
2.8 SET FLAG (Massively)
Set massively (bulk set) flags such as read, unread … using sequence number range
a STORE 1:* +FLAGS \Seen set read all emails
a STORE 1:* -FLAGS \Seen set unread all emails
a STORE 10:100 +FLAGS \Seen set as read emails from 10 to 100(sequence number range)
a STORE 22 +FLAGS \Deleted set as deleted email 22 (twenty-second email)
a STORE 22 -FLAGS \Deleted restore, undelete ... email n. 22 in mailbox
2.9 EXPURGE
Emails that are set as “Deleted” are actually still present (at most moved in trash by client). If you need to delete them you have to run “EXPUNGE” command.
a STORE 22 +FLAGS \Deleted
* 22 FETCH (FLAGS (\Deleted \Seen)) a OK STORE complete a EXPUNGE * 22 EXPUNGE a OK EXPUNGE complete
#3 List of Flags
- \Seen Message has been read
- \Answered Message has been answered
- \Flagged Message is “flagged”for urgent/special attention
- \Deleted Message is “deleted” for removal by later EXPUNGE
- \Draft Message has not completed composition
- \Recent Message has arrived since the previous time this mailbox was selected.
#4 Use of Range
Some commands have possibility to specify range (for example STORE command).
Possible sequences (of UID or Message Sequence Number ) :
- 1:*
- 2,4,5,6,7,9,12,13,14,15
- *:3,8,0
- 2,4:7,9,12:*
sequence-set = (seq-number / seq-range) *(","sequence-set) ; set of seq-number values, regardless of order. ; Servers MAY coalesce overlaps and/or execute the ; sequence in any order. ; Example: a message sequence number set of ; 2,4:7,9,12:* for a mailbox with 15 messages is ; equivalent to 2,4,5,6,7,9,12,13,14,15 ; Example: a message sequence number set of *:4,5:7 ; for a mailbox with 10 messages is equivalent to ; 10,9,8,7,6,5,4,5,6,7 and MAY be reordered and ; overlap coalesced to be 4,5,6,7,8,9,10.
#4.1 UID Vs. Message Sequence Number
Two types of ID for an email :
- UID : Unique Identifier is an unique number referencing an email
- Message Sequence Number: the relative position from the first message in the mailbox
[ the unique identifier of a message MUST NOT change during the session, and SHOULD NOT change between sessions. Any change of unique identifiers between sessions MUST be detectable using the UIDVALIDITY mechanism discussed below.] ... ...and... [Unique identifiers MUST be strictly ascending in the mailbox at all times.].... ...and... [ The combination of mailbox name, UIDVALIDITY, and UID must refer to a single immutable message on that server forever. ]...
So sequence number doesn’t uniquely identify an email example (delete first email in mailbox) :
a FETCH 1 (FLAGS BODY[HEADER.FIELDS (DATE FROM SUBJECT)]) * 1 FETCH (FLAGS (\Seen) BODY[HEADER.FIELDS (DATE FROM SUBJECT)] {112} Subject: test Date: Tue, 9 Oct 2007 11:32:52 +0200 ... a OK FETCH complete a STORE 1 +FLAGS \Deleted * 1 FETCH (FLAGS (\Deleted \Seen)) a OK STORE complete a expunge * 1 EXPUNGE a OK EXPUNGE complete a FETCH 1 (FLAGS BODY[HEADER.FIELDS (DATE FROM SUBJECT)]) * 1 FETCH (FLAGS (\Seen) BODY[HEADER.FIELDS (DATE FROM SUBJECT)] {117} Subject: testtest2 Date: Tue, 9 Oct 2007 11:34:26 +0200 ... a OK FETCH complete
So if you work on email n.1 you can not be sure that the email in position 1 will remain the same in whole IMAP session.
So UID uniquely identify an email example (delete email with UID 204 in mailbox) : :
a UID FETCH 204 (FLAGS BODY[HEADER.FIELDS (DATE FROM SUBJECT)]) * 4 FETCH (FLAGS (\Seen) BODY[HEADER.FIELDS (DATE FROM SUBJECT)] {118} From: Giovanni <giovanni@xyz.net> Subject: test Date: Fri, 26 Nov 2010 14:05:47 +0100 ''' a OK FETCH complete a UID STORE 204 +FLAGS \Deleted * 4 FETCH (FLAGS (\Deleted \Seen) UID 204) a OK STORE complete a EXPUNGE * 4 EXPUNGE a OK EXPUNGE complete a UID FETCH 204 (FLAGS BODY[HEADER.FIELDS (DATE FROM SUBJECT)]) a OK FETCH complete
The UID command has two forms :
UID <COMMAND> where
UID SEARCH where returned values are UIDs (and not message sequence numbers)
Example FETCH email with UID 127 :
a UID FETCH 127 (FLAGS BODY[HEADER.FIELDS (DATE FROM SUBJECT)]) * 1 FETCH (FLAGS (\Seen) BODY[HEADER.FIELDS (DATE FROM SUBJECT)] {117} ... UID 127) a OK FETCH complete
UID COPY <UID>
Example COPY email with UID 502 :
a UID COPY 502 Trash a OK [COPYUID 1424344530 502 2] command complete
UID STORE <UID>
Example STORE emails with UID Range :
a UID STORE 500:* +FLAGS \Deleted * 205 FETCH (FLAGS (\Deleted \Seen) UID 500) * 206 FETCH (FLAGS (\Deleted \Seen) UID 501) * 207 FETCH (FLAGS (\Deleted \Seen) UID 504) a OK STORE complete
a UID SEARCH FROM X.Y@XYZ.com * SEARCH 367 383 389 441 482 483 484 UIDs a OK SEARCH complete a SEARCH FROM X.Y@XYZ.com * SEARCH 126 140 146 157 190 191 192 Sequence Numbers a OK SEARCH complete a SEARCH UID 441 * SEARCH 157 UID to Sequence Numbers a OK SEARCH complete a UID SEARCH 157 * SEARCH 441 Sequence Numbers to UID a OK SEARCH complete
#4.2 How to search UID related to a Message Sequence Number
Seq. number UID : UID SEARCH <Message Sequence Number>
UID Seq. number : SEARCH UID <UID>
Example :
UID of first (1) message in mailbox is 127 a UID SEARCH 1 * SEARCH 127 a OK SEARCH complete a SEARCH UID 127 * SEARCH 1 a OK SEARCH complete
[…] – Sean Tunner & Russ Houseley https://en.wikipedia.org/wiki/Simple_Mail_Transfer_Protocol https://busylog.net/telnet-imap-commands-note https://support.google.com/a/answer/176600?hl=en […]
[…] Telnet IMAP Commands Note […]