Document Sets are a powerful feature in SharePoint that allow you to group related documents into a single entity where they can share metadata, workflows, and versioning. While many developers are familiar with creating Document Sets using the Client-Side Object Model (CSOM) or JavaScript Object Model (JSOM), doing so via the REST API can sometimes feel less intuitive. However, using the REST interface is often necessary when building platform-independent applications or lightweight client-side scripts.

In this guide, you will learn how to leverage the SharePoint REST API to programmatically create Document Sets. We will focus on a proven method using the listdata.svc service, which provides a streamlined approach to handling folder-based content types.

Understanding the Document Set REST Challenge

When you create a standard folder in SharePoint via REST, you typically send a POST request to the folders collection of a library. However, a Document Set is not just a folder; it is a specialized content type (inheriting from the Folder base type) that carries specific properties and behaviors.

To create a Document Set successfully, you must ensure two things: 1. The Document Set feature is activated at the Site Collection level. 2. The Document Set Content Type (or a child of it) is added to your target Document Library.

The standard _api/web endpoint can be used, but many developers find the legacy _vti_bin/listdata.svc endpoint more reliable for this specific task because of how it handles the Slug header to define the path and content type simultaneously.

Step 1: Retrieving the Library Server Relative URL

Before creating the Document Set, you need to know exactly where it will reside. The following helper function, getListUrl, uses the standard REST API to fetch the ServerRelativeUrl of the library's root folder. This path is essential for constructing the location of your new Document Set.

function getListUrl(webUrl, listName, success, error) 
{
    var headers = {};
    $.ajax({       
       url: webUrl + "/_api/lists/getbytitle('" + listName + "')/rootFolder?$select=ServerRelativeUrl",   
       type: "GET",   
       contentType: "application/json;odata=verbose",
       headers: {
          "Accept": "application/json;odata=verbose"
       },   
       success: function(data){
           success(data.d.ServerRelativeUrl);
       },
       error: error
    });
}

Step 2: The Core Creation Logic

The heavy lifting is done by the createFolder function. This function targets the listdata.svc endpoint. The critical component here is the Slug header. The Slug header tells SharePoint two pieces of information: the destination path and the Content Type ID, separated by a pipe (|) symbol.

For a standard Document Set, the Content Type ID is 0x0120D520. If you have created a custom Document Set content type, you would use that specific ID instead.

function createFolder(webUrl, listName, folderName, folderContentTypeId, success, error) 
{  
    getListUrl(webUrl, listName,
      function(listUrl) {
          var folderPayload = {
             'Title' : folderName,
             'Path' : listUrl
          };

          // Create the Document Set resource
          $.ajax({
                url: webUrl + "/_vti_bin/listdata.svc/" + listName,
                type: "POST",
                contentType: "application/json;odata=verbose",
                data: JSON.stringify(folderPayload),
                headers: {
                   "Accept": "application/json;odata=verbose",
                   "Slug": listUrl + "/" + folderName + "|" + folderContentTypeId
                },
                success: function (data) {
                    success(data.d);
                },
                error: error
          });
      },
      error);
}

Step 3: Implementing the Wrapper Function

To make your code cleaner and more reusable, you can wrap the logic into a specific createDocumentSet function. This abstracts away the Content Type ID, making the call much simpler for other developers on your team.

function createDocumentSet(webUrl, listName, folderName, success, error)
{
   // The ID '0x0120D520' is the base Document Set Content Type
   createFolder(webUrl, listName, folderName, '0x0120D520', success, error);
}

Putting It All Together

To execute the creation, you simply need to provide the web URL, the library name, and the desired name of your new Document Set. In a SharePoint environment, you can often use the global _spPageContextInfo object to dynamically get the current site URL.

createDocumentSet(_spPageContextInfo.webAbsoluteUrl, 'Documents', 'Orders',
  function(folder){
    console.log('Document Set ' + folder.Name + ' has been created successfully'); 
  },
  function(error){
    console.log('Error creating Document Set: ' + JSON.stringify(error));
  }
);

Important Considerations

Authentication and Context

When running this code outside of a SharePoint page (for example, in a standalone Node.js app or a remote integration), you must ensure your request includes a valid Request Digest (X-RequestDigest) or an OAuth bearer token. If you are running this within a SharePoint site page using jQuery, the listdata.svc endpoint handles much of the context automatically, but for modern SPFx applications, you should consider using the SPHttpClient which handles headers more securely.

Version Compatibility

While the code above is designed for SharePoint 2013 and later (including SharePoint Online), the listdata.svc endpoint is technically an OData v2 service. While Microsoft continues to support this for backward compatibility, it is always wise to verify its availability in your specific tenant settings, especially as Microsoft pushes toward the Graph API and modern REST endpoints.

Permissions

The user executing the code must have at least Contribute permissions on the target library. Specifically, they need the ability to add items and manage content types if the Document Set requires specific metadata initialization.

Frequently Asked Questions

Can I create a Document Set using the newer _api/web/lists endpoint?

Yes, it is possible by creating a folder and then updating its ContentTypeId property. However, the listdata.svc method with the Slug header is often preferred because it performs the creation and type assignment in a single request, reducing the risk of orphaned folders that failed to convert into Document Sets.

What is the default Content Type ID for a Document Set?

The base ID is 0x0120D520. If you have created a custom Document Set, your ID will start with this string but will be longer (e.g., 0x0120D520...). Always use the most specific ID for your business requirements.

Does this method work in SharePoint Online?

Yes, this method currently works in SharePoint Online. However, for new enterprise-scale projects, you may want to explore the Microsoft Graph API, although its support for specific Document Set metadata can sometimes be more complex to implement than the native SharePoint REST API.

Wrapping Up

Creating Document Sets via the REST API provides a flexible way to automate document management without relying on heavy client-side libraries. By using the listdata.svc endpoint and the Slug header, you can ensure that your Document Sets are created with the correct content type and location in a single, efficient operation.

Whether you are migrating legacy systems or building modern automation workflows, mastering these REST techniques will give you greater control over your SharePoint environment.