Basic IMAP Programming Reference

This document provides examples for all supported basic IMAP operations.

More advanced scenarios and solutions to common problems can be found in the Advanced IMAP Programming Reference.

General Connection Handling
Mailbox Manipulation
Message Manipulation

Getting Started

In order to use the IMAP client we need to add all necessary dependencies to the project.

  • Crystalbyte.Equinox.Imap.dll
  • Crystalbyte.Equinox.Mime.dll
  • Crystalbyte.Equinox.Core.dll

Finally we need to import the following namespaces.

using Crystalbyte.Equinox.Imap;
using Crystalbyte.Equinox.Security;

We can now create an instance of the ImapClient.

var client = new ImapClient();

Connecting & Disconnecting the Client

A connection can be established by using the client’s Connect method. The method requires a hostname and a port.

var host = ""
var port = 143;
using(var client = new ImapClient()) {
client.Connect(host, port);
The client can be disconnected by calling the Disconnect method explicitly or implicitly when leaving the scope of a “using” block.

“The code above also works for the SMTP and POP3 client, since all clients share the same connection algorithms.”

Securing the Connection Stream using TLS/SSL

By default the client uses TLS when establishing a connection. The policy can be changed by setting the Security property prior to connecting the client.

While unencrypted connections and TLS negotiations can be established on port 143, an SSL connection usually requires the port 993 to work.

client.Security = SecurityPolicies.None; // None
client.Security = SecurityPolicies.Implicit; // TLS
client.Security = SecurityPolicies.Explicit; // SSL

“The code above also works for the SMTP and POP3 client, since all clients share the same connection algorithms.”


The client supports multiple SASL mechanism to authenticate the user. Ideally the client will detect supported mechanism, choose the best and use it for authentication.

To automatically let the client negotiate the authentication protocols we merely need to call the client’s Authenticate method with the username and password.

var username = "john";
var password = "wayne";
client.Authenticate(username, password);

There is however the possibility that the server and the client negotiations fail due to incompatible supported mechanism. If the client is unable to automatically log in the user it will raise the ManualSaslAuthenticationRequired event.

If subscribed it offers the user the right moment to issue a manual authentication or abort the procedure. If for some reason a special mechanism must be issued without regard to the servers capability announcements, it is possible to force the client to start a specific mechanism by adding it as a third param to the Authentication method.

var username = "john";
var password = "wayne";
client.Authenticate(username, password, SaslMechanics.CramMd5);
It is however noteworthy that issuing not propagated mechanisms will most likely fail, therefor it is not recommended.

If you need to use XOAUTH to log into Gmail or Yahoo, you will find detailed information here (Authentication using XOAUTH).

“The code above also works for the SMTP and POP3 client, since all clients share the same connection algorithms.”

Establishing and using an IDLE connection

In order to use the libraries IDLE feature to support real-time updates, we need to subscribe to the StatusUpdateReceived event, select the folder we wish to observe and start an IDLE session by calling the StartIdle method.

client.StatusUpdateReceived += OnStatusUpdateReceived;
Once the IDLE command has been issued the current thread will block until the server sends an update which then will trigger the StatusUpdateReceived event. Before the event is issued however, the client will automatically abort the IDLE session, the session will resume once the status update event handler has been processed. By setting the IsCancelled property on the event arguments to true we can prevent the client from resuming the IDLE session. Since the server may send status updates arbitrarily the event will not necessarily be invoked only while idling; In order to check whether the update was issued from an idling client we can check against the IsIdleUpdate property.
private void OnStatusUpdateReceived(object sender, StatusUpdateReceivedEventArgs e)
var client = sender as ImapClient;
if (client == null) {

// Respond to change notifications
// i.E. client.Messages.Where(x.Uid > myLastKnownHighestUid).Select(x => x.Envelope) ...

if (e.IsIdleUpdate) {
e.IsIdleCancelled = true; // cancel IDLE session (false default)

There is also the possibility to abort an IDLE session even while the thread is blocked. In order to do that we need to call the StopIdleAsync method from a different than the blocked one.

Creating a Mailbox

To create a mailbox we simply need to call the Create method.

var delimiter = "/";
var fullname = string.Format("level0{0}level1{0}level2");
The delimiter chosen above is selected arbitrarily and can vary from server to server, most use “/” as a delimiter but also “.” is not uncommon. We received the delimiter within the Select method response.

Deleting a Mailbox

Deleting a mailbox can be accomplished by calling the Delete method.


Renaming a Mailbox

Renaming a mailbox can be accomplished by calling the Rename method. This method takes the source and destination names as arguments.

client.Rename("Source", "Destination");

Selecting & Examining Mailboxes

Selecting and examining mailboxes can be done by calling the associated methods Select and Examine. Both methods will return the same response containing detailed information about the selected/examined mailbox.


Subscribing to Mailboxes

We can subscribe to a mailbox by calling the Subscribe method. Any subscribed mailbox will be returned by the LSub command.


Unsubscribing is being done by calling Unsubscribe.


Listing Mailboxes

In order to list available mailboxes the IMAP protocol exposes two methods. The List method will list all mailboxes fitting the given criteria, while the LSub method will only return mailboxes that fit the criteria and have been subscribed to.


Changing Flags & Keywords of a Message

The IMAP protocol allows the user tag messages with keywords. Some keywords are variant while others are non optional and must be supported by all IMAP servers, these are also known as message flags.

If the server supports additional keywords than just the message flags these will be listed inside the Select/Examine response’s PermanentFlags property. The method exposed by the client to add or remove keywords from a message is Store.

var set = SequenceSet.CreateUidSet(144);
client.Store(set, MessageFlags.Seen, StoreProcedures.Add);
The first argument is a set, containing sequence numbers or uids of all messages to apply the change to. The second is the actual keyword, and the last specifies whether to remove or add the given keywords.

Appending a Message

The client exposes the Append method to store a message on the server without the need to send it via SMTP. This is useful when storing sent messages inside the “sent” mailbox.

var destination = "sent";
var message = new Message();
message.Subject = "I'm an appended message";
client.Append(destination, message, MessageFlags.Draft);
The Append method takes the full name of the destination mailbox and the message to append. The last argument is optional and may be used to tag the appended messages in advance.

Copying a Message

The Copy method lets you copy messages from a mailbox to another, obviously.

var set = SequenceSet.FromString("UID 1,2,3,4,5")
client.Copy(set, "Destination");
The above code will copy the messages with the uids 1,2,3,4 and 5 to the mailbox with the name “Destination”.

Deleting Messages

The IMAP protocol exposes the Expunge method to delete messages from a mailbox. The Expunge method will remove all messages from a mailbox that are tagged with the Deleted flag.

The above code will remove all “deleted” messages from the mailbox “INBOX”.

Searching for Messages manually

The client exposes the Search method in order to search for messages manually. The search message takes a string as argument which will be sent without alteration to the server.

If the syntax was correct and the server accepts the query, the method will return a sequence set containing sequence numbers or uids for all messages matching the search criteria.

var set = client.Search("(RECENT UNSEEN)", true);
The above code will return the uids for all “new” messages from the selected mailbox.

Details can be found in the associated RFC section (IMAP RFC3501 - Section 6.4.4).

Fetching Messages manually

Similar to the search method we can send fetch requests to the server. The Fetch method will then return the server response as a raw string.

Details can be found in the associated RFC section (IMAP RFC3501 - Section 6.4.5).

var set = SequenceSet.CreateSet(1);
var response = client.Fetch(set, "ENVELOPE");
The code above will return the envelope for the oldest message in the selected mailbox.

Last edited Jul 4, 2011 at 3:35 PM by Krasshirsch, version 9


No comments yet.