# Technical Documentation: jstedfast/MailKit

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/jstedfast/MailKit)

### Overview (`README.md`)

# MailKit

|  Package  |Latest Release|Latest Build|
|:----------|:------------:|:----------:|
|**MimeKit**|[](https://www.nuget.org/packages/MimeKit)|[](https://www.myget.org/feed/mimekit/package/nuget/MimeKit)|
|**MimeKit.Core**|[](https://www.nuget.org/packages/MimeKit.Core)|[](https://www.myget.org/feed/mimekit/package/nuget/MimeKit.Core)|
|**MimeKit.Cryptography**|[](https://www.nuget.org/packages/MimeKit.Cryptography)|[](https://www.myget.org/feed/mimekit/package/nuget/MimeKit.Cryptography)|
|**MailKit**|[](https://www.nuget.org/packages/MailKit)|[](https://www.myget.org/feed/mimekit/package/nuget/MailKit)|


|  Platform   |Build Status|Code Coverage|Static Analysis|
|:------------|:----------:|:-----------:|:-------------:|
|**Linux/Mac**|[](https://github.com/jstedfast/MailKit/actions/workflows/main.yml)|[](https://coveralls.io/r/jstedfast/MailKit?branch=master)|[](https://scan.coverity.com/projects/3202)|
|**Windows**  |[](https://github.com/jstedfast/MailKit/actions/workflows/main.yml)|[](https://coveralls.io/r/jstedfast/MailKit?branch=master)|[](https://scan.coverity.com/projects/3202)|


**Obsolete Packages:**
|  Package  |Latest Release|
|:----------|:------------:|
|**MimeKitLite**|[](https://www.nuget.org/packages/MimeKitLite)|
|**MailKitLite**|[](https://www.nuget.org/packages/MailKitLite)|

## What is MailKit?

MailKit is a cross-platform mail client library built on top of [MimeKit](https://github.com/jstedfast/MimeKit).

**Supported platforms:** .NET 8.0 and later, .NET Framework 4.6.2 and later, and any platform that implements
.NET Standard 2.0 or 2.1 (such as Mono, .NET MAUI and Unity).

**Upgrading from MailKit 4.x?** MailKit 5.0 contains a number of breaking changes. See the
[Porting Guide](https://github.com/jstedfast/MailKit/blob/master/PortingGuide.md) for step-by-step migration instructions and the [Release Notes](https://github.com/jstedfast/MailKit/blob/master/ReleaseNotes.md)
for the complete list of changes.

## Contents

* [Donate](#donate)
* [Features](#features)
* [Goals](#goals)
* [License Information](#license-information)
* [Installing via NuGet](#installing-via-nuget)
  * [Cryptography Support (S/MIME, OpenPGP, DKIM and ARC)](#cryptography-support-smime-openpgp-dkim-and-arc)
* [Getting the Source Code](#getting-the-source-code)
* [Building](#building)
* [Using MailKit](#using-mailkit)
  * [Connecting Securely](#connecting-securely)
  * [Authenticating with OAuth2](#authenticating-with-oauth2)
  * [Logging and Diagnostics](#logging-and-diagnostics)
  * [Sending Messages](#sending-messages)
* [Retrieving Messages (via Pop3)](#retrieving-messages-via-pop3)
* [Using IMAP](#using-imap)
  * [Fetching Information About the Messages in an IMAP Folder](#fetching-information-about-the-messages-in-an-imap-folder)
  * [Setting Message Flags in IMAP](#setting-message-flags-in-imap)
  * [Deleting Messages in IMAP](#deleting-messages-in-imap)
  * [Searching an IMAP Folder](#searching-an-imap-folder)
  * [Navigating Folders in IMAP](#navigating-folders-in-imap)
  * [Monitoring an IMAP Folder for Changes](#monitoring-an-imap-folder-for-changes)
* [Contributing](#contributing)
* [Reporting Bugs](#reporting-bugs)
* [Documentation](#documentation)
  * [Further Reading](#further-reading)
* [.NET Foundation](#net-foundation)

## Donate

MailKit is a personal open source project that I have put thousands of hours into perfecting with the
goal of making it the very best email framework for .NET. I need your help to achieve this.

Donating helps pay for things such as web hosting, domain registration and licenses for developer tools
such as a performance profiler, memory profiler, a static code analysis tool, and more. It also helps
motivate me to continue working on the project.

<a href="https://github.com/sponsors/jstedfast" _target="blank"><img alt="Click here to lend your support to MailKit by making a donation!" src="https://www.paypal.com/en_US/i/btn/x-click-but21.gif"></a>

## Features

* SASL Authentication
  * Supports the following mechanisms: [CRAM-MD5](https://tools.ietf.org/html/rfc2195), [DIGEST-MD5](https://tools.ietf.org/html/rfc2831),
  [LOGIN](https://tools.ietf.org/html/draft-murchison-sasl-login-00), [NTLM](https://davenport.sourceforge.net/ntlm.html),
  [PLAIN](https://tools.ietf.org/html/rfc2595), [SCRAM-SHA-1[-PLUS]](https://tools.ietf.org/html/rfc5802),
  [SCRAM-SHA-256[-PLUS]](https://tools.ietf.org/html/rfc5802), [SCRAM-SHA-512[-PLUS]](https://tools.ietf.org/html/draft-melnikov-scram-sha-512-04),
  [OAUTHBEARER](https://tools.ietf.org/html/rfc7628) and XOAUTH2
* Proxy Support
  * Supports the following types of proxies: [SOCKS4/4a](https://www.openssh.com/txt/socks4.protocol), [SOCKS5](https://tools.ietf.org/html/rfc1928),
  and [HTTP/S](https://tools.ietf.org/html/rfc2616)
* SMTP Client
  * Supports all of the SASL mechanisms listed above.
  * Supports SSL-wrapped connections via the "smtps" protocol.
  * Supports client SSL/TLS certificates.
  * Supports the following extensions: [SIZE](https://tools.ietf.org/html/rfc1870), [DSN](https://tools.ietf.org/html/rfc1891),
  [AUTH](https://tools.ietf.org/html/rfc2554), [8BITMIME](https://tools.ietf.org/html/rfc2821), [PIPELINING](https://tools.ietf.org/html/rfc2920),
  [BINARYMIME](https://tools.ietf.org/html/rfc3030), [CHUNKING](https://tools.ietf.org/html/rfc3030), [STARTTLS](https://tools.ietf.org/html/rfc3207),
  and [SMTPUTF8](https://tools.ietf.org/html/rfc6531)
  * All APIs are cancellable.
  * Async APIs are available.
* POP3 Client
  * Supports all of the SASL mechanisms listed above.
  * Also supports authentication via [APOP](https://tools.ietf.org/html/rfc1939#page-15) and `USER`/`PASS`.
  * Supports SSL-wrapped connections via the "pops" protocol.
  * Supports client SSL/TLS certificates.
  * Supports the following extensions: [TOP](https://tools.ietf.org/html/rfc1939#page-11), [UIDL](https://tools.ietf.org/html/rfc1939#page-12),
  [EXPIRE](https://tools.ietf.org/html/rfc2449), [LOGIN-DELAY](https://tools.ietf.org/html/rfc2449), [PIPELINING](https://tools.ietf.org/html/rfc2449),
  [SASL](https://tools.ietf.org/html/rfc2449), [STLS](https://tools.ietf.org/html/rfc2595), [UTF8](https://tools.ietf.org/html/rfc6856),
  [UTF8=USER](https://tools.ietf.org/html/rfc6856), and [LANG](https://tools.ietf.org/html/rfc6856)
  * All APIs are cancellable.
  * Async APIs are available.
* IMAP4 Client
  * Supports all of the SASL mechanisms listed above.
  * Supports SSL-wrapped connections via the "imaps" protocol.
  * Supports client SSL/TLS certificates.
  * Supports [IMAP4rev1](https://tools.ietf.org/html/rfc3501) and [IMAP4rev2](https://tools.ietf.org/html/rfc9051).
  * Supports the following extensions: [ACL](https://tools.ietf.org/html/rfc4314), [QUOTA](https://tools.ietf.org/html/rfc2087),
  [LITERAL+](https://tools.ietf.org/html/rfc2088), [IDLE](https://tools.ietf.org/html/rfc2177), [NAMESPACE](https://tools.ietf.org/html/rfc2342),
  [ID](https://tools.ietf.org/html/rfc2971), [CHILDREN](https://tools.ietf.org/html/rfc3348), [LOGINDISABLED](https://tools.ietf.org/html/rfc3501),
  [STARTTLS](https://tools.ietf.org/html/rfc3501), [MULTIAPPEND](https://tools.ietf.org/html/rfc3502), [UNSELECT](https://tools.ietf.org/html/rfc3691),
  [UIDPLUS](https://tools.ietf.org/html/rfc4315), [CONDSTORE](https://tools.ietf.org/html/rfc4551), [ESEARCH](https://tools.ietf.org/html/rfc4731),
  [SASL-IR](https://tools.ietf.org/html/rfc4959), [COMPRESS](https://tools.ietf.org/html/rfc4978), [WITHIN](https://tools.ietf.org/html/rfc5032),
  [ENABLE](https://tools.ietf.org/html/rfc5161), [QRESYNC](https://tools.ietf.org/html/rfc5162), [SORT](https://tools.ietf.org/html/rfc5256),
  [THREAD](https://tools.ietf.org/html/rfc5256), [ANNOTATE](https://tools.ietf.org/html/rfc5257), [LIST-EXTENDED](https://tools.ietf.org/html/rfc5258),
  [ESORT](https://tools.ietf.org/html/rfc5267), [METADATA / METADATA-SERVER](https://tools.ietf.org/html/rfc5464), [NOTIFY](https://tools.ietf.org/html/rfc5465),
  [FILTERS](https://tools.ietf.org/html/rfc5466), [LIST-STATUS](https://tools.ietf.org/html/rfc5819), [SORT=DISPLAY](https://tools.ietf.org/html/rfc5957),
  [SPECIAL-USE / CREATE-SPECIAL-USE](https://tools.ietf.org/html/rfc6154), [SEARCH=FUZZY](https://tools.ietf.org/html/rfc6203),
  [MOVE](https://tools.ietf.org/html/rfc6851), [UTF8=ACCEPT / UTF8=ONLY](https://tools.ietf.org/html/rfc6855), [LITERAL-](https://tools.ietf.org/html/rfc7888),
  [APPENDLIMIT](https://tools.ietf.org/html/rfc7889), [STATUS=SIZE](https://tools.ietf.org/html/rfc8438), [OBJECTID](https://tools.ietf.org/html/rfc8474),
  [REPLACE](https://tools.ietf.org/html/rfc8508), [SAVEDATE](https://tools.ietf.org/html/rfc8514), [PREVIEW](https://tools.ietf.org/html/rfc8970),
  [QUOTA=RES-* / QUOTASET](https://tools.ietf.org/html/rfc9208), [PARTIAL](https://tools.ietf.org/html/rfc9394),
  [INPROGRESS](https://tools.ietf.org/html/rfc9585), [XLIST](https://developers.google.com/gmail/imap_extensions),
  and [X-GM-EXT1](https://developers.google.com/gmail/imap_extensions) (X-GM-MSGID, X-GM-THRID, X-GM-RAW and X-GM-LABELS)
  * All APIs are cancellable.
  * Async APIs are available.
* Client-side sorting and threading of messages.

## Goals

The main goal of this project is to provide the .NET world with robust, fully featured and RFC-compliant
SMTP, POP3, and IMAP client implementations.

All of the other .NET IMAP client implementations that I could find suffer from major architectural
problems such as ignoring unexpected untagged responses, assuming that literal string tokens will
never be used for anything other than message bodies (when in fact they could be used for pretty
much any string token in a response), assuming that the way to find the end of a message body in a
FETCH response is by scanning for `") UID"`, and not properly handling mailbox names with international
characters to simply name a few.

IMAP requires a LOT of time spent laboriously reading and re-reading the IMAP specifications (as well
as the MIME specifications) to understand all of the subtleties of the protocol and most (all?) of the
other Open Source .NET IMAP libraries, at least, were written by developers that only cared enough that
it worked for their simple needs. There's nothing necessarily wrong with doing that, but the web is full
of half-working, non-RFC-compliant IMAP implementations out there that it was finally time for a carefully
designed and implemented IMAP client library to be written.

For POP3, libraries such as OpenPOP.NET are actually fairly decent, although the MIME parser is far
too strict - throwing exceptions any time it encounters a Content-Type or Content-Disposition
parameter that it doesn't already know about, which, if you read over the mailing-list, is a problem
that OpenPOP.NET users are constantly running into. MailKit's Pop3Client, of course, doesn't have this
problem. It also parses messages directly from the socket instead of downloading the message into a
large string buffer before parsing it, so you'll probably find that not only is MailKit faster (MailKit's
MIME parser, [MimeKit](https://github.com/jstedfast/MimeKit), parses messages from disk 25x faster than
OpenPOP.NET's parser), but also uses far less memory.

For SMTP, most developers use System.Net.Mail.SmtpClient which suits their needs more-or-less satisfactorily
and so is probably not high on their list of needs. However, the SmtpClient implementation included with
MailKit is a much better option if cross-platform support is needed or if the developer wants to be able to
save and re-load MIME messages before sending them via SMTP. MailKit's SmtpClient also supports PIPELINING
which should improve performance of sending messages (although might not be very noticeable).

## License Information

```text
MIT License

Copyright (C) 2013-2026 .NET Foundation and Contributors

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
```

## Installing via NuGet

The easiest way to install MailKit is via [NuGet](https://www.nuget.org/packages/MailKit/):

```bash
dotnet add package MailKit
```

Or, in Visual Studio's [Package Manager Console](https://learn.microsoft.com/nuget/consume-packages/install-use-packages-powershell):

```powershell
Install-Package MailKit
```

MailKit depends on [MimeKit.Core](https://www.nuget.org/packages/MimeKit.Core), which provides MIME parsing and
message construction.

### Cryptography Support (S/MIME, OpenPGP, DKIM and ARC)

MailKit itself does not need any cryptography packages, but if you want to sign, encrypt, decrypt or verify
messages using S/MIME, OpenPGP, DKIM or ARC, you will also need to add a reference to
[MimeKit.Cryptography](https://www.nuget.org/packages/MimeKit.Cryptography) (or to the
[MimeKit](https://www.nuget.org/packages/MimeKit) meta-package, which references both MimeKit.Core and
MimeKit.Cryptography):

```bash
dotnet add package MimeKit.Cryptography
```

Then initialize MimeKit's cryptography support once at startup, before using any of those features:

```csharp
using MimeKit.Cryptography;

CryptographyModule.Initialize ();
```

For more information, see MimeKit's documentation on
[using its cryptography support](https://github.com/jstedfast/MimeKit#initializing-mimekits-cryptography-support).

## Getting the Source Code

MailKit includes MimeKit as a git submodule, so make sure to clone recursively:

```bash
git clone --recursive https://github.com/jstedfast/MailKit.git
```

To update an existing clone later:

```bash
git pull
git submodule update --init --recursive
```

## Building

MailKit requires the [.NET 10.0 SDK](https://dotnet.microsoft.com/download) (or later) to build. The .NET 8.0 runtime
is also required to run the unit tests.

In the top-level MailKit directory, there are a number of solution files; they are:

* **MailKit.sln** - includes the projects for .NET Framework 4.6.2/4.7/4.8, .NETStandard 2.0/2.1, .NET 8.0/10.0 as well as the unit tests.
* **MailKit.Coverity.sln** - this is used to generate Coverity static analysis builds and is not generally useful.
* **MailKit.Documentation.sln** - this is used to generate the documentation found at https://mimekit.net/docs
and requires [Sandcastle Help File Builder](https://github.com/EWSoftware/SHFB).

To build from the command-line, run the following commands in the top-level MailKit directory:

    dotnet build MailKit.sln -c Release
    dotnet test UnitTests/UnitTests.csproj -c Release

Alternatively, you can open **MailKit.sln** in [Visual Studio 2026](https://visualstudio.microsoft.com/downloads/) (or later),
choose the **Debug** or **Release** build configuration and then build.

Note: The **Release** build will generate the xml API documentation, but the **Debug** build will not.

## Using MailKit

Every MailKit API that performs network I/O has both a synchronous and an asynchronous (`*Async`) variant. The
samples below use the async APIs, which are recommended for most applications (especially UI and server
applications), but the synchronous APIs work the same way.

### Connecting Securely

The `Connect` and `ConnectAsync` methods take a
[SecureSocketOptions](https://www.mimekit.net/docs/html/T_MailKit_Security_SecureSocketOptions.htm) value that
controls how SSL/TLS is used:

| Option | Description | Typical Ports |
|:-------|:------------|:--------------|
| `SslOnConnect` | Use SSL/TLS immediately upon connecting. | SMTP: 465, POP3: 995, IMAP: 993 |
| `StartTls` | Connect in plain text, then upgrade the connection using STARTTLS (fails if the server doesn't support it). | SMTP: 587, POP3: 110, IMAP: 143 |
| `StartTlsWhenAvailable` | Like `StartTls`, but continues unencrypted if the server doesn't support STARTTLS. **Not recommended.** | SMTP: 25/587, POP3: 110, IMAP: 143 |
| `Auto` | Choose `SslOnConnect` or `StartTlsWhenAvailable` based on the port. | Any |
| `None` | No SSL/TLS. **Not recommended.** | Any |

```csharp
await client.ConnectAsync ("smtp.friends.com", 587, SecureSocketOptions.StartTls);
```

By default, MailKit rejects server certificates that fail validation. If you need to customize this (for example,
to trust a self-signed certificate used by your own server), set the client's
[ServerCertificateValidationCallback](https://www.mimekit.net/docs/html/P_MailKit_MailService_ServerCertificateValidationCallback.htm)
property before connecting. Please don't simply `return true`, as that disables protection against
man-in-the-middle attacks. See the [FAQ](https://github.com/jstedfast/MailKit/blob/master/FAQ.md#ssl-handshake-exception)
for more details.

### Authenticating with OAuth2

Many mail providers, including Microsoft 365/Exchange Online and GMail, require (or strongly encourage) OAuth2
instead of passwords. Once you have obtained an access token for the user, authenticate using
[SaslMechanismOAuth2](https://www.mimekit.net/docs/html/T_MailKit_Security_SaslMechanismOAuth2.htm):

```csharp
using MailKit.Security;

var oauth2 = new SaslMechanismOAuth2 (emailAddress, accessToken);

await client.AuthenticateAsync (oauth2);
```

For step-by-step instructions on obtaining an access token, see:

* [Using OAuth2 With Exchange (IMAP, POP3 or SMTP)](https://github.com/jstedfast/MailKit/blob/master/ExchangeOAuth2.md)
* [Using OAuth2 With GMail (IMAP, POP3 or SMTP)](https://github.com/jstedfast/MailKit/blob/master/GMailOAuth2.md)

### Logging and Diagnostics

When something isn't working, the first thing to look at is the protocol log. Pass a
[ProtocolLogger](https://www.mimekit.net/docs/html/T_MailKit_ProtocolLogger.htm) to the client's constructor to
record the conversation between the client and the server:

```csharp
using var client = new SmtpClient (new ProtocolLogger ("smtp.log"));
```

Authentication secrets are redacted from the log by default, which makes it safe to include in bug reports.

On .NET 8.0 and later, MailKit also supports metrics and tracing via `System.Diagnostics`, so it integrates with
OpenTelemetry. Call `Telemetry.SmtpClient.Configure ()` (or the equivalent for `Socket`, `Pop3Client` or
`ImapClient`) to enable the meters. For a list of the available metrics and activities, see
[Telemetry.md](https://github.com/jstedfast/MailKit/blob/master/Telemetry.md).

### Sending Messages

One of the more common operations that MailKit is meant for is sending email messages.

```csharp
using System;
using System.Threading.Tasks;

using MailKit.Net.Smtp;
using MailKit.Security;
using MailKit;
using MimeKit;

namespace TestClient {
    class Program
    {
        public static async Task Main (string[] args)
        {
            var message = new MimeMessage ();
            message.From.Add (new MailboxAddress ("Joey Tribbiani", "joey@friends.com"));
            message.To.Add (new MailboxAddress ("Mrs. Chanandler Bong", "chandler@friends.com"));
            message.Subject = "How you doin'?";

            message.Body = new TextPart ("plain") {
                Text = @"Hey Chandler,

I just wanted to let you know that Monica and I were going to go play some paintball, you in?

-- Joey"
            };

            using (var client = new SmtpClient ()) {
                await client.ConnectAsync ("smtp.friends.com", 587, SecureSocketOptions.StartTls);

                // Note: only needed if the SMTP server requires authentication
                await client.AuthenticateAsync ("joey", "password");

                var result = await client.SendAsync (message);
                Console.WriteLine ("The server accepted the message: {0}", result.ResponseText);

                await client.DisconnectAsync (true);
            }
        }
    }
}
```

`SendAsync ()` returns a [SendResult](https://www.mimekit.net/docs/html/T_MailKit_SendResult.htm) that contains the
server's response along with the lists of accepted and rejected recipients.

By default, `SmtpClient` throws an `SmtpCommandException` if the server rejects any of the recipients. To deliver
the message to the remaining recipients instead, use an `SmtpSendRequest` that overrides `OnRecipientNotAccepted ()`:

```csharp
class LenientSendRequest : SmtpSendRequest
{
    public LenientSendRequest (MimeMessage message) : base (message)
    {
    }

    public override void OnRecipientNotAccepted (MailboxAddress recipient, SmtpResponse response)
    {
        // Don't throw; the recipient will be listed in SendResult.RejectedRecipients instead.
    }
}

// ...

var result = await client.SendAsync (new LenientSendRequest (message));

foreach (var recipient in result.RejectedRecipients)
    Console.WriteLine ("Rejected: {0}", recipient);
```

`SmtpSendRequest` is also how you request per-message SMTP options such as delivery status notifications (DSN).

## Retrieving Messages (via Pop3)

One of the other main uses of MailKit is retrieving messages from pop3 servers.

```csharp
using System;
using System.Threading.Tasks;

using MailKit.Net.Pop3;
using MailKit.Security;
using MailKit;
using MimeKit;

namespace TestClient {
    class Program
    {
        public static async Task Main (string[] args)
        {
            using (var client = new Pop3Client ()) {
                await client.ConnectAsync ("pop.friends.com", 995, SecureSocketOptions.SslOnConnect);

                await client.AuthenticateAsync ("joey", "password");

                for (int i = 0; i < client.Count; i++) {
                    var message = await client.GetMessageAsync (i);
                    Console.WriteLine ("Subject: {0}", message.Subject);
                }

                await client.DisconnectAsync (true);
            }
        }
    }
}
```

## Using IMAP

More important than POP3 support is the IMAP support. Here's a simple use-case of retrieving messages from an IMAP server:

```csharp
using System;
using System.Threading.Tasks;

using MimeKit;
using MailKit;
using MailKit.Search;
using MailKit.Security;
using MailKit.Net.Imap;

namespace TestClient {
    class Program
    {
        public static async Task Main (string[] args)
        {
            using (var client = new ImapClient ()) {
                await client.ConnectAsync ("imap.friends.com", 993, SecureSocketOptions.SslOnConnect);

                await client.AuthenticateAsync ("joey", "password");

                // The Inbox folder is always available on all IMAP servers...
                var inbox = client.Inbox;
                await inbox.OpenAsync (FolderAccess.ReadOnly);

                Console.WriteLine ("Total messages: {0}", inbox.Count);
                Console.WriteLine ("Recent messages: {0}", inbox.Recent);

                for (int i = 0; i < inbox.Count; i++) {
                    var message = await inbox.GetMessageAsync (i);
                    Console.WriteLine ("Subject: {0}", message.Subject);
                }

                await client.DisconnectAsync (true);
            }
        }
    }
}
```

### Fetching Information About the Messages in an IMAP Folder

One of the advantages of IMAP over POP3 is that the IMAP protocol allows clients to retrieve information about
the messages in a folder without having to first download all of them.

Using the [Fetch](https://www.mimekit.net/docs/html/Overload_MailKit_Net_Imap_ImapFolder_Fetch.htm) and
[FetchAsync](https://www.mimekit.net/docs/html/Overload_MailKit_Net_Imap_ImapFolder_FetchAsync.htm) method overloads
(or the convenient [extension methods](https://www.mimekit.net/docs/html/Overload_MailKit_IMailFolderFetchExtensions_Fetch.htm)),
it's possible to obtain any subset of summary information for any range of messages in a given folder.

```csharp
foreach (var summary in await inbox.FetchAsync (0, -1, MessageSummaryItems.Envelope)) {
    Console.WriteLine ("[summary] {0:D2}: {1}", summary.Index, summary.Envelope.Subject);
}
```

It's also possible to use Fetch/FetchAsync APIs that take an [IFetchRequest](https://www.mimekit.net/docs/html/T_MailKit_IFetchRequest.htm)
argument to get even more control over what to fetch:

```csharp
// Let's Fetch non-Received headers:
var request = new FetchRequest {
    Headers = new HeaderSet (new HeaderId[] { HeaderId.Received }) {
        Exclude = true
    }
};

foreach (var summary in await inbox.FetchAsync (0, -1, request)) {
    Console.WriteLine ("[summary] {0:D2}: {1}", summary.Index, summary.Headers[HeaderId.Subject]);
}
```

The results of a Fetch method can also be used to download individual MIME parts rather
than downloading the entire message. For example:

```csharp
foreach (var summary in await inbox.FetchAsync (0, -1, MessageSummaryItems.UniqueId | MessageSummaryItems.BodyStructure)) {
    if (summary.TextBody != null) {
        // this will download *just* the text/plain part
        var text = await inbox.GetBodyPartAsync (summary.UniqueId, summary.TextBody);
    }

    if (summary.HtmlBody != null) {
        // this will download *just* the text/html part
        var html = await inbox.GetBodyPartAsync (summary.UniqueId, summary.HtmlBody);
    }

    // if you'd rather grab, say, an image attachment... it might look something like this:
    if (summary.Body is BodyPartMultipart) {
        var multipart = (BodyPartMultipart) summary.Body;

        var attachment = multipart.BodyParts.OfType<BodyPartBasic> ().FirstOrDefault (x => x.FileName == "logo.jpg");
        if (attachment != null) {
            // this will download *just* the attachment
            var part = await inbox.GetBodyPartAsync (summary.UniqueId, attachment);
        }
    }
}
```

### Setting Message Flags in IMAP

In order to set or update the flags on a particular message, what is actually needed is the UID or index of the message and
the folder that it belongs to.

An obvious reason to want to update message flags is to mark a message as "read" (aka "seen") after a user has opened a
message and read it.

```csharp
await folder.StoreAsync (uid, new StoreFlagsRequest (StoreAction.Add, MessageFlags.Seen) { Silent = true });
```

### Deleting Messages in IMAP

Deleting messages in IMAP involves setting a `\Deleted` flag on a message and, optionally, expunging it from the folder.

The way to mark a message as `\Deleted` works the same way as marking a message as `\Seen`.

```csharp
await folder.StoreAsync (uid, new StoreFlagsRequest (StoreAction.Add, MessageFlags.Deleted) { Silent = true });
await folder.ExpungeAsync ();
```

### Searching an IMAP Folder

You may also be interested in sorting and searching...

```csharp
// let's search for all messages received after Jan 12, 2013 with "MailKit" in the subject...
var query = SearchQuery.DeliveredAfter (DateTime.Parse ("2013-01-12"))
    .And (SearchQuery.SubjectContains ("MailKit")).And (SearchQuery.Seen);

foreach (var uid in await inbox.SearchAsync (query)) {
    var message = await inbox.GetMessageAsync (uid);
    Console.WriteLine ("[match] {0}: {1}", uid, message.Subject);
}

// let's do the same search, but this time sort them in reverse arrival order
var orderBy = new [] { OrderBy.ReverseArrival };
foreach (var uid in await inbox.SortAsync (query, orderBy)) {
    var message = await inbox.GetMessageAsync (uid);
    Console.WriteLine ("[match] {0}: {1}", uid, message.Subject);
}

// you'll notice that the orderBy argument is an array... this is because you
// can actually sort the search results based on multiple columns:
orderBy = new [] { OrderBy.ReverseArrival, OrderBy.Subject };
foreach (var uid in await inbox.SortAsync (query, orderBy)) {
    var message = await inbox.GetMessageAsync (uid);
    Console.WriteLine ("[match] {0}: {1}", uid, message.Subject);
}
```

Of course, instead of downloading the message, you could also fetch the summary information for the matching messages
or do any of a number of other things with the UIDs that are returned.

### Navigating Folders in IMAP

How about navigating folders? MailKit can do that, too:

```csharp
// Get the first personal namespace and list the toplevel folders under it.
var personal = client.GetFolder (client.PersonalNamespaces[0]);
foreach (var folder in await personal.GetSubfoldersAsync (false))
    Console.WriteLine ("[folder] {0}", folder.Name);
```

If the IMAP server supports the SPECIAL-USE or the XLIST (GMail) extension, you can get a hold of
the pre-defined All, Drafts, Flagged (aka Important), Junk, Sent, Trash, etc folders like this:

```csharp
if (client.Capabilities.Contains (ImapCapability.SpecialUse) || client.Capabilities.Contains (ImapCapability.XList)) {
    var drafts = client.GetFolder (SpecialFolder.Drafts);
} else {
    // maybe check the user's preferences for the Drafts folder?
}
```

In cases where the IMAP server does *not* support the SPECIAL-USE or XLIST extensions, you'll have to
come up with your own heuristics for getting the Sent, Drafts, Trash, etc folders. For example, you
might use logic similar to this:

```csharp
static string[] CommonSentFolderNames = { "Sent Items", "Sent Mail", "Sent Messages", /* maybe add some translated names */ };

static async Task<IMailFolder?> GetSentFolderAsync (ImapClient client, CancellationToken cancellationToken)
{
    var personal = client.GetFolder (client.PersonalNamespaces[0]);

    foreach (var folder in await personal.GetSubfoldersAsync (false, cancellationToken)) {
        foreach (var name in CommonSentFolderNames) {
            if (folder.Name == name)
                return folder;
        }
    }

    return null;
}
```

Using LINQ, you could simplify this down to something more like this:

```csharp
static string[] CommonSentFolderNames = { "Sent Items", "Sent Mail", "Sent Messages", /* maybe add some translated names */ };

static async Task<IMailFolder?> GetSentFolderAsync (ImapClient client, CancellationToken cancellationToken)
{
    var personal = client.GetFolder (client.PersonalNamespaces[0]);

    var folders = await personal.GetSubfoldersAsync (false, cancellationToken);

    return folders.FirstOrDefault (x => CommonSentFolderNames.Contains (x.Name));
}
```

Another option might be to allow the user of your application to configure which folder he or she wants to use as their
Sent folder, Drafts folder, Trash folder, etc.

How you handle this is up to you.

### Monitoring an IMAP Folder for Changes

To be notified when new messages arrive (or when messages are deleted or their flags change), use an
[ImapIdleSession](https://www.mimekit.net/docs/html/T_MailKit_Net_Imap_ImapIdleSession.htm). It uses the
`IDLE` command when the server supports it (restarting it periodically so that the connection isn't dropped)
and falls back to polling with `NOOP` when the server doesn't:

```csharp
await client.Inbox.OpenAsync (FolderAccess.ReadOnly);

var session = client.CreateIdleSession ();

// Cancel the token to stop monitoring; the IDLE command is ended gracefully and the client remains usable.
try {
    await foreach (var changes in session.ReadChangesAsync (cancellationToken)) {
        if (changes.MessagesArrived)
            Console.WriteLine ("New messages have arrived! The Inbox now has {0} messages.", client.Inbox.Count);
    }
} catch (OperationCanceledException) {
}
```

The `IDLE` command has already been ended by the time each batch of changes is returned, so it is safe to issue
other commands (such as fetching the new messages) while processing them. For a more complete example, see
[ImapIdleSessionExample.cs](https://github.com/jstedfast/MailKit/blob/master/Documentation/Examples/ImapIdleSessionExample.cs).

## Contributing

The first thing you'll need to do is fork MailKit to your own GitHub repository. For instructions on how to
clone it, see the section titled **Getting the Source Code**.

MailKit uses an [`.editorconfig`](https://github.com/jstedfast/MailKit/blob/master/.editorconfig) file to describe
its coding style (tabs for indentation and a space before the opening parenthesis of method calls and
declarations), which is supported by Visual Studio, Visual Studio Code, Rider and most other editors. Please try
to follow the existing coding style as best as you can.

Once you've got some changes that you'd like to submit upstream to the official MailKit repository,
send me a **Pull Request** and I will try to review your changes in a timely manner.

If you'd like to contribute but don't have any particular features in mind to work on, check out the issue
tracker and look for something that might pique your interest!

## Reporting Bugs

Have a bug or a feature request? Please open a new
[bug report](https://github.com/jstedfast/MailKit/issues/new?template=bug_report.md)
or
[feature request](https://github.com/jstedfast/MailKit/issues/new?template=feature_request.md).

Before opening a new issue, please search through any [existing issues](https://github.com/jstedfast/MailKit/issues)
to avoid submitting duplicates. It may also be worth checking the
[FAQ](https://github.com/jstedfast/MailKit/blob/master/FAQ.md) for common questions that other developers
have had.

If MailKit does not work with your mail server, please include a [protocol
log](https://github.com/jstedfast/MailKit/blob/master/FAQ.md#protocol-log) in your bug report, otherwise
there is nothing I can do to fix the problem.

If you are getting an exception from somewhere within MailKit, don't just provide the `Exception.Message`
string. Please include the `Exception.StackTrace` as well. The `Message`, by itself, is often useless.

## Documentation

API documentation can be found at [https://www.mimekit.net/docs](https://www.mimekit.net/docs).

Some example snippets can be found in the [`Documentation/Examples`](https://github.com/jstedfast/MailKit/tree/master/Documentation/Examples) directory.

Sample applications can be found in the [`samples`](https://github.com/jstedfast/MailKit/tree/master/samples) directory.

A copy of the XML-formatted API reference documentation is also included in the NuGet package.

### Further Reading

* [Frequently Asked Questions](https://github.com/jstedfast/MailKit/blob/master/FAQ.md)
* [Porting Guide (MailKit 4.x to 5.0)](https://github.com/jstedfast/MailKit/blob/master/PortingGuide.md)
* [Release Notes](https://github.com/jstedfast/MailKit/blob/master/ReleaseNotes.md)
* [Using OAuth2 With Exchange](https://github.com/jstedfast/MailKit/blob/master/ExchangeOAuth2.md)
* [Using OAuth2 With GMail](https://github.com/jstedfast/MailKit/blob/master/GMailOAuth2.md)
* [Telemetry (Metrics and Tracing)](https://github.com/jstedfast/MailKit/blob/master/Telemetry.md)
* [Supported RFCs](https://github.com/jstedfast/MailKit/blob/master/RFCs.md)
* [Security Policy](https://github.com/jstedfast/MailKit/blob/master/SECURITY.md)

## .NET Foundation

MailKit is a [.NET Foundation](https://www.dotnetfoundation.org/projects) project.

This project has adopted the code of conduct defined by the [Contributor Covenant](https://contributor-covenant.org/) to clarify expected behavior in our community. For more information, see the [.NET Foundation Code of Conduct](https://www.dotnetfoundation.org/code-of-conduct).

General .NET OSS discussions: [.NET Foundation forums](https://forums.dotnetfoundation.org)

---

### Documentation Examples InlinePGPExample (`Documentation/Examples/InlinePGPExample.txt`)

Return-Path: <pgp-enthusiast@example.com>
Received: from [127.0.0.1] (hostname.example.com. [201.95.8.17])
    by mx.google.com with ESMTPSA id l67sm26628445yha.8.2014.04.27.13.49.44
    for <pgp-enthusiast@example.com>
    (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128);
    Sun, 27 Apr 2014 13:49:44 -0700 (PDT)
Message-ID: <535D6D67.8020803@example.com>
Date: Sun, 27 Apr 2014 17:49:43 -0300
From: Die-Hard PGP Fan <pgp-enthusiast@example.com>
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:24.0) Gecko/20100101 Thunderbird/24.4.0
MIME-Version: 1.0
To: undisclosed-recipients:;
Subject: Test of inline encrypted PGP blocks
X-Enigmail-Version: 1.6
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit
X-Antivirus: avast! (VPS 140427-1, 27/04/2014), Outbound message
X-Antivirus-Status: Clean

-----BEGIN PGP MESSAGE-----
Charset: ISO-8859-1
Version: GnuPG v2.0.22 (MingW32)
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

SGFoISBJIGZvb2xlZCB5b3UsIHRoaXMgdGV4dCBpc24ndCBhY3R1YWxseSBlbmNy
eXB0ZWQgd2l0aCBQR1AsCml0J3MgYWN0dWFsbHkgb25seSBiYXNlNjQgZW5jb2Rl
ZCEKCkknbSBqdXN0IHVzaW5nIHRoaXMgYXMgYW4gZXhhbXBsZSwgdGhvdWdoLCBz
byBpdCBkb2Vzbid0IHJlYWxseSBtYXR0ZXIuCgpGb3IgdGhlIHNha2Ugb2YgYXJn
dW1lbnQsIHdlJ2xsIHByZXRlbmQgdGhhdCB0aGlzIGlzIGFjdHVhbGx5IGFuIGVu
Y3J5cHRlZApibHVyYi4gTW1ta2F5PyBUaGFua3MuCg==
-----END PGP MESSAGE-----

---

--- METRICS ---
- Files Extracted: 2
- Estimated Token Budget: ~9382 tokens
- Canonical Reference: https://codewiki.google/github.com/jstedfast/MailKit
