Why is my Web API with Application Permissions to Bookings.ReadWrite.All unauthorized when querying Graph API Bookings endpoints

Steven Bitaxi 21 Reputation points
2025-06-11T18:02:43.7766667+00:00

We are building an API to get and update Booking Appointments using Microsoft Graph API and application permissions.

We have registered an app in Azure, added the Bookings.ReadWrite.All application permission and admin consent has been granted. Screenshot of API permissions assigned in Azure Admin portal

When we query the endpoint with application permissions we receive an Unauthorized error, but if we query using delegated permissions, as a user who is a member of the Bookings Calendar, it's fine.

var result = await _graphServiceClient.Solutions.BookingBusinesses[_BookingCalendarId].Appointments[appointmentId].GetAsync();

We have queried Appointments, StaffMembers and Services all with the same result.

We're constructing our Graph Service Client this way:

    public AppGraphService(IConfiguration config)
    {
        _config = config ?? throw new ArgumentNullException(nameof(config));
        _client = new Lazy<GraphServiceClient>(() =>
        {
            var credential = new ClientSecretCredential(
            config["AzureAd:TenantId"],
            config["AzureAd:ClientId"],
            config["AzureAd:ClientSecret"]);

            return new GraphServiceClient(credential, new[] { "https://graph.microsoft.com/.default" });
        });
    }

We inspected the Token for the Graph Client to ensure it had the expected scopes


{
  "typ": "JWT",
  "nonce": "[REDACTED_NONCE]",
  "alg": "RS256",
  "x5t": "[REDACTED_X5T]",
  "kid": "[REDACTED_KID]"
}.
{
  "aud": "https://graph.microsoft.com",
  "iss": "https://sts.windows.net/[TENANT_ID]/",
  "iat": 1749575758,
  "nbf": 1749575758,
  "exp": 1749579658,
  "aio": "[REDACTED_AIO]",
  "app_displayname": "[APP_DISPLAY_NAME]",
  "appid": "[APP_ID]",
  "appidacr": "1",
  "idp": "https://sts.windows.net/[TENANT_ID]/",
  "idtyp": "app",
  "oid": "[OBJECT_ID]",
  "rh": "[REDACTED_RH]",
  "roles": [
    "Bookings.ReadWrite.All",
    "OnlineMeetings.ReadWrite.All"
  ],
  "sub": "[OBJECT_ID]",
  "tenant_region_scope": "NA",
  "tid": "[TENANT_ID]",
  "uti": "[REDACTED_UTI]",
  "ver": "1.0",
  "wids": [
    "[REDACTED_WID]"
  ],
  "xms_ftd": "[REDACTED_XMS_FTD]",
  "xms_idrel": "[REDACTED_XMS_IDREL]",
  "xms_rd": "[REDACTED_XMS_RD]",
  "xms_tcdt": 1523990055
}.
[Signature]

We retrieved the request URI and tried it in Graph Explorer and that worked fine

var uriinfo = _graphServiceClient.Solutions.BookingBusinesses[_BookingCalendarId].Appointments[appointmentId].ToGetRequestInformation();

return uriinfo.URI.AbsoluteUri;

Retrieving a token via Thunder Client returns a token with the correct roles, but when we use that token immediately following the request fails with a 500 error.

The same request with a User token is always successful.

// Sample from https://learn.microsoft.com/en-us/graph/auth-v2-service?tabs=http#token-request used to get an App token

POST https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token HTTP/1.1
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded

client_id=535fb089-9ff3-47b6-9bfb-4f1264799865
&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
&client_secret=qWgdYA....L1qKv5bPX
&grant_type=client_credentials

According to the Devblog post from 2022-06

"In this release, we are providing application permissions for a limited set of Bookings APIs. This includes application permissions support for read and write APIs for the ‘bookingCustomer ‘and ‘bookingAppointment’ entities. For other entities, including ‘bookingBusiness’, ‘bookingStaffMember’, ‘bookingCustomQuestion’ and ‘bookingService’, we are supporting the read APIs only. Because these tasks are for Bookings admins, delegated permissions are recommended for these use cases."

We should be able to work with the API using Application Permissions. Yes, it specifies beta and we have used both v1.0 and beta for our queries with the same result.

Why isn't the app able to query the Bookings endpoint at all? What else should we try in order to resolve this? Is there another permission, similar to an Application Access Policy in Exchange?

Microsoft Graph
Microsoft Graph
A Microsoft programmability model that exposes REST APIs and client libraries to access data on Microsoft 365 services.
13,685 questions
0 comments No comments
{count} votes

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.