A Step-by-Step Guide for Microsoft 365 Copilot API Development
What is the best way to run programmatic prompts and responses against Microsoft 365 Copilot? Is it directly from the user? Maybe specific services? Or through a cloud application (Entra ID Enterprise Application)? All answers can be correct as long as they run within a process. Another issue is whether to ask for Microfot 365 Copilot or Copilot Work, or else… And what endpoints are needed? There are many differences between the API endpoints of plugins and API plugins.
The most important thing isn’t to allow users to run direct requests against API endpoints.
This guide will walk you through creating a Copilot 365 API to interact with Microsoft 365 services such as Outlook, OneDrive, and Teams using Entra ID, Microsoft Graph API, and Python. It is designed for MacOS developers who want to automate and interact using Bash and Python.
This guide, “A Step-by-Step Guide for Microsoft 365 Copilot API Development”, outlines the development of a Microsoft 365 Copilot web application using Python. We’ll use the Microsoft 365 Copilot API, Microsoft Authentication Library (MSAL) for authentication, and the Microsoft Graph API to access Microsoft 365 services such as emails, chats, files, and more. The app will include a chatbot-like interface to interact with users via Copilot.
Prerequisites:
- Microsoft 365 Copilot Access: Ensure that your Microsoft 365 tenant has Copilot capabilities enabled.
- Azure Subscription: Required to manage the enterprise application and access the Microsoft Graph API.
- Python 3.x is installed on your MacOS machine.
- Azure Active Directory (Entra ID) manages API permissions and authentication flows.
- Postman or curl: This is for testing API requests.
Step 1: Configure an Entra ID (Azure AD) Application
1. Create an Azure AD App Registration:
- Go to Azure Portal > Azure Active Directory > App registrations > New registration.
- Name your app (e.g., “M365 Copilot API App”).
- Under Redirect URI, select
Weband addhttp://localhost:5000/getAToken(used for local development). - Click Register.
2. Configure API Permissions:
You must grant your app permission to interact with Microsoft 365 services via Microsoft Graph API.
- Go to the API Permissions tab when you register for your app.
- Click Add a permission.
- Choose Microsoft Graph > Delegated Permissions.
- Add the following permissions:
User.Read(to read the user profile),Mail.Read(to read user’s emails),Files.Read(to access OneDrive files),Calendars.Read(to access calendar events),Chat.Read(to access Teams chats).
- Click Grant admin consent to apply these permissions for your organization.

3. Generate a Client Secret:
- Go to Certificates & Secrets when registering for your app.
- Create a new Client Secret and store it securely, as it will be needed for authentication.
- Note down the client secret and client ID, as you will use them in your Python code.
Python Environment Setup
1. Install Python:
Ensure Python 3.x is installed on your macOS machine. Check the installation by running:

If not installed, use Homebrew to install it:
brew install python
Create a Python Virtual Environment:
It’s recommended to create a virtual environment to isolate your project dependencies:
python3 -m venv copilot-env
source copilot-env/bin/

Install Required Libraries:
Install the necessary Python libraries using pip:
pip3 install requests msal flask

requests: Used to send HTTP requests to Microsoft Graph API.msal: Microsoft Authentication Library will handle OAuth2 authentication with Azure AD.flask: A lightweight framework to create web services for handling chat interactions.
Implement Authentication with MSAL
1. Configure MSAL for OAuth2 Authentication:
In your project directory, create a file named app.py and set up the MSAL configuration:

- CLIENT_ID and CLIENT_SECRET are from the Azure AD app you registered.
- TENANT_ID is your Azure AD tenant’s unique identifier.
- SCOPES is the list of permissions that your app will request access to. For example,
User.Readfor basic profile access,Mail.Readfor reading user emails, etc.
Get an Access Token:
The following function will acquire an access token using the confidential client credentials:
token = get_token()
if token:
print(“Access Token: “, token)
else:
print(“Failed to acquire token”)
Make API Requests to Microsoft Graph
Once you have the token, you can request Microsoft Graph API to fetch Microsoft 365 data.
1. Fetch User Profile Information:
This function fetches the profile information of the logged-in user using the /me endpoint of Microsoft Graph:
GRAPH_API_URL = ‘https://graph.microsoft.com/v1.0’
def get_user_profile(token):
headers = {‘Authorization’: f’Bearer {token}’}
response = requests.get(f”{GRAPH_API_URL}/me”, headers=headers)
return response.json()# Example call to fetch user profile
profile = get_user_profile(token)
print(profile)

