Paging Microsoft Graph data in your app

Some GET queries against Microsoft Graph return multiple pages of data either due to server-side paging or client-side paging. Paging data helps improve the performance of your app and the response time of Microsoft Graph.

Learn more about pagination through the following video.

How paging works

In client-side paging, a client app specifies the number of results it wants Microsoft Graph to return in a single page by using the $top, $skip, or $skipToken query parameters. Support for client-side paging, including the number of results that the client can request for in a single page depends on the API and the query being performed. For example, the /users endpoint supports $top but not $skip.

In server-side paging, the Microsoft Graph service returns a default number of results in a single page without the client specifying the number of results to return using $top. For example, the GET /users endpoint returns a default of 100 results in a single page.

When more than one query request is required to retrieve all the results, Microsoft Graph returns an @odata.nextLink property in the response that contains a URL to the next page of results. You can retrieve the next page of results by sending the URL value of the @odata.nextLink property to Microsoft Graph. Microsoft Graph will continue to return a reference to the next page of results in the @odata.nextLink property with each response until there are no more pages of results to retrieve. To read all results, you must continue to call Microsoft Graph with the @odata.nextLink property returned in each response until the @odata.nextLink property is no longer returned.

For example, the following example shows client-side paging where the client uses the $top query parameter to request up to five users in the tenant.

GET https://graph.microsoft.com/v1.0/users?$top=5

If the result contains more results, Microsoft Graph returns an @odata.nextLink property similar to the following along with the first page of results:

"@odata.nextLink": "https://graph.microsoft.com/v1.0/users?$top=5&$skiptoken=RFNwdAIAAQAAAD8...AAAAAAAA"

You should include the entire URL in the @odata.nextLink property in your request for the next page of results. Depending on the API that the query is being performed against, the @odata.nextLink URL value contains either a $skiptoken or a $skip query parameter. The URL also contains all the other query parameters present in the original request. Don't try to extract the $skiptoken or $skip value and use it in a different request.

Paging behavior varies across different Microsoft Graph APIs. Consider the following when working with paged data:

  • A page of results may contain zero or more results.
  • Different APIs might have different default and maximum page sizes.
  • Different APIs might behave differently if you specify a page size (via the $top query parameter) that exceeds the maximum page size for that API. Depending on the API, the requested page size might be ignored, it might default to the maximum page size for that API, or Microsoft Graph might return an error.
  • Not all resources or relationships support paging. For example, queries against directoryRole don't support paging. This includes reading role objects themselves and role members.
  • When paging against directory resources, any custom request headers (headers that aren't Authorization or Content-Type headers) such as the ConsistencyLevel header aren't included by default in subsequent page requests. If those headers need to be sent on subsequent requests, you must set them explicitly.
  • When using the $count=true query string when querying against directory resources, the @odata.count property is returned only in the first page of the paged result set.