Microsoft Copilot APIs: From Retrieval to Chat – Practical Implementation Guide

What Are Microsoft Copilot APIs?

Microsoft 365 Copilot APIs are REST-based APIs exposed through Microsoft Graph that deliver AI-powered reasoning over your organizational data. Unlike standard Graph APIs that handle CRUD operations, these APIs provide semantic understanding β€” intelligent search, AI-generated meeting summaries, and conversational experiences grounded in your Microsoft 365 content.

The key advantage? Everything runs in-place. Your data stays where it is, existing permissions and sensitivity labels are respected, and you get production-grade AI without building infrastructure from scratch.

Microsoft Copilot APIs Overview

Why Copilot APIs Instead of Building Your Own?

Aspect Custom AI Solution Copilot APIs
Data Security Must build extraction and indexing pipelines Works in-place with existing permissions
Compliance Manage separate compliance controls Inherits Microsoft 365 compliance features
AI Infrastructure Must maintain language models and infrastructure Production-grade AI included
Time to Market Months of development Weeks or days
Cost of Ownership High (data pipelines, indexing, storage, models) Lower (API consumption based)

Licensing Requirements

Before we get into the APIs, let’s address the elephant in the room β€” licensing. Every user accessing Copilot APIs needs:

  • Microsoft 365 Copilot license β€” non-negotiable, provides the underlying AI capabilities
  • Microsoft 365 E3 or E5 (or equivalent) β€” the foundation for your Microsoft 365 data

Standard Microsoft Graph APIs work with regular M365 licenses. Copilot APIs require the dedicated Copilot license because they deliver AI-powered capabilities on top of your data.


The Copilot APIs at a Glance

Microsoft provides several Copilot APIs. Here are the six we’ll cover in this post:

API Purpose Status
Retrieval API RAG with semantic search across SharePoint, OneDrive, Connectors GA
Search API Hybrid semantic + lexical search over OneDrive Preview
Meeting Insights AI-generated summaries & action items from Teams meetings GA
Change Notifications Real-time webhooks for Copilot interaction events Preview
Chat API Embed Copilot conversations in your apps Preview
Usage Reports Per-user Copilot adoption monitoring across M365 apps Preview

See it in action

I built an SPFx sample β€” Copilot API Explorer that demonstrates Chat, Search, Meeting Insights, and Usage Reports through a tabbed web part. All code examples in this post follow the same patterns.


1. Retrieval API - Grounding Your AI with Enterprise Knowledge πŸ”

The Retrieval API is your gateway to building Retrieval-Augmented Generation (RAG) applications grounded in enterprise data. Instead of extracting data to external indexes, this API retrieves relevant context directly from SharePoint, OneDrive, and Copilot connectors β€” all while respecting security and compliance controls.

Think of it as a smart search engine that understands intent, not just keywords.

Real-World Example: A consulting firm needs to prepare client briefings. Instead of manually searching SharePoint, they use the Retrieval API to surface relevant documents, case studies, and precedents based on natural language queries β€” with information barriers between competing clients fully enforced.

When to Use It

  • Custom knowledge apps that answer questions from your organization’s documentation and policies
  • Multi-source RAG systems combining SharePoint, OneDrive, and connector data into a unified knowledge base
  • Finance & legal search requiring precision filtering with information barrier support

Prerequisites & Permissions

Prerequisites

Microsoft 365 Copilot license, M365 E3/E5, and semantic indexing enabled (automatic for most tenants).

Permission Scope Data Source
Files.Read.All Delegated, Application SharePoint, OneDrive
Sites.Read.All Delegated, Application SharePoint
ExternalItem.Read.All Application only Copilot connectors

Implementation

import { MSGraphClientFactory, MSGraphClientV3 } from "@microsoft/sp-http";

const msGraphClient: MSGraphClientV3 = await msGraphClientFactory.getClient("3");