- GRAPH_API_URL: The base URL for all Microsoft Graph API requests.
- The
/meendpoint returns details about the currently authenticated user.
2. Fetch Emails:
This function retrieves the user’s emails using the /me/messages endpoint of Microsoft Graph:
def get_emails(token):
headers = {‘Authorization’: f’Bearer {token}’}
response = requests.get(f”{GRAPH_API_URL}/me/messages”, headers=headers)
return response.json()# Example call to fetch emails
emails = get_emails(token)
print(emails)

This request retrieves the authenticated user’s emails. The API will return a collection of emails by default, but you can customize the query to filter emails or specify additional data fields.
Implement the Copilot Chat Feature
In this step, we’ll build a Flask-based web interface to handle user chat interactions and the Copilot API.
1. Chat Function with Copilot:
Create a new route /chat in app.py to handle POST requests from users. The function will call the Microsoft Graph API based on the user’s message.
@app.route(‘/chat’, methods=[‘POST’])
def chat_with_copilot():
user_message = request.json.get(‘message’)
token = get_token()if ’email’ in user_message.lower():
emails = get_emails(token)
summary = summarize_emails(emails)
return jsonify({“response”: summary})
else:
return jsonify({“response”: “I’m here to help with your Microsoft 365 tasks!”})def summarize_emails(emails):
email_list = emails[‘value’][:3] # Get the latest 3 emails
summary = “Here are your last 3 emails:\n”
for email in email_list:
summary += f”- {email[‘subject’]} from {email[‘from’][’emailAddress’][‘name’]}\n”
return summary
- chat_with_copilot: Processes the incoming POST request. If the message contains the word “email”, it fetches emails using the get_emails function.
- summarize_emails: Extracts and summarizes the latest 3 emails.
2. Example Chat Input:
You can test the /chat endpoint by sending a POST request using curl or Postman:
curl -X POST http://127.0.0.1:5000/chat -H “Content-Type: application/json” -d ‘{“message”: “Summarize my emails”}’
Expected Response:
{
“response”: “Here are your last 3 emails:\n- Project update from John Doe\n- Meeting invite from Sarah Lee\n- Budget approval from Finance Team”
}
Running the Flask Application
To run your application locally:
python app.py
You can access your Copilot API at http://127.0.0.1:5000.
The entire Python script will be
import msalimport requestsimport json# MSAL ConfigurationCLIENT_ID = ‘CID’CLIENT_SECRET = ‘Secret’TENANT_ID = ‘TID’AUTHORITY = f”https://login.microsoftonline.com/TID”SCOPES = [‘https://graph.microsoft.com/.default’%5D # /.default for client credential flow# Microsoft Graph API Base URLGRAPH_API_URL = ‘https://graph.microsoft.com/v1.0’# Function to acquire an access token using MSALdef get_access_token():app = msal.ConfidentialClientApplication(CLIENT_ID,authority=AUTHORITY,client_credential=CLIENT_SECRET)# Request a token for the /.default scopetoken_response = app.acquire_token_for_client(scopes=SCOPES)if”access_token”in token_response:return token_response[‘access_token’]else:print(“Failed to acquire token: “, token_response.get(“error_description”))returnNone# Function to fetch recent emails from Microsoft Graph APIdef get_emails(access_token):headers = {‘Authorization’: f’Bearer {access_token}’,‘Content-Type’: ‘application/json’}# Fetch the user’s emails using Microsoft Graphresponse = requests.get(f'{GRAPH_API_URL}/me/messages’, headers=headers)if response.status_code == 200:emails = response.json()return emails[‘value’] # Return the list of emailselse:print(“Failed to fetch emails: “, response.status_code, response.text)return []# Function to summarize emailsdef summarize_emails(emails):iflen(emails) == 0:return”No recent emails found.”summary = “Here are your last 3 emails:\n”# Loop through the top 3 emails and summarize themfor email in emails[:3]:subject = email[‘subject’]sender = email[‘from’][’emailAddress’][‘name’]summary += f”- {subject} from {sender}\n”return summary# Function to simulate a conversation with Copilotdef run_copilot():# Step 1: Acquire Access Tokenaccess_token = get_access_token()if access_token:# Simulate some common Copilot interactions by fetching data from Microsoft Graphuser_query = input(“Ask Copilot something (e.g., ‘Summarize my emails’): “).lower()if”email”in user_query:# Step 2: Fetch and summarize emailsemails = get_emails(access_token)summary = summarize_emails(emails)print(summary)else:print(“Sorry, I can only summarize emails for now.”)else:print(“Could not acquire access token.”)# Entry point to run the scriptif __name__ == ‘__main__’:print(“Running Microsoft 365 Copilot-like Script…\n”)run_copilot()
While running

Conclusion
This guide demonstrates how to develop a Microsoft 365 Copilot web application using Python. By leveraging MSAL for authentication and Microsoft Graph API for data access, you can integrate a chatbot to handle real-time user queries for Microsoft 365 services like emails, files, and calendar events.