Track changes in a driveItem and its children over time.
Your app begins by calling delta without any parameters.
The service starts enumerating the drive's hierarchy, returning pages of items and either an @odata.nextLink or an @odata.deltaLink, as described below.
Your app should continue calling with the @odata.nextLink until you no longer see an @odata.nextLink returned, or you see a response with an empty set of changes.
After you have finished receiving all the changes, you may apply them to your local state.
To check for changes in the future, call delta again with the @odata.deltaLink from the previous response.
Deleted items are returned with the deleted facet.
Items with this property set should be removed from your local state.
Note: you should only delete a folder locally if it is empty after syncing all the changes.
Permissions
Choose the permission or permissions marked as least privileged for this API. Use a higher privileged permission or permissions only if your app requires it. For details about delegated and application permissions, see Permission types. To learn more about these permissions, see the permissions reference.
GET /drives/{drive-id}/root/delta
GET /groups/{groupId}/drive/root/delta
GET /me/drive/root/delta
GET /sites/{siteId}/drive/root/delta
GET /users/{userId}/drive/root/delta
Function parameters
Parameter
Type
Description
token
string
Optional. If unspecified, enumerates the hierarchy's current state. If latest, returns empty response with latest delta token. If a previous delta token, returns new state since that token.
Optional query parameters
This method supports the $select, $expand, and $topOData query parameters to customize the response.
GET https://graph.microsoft.com/v1.0/me/drive/root/delta
// Code snippets are only available for the latest version. Current version is 5.x
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=csharp
var result = await graphClient.Drives["{drive-id}"].Items["{driveItem-id}"].Delta.GetAsDeltaGetResponseAsync();
// Code snippets are only available for the latest major version. Current major version is $v1.*
// Dependencies
import (
"context"
msgraphsdk "github.com/microsoftgraph/msgraph-sdk-go"
//other-imports
)
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=go
delta, err := graphClient.Drives().ByDriveId("drive-id").Items().ByDriveItemId("driveItem-id").Delta().GetAsDeltaGetResponse(context.Background(), nil)
// Code snippets are only available for the latest version. Current version is 6.x
GraphServiceClient graphClient = new GraphServiceClient(requestAdapter);
var result = graphClient.drives().byDriveId("{drive-id}").items().byDriveItemId("{driveItem-id}").delta().get();
# Code snippets are only available for the latest version. Current version is 1.x
from msgraph import GraphServiceClient
# To initialize your graph_client, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=python
result = await graph_client.drives.by_drive_id('drive-id').items.by_drive_item_id('driveItem-id').delta.get()
This response includes the first page of changes, and the @odata.nextLink property indicates that there are more items available in the current set of items.
Your app should continue to request the URL value of @odata.nextLink until all pages of items have been retrieved.
Example 2: Last page in a set
Here's an example of how to call this API to update your local state.
Request
Here's an example request after the initial request.
GET https://graph.microsoft.com/v1.0/me/drive/root/delta(token='MzslMjM0OyUyMzE7MzsyM2YwNDVhMS1lNmRmLTQ1N2MtOGQ5NS1hNmViZDVmZWRhNWQ7NjM3OTQzNzQwODQ3NTcwMDAwOzU4NTk2OTY0NDslMjM7JTIzOyUyMzA')
// Code snippets are only available for the latest version. Current version is 5.x
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=csharp
var result = await graphClient.Drives["{drive-id}"].Items["{driveItem-id}"].DeltaWithToken("{token}").GetAsDeltaWithTokenGetResponseAsync();
// Code snippets are only available for the latest major version. Current major version is $v1.*
// Dependencies
import (
"context"
msgraphsdk "github.com/microsoftgraph/msgraph-sdk-go"
//other-imports
)
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=go
token := "{token}"
delta, err := graphClient.Drives().ByDriveId("drive-id").Items().ByDriveItemId("driveItem-id").DeltaWithToken(&token).GetAsDeltaWithTokenGetResponse(context.Background(), nil)
// Code snippets are only available for the latest version. Current version is 6.x
GraphServiceClient graphClient = new GraphServiceClient(requestAdapter);
var result = graphClient.drives().byDriveId("{drive-id}").items().byDriveItemId("{driveItem-id}").deltaWithToken("{token}").get();
# Code snippets are only available for the latest version. Current version is 1.x
from msgraph import GraphServiceClient
# To initialize your graph_client, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=python
result = await graph_client.drives.by_drive_id('drive-id').items.by_drive_item_id('driveItem-id').delta_with_token("{token}").get()
This response indicates that the item named folder2 was deleted and the item file.txt was either added or modified between the initial request and this request to update the local state.
The final page of items includes the @odata.deltaLink property, which provides the URL that can be used later to retrieve changes since the current set of items.
There may be cases when the service can't provide a list of changes for a given token (for example, if a client tries to reuse an old token after being disconnected for a long time, or if server state has changed and a new token is required).
In these cases the service returns an HTTP 410 Gone error with an error response containing one of the error codes below, and a Location header containing a new nextLink that starts a fresh delta enumeration from scratch.
After finishing the full enumeration, compare the returned items with your local state and follow these instructions.
Error Type
Instructions
resyncChangesApplyDifferences
Replace any local items with the server's version (including deletes) if you're sure that the service was up to date with your local changes when you last synched. Upload any local changes that the server doesn't know about.
resyncChangesUploadDifferences
Upload any local items that the service didn't return, and upload any files that differ from the server's version (keeping both copies if you're not sure which one is more up-to-date).
Example 3: Retrieving the current deltaLink
In some scenarios, it may be useful to request the current deltaLink value without first enumerating all of the items in the drive already.
This can be useful if your app only wants to know about changes, and doesn't need to know about existing items.
To retrieve the latest deltaLink, call delta with a query string parameter ?token=latest.
Note: If you are trying to maintain a full local representation of the items in a folder or a drive, you must use delta for the initial enumeration.
Other approaches, such as paging through the children collection of a folder, are not guaranteed to return every single item if any writes take place during the enumeration.
Using delta is the only way to guarantee that you've read all of the data you need to.
// Code snippets are only available for the latest version. Current version is 5.x
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=csharp
var result = await graphClient.Drives["{drive-id}"].Items["{driveItem-id}"].Delta.GetAsDeltaGetResponseAsync((requestConfiguration) =>
{
requestConfiguration.QueryParameters.Token = "latest";
});
// Code snippets are only available for the latest major version. Current major version is $v1.*
// Dependencies
import (
"context"
msgraphsdk "github.com/microsoftgraph/msgraph-sdk-go"
graphdrives "github.com/microsoftgraph/msgraph-sdk-go/drives"
//other-imports
)
requestToken := "latest"
requestParameters := &graphdrives.DriveItemItemItemDeltaWithRequestBuilderGetQueryParameters{
Token: &requestToken,
}
configuration := &graphdrives.DriveItemItemItemDeltaWithRequestBuilderGetRequestConfiguration{
QueryParameters: requestParameters,
}
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=go
delta, err := graphClient.Drives().ByDriveId("drive-id").Items().ByDriveItemId("driveItem-id").Delta().GetAsDeltaGetResponse(context.Background(), configuration)
// Code snippets are only available for the latest version. Current version is 6.x
GraphServiceClient graphClient = new GraphServiceClient(requestAdapter);
var result = graphClient.drives().byDriveId("{drive-id}").items().byDriveItemId("{driveItem-id}").delta().get(requestConfiguration -> {
requestConfiguration.queryParameters.token = "latest";
});
# Code snippets are only available for the latest version. Current version is 1.x
from msgraph import GraphServiceClient
from msgraph.generated.drives.item.items.item.delta.delta_request_builder import DeltaRequestBuilder
from kiota_abstractions.base_request_configuration import RequestConfiguration
# To initialize your graph_client, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=python
query_params = DeltaRequestBuilder.DeltaRequestBuilderGetQueryParameters(
token = "latest",
)
request_configuration = RequestConfiguration(
query_parameters = query_params,
)
result = await graph_client.drives.by_drive_id('drive-id').items.by_drive_item_id('driveItem-id').delta.get(request_configuration = request_configuration)
Example 4: Retrieving delta results using a timestamp
In some scenarios, the client may know the state of a drive up to a specific time, but not have a deltaLink for that point in time. In this case, the client can call delta using a URL encoded timestamp for the value of the token query string parameter, for example, ?token=2021-09-29T20%3A00%3A00Z or '?token=2021-09-29T12%3A00%3A00%2B8%3A00'.
Using a timestamp in place of a token is only supported on OneDrive for Business and SharePoint.
Note: Clients should use the deltaLink provided by delta queries when possible, rather than generating their own token. This capability should only be utilized when the deltaLink is not known.
GET /me/drive/root/delta?token=2021-09-29T20%3A00%3A00Z
// Code snippets are only available for the latest version. Current version is 5.x
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=csharp
var result = await graphClient.Drives["{drive-id}"].Items["{driveItem-id}"].Delta.GetAsDeltaGetResponseAsync((requestConfiguration) =>
{
requestConfiguration.QueryParameters.Token = "2021-09-29T20:00:00Z";
});
// Code snippets are only available for the latest major version. Current major version is $v1.*
// Dependencies
import (
"context"
msgraphsdk "github.com/microsoftgraph/msgraph-sdk-go"
graphdrives "github.com/microsoftgraph/msgraph-sdk-go/drives"
//other-imports
)
requestToken := "2021-09-29T20:00:00Z"
requestParameters := &graphdrives.DriveItemItemItemDeltaWithRequestBuilderGetQueryParameters{
Token: &requestToken,
}
configuration := &graphdrives.DriveItemItemItemDeltaWithRequestBuilderGetRequestConfiguration{
QueryParameters: requestParameters,
}
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=go
delta, err := graphClient.Drives().ByDriveId("drive-id").Items().ByDriveItemId("driveItem-id").Delta().GetAsDeltaGetResponse(context.Background(), configuration)
// Code snippets are only available for the latest version. Current version is 6.x
GraphServiceClient graphClient = new GraphServiceClient(requestAdapter);
var result = graphClient.drives().byDriveId("{drive-id}").items().byDriveItemId("{driveItem-id}").delta().get(requestConfiguration -> {
requestConfiguration.queryParameters.token = "2021-09-29T20:00:00Z";
});
# Code snippets are only available for the latest version. Current version is 1.x
from msgraph import GraphServiceClient
from msgraph.generated.drives.item.items.item.delta.delta_request_builder import DeltaRequestBuilder
from kiota_abstractions.base_request_configuration import RequestConfiguration
# To initialize your graph_client, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=python
query_params = DeltaRequestBuilder.DeltaRequestBuilderGetQueryParameters(
token = "2021-09-29T20:00:00Z",
)
request_configuration = RequestConfiguration(
query_parameters = query_params,
)
result = await graph_client.drives.by_drive_id('drive-id').items.by_drive_item_id('driveItem-id').delta.get(request_configuration = request_configuration)
The delta feed shows the latest state for each item, not each change. If an item were renamed twice, it would only show up once, with its latest name.
The same item may appear more than once in a delta feed, for various reasons. You should use the last occurrence you see.
The parentReference property on items won't include a value for path. This occurs because renaming a folder doesn't result in any descendants of the folder being returned from delta. When using delta you should always track items by id.
Delta query won't return some DriveItem properties, depending on the operation and service type, as shown in the following tables.
OneDrive for Business
Operation type
Properties omitted by delta query
Create/Modify
ctag
Delete
ctag, name
OneDrive (consumer)
Operation type
Properties omitted by delta query
Create/Modify
n/a
Delete
ctag, size
Scanning permissions hierarchies
By default, the delta query response includes sharing information for all items in the query that changed even if they inherit their permissions from their parent and didn't have direct sharing changes themselves. This typically then results in a follow-up call to get the permission details for every item rather than just the ones whose sharing information changed. You can optimize your understanding of how permission changes happen by adding the Prefer: hierarchicalsharing header to your delta query request.
When the Prefer: hierarchicalsharing header is provided, sharing information is returned for the root of the permissions hierarchy, and items that explicitly have sharing changes. In cases where the sharing change is to remove sharing from an item, you find an empty sharing facet to differentiate between items that inherit from their parent and those that are unique but have no sharing links. You'll also see this empty sharing facet on the root of a permission hierarchy that isn't shared to establish the initial scope.
In many scanning scenarios, you might be interested specifically in changes to permissions. To make it clear in the delta query response which changes are the result of permissions being changed, you can provide the Prefer: deltashowsharingchanges header. When this header is provided, all items that appear in the delta query response due to permission changes have the @microsoft.graph.sharedChanged":"True" OData annotation. This feature is applicable to SharePoint and OneDrive for Business but not consumer OneDrive accounts.
Note
The use of Prefer: deltashowsharingchanges header requires you to use Prefer: deltashowremovedasdeleted and Prefer: deltatraversepermissiongaps. These header values can be joined together in a single header: Prefer: deltashowremovedasdeleted, deltatraversepermissiongaps, deltashowsharingchanges.
In order to process permissions correctly your application will need to request Sites.FullControl.All permissions.