try {
const requestBody = {
dataSource: "SharePoint", // SharePoint, OneDrive, or ExternalItems
queryString: "What is our latest product roadmap?",
maximumNumberOfResults: 10
};

const result = await msGraphClient
.api("/copilot/retrieval")
.version("beta")
.post(requestBody);

if (result?.retrievalHits?.length > 0) {
result.retrievalHits.forEach((hit: any) => {
console.log(`Document: ${hit.webUrl}`);
console.log(`Type: ${hit.resourceType}`);

// Each hit contains extracts with relevance scores
hit.extracts?.forEach((extract: any) => {
console.log(`Content: ${extract.text}`);
console.log(`Relevance: ${extract.relevanceScore}`);
});

// Sensitivity labels are included when present
if (hit.sensitivityLabel) {
console.log(`Classification: ${hit.sensitivityLabel.displayName}`);
}
});
}
} catch (error: any) {
if (error.status === 429) {
console.log("Rate limited β€” implement exponential backoff");
} else if (error.status === 401) {
console.log("Unauthorized β€” check permissions and licenses");
}
}

Limitations & Tips

  • Query string limited to 1,500 characters β€” keep queries focused and context-rich
  • Maximum 25 results per request, 200 requests/user/hour throttle
  • Only text content is indexed β€” images, charts, and nontextual content not supported
  • Files over 512 MB (.docx, .pptx, .pdf) or 150 MB (other types) are skipped
  • Semantic retrieval supports: .doc, .docx, .pptx, .pdf, .aspx, .one
  • Send all returned extracts to your LLM for answer generation β€” don’t cherry-pick
  • The Retrieval API also supports pay-as-you-go pricing (preview) for tenant-level data sources, so you don’t need to license every user

2. Search API β€” Natural Language Document Discovery πŸ”Ž

While the Retrieval API excels at grounding AI responses, the Search API is built for document discovery. It performs hybrid search (semantic + lexical) across OneDrive content, enabling natural language queries that understand context and intent.

Users no longer need to remember exact filenames β€” they describe what they’re looking for naturally.

Copilot Search API

Practical Example: A financial analyst searches for β€œQ4 budget forecasts we discussed last month.” The Search API understands the intent and returns budget-related documents modified in that timeframe β€” no exact filename needed.

When to Use It

  • AI-powered search experiences with natural language understanding in portals and apps
  • Document discovery β€” help users find the right file based on descriptions, not keywords
  • Enterprise search that understands context and intent

Prerequisites & Permissions

Prerequisites

Microsoft 365 Copilot license. Currently limited to OneDrive for work or school (SharePoint and other sources coming in future releases).

Permission Scope Purpose
Files.Read.All Delegated, Application Read OneDrive file metadata and content
Sites.Read.All Delegated, Application Access OneDrive storage permissions

Implementation

import { MSGraphClientFactory, MSGraphClientV3 } from "@microsoft/sp-http";

const msGraphClient: MSGraphClientV3 = await msGraphClientFactory.getClient("3");

try {
const requestBody = {
query: "Q4 financial projections",
pageSize: 20,
dataSources: {
oneDrive: {
filterExpression: "path:'/Documents/Finance'",
resourceMetadataNames: ["title", "author"]
}
}
};

const result = await msGraphClient
.api("/copilot/search")
.version("beta")
.post(requestBody);

console.log(`Total results: ${result.totalCount}`);

result.searchHits?.forEach((hit: any) => {
console.log(`Title: ${hit.resourceMetadata?.title}`);
console.log(`Author: ${hit.resourceMetadata?.author}`);
console.log(`URL: ${hit.webUrl}`);
console.log(`Preview: ${hit.preview}`);
});

// Handle pagination
if (result["@odata.nextLink"]) {
console.log("More results available");
}
} catch (error: any) {
if (error.status === 429) {
console.log("Rate limited β€” implement exponential backoff");
}
}

Source Code

For a full React implementation with search UI, see the CopilotSearchTab in our SPFx sample.

