December 21st, 2021

New features in Microsoft Graph Bookings APIs provide enhanced booking infrastructure

The Microsoft Graph team is committed to providing booking infrastructure through the Bookings APIs so that customers can build robust customized solutions. We have been listening to customers and have received many requests for new features. Based on this feedback, we have launched some key new features such as SMS notifications, online meetings, group appointments and custom questions.

SMS notifications

SMS notifications have always been one of the major asks of customers across industries like healthcare, retail, and finance because reaching consumers is often more convenient through SMS notifications.  Recently, we went GA with a SMS notification feature in the United States and Canada. Today, we are excited to announce the addition of SMS notification support in the Bookings API. Currently, this feature is only available for customers in US and Canada on Bookings Calendars created in the NAM region. We will look to expand availability to other countries in the future.

SMS notifications can be enabled for a bookingService and at a bookingAppointment level as well, with the bookingAppointment level setting taking precedence.

Attribute Resource Type Description
smsNotificationsEnabled bookingService Indicates if SMS is enabled for the service
smsNotificationsEnabled bookingAppointment Indicates if SMS is enabled for the appointment

Online meetings

Support for online meetings was launched for our web and Team’s apps. It has been one of the key features of Bookings and has seen tremendous growth over the last couple of years. Now, one can enable online meetings for a bookingService via APIs. For an appointment of such a service, a Team’s meeting link will be auto generated. This link is part of the appointment resource type and can be accessed via APIs.

Attribute Resource Type Description
isLocationOnline bookingService Indicates if the meeting is online
joinWebUrl bookingAppointment The URL to join the online meeting

 

Staff and customer time zones

The bookingAppointment resource type has an attribute for customer timezone and the bookingStaffMember resource type has an attribute for the staff timezone.

Attribute Resource Type Description
customerTimeZone bookingAppointment Timezone of the customer for the appointment
timeZone bookingStaffMember Timezone of the staff member

 

Enhanced bookingCustomer resource type

We have enhanced the resource type to bring it at par with our webapp in which one can add and view additional customer properties such as address and phone number. The following new attributes have been added.

Attribute Resource Type Description
location bookingCustomer The address of the customer. Location is of type physicalAddress. However only the “other” address type is supported.
phone bookingCustomer The phone number of the customer

 

Custom questions

Custom questions are one of the key features of Bookings. It can be used to collect additional information in an appointment.

Custom questions are created for a ‘bookingBusiness’ resource type. They can be attached to bookingServices resource type of that bookingBusiness. Finally, a bookingAppointment of these bookingServices will contain the custom questions and answers to those question.

CRUD operations can be done on custom questions via APIs.

Example of CRUD operations for custom questions

Retrieve a custom question object

GET https://graph.microsoft.com/beta/bookingBusinesses/<businessId>/customQuestions/<questionId>

HTTP/1.1 200 OK
{
  "id": "3bc6fde0-4ad3-445d-ab17-0fc15dba0774",
  "displayName": "What is your age",
  "answerInputType": "text",
  "answerOptions": []
}

List all custom questions in a business

GET https://graph.microsoft.com/beta/bookingBusinesses/<businessId>/customQuestions

HTTP/1.1 200 OK
[
  {
    "id": "",
    "displayName": "What’s your faviourite color",
    "answerInputType": "text",
    "answerOptions": []
  },
  {
    "id": "",
    "displayName": "What do you want to get from this session?",
    "answerInputType": "text",
    "answerOptions": []
  }
]

Create a custom question

POST https://graph.microsoft.com/beta/bookingBusinesses/<businessId>/customQuestions
{
  "displayName": "What is your age",
  "answerInputType": "text",
  "answerOptions": []
}

HTTP/1.1 201 Created
{
  "id": "3bc6fde0-4ad3-445d-ab17-0fc15dba0774",
  "displayName": "What is your age",
  "answerInputType": "text",
  "answerOptions": []
}

Update a custom question

PATCH https://graph.microsoft.com/beta/bookingBusinesses/<businessId>/customQuestions/<questionId>
{
  "displayName": "What is your date of Birth"
}

HTTP/1.1 204 No Content

DELETE https://graph.microsoft.com/beta/bookingBusinesses/<businessId>/customQuestions/<questionId>

HTTP/1.1 204 NO CONTENT

Custom questions in a bookingService

One can associate any custom question in a bookingService. It can be done by using a complex type called custom questions. An example is shown below in which a service is being created with custom fields. The “isRequired” field indicates if it is mandatory to have a value for this custom field in an appointment.

