The delta query in Microsoft Graph lets you query for additions, deletions, or updates to supported resources. It is enabled through a series of delta requests. For users, the delta query enables you to discover changes without fetching the entire set of users to compare changes.
Clients that synchronize users with a local profile store can use the delta query for both their initial full synchronization along with subsequent incremental synchronizations. Typically, a client would do an initial full synchronization of all the users in a tenant, and then, get incremental changes to users periodically.
Track changes to users
Track user changes through one or more GET requests with the delta function. The GET request is like a list users request, except with the following extra objects in the URL:
The delta function.
A state token (deltaToken or skipToken) from the previous GET delta function call.
Example: track changes to users
The following example shows a series of requests to track changes to users:
GET https://graph.microsoft.com/v1.0/users/delta?$select=displayName,givenName,surname
var graphClient = new GraphServiceClient(requestAdapter);
var result = await graphClient.Users.Delta.GetAsync((requestConfiguration) =>
{
requestConfiguration.QueryParameters.Select = new string []{ "displayName","givenName","surname" };
});
<?php
// THIS SNIPPET IS A PREVIEW FOR THE KIOTA BASED SDK. NON-PRODUCTION USE ONLY
$graphServiceClient = new GraphServiceClient($requestAdapter);
$requestConfiguration = new DeltaRequestBuilderGetRequestConfiguration();
$queryParameters = new DeltaRequestBuilderGetQueryParameters();
$queryParameters->select = ["displayName","givenName","surname"];
$requestConfiguration->queryParameters = $queryParameters;
$requestResult = $graphServiceClient->users()->delta()->get($requestConfiguration);
If successful, this method returns 200 OK response code and user collection object in the response body. Assuming the entire set of users is too large, the response will also include a @odata.nextLink state token in an @odata.nextLink parameter.
In this example, a @odata.nextLink URL is returned indicating there are more pages of data to be retrieved in the session. The $select query parameter from the initial request is encoded into the @odata.nextLink URL.
GET https://graph.microsoft.com/v1.0/users/delta?$skiptoken=oEBwdSP6uehIAxQOWq_3Ksh_TLol6KIm3stvdc6hGhZRi1hQ7Spe__dpvm3U4zReE4CYXC2zOtaKdi7KHlUtC2CbRiBIUwOxPKLa
var graphClient = new GraphServiceClient(requestAdapter);
var result = await graphClient.Users.Delta.GetAsync((requestConfiguration) =>
{
requestConfiguration.QueryParameters.Skiptoken = "oEBwdSP6uehIAxQOWq_3Ksh_TLol6KIm3stvdc6hGhZRi1hQ7Spe__dpvm3U4zReE4CYXC2zOtaKdi7KHlUtC2CbRiBIUwOxPKLa";
});
<?php
// THIS SNIPPET IS A PREVIEW FOR THE KIOTA BASED SDK. NON-PRODUCTION USE ONLY
$graphServiceClient = new GraphServiceClient($requestAdapter);
$requestConfiguration = new DeltaRequestBuilderGetRequestConfiguration();
$queryParameters = new DeltaRequestBuilderGetQueryParameters();
$queryParameters->skiptoken = "oEBwdSP6uehIAxQOWq_3Ksh_TLol6KIm3stvdc6hGhZRi1hQ7Spe__dpvm3U4zReE4CYXC2zOtaKdi7KHlUtC2CbRiBIUwOxPKLa";
$requestConfiguration->queryParameters = $queryParameters;
$requestResult = $graphServiceClient->users()->delta()->get($requestConfiguration);
The response contains another @odata.nextLink with a new skipToken value, which indicates that more changes that were tracked for users are available. Use the @odata.nextLink URL in more requests until a @odata.deltaLink URL (in an @odata.deltaLink parameter) is returned in the final response, even if the value is an empty array.
GET https://graph.microsoft.com/v1.0/users/delta?$skiptoken=pqwSUjGYvb3jQpbwVAwEL7yuI3dU1LecfkkfLPtnIjtQ5LOhVoS7qQG_wdVCHHlbQpga7
var graphClient = new GraphServiceClient(requestAdapter);
var result = await graphClient.Users.Delta.GetAsync((requestConfiguration) =>
{
requestConfiguration.QueryParameters.Skiptoken = "pqwSUjGYvb3jQpbwVAwEL7yuI3dU1LecfkkfLPtnIjtQ5LOhVoS7qQG_wdVCHHlbQpga7";
});
<?php
// THIS SNIPPET IS A PREVIEW FOR THE KIOTA BASED SDK. NON-PRODUCTION USE ONLY
$graphServiceClient = new GraphServiceClient($requestAdapter);
$requestConfiguration = new DeltaRequestBuilderGetRequestConfiguration();
$queryParameters = new DeltaRequestBuilderGetQueryParameters();
$queryParameters->skiptoken = "pqwSUjGYvb3jQpbwVAwEL7yuI3dU1LecfkkfLPtnIjtQ5LOhVoS7qQG_wdVCHHlbQpga7";
$requestConfiguration->queryParameters = $queryParameters;
$requestResult = $graphServiceClient->users()->delta()->get($requestConfiguration);
When a @odata.deltaLink URL is returned, there's no more data about the existing state of the user objects. For future requests, the application uses the @odata.deltaLink URL to learn about other changes to users. Save the deltaToken and use it in the subsequent request URL to discover more changes to users.
GET https://graph.microsoft.com/v1.0/users/delta?$deltatoken=oEcOySpF_hWYmTIUZBOIfPzcwisr_rPe8o9M54L45qEXQGmvQC6T2dbL-9O7nSU-njKhFiGlAZqewNAThmCVnNxqPu5gOBegrm1CaVZ-ZtFZ2tPOAO98OD9y0ao460
var graphClient = new GraphServiceClient(requestAdapter);
var result = await graphClient.Users.Delta.GetAsync((requestConfiguration) =>
{
requestConfiguration.QueryParameters.Deltatoken = "oEcOySpF_hWYmTIUZBOIfPzcwisr_rPe8o9M54L45qEXQGmvQC6T2dbL-9O7nSU-njKhFiGlAZqewNAThmCVnNxqPu5gOBegrm1CaVZ-ZtFZ2tPOAO98OD9y0ao460";
});
<?php
// THIS SNIPPET IS A PREVIEW FOR THE KIOTA BASED SDK. NON-PRODUCTION USE ONLY
$graphServiceClient = new GraphServiceClient($requestAdapter);
$requestConfiguration = new DeltaRequestBuilderGetRequestConfiguration();
$queryParameters = new DeltaRequestBuilderGetQueryParameters();
$queryParameters->deltatoken = "oEcOySpF_hWYmTIUZBOIfPzcwisr_rPe8o9M54L45qEXQGmvQC6T2dbL-9O7nSU-njKhFiGlAZqewNAThmCVnNxqPu5gOBegrm1CaVZ-ZtFZ2tPOAO98OD9y0ao460";
$requestConfiguration->queryParameters = $queryParameters;
$requestResult = $graphServiceClient->users()->delta()->get($requestConfiguration);
If changes have occurred, a collection of changed user objects is included. The response also contains either a @odata.nextLink - in case there are multiple pages of changes to retrieve - or a @odata.deltaLink. Implement the same pattern of following the @odata.nextLink and persist the final @odata.deltaLink for future calls.
Note
This request might have replication delays for users that were recently created, updated, or deleted. Retry the @odata.nextLink or @odata.deltaLink after some time to retrieve the latest changes.