Limitations & Tips

  • Query limited to 1,500 characters, page size up to 100 results
  • Only OneDrive content supported today (SharePoint coming soon)
  • Only path expressions supported in filters (more KQL properties coming)
  • 200 requests/user/hour throttle
  • Results come from the user’s personalized working set β€” not all OneDrive content
  • Use natural language, descriptive queries for best results

3. Meeting Insights API β€” Turning Meetings into Action πŸ“‹

Teams meetings generate valuable context, decisions, and action items. The Meeting Insights API automatically extracts AI-generated summaries, action items, and discussion topics β€” no manual note-taking required.

This is the API that transforms meetings from time spent to value created.

Copilot Meeting Insights API

Real-World Example: A sales team conducts customer calls. After each meeting, the API extracts call summaries, action items with assigned owners, and mentions of budget, timeline, or stakeholders β€” all automatically logged into Salesforce.

When to Use It

  • CRM integration β€” auto-populate meeting summaries and follow-ups in Salesforce, HubSpot, or Dynamics
  • Project management β€” extract action items into Azure DevOps, Jira, or Monday.com
  • Compliance & auditing β€” archive meeting insights for regulated industries

Prerequisites & Permissions

Prerequisites

Microsoft 365 Copilot license and a Teams meeting with transcription or recording enabled. Insights become available up to 4 hours after the meeting ends.

Important Note

Private scheduled meetings, town halls, webinars, and Meet Now are supported. Channel meetings are not yet supported.

Permission Scope Purpose
OnlineMeetingAiInsight.Read.All Delegated, Application Read AI-generated insights
OnlineMeetingTranscript.Read.All Delegated, Application Read meeting transcripts

Implementation

There’s an important nuance here β€” the list endpoint may only return insight IDs without the detailed content. You need to check and make a second call to get the full notes, action items, and mentions:

import { MSGraphClientFactory, MSGraphClientV3 } from "@microsoft/sp-http";

const msGraphClient: MSGraphClientV3 = await msGraphClientFactory.getClient("3");

try {
const userId = "me";
const meetingId = "YOUR_MEETING_ID";

// Step 1: Get the list of AI insights for the meeting
const response = await msGraphClient
.api(`/copilot/users/${userId}/onlineMeetings/${meetingId}/aiInsights`)
.version("v1.0")
.get();

if (!response?.value?.length) {
console.log("No insights available yet (may take up to 4 hours)");
return;
}

let insight = response.value[0];

// Step 2: Check if the list response contains detailed content
// The list call may only return IDs β€” if so, fetch the full insight by ID
const hasDetailedContent =
(insight.meetingNotes?.length || 0) > 0 ||
(insight.actionItems?.length || 0) > 0 ||
(insight.viewpoint?.mentionEvents?.length || 0) > 0;

if (!hasDetailedContent && insight.id) {
// Fetch the full insight with notes, action items, and mentions
insight = await msGraphClient
.api(`/copilot/users/${userId}/onlineMeetings/${meetingId}/aiInsights/${insight.id}`)
.version("v1.0")
.get();
}

// Now process the detailed insight
// Meeting notes with structured subpoints
insight.meetingNotes?.forEach((note: any) => {
console.log(`πŸ“Œ ${note.title}: ${note.text}`);
note.subpoints?.forEach((sub: any) => {
console.log(` β€’ ${sub.title}: ${sub.text}`);
});
});

// Action items with owners
insight.actionItems?.forEach((item: any) => {
console.log(`βœ… ${item.title}: ${item.text}`);
console.log(` πŸ‘€ Owner: ${item.ownerDisplayName}`);
});

// When participants were mentioned (with timestamps)
insight.viewpoint?.mentionEvents?.forEach((mention: any) => {
console.log(`⏰ ${mention.eventDateTime} β€” ${mention.speaker?.user?.displayName}`);
console.log(` πŸ’¬ "${mention.transcriptUtterance}"`);
});
} catch (error) {
console.error("Meeting Insights error:", error);
}

Source Code