POST https://graph.microsoft.com/beta/bookingBusinesses/Contosolunchdelivery@M365B489948.onmicrosoft.com/services
Content-type: application/json

{
    "@odata.type":"#microsoft.graph.bookingService",
    ..
    ..
    ..
    
    "customQuestions": [
        {
            "questionId": "75fc2eaf-624f-40b2-a289-63e51a56fcf2",
            "isRequired": true
        },
        {
            "questionId": "b90e7840-4c0c-430f-b96f-74ad9d2f64f7",
            "isRequired": false
        }
    ]
}

Custom questions in an appointment

Within a bookingAppointment, answers to custom questions can be added for an individual customer within a customer collection. Note that depending on the setting in the service some of the answers may be mandatory.

Here, a snippet is shown where an appointment is being created with custom questions.

POST https://graph.microsoft.com/beta/bookingBusinesses/Contosolunchdelivery@M365B489948.onmicrosoft.com/appointments
Content-type: application/json

{
    "@odata.type":"#microsoft.graph.bookingAppointment",
     ...
     ...
     ...
    "customers": [
        {
            "@odata.type":"#microsoft.graph.bookingCustomerInformation",
            "customerName":"Jordan Miller",
           
           ...
           ...
            "customQuestionAnswers": [
                {
                    "questionId": "75fc2eaf-624f-40b2-a289-63e51a56fcf2",
                    "answer": "Bread",
                    "selectedOptions": ["Bread"]
                }
            ],
             ...
             ...
            }
        }
    ],
    ...
    ...
    ...

}

Here is another example where an appointment is being retrieved

GET https://graph.microsoft.com/beta/bookingBusinesses/Contosolunchdelivery@M365B489948.onmicrosoft.com/appointments/AAMkADKnAAA=

Response

HTTP/1.1 200 OK
Content-type: application/json

{
    "@odata.context": "https://graph.microsoft.com/beta/$metadata#bookingBusinesses('Contosolunchdelivery%40M365B489948.onmicrosoft.com')/appointments/$entity",
    "id": "AAMkADKnAAA=",
    "selfServiceAppointmentId": "00000000-0000-0000-0000-000000000000",
    ...
    ...
    "customers": [
        {
            "customerId": "7ed53fa5-9ef2-4f2f-975b-27447440bc09",
            "customerName": "Jordan Miller",
            ...
            ...
            "customQuestionAnswers": [
                {
                    "questionId": "75fc2eaf-624f-40b2-a289-63e51a56fcf2",
                    "question": "What's your favourite food",
                    "answerInputType": "radioButton",
                    "answerOptions": [
                        "Banana Bread",
                        "Apple Pie",
                        "Cheese Cake"
                    ],
                    "isRequired": true,
                    "answer": "Apple Pie",
                    "selectedOptions": ["Apple Pie"]
                }
            ],
            ...
            ...
            }
        }
    ]
}

Attributes and complex types of custom questions

Attribute Resource Type Description
Id bookingCustomQuestions The unique id
displayName bookingCustomQuestions The display name for the custom question
answerInputType bookingCustomQuestions The answer type. The data type is graph.answerInputType. Supported values are radio button and text.
answerOptions bookingCustomQuestions This field is applicable if the answer type is radio button. This is a collection of strings
 
customQuestions bookingService Collection of bookingQuestionAssignment for the service
customQuestionAnswers bookingAppointment Collection of bookingQuestionAnswer. This collection is an attribute within a complex type bookingCustomerInformation, which itself is present in bookingAppointment.

 

Attribute ComplexType Description
questionId bookingQuestionAssignment

 

The id of the custom question which is being attached to the service.
isRequired bookingQuestionAssignment Indicates if the custom question answer is mandatory in the service
questionId bookingQuestionAnswer The is of custom question
question bookingQuestionAnswer The display name of the question when the appointment was created
answerInputType bookingQuestionAnswer The answer Input type of the question at the time of creation of appointment
answerOptions bookingQuestionAnswer The possible answer options of the question at the time of creation of an appointment
isRequired bookingQuestionAnswer If the answer is mandatory. It reflects the value at the time of appointment creation
answer bookingQuestionAnswer The answer for the question
selectedOptions bookingQuestionAnswer The selected option for the question if the question was of non-text type

 

Appointments with more than one customer (group appointments)

In the web app we support appointments in which more than one customer can attend. We call these appointments “group appointments”. One can set a service to support group appointments by increasing the count of attribute maximumAttendeesCount. In the bookingAppointment resource type, maximumAttendeesCount, indicates the maximum number of allowed attendees and is inherited from the same-named attribute in the bookingService resource type. The filledAttendeesCount attribute denotes the current number of customers in an appointment.

