{"id":87587,"date":"2020-07-21T14:06:32","date_gmt":"2020-07-21T14:06:32","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/?p=87587"},"modified":"2026-04-15T18:37:10","modified_gmt":"2026-04-15T18:37:10","slug":"getting-started-with-microsoft-graph-api","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/development\/dotnet-development\/getting-started-with-microsoft-graph-api\/","title":{"rendered":"Getting Started with Microsoft Graph API"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\" id=\"h-executive-summary\">Executive Summary<\/h2>\n\n\n\n<p><strong>Microsoft Graph API is Microsoft&#8217;s unified REST API for accessing data and services in Microsoft 365 &#8211; including users, email, calendar, files (OneDrive and SharePoint), Teams, and more. Any application that needs to read or write to a user&#8217;s Microsoft 365 account uses Microsoft Graph. The API follows a consistent URL pattern: https:\/\/graph.microsoft.com\/{version}\/{resource}. This article introduces the request structure, demonstrates the Graph Explorer tool for testing endpoints interactively, and shows a .NET Core integration that retrieves user profile data and sends an email using the Microsoft Graph SDK.<\/strong><\/p>\n\n\n\n<p>It is a common practice for big players in the cloud market to allow their users to have more than one method to access their data. With Google, for example, you can have one single account and easy access to a bunch of free services like Gmail and Drive.<\/p>\n\n\n\n<p>Google also provides public APIs for developers to be able to access data via other applications. The whole process happens through the usual OAuth +, an application provided by the player.<\/p>\n\n\n\n<p>With Microsoft, there\u2019s <a href=\"https:\/\/developer.microsoft.com\/en-us\/graph\/\">Microsoft Graph<\/a>. It provides some REST endpoints that allow access to their services like Office 365 (which is in the cloud, unlike the older versions), Azure and Outlook.<\/p>\n\n\n\n<p>Here\u2019s a single example for you to get a taste. A common URL endpoint to retrieve personal information about a specific account is <a href=\"https:\/\/graph.microsoft.com\/v1.0\/me\">https:\/\/graph.microsoft.com\/v1.0\/me<\/a>. Here\u2019s what you\u2019ll get if you try it out in a browser tab:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">{\n  \"error\": {\n    \"code\": \"InvalidAuthenticationToken\",\n    \"message\": \"Access token is empty.\",\n    \"innerError\": {\n      \"request-id\": \"a2115c87-341f-405a-b127-d3432748d38b\",\n      \"date\": \"2020-06-08T13:46:07\"\n    }\n  }\n}<\/pre>\n\n\n\n<p>That\u2019s when OAuth takes place. The URL, in turn, follows some pattern rules that you\u2019ll see right away.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-microsoft-graph-api-structure\">Microsoft Graph API Structure<\/h2>\n\n\n\n<p>The access to each resource must follow a pattern. Here\u2019s the request construction:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">{HTTP method} https:\/\/graph.microsoft.com\/{version}\/{resource}?{query-parameters}<\/pre>\n\n\n\n<p>First, as usual, you define the HTTP method for the operation. Note that it\u2019s not up to you to decide that; you must go to the docs and check which method is available for that operation. Plus, the endpoints follow the <a href=\"https:\/\/restfulapi.net\/\">RESTful principles<\/a>, so make sure to refer to it for better comprehension.<\/p>\n\n\n\n<p>Then it comes the version of the Graph API you\u2019re targeting. As per the writing of this article, the only available versions are <em>v1.0<\/em> and <em>beta<\/em>. As you may have noticed, for production purposes, only the <em>v1.0<\/em> version should be used. The <em>beta<\/em> version brings some new stuff, which might include breaking changes, so be careful when using it.<\/p>\n\n\n\n<p>The <em>resource<\/em> defines the entity (and its properties) you\u2019re willing to access. These resources usually come alone like in the previous example (<em>\/me<\/em>), so they\u2019re called top-level entity resources. However, you may want additional inheriting data, like <em>\/me\/messages<\/em>, for example. You can refer to the list of available resources <a href=\"https:\/\/docs.microsoft.com\/en-us\/graph\/traverse-the-graph\">here<\/a>.<\/p>\n\n\n\n<p>Remember that each resource is secure information, so it requires <a href=\"https:\/\/docs.microsoft.com\/en-us\/graph\/permissions-reference\">permission<\/a> to be accessed. You\u2019ll see more about how to do it soon.<\/p>\n\n\n\n<p>Finally, you have the parameters. Like the other REST API endpoints, it\u2019s necessary to provide the filters for the endpoints that demand that, like when retrieving all of your email messages filtered by the sender, for example.<\/p>\n\n\n\n<p>Microsoft Graph API makes use of the <a href=\"https:\/\/www.odata.org\/\">OData<\/a> (Open Data Protocol) namespace, which defines a set of best practices for building and consuming RESTful APIs. You can read more detailed information about the whole API architecture <a href=\"https:\/\/docs.microsoft.com\/en-us\/graph\/use-the-api\">here<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-seeing-it-in-action\">Seeing it in Action<\/h2>\n\n\n\n<p>Microsoft Graph also provides a great tool to easily explore the endpoints, and it\u2019s the <a href=\"https:\/\/developer.microsoft.com\/en-us\/graph\/graph-explorer\">Graph Explorer<\/a>. Open it, check out at the top of the screen if you\u2019re already logged in, otherwise log in to your Microsoft account. Figure 1 shows how it looks.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"2500\" height=\"1206\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/07\/word-image-37.png\" alt=\"\" class=\"wp-image-87588\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>Figure 1. Microsoft Graph Explorer view.<\/strong><\/p>\n\n\n\n<p>In the top bar of this screen, you&#8217;ll see a few combo boxes and a text field to customize your search. Number 1 shows the option to select which HTTP method you want this search to be run. Number 2 states the API version (<em>v1.0<\/em> or <em>beta<\/em>).<\/p>\n\n\n\n<p>Number 3 represents the full URL of the necessary resource. In this example, the <em>\/me<\/em> was filled by the first option available at <em>Sample queries<\/em> tab (number 6). It helps you to figure out the available options, pre-filling the required values and making the Explorer ready to run the request. The <em>History<\/em> tab lists the searches executed until now.<\/p>\n\n\n\n<p>Number 5 brings four other options:<\/p>\n\n\n<div class=\"block-core-list\">\n<ul class=\"wp-block-list\">\n<li>The request body with the request data your search may need.<\/li>\n\n\n\n<li>The request headers.<\/li>\n\n\n\n<li>Modify permissions: once you\u2019ve authorized the Explorer to have access to your account data, you can customize each permission individually.<\/li>\n\n\n\n<li>Access token: the access token needed to perform each request. Explorer automatically generates it. In case you need to search in another environment other than here, the token must be generated each time.<\/li>\n<\/ul>\n<\/div>\n\n\n<p>Number 7, finally, deals with the tabs of the API responses. Here you\u2019ll have the response body preview (once it\u2019s completed) and the response headers.<\/p>\n\n\n\n<p>The <em>Adaptive cards<\/em> functionality is just a nice feature in which Microsoft tries to adapt the returned information into cards, like a business card.<\/p>\n\n\n\n<p>The <em>Code snippets<\/em> tab is very interesting. It auto-generates the code for the current request in four different languages: CSharp (Figure 2), JavaScript, Java and Objective-C:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1376\" height=\"534\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/07\/word-image-38.png\" alt=\"\" class=\"wp-image-87589\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>Figure 2. Code snippets for 4 languages.<\/strong><\/p>\n\n\n\n<p>Besides all that, you still need to sign in to Graph Explorer with your Microsoft account to fetch its data. For this, click the <em>Sign in to Graph Explorer<\/em> button in the left side panel. Then, you\u2019ll be redirected to the access page to permit the Graph Explorer app (Figure 3). Click the <em>Yes<\/em> button.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1190\" height=\"1534\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/07\/word-image-39.png\" alt=\"\" class=\"wp-image-87590\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>Figure 3. Giving access to the Graph Explorer app.<\/strong><\/p>\n\n\n\n<p>Once you\u2019re logged, run the <em>\/me<\/em> request. Listing 1 shows the response content that\u2019ll be shown in the <em>Response preview<\/em> tab.<\/p>\n\n\n\n<p><strong>Listing 1. Response content for <em>\/me<\/em> request.<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">{\n   \"@odata.context\": \"https:\/\/graph.microsoft.com\/v1.0\/$metadata#users\/$entity\",\n   \"displayName\": \"Julio Sampaio\",\n   \"surname\": \"Sampaio\",\n   \"givenName\": \"Julio\",\n   \"id\": \"4e108eb8cbcb0495\",\n   \"userPrincipalName\": \"-----@outlook.com\",\n   \"businessPhones\": [],\n   \"jobTitle\": null,\n   \"mail\": null,\n   \"mobilePhone\": null,\n   \"officeLocation\": null,\n   \"preferredLanguage\": null\n}<\/pre>\n\n\n\n<p>Sometimes, depending on the operation you\u2019re performing, you\u2019ll be prompted to consent to the specific permissions, in the <em>Modify permissions<\/em> tab.<\/p>\n\n\n\n<p>Run another sample query. Go to the <em>Sample queries<\/em> tab and search for <em>my mails from an address<\/em>, then click the GET option shown in Figure 4:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"704\" height=\"542\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/07\/word-image-40.png\" alt=\"\" class=\"wp-image-87591\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>Figure 4. Searching for a sample query.<\/strong><\/p>\n\n\n\n<p>When you try to run this query, you\u2019ll get the following error message: <em>Forbidden &#8211; 403 &#8211; 260ms. You need to consent to the permissions on the <\/em><strong><em>Modify permissions<\/em><\/strong><em> tab.<\/em><\/p>\n\n\n\n<p>Opening the referred tab, you\u2019ll see the <em>Consent<\/em> buttons in the <em>Status<\/em> column, like in Figure 5. If you\u2019re in a small screen, pay attention that the buttons are \u201chidden\u201d, so you have to scroll to see them horizontally.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"2120\" height=\"674\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/07\/word-image-41.png\" alt=\"\" class=\"wp-image-87592\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>Figure 5. Consenting to the permissions.<\/strong><\/p>\n\n\n\n<p>If the operation goes on successfully, you\u2019ll see the status changing to <em>Consented<\/em>. Now, run the query. Don\u2019t forget to change the email parameter to one of yours at the query text field.<\/p>\n\n\n\n<p>The result should be similar to Figure 6.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"2310\" height=\"1338\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/07\/word-image-42.png\" alt=\"\" class=\"wp-image-87593\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>Figure 6. Querying email messages by sender email.<\/strong><\/p>\n\n\n\n<p>Now to move to an example that creates data in the server, using the API to send an email. For this, go again to the <em>Sample querie<\/em>s tab and search for <em>send an email<\/em>, then click the button. You\u2019ll notice that Graph Explorer fills in the <em>Request body<\/em> area with a pre-generated JSON. It is pretty much what\u2019s necessary to send a basic email. Obviously, you may change its contents to your preferences. Listing 2 shows what the JSON looks.<\/p>\n\n\n\n<p><strong>Listing 2. JSON example to send an email.<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">{\n   \"message\": {\n       \"subject\": \"Meet for lunch?\",\n       \"body\": {\n           \"contentType\": \"Text\",\n           \"content\": \"The new cafeteria is open.\"\n       },\n       \"toRecipients\": [\n           {\n               \"emailAddress\": {\n                   \"address\": \"YOUR_EMAIL@outlook.com\"\n               }\n           }\n       ]\n   }\n}<\/pre>\n\n\n\n<p>Before submitting the query, remember that you have to authorize Graph Explorer with the right permissions. Go to the <em>Modify permissions<\/em> tab again and allow the required accesses.<\/p>\n\n\n\n<p>Run it. If everything went right, you\u2019ll see the successful message with an HTTP <em>201 &#8211; Accepted<\/em> code. It means that the request was OK, and something was created in the server. In this case, the sent email.<\/p>\n\n\n\n<p>Go to your email inbox and check that the email was sent (Figure 7).<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"2110\" height=\"628\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/07\/word-image-43.png\" alt=\"\" class=\"wp-image-87594\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>Figure 7. Email sent successfully.<\/strong><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-integrating-net-core-with-microsoft-graph\">Integrating .NET Core with Microsoft Graph<\/h2>\n\n\n\n<p>Here\u2019s another example. This time, you\u2019ll integrate a simple .NET Core application with Microsoft Graph to retrieve user\u2019s data and send an email as well.<\/p>\n\n\n\n<p>First, create a new app by running the following command:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">dotnet new console -o simpletalk-graph-api<\/pre>\n\n\n\n<p>This command creates a Console app. Then, add the required NuGet dependencies:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">dotnet add package Microsoft.Extensions.Configuration.UserSecrets\ndotnet add package Microsoft.Identity.Client\ndotnet add package Microsoft.Graph<\/pre>\n\n\n\n<p>To enable the use of Graph API within .NET applications, you\u2019ll need to set up an Azure AD application. For this, go to the <a href=\"https:\/\/portal.azure.com\/#home\">Azure Admin Center<\/a> and log in to your Microsoft account.<\/p>\n\n\n\n<p>In the home page, click the <em>All resources &gt; Manage Azure Active Directory<\/em> option and, finally, go to the <em>App registrations<\/em> option. Click the <em>New registration<\/em> button. In the next screen, give the app a name (<em>simple-talk-graph-app<\/em>, for example) and fill the options like shown in Figure 8.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1039\" height=\"855\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/07\/word-image-44.png\" alt=\"\" class=\"wp-image-87595\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>Figure 8. Registering a new application.<\/strong><\/p>\n\n\n\n<p>The next screen you will see shows the app details, including the <em>Application id<\/em>, which is going to be used soon in the C# code. It\u2019s also necessary that this app is treated as a public client, so you need to toggle it going to the <em>Authentication &gt; Advanced Settings &gt; Default client type<\/em> option. Toggle it and click <em>Save<\/em>.<\/p>\n\n\n\n<p>Next, you need to initialize the .NET development secret store. Since it\u2019s necessary to generate new OAuth tokens for every new request, the automatic way to do it is by <a href=\"https:\/\/github.com\/AzureAD\/microsoft-authentication-library-for-dotnet\">Azure AD<\/a>:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">dotnet user-secrets init<\/pre>\n\n\n\n<p>After it\u2019s initialized, you can add the credentials related to the client id and the scopes (permissions):<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">dotnet user-secrets set appId \"3f2458ff-43d2-45f8-a0f0-b2f403461ef4\"\ndotnet user-secrets set scopes \"User.Read;Mail.Send\"<\/pre>\n\n\n\n<p>Remember to replace the <code>appId<\/code> with yours. Now, open the created project into Visual Studio and create two new folders: <em>Auth <\/em>(to deal with the auth flow) and <em>Graph <\/em>(to store the graph helpers).<\/p>\n\n\n\n<p>Start with the authentication process. Create a new class into the <em>Auth<\/em> folder called <em>DeviceCodeAuthProvider.cs<\/em>. The name already suggests that this is the flow this example uses to authenticate users. Listing 3 shows the code.<\/p>\n\n\n\n<p><strong>Listing 3. DeviceCodeAuthProvider code.<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">using Microsoft.Graph;\nusing Microsoft.Identity.Client;\nusing System;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Threading.Tasks;\nnamespace simpletalk_graph_api.Auth\n{\n    public class DeviceCodeAuthProvider : IAuthenticationProvider\n    {\n        private IPublicClientApplication _msalClient;\n        private string[] _scopes;\n        private IAccount _userAccount;\n        public DeviceCodeAuthProvider(string appId, string[] scopes)\n        {\n            _scopes = scopes;\n            _msalClient = PublicClientApplicationBuilder\n                .Create(appId)\n                .WithAuthority(AadAuthorityAudience.AzureAdAndPersonalMicrosoftAccount, true)\n                .Build();\n        }\n        public async Task&lt;string&gt; GetAccessToken()\n        {\n            if (_userAccount == null)\n            {\n                try\n                {\n                    var result = await _msalClient.AcquireTokenWithDeviceCode(_scopes, callback =&gt; {\n                        Console.WriteLine(callback.Message);\n                        return Task.FromResult(0);\n                    }).ExecuteAsync();\n                    _userAccount = result.Account;\n                    return result.AccessToken;\n                }\n                catch (Exception exception)\n                {\n                    Console.WriteLine($\"Error getting access token: {exception.Message}\");\n                    return null;\n                }\n            }\n            else\n            {\n                var result = await _msalClient\n                    .AcquireTokenSilent(_scopes, _userAccount)\n                    .ExecuteAsync();\n                return result.AccessToken;\n            }\n        }\n        public async Task AuthenticateRequestAsync(HttpRequestMessage requestMessage)\n        {\n            requestMessage.Headers.Authorization =\n                new AuthenticationHeaderValue(\"bearer\", await GetAccessToken());\n        }\n    }\n}<\/pre>\n\n\n\n<p>The code is designed under the <a href=\"https:\/\/github.com\/AzureAD\/microsoft-authentication-library-for-dotnet\">MSAL<\/a> patterns. It injects the scopes and credentials you\u2019ve previously set in the command line. There are two main methods: one to generate new access tokens and another one to authenticate each of the requests, feeding them with the proper bearer tokens.<\/p>\n\n\n\n<p>Listing 4 shows the code to be placed in the <em>GraphHelper.cs<\/em> file (please, create it under the <em>Graph<\/em> folder).<\/p>\n\n\n\n<p><strong>Listing 4. GraphHelper code.<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">using Microsoft.Graph;\nusing System;\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\nnamespace simpletalk_graph_api.Graph\n{\n    public class GraphHelper\n    {\n        private static GraphServiceClient graphClient;\n        public static void Initialize(IAuthenticationProvider authProvider)\n        {\n            graphClient = new GraphServiceClient(authProvider);\n        }\n        public static async Task&lt;User&gt; GetMeAsync()\n        {\n            try\n            {\n                \/\/ GET \/me\n                return await graphClient.Me.Request().GetAsync();\n            }\n            catch (ServiceException ex)\n            {\n                Console.WriteLine($\"Error getting signed-in user: {ex.Message}\");\n                return null;\n            }\n        }\n        public static async void SendMailAsync()\n        {\n            try\n            {\n                var message = new Message\n                {\n                    Subject = \"Testing from .NET SDK\",\n                    Body = new ItemBody\n                    {\n                        ContentType = BodyType.Text,\n                        Content = \"The SDK is working fine!\"\n                    },\n                    ToRecipients = new List&lt;Recipient&gt;()\n                    {\n                        new Recipient\n                        {\n                            EmailAddress = new EmailAddress\n                            {\n                                Address = \"YOUR_EMAIL@outlook.com\"\n                            }\n                        }\n                    }\n                };\n                await graphClient.Me\n                    .SendMail(message, null)\n                    .Request()\n                    .PostAsync();\n            }\n            catch (ServiceException ex)\n            {\n                Console.WriteLine($\"Error getting signed-in user: {ex.Message}\");\n            }\n        }\n    }\n}<\/pre>\n\n\n\n<p>The code of these methods was extracted from the auto-generated ones shown in the Graph Explorer before. Once you have the auth provider, you can instantiate the graph client and call the respective Graph operation.<\/p>\n\n\n\n<p>Finally, move on to the code of <em>Program.cs<\/em> file, which calls these methods. Listing 5 shows the content.<\/p>\n\n\n\n<p><strong>Listing 5. Program class code.<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">using Microsoft.Extensions.Configuration;\nusing simpletalk_graph_api.Auth;\nusing simpletalk_graph_api.Graph;\nusing System;\nnamespace simpletalk_graph_api\n{\n    class Program\n    {\n        static async System.Threading.Tasks.Task Main(string[] args)\n        {\n            var appConfig = LoadAppSettings();\n            var appId = appConfig[\"appId\"];\n            var scopesString = appConfig[\"scopes\"];\n            var scopes = scopesString.Split(';');\n            var authProvider = new DeviceCodeAuthProvider(appId, scopes);\n            var accessToken = await authProvider.GetAccessToken();\n            Console.WriteLine($\"Access token: {accessToken}\\n\");\n            GraphHelper.Initialize(authProvider);\n            var user = await GraphHelper.GetMeAsync();\n            Console.WriteLine($\"Welcome {user.DisplayName}!\\n\");\n            GraphHelper.SendMailAsync();\n            Console.WriteLine(\"Email sent!\");\n        }\n        static IConfigurationRoot LoadAppSettings()\n        {\n            var appConfig = new ConfigurationBuilder()\n                .AddUserSecrets&lt;Program&gt;()\n                .Build();\n            if (string.IsNullOrEmpty(appConfig[\"appId\"]) ||\n                string.IsNullOrEmpty(appConfig[\"scopes\"]))\n            {\n                return null;\n            }\n            return appConfig;\n        }\n    }\n}<\/pre>\n\n\n\n<p>First, you need to load the app settings where the credentials and scopes were placed. After extracting the app id and scopes array, you may retrieve a valid access token (which is going to be printed to make sure it works), initialize the graph helper (that will, in turn, create the graph client from the auth provider) and, finally, call the <em>\/me<\/em> and <em>\/sendMail<\/em> operations.<\/p>\n\n\n\n<p>When you run the app, a new console window opens and asks you to access the <a href=\"https:\/\/microsoft.com\/devicelogin\">https:\/\/microsoft.com\/devicelogin<\/a> URL and enter a printed code to authenticate. Copy the code, access the URL and paste it. Click <em>Next<\/em>, then authenticate to your Microsoft account.<\/p>\n\n\n\n<p>The final screen shows what type of information the app is trying to access and ask for your permission (Figure 9):<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"490\" height=\"855\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/07\/word-image-45.png\" alt=\"\" class=\"wp-image-87596\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>Figure 9. Giving access to the Graph app.<\/strong><\/p>\n\n\n\n<p>Click <em>Yes<\/em> and close the window. When you get back to the console, the username is printed, and the email was sent as shown in Figure 10.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1445\" height=\"354\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/07\/word-image-46.png\" alt=\"\" class=\"wp-image-87597\"\/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>Figure 10. Second email sent via SDK.<\/strong><\/p>\n\n\n\n<p><em>Note: Be aware that, due to occasional instabilities, sometimes this service can fail or time out. If you face an error, wait a minute and try again.<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-conclusion\">Conclusion<\/h2>\n\n\n\n<p>From here, the best place you can follow up for more accurate information, especially regarding the latest updates, is the <a href=\"https:\/\/docs.microsoft.com\/en-us\/graph\/\">official docs<\/a>.<\/p>\n\n\n\n<p>Microsoft Graph is continuously working to add more and more resources to the API. The possibility to manage the Outlook Calendar and Cloud communications, for example, are very recent due to that constant upgrade process. In the end, it is a powerful API if you want to embody your own projects with Microsoft product\u2019s data. Best of luck!<\/p>\n\n\n\n<section id=\"faq\" class=\"faq-block my-5xl\">\n    <h2>FAQs: Getting Started with Microsoft Graph API<\/h2>\n\n                        <h3 class=\"mt-4xl\">1. What is the Microsoft Graph API?<\/h3>\n            <div class=\"faq-answer\">\n                <p>Microsoft Graph is Microsoft&#8217;s unified REST API for accessing data across Microsoft 365 services &#8211; including Outlook (email, calendar, contacts), OneDrive files, SharePoint, Teams, Azure Active Directory user profiles, and more. Applications authenticate with Azure AD (now Entra ID) to get an access token, then call graph.microsoft.com endpoints to read or write user and organisational data. Microsoft provides SDKs for .NET, JavaScript, Python, Java, and Go that wrap the raw HTTP calls.<\/p>\n            <\/div>\n                    <h3 class=\"mt-4xl\">2. How do I authenticate to Microsoft Graph API from a .NET application?<\/h3>\n            <div class=\"faq-answer\">\n                <p>Register an application in the Azure Portal (Azure Active Directory \/ Entra ID). Add the Microsoft.Identity.Client NuGet package (MSAL.NET). Obtain an access token using the client credentials flow (for daemon\/service apps) or the authorization code flow (for apps that act on behalf of a user). Pass the token as a Bearer header in Graph API calls, or use the Microsoft.Graph SDK which handles authentication through an IAuthenticationProvider. The Microsoft.Graph NuGet package simplifies API calls with strongly-typed client methods.<\/p>\n            <\/div>\n                    <h3 class=\"mt-4xl\">3. What can I do with Microsoft Graph API?<\/h3>\n            <div class=\"faq-answer\">\n                <p>Common Microsoft Graph use cases: read and send email via Outlook (Mail.Read, Mail.Send permissions); read and write calendar events; manage OneDrive files; search SharePoint content; access Azure AD user profiles, group memberships, and directory data; send Teams messages; access Microsoft Planner tasks; create Excel workbooks and write data to them; and access usage reports. The Graph Explorer at developer.microsoft.com\/graph lets you try any endpoint interactively before writing code.<\/p>\n            <\/div>\n                    <h3 class=\"mt-4xl\">4. What permissions does Microsoft Graph API require?<\/h3>\n            <div class=\"faq-answer\">\n                <p>Each Graph API operation requires specific permission scopes granted to your Azure AD app registration. Permissions are either delegated (acting as a specific signed-in user) or application (acting as the application itself without a user). Example: Mail.Read (delegated) allows the app to read the signed-in user&#8217;s email; Mail.Read (application) allows reading all users&#8217; email without sign-in. Permissions must be declared in the app registration and consented to by an administrator (for application permissions or admin-required delegated permissions) or the user (for standard delegated permissions).<\/p>\n            <\/div>\n            <\/section>\n","protected":false},"excerpt":{"rendered":"<p>The Microsoft Graph API allows access to Microsoft cloud resources such as Office365 and Enterprise Mobility and Security Services. In this article, Julio Sampaio demonstrates the Graph Explorer and builds an example that sends an email.&hellip;<\/p>\n","protected":false},"author":323407,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":true,"footnotes":""},"categories":[143538,137091],"tags":[5134],"coauthors":[93894],"class_list":["post-87587","post","type-post","status-publish","format-standard","hentry","category-dotnet-development","category-azure","tag-sql-prompt"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/87587","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/323407"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=87587"}],"version-history":[{"count":5,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/87587\/revisions"}],"predecessor-version":[{"id":109805,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/87587\/revisions\/109805"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=87587"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=87587"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=87587"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=87587"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}