For a complete React component with loading states and error handling, see the MeetingInsightsTab in our SPFx sample.

Limitations & Tips

  • Insights are not real-time β€” available only after the meeting ends (up to 4-hour delay)
  • Channel meetings are not yet supported
  • Requires transcription or recording to be enabled during the meeting
  • AI-generated content may need human validation for critical decisions

4. Change Notifications API β€” Real-Time Compliance Monitoring πŸ””

The Change Notifications API lets you subscribe to Copilot interactions and receive real-time webhooks whenever users query Copilot or receive responses. This is essential for compliance, auditing, and understanding AI usage patterns across your organization.

Instead of polling for interactions, notifications come to you as they happen.

When to Use It

  • Compliance & auditing β€” capture all Copilot interactions for HIPAA, SOX, or GDPR
  • Anomaly detection β€” monitor for unusual usage patterns or sensitive queries
  • Usage analytics β€” build dashboards showing Copilot adoption trends by department

Prerequisites & Permissions

Prerequisites

Microsoft 365 Copilot license, an HTTPS webhook endpoint with a valid SSL certificate, and an encryption certificate for encrypted payloads.

User-scoped subscriptions:

Permission Scope Purpose
AiEnterpriseInteraction.Read Delegated Subscribe to user’s own interactions
AiEnterpriseInteraction.Read.User Application (RSC)* Subscribe to a specific user’s interactions
AiEnterpriseInteraction.Read.All Application Subscribe to all interactions for a user

Tenant-scoped subscriptions:

Permission Scope Purpose
AiEnterpriseInteraction.Read.All Application Subscribe to all tenant interactions

*RSC = Resource-Specific Consent. Requires Teams app manifest configuration.

Implementation

Subscribe to a specific user’s Copilot interactions:

import { MSGraphClientFactory, MSGraphClientV3 } from "@microsoft/sp-http";

const msGraphClient: MSGraphClientV3 = await msGraphClientFactory.getClient("3");
const userId = "user-id";

try {
const subscription = {
changeType: "created,updated,deleted",
notificationUrl: "https://webhook.contoso.com/api/copilot-notifications",
resource: `/copilot/users/${userId}/interactionHistory/getAllEnterpriseInteractions`,
includeResourceData: true,
encryptionCertificate: "<base64-encoded-certificate>",
encryptionCertificateId: "cert-id-12345",
lifecycleNotificationUrl: "https://webhook.contoso.com/api/lifecycle",
expirationDateTime: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(),
clientState: "your-secret-state"
};

const result = await msGraphClient
.api("/subscriptions")
.version("v1.0")
.post(subscription);

console.log(`Subscription created: ${result.id}`);
console.log(`Expires: ${result.expirationDateTime}`);
} catch (error) {
console.error("Subscription error:", error);
}

You can also filter to specific Copilot apps:

// Subscribe only to Teams Copilot interactions
const teamsSubscription = {
changeType: "created,updated,deleted",
notificationUrl: "https://webhook.contoso.com/api/teams-copilot",
resource: `/copilot/interactionHistory/getAllEnterpriseInteractions?$filter=appClass eq 'IPM.SkypeTeams.Message.Copilot.Teams'`,
includeResourceData: true,
expirationDateTime: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(),
clientState: "teams-filter"
};

Example notification payload (decrypted):

{
"id": "1731701801008",
"appClass": "IPM.SkypeTeams.Message.Copilot.Teams",
"interactionType": "aiResponse",
"conversationType": "appchat",
"createdDateTime": "2024-11-15T20:16:41.008Z",
"from": {
"user": {
"id": "48902e20-56dc-48cf-ab15-0b65e15dda67",
"displayName": "John Doe",
"userIdentityType": "aadUser"
}
},
"body": {
"contentType": "text",
"content": "What is our Q4 budget forecast?"
}
}

