Getting term label values with the SharePoint RenderListDataAsStream API endpoint

Recently Microsoft released a new API endpoint for retrieving SharePoint listitem data. With this RenderListDataAsStream  API you can now retrieve both managed metadata field values and lookup field values very easily.

I was using the SharePoint items REST API endpoint like this:


While I was using this only for retrieving data from lists on the site collection root level, it seemed to work just fine. With the $expand I managed to get the Editor’s name, the Project title and the term label by using the special field TaxCatchAll. Until I got a phone call from a customer that he got some errors and was not seeing his documents with the metatdata anymore.

After some thorough testing, troubleshooting and debugging I could confirm it was not working indeed and that the problem was not getting any data from the TaxCatchAll field. I searched around on the net and hit the blog post by Elio Struyf Using the SharePoint RenderListDataAsStream API to fetch lookup and single managed metadata field values. Interesting!

I decided to refactor my code. Now, couple of things to bear in mind. First, the RenderListDataAsStream  API is using a POST method, not a GET. So you cannot test it directly in the browser. Second, (afaik) you can only get the fields exposed by views. Since I also required the ServerRedirectedEmbedUri field, I had to solve that problem also. Third and last, the response is of a different structure. You might need to change some logic as well to map the values to your model.

C# snippet:

var filter = $@"<Query><Where><BeginsWith><FieldRef Name =""ContentTypeId"" /><Value Type =""ContentTypeId"">{Common.documentContentTypeId}</Value></BeginsWith></Where><OrderBy><FieldRef Name=""Created"" Ascending=""FALSE"" /></OrderBy></Query><RowLimit Paged=""FALSE"">5</RowLimit>";

var apiUrl = $"{url}/_api/web/lists/GetByTitle('{getDocumentsRequest.LibraryName}')/RenderListDataAsStream";
var camlQuery = $@"<View><ViewFields><FieldRef Name=""ID"" /><FieldRef Name=""Title"" /><FieldRef Name=""FileLeafRef"" /><FieldRef Name=""MavProject"" /><FieldRef Name=""MavCategory"" /><FieldRef Name=""Editor"" /><FieldRef Name=""Modified"" /></ViewFields>{filter}</View>";
var bodyRequest = JsonConvert.SerializeObject(new { parameters = new { RenderOptions = 2, ViewXml = camlQuery } });
var authenticationHeader = RestUtility.GetAuthenticationHeader(url);

var requestHeader = new Dictionary<string, string>
        "Accept", "application/json;odata=nometadata"

var result = await RestUtility.ExecutePostQuery<JObject>(apiUrl, authenticationHeader, bodyRequest, requestHeader, HttpMethod.Post);

So, basically I define a (good old) CAML query and pass that into my body request. After the call the JSON result looks like this:

  "Row": [
      "ID": "3",
      "PermMask": "0x3008031061",
      "FSObjType": "0",
      "HTML_x0020_File_x0020_Type": "",
      "UniqueId": "{86F08A9E-21D1-4329-AB0A-4F4A44F22DBF}",
      "ProgId": "",
      "NoExecute": "0",
      "ContentTypeId": "0x0101007442F1819EDBDA4F86864C1AF568BEC60033987CB06F38A8428A68D8F82C9354B3",
      "FileRef": "/sites/octavie-test/Shared Documents/Microsoft Azure Infographic 2015 2.5.pdf",
      "FileRef.urlencode": "%2Fsites%2Foctavie%2Dtest%2FShared%20Documents%2FMicrosoft%20Azure%20Infographic%202015%202%2E5%2Epdf",
      "FileRef.urlencodeasurl": "/sites/octavie-test/Shared%20Documents/Microsoft%20Azure%20Infographic%202015%202.5.pdf",
      "FileRef.urlencoding": "/sites/octavie-test/Shared%20Documents/Microsoft%20Azure%20Infographic%202015%202.5.pdf",
      "ItemChildCount": "0",
      "FolderChildCount": "0",
      "SMTotalSize": "5142280",
      "File_x0020_Size": "1074629",
      "MediaServiceFastMetadata": "",
      "Title": "Azure Infografic",
      "FileLeafRef": "Microsoft Azure Infographic 2015 2.5.pdf",
      "FileLeafRef.Name": "Microsoft Azure Infographic 2015 2.5",
      "FileLeafRef.Suffix": "pdf",
      "MavProject": [
          "lookupId": 2,
          "lookupValue": "Project B",
          "isSecretFieldValue": false
      "MavProject.": "2;#Project B",
      "MavCategory": {
        "__type": "TaxonomyFieldValue:#Microsoft.SharePoint.Taxonomy",
        "Label": "Azure",
        "TermID": "dcc41962-ba2c-4e1f-a38e-787a0c507052"
      "MavCategory.": "2;#Azure",
      "Editor": [
          "id": "11",
          "title": "Octavie van Haaften",
          "email": "",
          "sip": "",
          "picture": ""
      "": "11",
      "Editor.title": "Octavie van Haaften",
      "Editor.span": "<remove-for-readability>",
      "": "",
      "Editor.sip": "",
      "Editor.jobTitle": "",
      "Editor.department": "",
      "Editor.picture": "",
      "Modified": "30-3-2018 08:57",
      "Modified.": "2018-03-30 08:57:17",
      "Created": "30-3-2018 08:56",
      "ContentVersion": "1",
      "_VirusStatus": "0",
      "ecb.dispex": "return DispEx(this,event,'TRUE','FALSE','','','1','','','','','11','0','','0x3008031061','','')"
  "FirstRow": 1,
  "FolderPermissions": "0x3008031061",
  "LastRow": 1,
  "RowLimit": 5,
  "FilterLink": "?",
  "ForceNoHierarchy": "1",
  "HierarchyHasIndention": ""

You can now see that the data from both MavProject and MavCategory are directly available! Cool stuff!

More information about the RenderListDataAsStream  API and what RenderOptions are available: