I'm trying to do paging on a document library (also trying this on a list) with SP 2013 using REST/OData but I can't seem to get the skipping of items working.

Here are some examples of URLs that I'm trying on my own SP 2013 farm and it also doesn't work on my Office 365 2013 Dev Preview farm. Results are returned and $top and $orderby work fine but it never skips any items. i.e. I can take the $skip out of the URL and I get the same result.


http://sp15/_api/web/lists/GetByTitle('Documents')/Items?$skip=2&$top=2&$orderby=ID desc


Any ideas on what I'm doing wrong?

6 Answers 6


I'm not that familiar with REST but try the old syntax: Example: *http://sp15/_vti_bin/ListData.svc/FAQ?$skip=4&$top=2*

  • saw this old post and found useful
    – Ankur
    Commented Jan 15, 2016 at 18:02
  • Hey have any idea about get items by page of List of sharepoint.? Commented Feb 23, 2016 at 9:28

Currently $skip query option is not supported in SharePoint 2013/Online.

According to Use OData query operations in SharePoint REST requests:

The $skip query option does not work with queries for SharePoint list items.

But you could utilize $skiptoken query option to return paged results as demonstrated below.

Format: $skiptoken=Paged=TRUE&p_ID=<last item id to skip>&$top=<items count>


The example demonstrates how to retrieve the limited count of items (2 items) with id equals or greater 2 from Pages library:

function getPagedItems(webUrl,listTitle,startItemId,itemsCount)
    var endpointUrl = webUrl + "/_api/web/lists/getbytitle('" + listTitle +  "')/items?$skiptoken=" + encodeURIComponent('Paged=TRUE&p_SortBehavior=0&p_ID=' + (startItemId-1) + '&$top=' + itemsCount);
    return executeRequest(endpointUrl,'GET');

    if(data.d.results.length == 0){
        console.log('Items not found');
    for(var i = 0; i < data.d.results.length; i++){
        var item = data.d.results[i];


function executeRequest(url,method,headers,payload) 
    if (typeof headers == 'undefined'){
        headers = {};
    headers["Accept"] = "application/json;odata=verbose";
    if(method == "POST") {
        headers["X-RequestDigest"] = $("#__REQUESTDIGEST").val();

    var ajaxOptions = 
       url: url,   
       type: method,  
       contentType: "application/json;odata=verbose",
       headers: headers
    if(method == "POST") {
      ajaxOptions.data = JSON.stringify(payload);

    return $.ajax(ajaxOptions);
  • 5
    This is the actual answer for SharePoint list items... not the accepted one, or the most upvoted one (which references a comment that seems to no longer exist...)
    – John-M
    Commented Jan 7, 2016 at 4:55
  • 1
    Link to documentation is broken. Actual link is: docs.microsoft.com/en-us/sharepoint/dev/sp-add-ins/…
    – Nils
    Commented Oct 18, 2021 at 12:09

In my experience, none of the above solutions work - this could be because I was attempting this using an external list. To implement paging, I added ?$skiptoken=Paged=TRUE&$top=100 to the end of the URI. The URI for the next page will be included under JSON.d.__next. Once the last page is reached __next will not be present

  • Keep in mind, that the JSON.d.__next will only be available if odata=verbose is set on accept header. Without that, d is missing (naturally....) and __next will be called odata.nextLink, so it needs to be accessed like JSON["odata.nextLink"]
    – Nils
    Commented Oct 18, 2021 at 12:29

I see the same issue on SP2013 online with the new OData V3 _api endpoint. For CRUD operation it might be better to use the OData v2 listdata.svc endpoint for the time being.

  • 1
    Paging sounds like something that will be added to the _api endpoint at somepoint soon - I'd go with this solution but make sure you pattern it in such a way so that you can swap out with code that DOES run on _api when that capability is added, it'll keep your code current and fully supported/upgradeable for vNext.
    – James Love
    Commented Nov 17, 2012 at 22:15

Vadim's response is very close, but his query string is off a bit. The issue isn't really his, its Microsoft's as they are not being consistent with their URI escaping.

I used the Postman extension for Chrome and by examining the __next value returned when using $top (which is alternative approach worth considering) I noticed that there is an ampersand that is not escaped properly in the __next values. Using that approach I was able to get pagination with 2013 REST OData calls working. Here is the relevant code to use in conjunction with Vadim's response.

var queryString = "?%24skiptoken=Paged%3DTRUE%26p_ID%3D" + (startItemId - 1) + '&%24top=' + itemCount;
  • Does this still work if you apply an "orderby" some other field than the ID?
    – SteveCl
    Commented Feb 18, 2015 at 19:43
  • The p_ID value is paged ID, not the list item's ID (I think). The list I was testing on was sorted by modified date and things seemed to be coming back as expected but I must confess to not looking closely. Commented Feb 18, 2015 at 20:59

The $skip parameter does not work in SharePoint 2013 for list items. It only works for collection of data (like list collections, ecc..). See my comment at the end of this article: http://msdn.microsoft.com/library/d4b5c277-ed50-420c-8a9b-860342284b72.aspx

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.