See the question and my original answer on StackOverflow

The general idea is to follow the tutorial here: Get Started with Mail, Calendar, and Contacts REST APIs but I will try to simplify it and demonstrate it with a Winforms sample.

Register App

First things first, you need to create and register an application to the Application Registration Portal (you should only have to do this once for a given application of course):

  1. create an app
  2. generate a new password
  3. add a platform, and choose mobile ("mobile" here means "any device", or "not for a browser"...)
  4. don't forget to click on save!


Now, in your "any device" code (including winforms), you'll need to authenticate. The simplest way is to use ADAL ("Active Directory Authentication Library"). The source is available here and the binary is available as a nuget.

Unfortunately, the latest version which you can get on nuget today named Microsoft.IdentityModel.Clients.ActiveDirectory does not work for me (It had a bug I've reported here that's already been fixed, but now the server complains about some app vs server incompatibility).

So you must use the old "Experimental" one (keep that in mind as someday in the future, we'll have to switch): Microsoft.Experimental.IdentityModel.Clients.ActiveDirectory

You want to make sure you use the proper scopes when you do acquire an auth token. Scopes are defined here: Outlook mail, calendar, and contacts scopes and represent an area of permission. Without specifying scope, you can do nothing else but authenticate.

So, if you want to read mails, use the "" scope.

When you try the application, after the authentication dialog, it should display to the user the consent screen (here we see we asked for mail scope: "Read Your Mail"):

enter image description here

Office/Outlook/OData API

Once authentication works, you can use the REST api directly which is not that easy, or be lazy and use another package: Microsoft.Office365.OutlookServices-V2.0 that will do all underlying REST/OData magic for you. The good news is this API is quite complete so it should allow you to do other things like, message creation, delete, etc.

There is an important remark for the case: not all accounts are enabled for this whole REST API (check the "REST API availability" chapter here: Outlook Mail), so you might want to create a new one for testing.

Here is the winforms code for a sample app that will query 10 messages and add them to a listbox.

using System;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.Experimental.IdentityModel.Clients.ActiveDirectory;
using Microsoft.Office365.OutlookServices;

namespace WindowsFormsApplication1
    public partial class Form1 : Form
        private const string authority = "";
        private const string clientId = "blablabl-abla-blab-abla-blablablab"; // TODO: put your application id here
        private const string redirectUri = "urn:ietf:wg:oauth:2.0:oob"; // put your redirect uri here (should be the same)

        // we cache the token for the duration of this form
        // you could/should use the FileCache class provided in the sample here
        private TokenCache _cache = new TokenCache();

        public Form1()

        private void button1_Click(object sender, EventArgs e)
            // since all packages force async,
            // we have to avoid threading issues
            BeginInvoke((Action)(() => GetMessages()));

        private async void GetMessages()
            // use the Microsoft.Experimental.IdentityModel.Clients.ActiveDirectory nuget package for auth
            var authContext = new AuthenticationContext(authority, _cache);
            var result = await authContext.AcquireTokenAsync(
                new[] { "" },
                new Uri(redirectUri),
                new PlatformParameters(PromptBehavior.Always, this));

            // use the Microsoft.Office365.OutlookServices-V2.0 nuget package from now on
            var client = new OutlookServicesClient(new Uri(""), () => Task.FromResult(result.Token));

            var messages = await client.Me.Messages
                                        .Take(10) // get only 10 messages

            // fill some list box
            // (beware, some messages have a null subject)
            foreach (var msg in messages.CurrentPage)