Attribute Resource Type Description
maximumAttendeesCount bookingService Max allowed number of customers in an appointment
maximumAttendeesCount bookingAppointment Max allowed number of customers in an appointment
filledAttendeesCount bookingAppointment Current number of customers in an appointment

 

Changes in customer information in a bookingAppointment resource type

Customer information was available at the root level in the appointment object. Since a list of customers is now supported, the information will be within a complex type. Customer information for appointments in which maximumAttendeesCount is 1 will continue to also exist at the root level in beta- however it will be deprecated.

The difference can be seen in the two code snippets below.

Old structure of bookingAppointment

Content-type: application/json

{
    "@odata.context": "https://graph.microsoft.com/beta/$metadata#bookingBusinesses('Contosolunchdelivery%40M365B489948.onmicrosoft.com')/appointments/$entity",
    "id": "AAMkADKnAAA=",
    "selfServiceAppointmentId": "00000000-0000-0000-0000-000000000000",
    "customerId": "7ed53fa5-9ef2-4f2f-975b-27447440bc09",
    "customerName": "Jordan Miller",
    "customerEmailAddress": "jordanm@contoso.com",
    "customerPhone": "213-555-0199",
    "customerNotes": null,
    "serviceId": "57da6774-a087-4d69-b0e6-6fb82c339976",
    "serviceName": "Catered bento",
  ...
  ...     
  ...
}

 

New structure of bookingAppointment

Content-type: application/json

{
    "@odata.context": "https://graph.microsoft.com/beta/$metadata#bookingBusinesses('Contosolunchdelivery%40M365B489948.onmicrosoft.com')/appointments/$entity",
    "id": "AAMkADKnAAA=",
    "selfServiceAppointmentId": "00000000-0000-0000-0000-000000000000",
    ...
    ...
    ...
   
    "customers": [
        {
            "customerId": "7ed53fa5-9ef2-4f2f-975b-27447440bc09",
            "customerName": "Jordan Miller",
            "customerEmailAddress": "jordanm@contoso.com",
            "customerPhone": "213-555-0199",
            "customerNotes": "notes",
            "customQuestionAnswers": [
                {
                    "questionId": "75fc2eaf-624f-40b2-a289-63e51a56fcf2",
                    "question": "What's your favourite food",
                    "answerInputType": "radioButton",
                    "answerOptions": [
                        "KFC",
                        "McDonald's",
                        "BurgerKing"
                    ],
                    "isRequired": true,
                    "answer": "KFC",
                    "selectedOptions": ["KFC"]
                }
            ],
            "customerLocation": {
                "displayName": "home",
                "locationEmailAddress": null,
                "locationUri": "",
                "locationType": null,
                "uniqueId": null,
                "uniqueIdType": null,
                "address": {
                    "type": "home",
                    "postOfficeBox": "",
                    "street": "",
                    "city": "",
                    "state": "",
                    "countryOrRegion": "",
                    "postalCode": ""
                },
                "coordinates": {
                    "altitude": null,
                    "latitude": null,
                    "longitude": null,
                    "accuracy": null,
                    "altitudeAccuracy": null
                }
            }
        }
    ]
    ...
    ...
}

 

The new complex type

The complex type is called bookingCustomerInformation. The “customers” attribute within appointment is a collection of this type.

Attribute Complex Type Description
Id bookingCustomerInformation The id of the customer
name bookingCustomerInformation The name of the customer
emailAddress bookingCustomerInformation The email address of the customer
phone bookingCustomerInformation The phone number of the customer
notes bookingCustomerInformation The notes of the customer
location bookingCustomerInformation The address of the customer. Location is of type physicalAddress. However only the “other” address type is supported.
timeZone bookingCustomerInformation The timeZone of the customer

 

We hope that these new features will help your custom applications be more comprehensive and robust. Please give us feedback and keep reaching out to us with your use cases and requests. Check out this link to find resources that will help you get started.

Stay tuned and keep following our blog for updates on our APIs.

Happy coding!

4 comments

Discussion is closed. Login to edit/delete existing comments.

  • David Swenson

    Awesome update for the API! Can we PLEASE get a native Power Automate Connector for Bookings with custom field support? This functionality is great but it does little to democratize the technology for us citizen developers 🙁

    • Kevin Peterson

      This needs to be done very quickly. Please assign resources to work on the custom field support.

    • William Perkins

      Agree also, an API is a start, but we need a Power Automate connector for Bookings to make the development process easier for most non SUPER TECH programmers.

    • Andrew Morrison

      100% agreed, this really needs added ASAP!