Limitations & Tips

  • Subscriptions expire and must be renewed (max 24 hours)
  • Always return 202 Accepted from your webhook β€” even if processing fails
  • Implement lifecycle notification handling for reauthorization events
  • For tenant-wide subscriptions, all six Copilot service plans must be active

5. Chat API β€” Copilot Conversations in Your Apps πŸ’¬

The Chat API (preview) lets you embed Microsoft 365 Copilot’s conversational capabilities directly into your custom applications. Users get intelligent, context-aware conversations grounded in their Microsoft 365 data β€” without leaving your app.

Copilot Chat API

When to Use It

  • Enterprise portals β€” add AI chat to internal knowledge portals
  • LOB apps β€” embed conversational AI in line-of-business applications
  • Mobile apps β€” bring Copilot to custom mobile experiences

Prerequisites & Permissions

Prerequisites

Microsoft 365 Copilot license and an Azure AD app registration. The Chat API inherits permissions from the data sources being accessed.

Data Source Required Permissions
OneDrive/SharePoint Files.Read.All, Sites.Read.All
Copilot Connectors ExternalItem.Read.All
Web Search None (included by default)

Implementation

import { MSGraphClientFactory, MSGraphClientV3 } from "@microsoft/sp-http";

const msGraphClient: MSGraphClientV3 = await msGraphClientFactory.getClient("3");

try {
// Step 1: Create a new conversation
const conversation = await msGraphClient
.api("/copilot/conversations")
.version("beta")
.post({});

const conversationId = conversation.id;
console.log(`Conversation created: ${conversationId}`);

// Step 2: Send a message
const response = await msGraphClient
.api(`/copilot/conversations/${conversationId}/chat`)
.version("beta")
.post({
message: {
text: "What are the top risks mentioned in our latest security audit?",
contentType: "text"
}
});

console.log(`Response: ${response.message?.text}`);
} catch (error) {
console.error("Chat API error:", error);
}

Source Code

For a full chat interface with conversation history, file attachments, and markdown rendering, see the CopilotChatTab in our SPFx sample.

Limitations & Tips

  • This is a beta API β€” endpoints and response shapes may change
  • Each conversation maintains context β€” no need to resend previous messages
  • Responses are grounded in the user’s Microsoft 365 data (respects existing permissions)
  • Web search results are included by default alongside organizational data
  • Handle long-running responses gracefully β€” AI generation can take several seconds

6. Usage Reports API β€” Tracking Copilot Adoption πŸ“Š

Rolling out Copilot across your organization is one thing β€” knowing whether people are actually using it is another. The Usage Reports API gives you per-user Copilot activity data across Teams, Word, Excel, PowerPoint, Outlook, OneNote, Loop, and Copilot Chat.

This is the API that answers the question every IT leader asks: β€œAre we getting value from our Copilot investment?”

Copilot Usage Reports API

When to Use It

  • Adoption dashboards β€” track which teams and users are actively using Copilot
  • License optimization β€” identify unused licenses and reallocate them
  • ROI reporting β€” demonstrate Copilot value to leadership with real usage data

Prerequisites & Permissions

Prerequisites

Microsoft 365 Copilot license. The caller must have an admin role such as Global Reader, Reports Reader, or Teams Admin.

Permission Scope Purpose
Reports.Read.All Delegated, Application Read usage reports across the tenant

Implementation

An important detail here β€” you must set the Accept header to application/json, otherwise the API returns CSV by default:

import { MSGraphClientFactory, MSGraphClientV3 } from "@microsoft/sp-http";

const msGraphClient: MSGraphClientV3 = await msGraphClientFactory.getClient("3");

