Sharepoint - Retrieve all sites and all subsites from the SharePoint REST API

You need to use STS_Site and STS_Web both in your queryText.

Your REST API endpoint should be as below:

https://{mycompany}.sharepoint.com/_api/search/query?
querytext='contentclass:STS_Site contentclass:STS_Web'
&selectproperties='Title,Path'&rowlimit=500

Am able to get deep subsites as well using the above endpoint . Check the below screenshot which shows the deep subsite.

enter image description here


✅ If you just want to get a list of site & subsite URLs, you can cheat slightly.

Instead of looking for the sites or subsites, look for a /path/to/newsfeed.aspx entry instead. This appears to be present for all sites and subsites.

Here's the URL:

https://{mycompany}.sharepoint.com/_api/search/query
   ?querytext='*/newsfeed.aspx'&trim&selectproperties='ParentLink'

The ParentLink property contains the base URL for the site/sub-site.

While this is correct, it just feels like the wrong way of doing things.

This method also does not return the actual name of the site/sub-site, so is only a partial answer, but the best I can find right now.


If you can use the Microsoft Graph, it's much easier...

https://graph.microsoft.com/v1.0/sites?search=*

...will give all sites and subsites with their names


You can use below code to achieve above functionality : Below code fetches Subsites of root site and their subsite mentioning their parents as well. Hope this solves your issue

//common Ajax call function which sends back the response call
function GETMethodAjaxCall(url, success) {
$.ajax({
    type: "GET",
    contentType: "application/json",
    url: url,
    headers: {
        "Accept": "application/json; odata=verbose"
    },
    dataType: "json",
    success: function(response) {
        success(response);
    },
    error: function(err) {
        alert("error")
    }
});
}
$(document).ready(function() {

var url = _spPageContextInfo.webAbsoluteUrl + "/_api/Web/webs";

GETMethodAjaxCall(url, function(data) {
    $.each(data.d.results, function(index, value) {
        console.log("Site: " + value.Title + " " + "is Parent Site");

        GETMethodAjaxCall(value.Url + "/_api/Web/webs", function(data) {
            $.each(data.d.results, function(ind, val) {
                console.log("SubSite: " + val.Title + " " + "is child of " + value.Title);
            });
        });

    });    
});
});