Series – Working with (Hidden) APIs that power SharePoint Knowledge Agents

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:

  1. You have Copilot licensing enabled.
  2. 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:

  1. Ensure the retire feature is enabled
  2. Set the _SPIsRetired field on the page to true

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:

https://tenant.sharepoint.com/site/mysite/sitepages/forms/byauthor.aspx?viewid=af57819e-cb3e-443d-9517-b1ee5dd499d8


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.