try {
const period = "D30"; // D7, D30, D90, or D180

// Must set Accept header to application/json β€” default returns CSV
const response = await msGraphClient
.api(`/reports/getMicrosoft365CopilotUsageUserDetail(period='${period}')`)
.version("beta")
.header("Accept", "application/json")
.get();

const users = response.value || [];
console.log(`Report refreshed: ${users[0]?.reportRefreshDate}`);
console.log(`Licensed users: ${users.length}`);

users.forEach((user: any) => {
console.log(`\nπŸ‘€ ${user.displayName}`);
console.log(` Last active: ${user.lastActivityDate}`);
console.log(` Teams: ${user.microsoftTeamsCopilotLastActivityDate || "-"}`);
console.log(` Word: ${user.wordCopilotLastActivityDate || "-"}`);
console.log(` Excel: ${user.excelCopilotLastActivityDate || "-"}`);
console.log(` PowerPoint: ${user.powerPointCopilotLastActivityDate || "-"}`);
console.log(` Outlook: ${user.outlookCopilotLastActivityDate || "-"}`);
console.log(` OneNote: ${user.oneNoteCopilotLastActivityDate || "-"}`);
console.log(` Loop: ${user.loopCopilotLastActivityDate || "-"}`);
console.log(` Chat: ${user.copilotChatLastActivityDate || "-"}`);
});
} catch (error) {
console.error("Usage Reports error:", error);
}

Source Code

For a complete React component with period selection and a data grid, see the UsageReportsTab in our SPFx sample.

Limitations & Tips

  • This is a beta API β€” response shape may change
  • Only returns data for users with a Copilot license
  • Requires admin-level permissions (Reports.Read.All)
  • Available periods: D7, D30, D90, D180
  • If you forget the Accept: application/json header, you’ll get CSV back instead of JSON

Putting It All Together 🧩

Which API Should You Start With?

Your Goal Start Here
Building a RAG app or knowledge assistant Retrieval API
Natural language search experience Search API
Automating meeting follow-ups Meeting Insights API
Compliance monitoring or audit logging Change Notifications API
Tracking Copilot adoption & license ROI Usage Reports API
Embedding conversational AI in your app Chat API
Error Handling Pattern β€” Reusable Retry Helper

All Copilot APIs share common error patterns. Here’s a reusable retry helper we use across our projects:

async function callWithRetry(
apiCall: () => Promise<any>,
maxRetries = 3
): Promise<any> {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await apiCall();
} catch (error: any) {
const status = error.status || error.statusCode;

if (status === 429) {
const retryAfter = error.headers?.["retry-after"] || Math.pow(2, attempt);
console.log(`Rate limited. Retrying in ${retryAfter}s...`);
await new Promise(r => setTimeout(r, retryAfter * 1000));
continue;
}

if (status === 401) throw new Error("Unauthorized β€” check permissions and Copilot license");
if (status === 403) throw new Error("Forbidden β€” insufficient permissions");

if (status >= 500 && attempt < maxRetries - 1) {
await new Promise(r => setTimeout(r, 1000 * Math.pow(2, attempt)));
continue;
}

throw error;
}
}
}

Key Things to Remember

Important Note

1. All Copilot APIs require a Microsoft 365 Copilot license β€” there's no way around this

2. Rate limits are 200 requests/user/hour for Retrieval and Search APIs

3. Start with Graph Explorer to test your queries before writing code

4. Use delegated permissions where possible β€” they're easier to manage in SPFx

5. Handle 429 responses with exponential backoff β€” Copilot APIs will throttle aggressively


Conclusion

Microsoft 365 Copilot APIs give us something we haven’t had before β€” a way to embed production-grade AI into our applications without building the entire AI stack ourselves. Whether it’s grounding a RAG app with the Retrieval API, building natural language search with the Search API, or automating meeting follow-ups with Meeting Insights, each API solves a real problem that developers face today.

I’ve been building with these APIs hands-on, and the Copilot API Explorer sample is my way of sharing what I’ve learned with the community. If you’re getting started, clone the sample, configure the permissions, and start experimenting.

The APIs are evolving fast β€” SharePoint support for Search, new Chat API capabilities, and more notification filters are all on the horizon. Now is the time to start building.


Resources

Author: Ejaz Hussain
Link: https://office365clinic.com/2026/02/22/microsoft-copilot-apis-comprehensive-guide/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.