Improve This Site Feature
With the rollout of Microsoft Copilot and the SharePoint Knowledge Agent, we’re starting to see more advanced AI-driven insights show up across modern SharePoint sites. One such set of features is under the “Improve this site” prompt, which surfaces recommendations like fixing broken links, retiring old pages, or identifying content gaps.
What most folks don’t realize is these suggestions are backed by hidden APIs (thanks Microsoft) that power the Knowledge Agent’s insights. In this post, I’ll walk you through how to interact with these APIs directly so you can integrate, debug, or automate them as needed.
One thing to understand early on: the SharePoint Knowledge Agent runs per site. That means each site collection evaluates and stores its own recommendations in isolation. If you’re an admin or developer looking to manage multiple sites across a hub or tenant, you’re going to be severely disappointed.
Let’s say you want to find all broken links across every marketing site in your org or retire outdated content from dozens of other sites. There’s no out-of-the-box way to do that centrally. Which, is really frustrating.
By using the APIs that power Knowledge Agent, you can build custom dashboards or admin tools that:
- Query and aggregate missing link reports across multiple sites
- Automate page retirement policies using Power Automate or Azure Functions
- Surface content quality issues without requiring site owners to manually check each site
If you’ve ever built custom inventory tools for SharePoint before, this should feel familiar.
As always, these are undocumented APIs and their usage likely won’t have much support from Microsoft.
Prerequisites
Before diving in, make sure the following are true for your environment:
- You have Copilot licensing enabled.
- The EnsureMissingLinksFeature is activated. You can enable it with the following API call:
fetch("https://tenant.sharepoint.com/_api/sitemanager/EnsureMissingLinksListFeature", {
method: "POST",
headers: {
"accept": "application/json;odata=verbose",
"content-type": "application/json;odata=verbose",
"x-requestdigest": "<yourRequestDigest>"
},
credentials: "include"
});
Fix Broken Links
The Fix Broken Links functionality identifies links on your site that no longer resolve. This is a POST request that takes a payload with maxCount and snoozedLinks as parameters. The response should provide you with the top maxCount links in your site pages which are bad or invalid links!
fetch("https://tenant.sharepoint.com/_api/sitemanager/TopMissingLinks", {
method: "POST",
headers: {
"accept": "application/json;odata=verbose",
"content-type": "application/json;odata=verbose",
"x-requestdigest": "<yourRequestDigest>"
},
body: JSON.stringify({
maxCount: 6,
snoozedLinks: ""
}),
credentials: "include"
});
Sample Response
{
"d": {
"TopMissingLinks": {
"MissingLinks": {
"results": []
}
}
}
}
If there are broken links, they will appear in the results array.
Retire Inactive Pages
This feature identifies pages that haven’t seen much activity and lets you retire them. Retired pages are:
- Deprioritized in search and Copilot experiences
- Display a banner noting the content may be outdated
Get Retirable Pages
fetch("https://tenant.sharepoint.com/_api/sitemanager/RetirablePages", {
method: "POST",
headers: {
"accept": "application/json;odata=verbose",
"content-type": "application/json;odata=verbose",
"x-requestdigest": "<yourRequestDigest>"
},
body: JSON.stringify({
top: 6,
isDebug: false,
snoozedPaths: ""
}),
credentials: "include"
});
The response includes a list of page metadata. Each result includes properties like Title, Path, LastActivityTimestamp, and a thumbnail image.
If you’re curious where this property is stored… it’s tracked on the Site Pages library using a hidden column named _SPIsRetired.
How to Retire a Page
There are two main steps:
- Ensure the retire feature is enabled
- Set the
_SPIsRetiredfield on the page totrue
Step 1 – Enable Retire Page Feature
fetch("https://tenant.sharepoint.com/_api/sitemanager/EnsureRetirePageFeature", {
method: "POST",
headers: {
"accept": "application/json;odata=verbose",
"content-type": "application/json;odata=verbose",
"x-requestdigest": "<yourRequestDigest>"
},
credentials: "include"
});
Step 2 – Update the Page Metadata
Use the ValidateUpdateListItem endpoint:
fetch("https://tenant.sharepoint.com/_api/web/getlistitemusingpath(DecodedUrl='/SitePages/WhoWeAre.aspx')/ValidateUpdateListItem", {
method: "POST",
headers: {
"accept": "application/json;odata=verbose",
"content-type": "application/json;odata=verbose",
"x-requestdigest": "<yourRequestDigest>"
},
body: JSON.stringify({
formValues: [
{
FieldName: "_SPIsRetired",
FieldValue: "true"
}
]
}),
credentials: "include"
});
Step 3 – Publish the Page
After updating the metadata, be sure to publish the page:
fetch("https://tenant.sharepoint.com/_api/web/getfilebyserverrelativepath(DecodedUrl='/SitePages/WhoWeAre.aspx')/Publish", {
method: "POST",
headers: {
"accept": "application/json;odata=verbose",
"x-requestdigest": "<yourRequestDigest>"
},
credentials: "include"
});
Once published, users visiting the page will see a warning banner indicating the page is no longer maintained.

Where to See All Retired Pages
There’s also a special view in the Site Pages library that lets you filter for retired content:
Final Thoughts
While most users only see the polished UI that Copilot and SharePoint surfaces, behind the scenes is a powerful and mostly hidden set of APIs driving these insights. I hope this post helped shed light on how these features actually work and how you can hook into them directly.
In future posts, I’ll explore how to surface Content Gaps across your sites using these same hidden APIs.
As mentioned, these are undocumented and YMMV if you are incorporating them into your own products.























