How to Delete SharePoint List Items Using Power Automate (3 Methods Compared)

Deleting SharePoint items in Power Automate is straightforward when working with small datasets, but the approach that works fine at a hundred records can become a reliability and throughput problem at ten thousand. The method you choose affects not just speed, but how SharePoint handles throttling, whether deleted items are recoverable, and how much operational complexity the flow introduces as it scales.

This article compares three production-ready deletion methods:

Each one is valid, but they behave differently under load and carry different trade-offs around recovery, throughput, and implementation complexity.

Scenario Overview

A typical deletion flow is triggered on a schedule. It retrieves a filtered set of items from a SharePoint list, then processes each one for removal. The trigger is almost always recurrence-based rather than item-based, since deletion is usually a maintenance operation rather than a response to a specific item event.

The structure of the flow is roughly the same across all three methods: retrieve, loop, delete. What changes is how the deletion step is executed, and that difference has meaningful consequences at scale.

Before choosing a method, it helps to understand the three behavioral factors that matter most in production environments: throttling, recycle bin recovery, and silent batch failures.

Throttling

Throttling is SharePoint’s built-in service protection mechanism. When a flow issues too many requests in a short period, SharePoint responds with HTTP 429 errors and Power Automate introduces automatic retry delays.

At small scale, throttling is rarely noticeable. At higher volume, it becomes the dominant factor affecting flow duration. This is especially relevant for deletion methods that issue one HTTP request per item.

Recycle Bin Recovery

Recycle bin behavior varies significantly by deletion method.

The Delete item action routes items through SharePoint’s normal recycle bin lifecycle, preserving both first-stage and second-stage recovery.

The REST API and Batch API can either permanently delete items or route them to the recycle bin depending on which endpoint is used. In practice, these methods are commonly used for permanent deletion scenarios, but they are not inherently irreversible.

Silent Batch Failures

The SharePoint Batch API returns HTTP 200 even when individual operations inside the batch fail. Power Automate therefore treats the HTTP request itself as successful unless the response body is inspected manually.

This behavior is one of the most important operational differences between the Batch API and the other deletion methods.

Choosing the Right Method

The right choice depends on three things:

The Delete item action is the right starting point for most scenarios. It is simple to implement, integrates cleanly with SharePoint’s native lifecycle, and preserves recycle bin recovery. The trade-off is that each deletion generates an individual request, which makes throttling increasingly significant as volume grows.

The REST API gives you more direct control over request handling and logging while supporting either permanent deletion or recycle bin routing depending on the endpoint used. Throughput characteristics are generally similar to the Delete item action because each item still requires its own request.

The Batch API becomes valuable when request volume itself is the bottleneck. By grouping many delete operations into a single HTTP request, it significantly reduces request pressure and improves throughput at scale. The trade-off is implementation complexity: batch formatting is strict, debugging is harder, and failures must be validated manually from the response body.

Delete Item ActionREST APIBatch API
Recycle bin recoveryYes, both stagesOptional via endpointOptional via endpoint
Implementation complexityLowMediumHigh
Throttling impact at scaleHighHighMuch lower
Silent batch failuresNoNoYes
Transactional (all or nothing)NoNoNo
Best forGeneral use, recoverable deletionsExplicit HTTP control and loggingHigh-volume deletion
Typical practical volume per run~500-1000 items~500-1000 items1000+ items

Method 1: Delete Items Using the Delete Item Action

Implementation

Start by creating a Scheduled cloud flow. Set the recurrence to match how often the deletion should run, typically daily or weekly for maintenance scenarios. In this example, an Instant cloud flow is used instead so that it can be triggered manually as needed.

Screenshot of the overall flow using the Delete Item action method in Power Automate.
Power Automate: Overall Flow for Delete Item Method

Add a Get items action and configure it against your SharePoint site and list. Under Advanced parameters, apply a Filter Query using OData syntax to limit results to only the records you intend to delete. Retrieving the entire list and filtering inside the loop is a common mistake that increases request volume unnecessarily.

In this example, the list contains a Method column used to flag items for a specific deletion strategy. The filter targets items where that column equals Delete Item:

Method eq 'Delete Item'
Screenshot of the example list structure in SharePoint.
SharePoint: Example List Structure

Set the Top Count field to control how many items are retrieved per run.

Screenshot of the Get Items action parameters in Power Automate.
Power Automate: Get Items Action Parameters

Under Settings, enable Pagination and set the Threshold to 5000.

Screenshot of the Get Items action Pagination settings in Power Automate.
Power Automate: Get Items Action Pagination Settings

Add an Apply to each (For each) action using the value output from Get items.

Screenshot of the Apply to Each parameters in Power Automate.
Power Automate: Apply to Each Parameters

Inside the loop, add the Delete item action and map the Id field using:

@{items('For_each')['ID']}
Screenshot of the Delete Item action parameters in Power Automate.
Power Automate: Delete Item Action Parameters

SharePoint Behavior and Recycle Bin Recovery

This method follows SharePoint’s standard deletion lifecycle.

Deleted items move to the site’s first-stage recycle bin, where they can typically be restored by the deleting user or site administrators. If removed from there, they move to the second-stage recycle bin, where a site collection administrator can still restore them before permanent removal.

If there is any realistic chance that a deletion might need to be reversed, this is the safest method.

Performance and Throttling

Each Delete item call generates a separate request to SharePoint. At low volume this is rarely a problem, but as the number of items increases, throttling delays become increasingly noticeable.

A flow deleting several hundred items may complete quickly, while the same flow deleting several thousand items may slow substantially once SharePoint begins issuing HTTP 429 responses and Power Automate introduces retry delays.

If throttling causes the flow to exceed its schedule window, reducing Top Count and running the flow more frequently is usually more reliable than attempting larger deletion runs.

Concurrency Considerations

Apply to each supports configurable concurrency in Power Automate settings. Enabling concurrency allows multiple delete operations to execute in parallel, which can improve throughput for moderate workloads.

However, higher concurrency also increases request pressure against SharePoint and can accelerate throttling under heavy load. It may also increase the likelihood of race conditions when multiple flows interact with the same list simultaneously.

For deletion-heavy flows, concurrency settings should be treated as a throughput tuning mechanism rather than a guaranteed performance improvement.

Method 2: Delete Items Using the SharePoint REST API

Implementation

The overall flow structure remains the same as Method 1: trigger, Get items, loop, delete.

The difference is that the Delete item action is replaced with Send an HTTP request to SharePoint.

Screenshot of the overall flow using the SharePoint REST API deletion method in Power Automate.
Power Automate: Overall Flow Using the REST API Method

In this example, the list is filtered for items where the Method column equals Delete Item Using REST API:

Method eq 'Delete Item Using REST API'

The Get items configuration for Top Count and Settings for Pagination are otherwise the same as Method 1.

Screenshot of the Get Items action Filter Query and Top Count parameters in Power Automate.
Power Automate: Get Items Action Parameters for Filter Query and Top Count

Configure the Send an HTTP request to SharePoint action as follows:

NOTE: Using POST instead of DELETE may look counterintuitive. SharePoint’s REST API uses POST as the base method for operations that modify data, with the X-HTTP-Method header overriding the operation type.

Some corporate firewalls and proxies also block the literal DELETE verb, making POST with X-HTTP-Method the more reliable approach in enterprise environments.

Set Uri to:

_api/web/lists/GetByTitle('YourListName')/items(@{items('For_each')['ID']})

Replace YourListName with your actual list display name. If the name contains spaces, include them as written:

GetByTitle('My Task List')
Screenshot of the Send an HTTP request to SharePoint parameters in Power Automate.
Power Automate: Send an HTTP Request to SharePoint Action Parameters

To send deleted items to the recycle bin instead of permanently deleting them, use:

_api/web/lists/GetByTitle('YourListName')/items(@{items('For_each')['ID']})/recycle()
Screenshot of the Send an HTTP request to SharePoint parameters using the Recycle endpoint in Power Automate.
Power Automate: Send an HTTP Request to SharePoint Action Parameters Using the Recycle Endpoint

Under Advanced parameters, add these headers:

IF-MATCH: *
X-HTTP-Method: DELETE

The IF-MATCH header bypasses ETag version checks. Without it, SharePoint returns HTTP 412 Precondition Failed.

Leave the Body empty.

SharePoint Behavior and Recycle Bin Recovery

The REST API supports both permanent deletion and recycle bin routing depending on the endpoint used.

Using the standard delete endpoint bypasses the normal recycle-bin-first behavior and permanently deletes the item. Using the /recycle() endpoint routes the item through SharePoint’s recycle bin lifecycle instead.

Microsoft Purview retention policies or other compliance configurations can override either behavior depending on tenant governance settings. If deletion behavior is compliance-sensitive, verify the actual outcome in your environment rather than assuming the API endpoint alone determines retention.

Performance and Throttling

The REST API does not significantly improve throughput compared to the Delete item action because each deletion still requires an individual HTTP request.

Its primary advantage is control. You gain direct access to request and response details, which simplifies custom logging and error handling.

For example, to log failures, add a Compose action after the HTTP request and capture:

outputs('Send_an_HTTP_request_to_SharePoint')?['statusCode']

Method 3: Bulk Deletion Using the SharePoint Batch API

The SharePoint Batch API allows multiple operations to be sent in a single HTTP request. Instead of one request per item, a single batch can contain many delete operations grouped together.

The primary advantage is reduced request pressure. SharePoint processes the batched operations internally after receiving a single HTTP request, significantly reducing network round trips and request overhead.

The trade-off is complexity. Batch formatting is strict, debugging is harder, and failures must be validated from the response body rather than the HTTP status code alone.

Important Batch API Behaviors

Before implementing batch deletion, several operational characteristics are important to understand:

These behaviors make the Batch API powerful, but also significantly less forgiving than the other deletion methods.

Implementation

The flow structure still begins with a trigger, Get items, and a processing loop.

The key difference is that the loop builds batches of delete operations rather than issuing one request per item.

Screenshot of the overall flow using the SharePoint Batch API deletion method in Power Automate.
Power Automate: Overall Flow Using the Batch API Deletion Method

Step 1: Initialize Flow Variables

Add four Initialize variable actions:

The batch size controls how many delete operations are included in each batch request. The final batch may contain fewer items if the remaining item count is smaller than the configured size.

A batch size of 250 is a stable starting point for most environments. Larger batches reduce request overhead further but increase debugging difficulty if failures occur.

Step 2: Retrieve SharePoint List Items

Add a Get items action to retrieve the items from the SharePoint list.

Step 3: Add a Do Until Loop

Power Automate does not have a native chunk or slice action, so processing the Get items results in batches requires index-based slicing inside a Do until loop.

Add a Do until control. Set the Loop until condition to:

@{greaterOrEquals(variables('iBatchOffset'), length(outputs('Get_items')?['body/value']))}

Each iteration processes the next chunk of items until the entire result set has been covered.

If Get items returns an empty result set, body/value will be an empty array and length() will return 0. The loop exits immediately without error.

Screenshot of the Do Until loop parameters in Power Automate.
Power Automate: Do Until Loop Parameters
Important Do Until Settings

By default, a Do until loop stops after:

These defaults can become a problem for high-volume batch deletion flows.

For example, a batch size of 250 with 20000 items requires 80 loop iterations.

Without adjusting the loop settings, the flow would terminate before completing the full dataset.

Open the Do until Parameters panel and adjust Count and Timeout based on your expected volume and execution time.

Step 4: Generate GUIDs

Each batch request requires two unique identifiers: one for the outer batch boundary and one for the inner changeset boundary.

Generate fresh GUIDs at the start of each loop iteration.

Inside the loop, add two Set variable actions:

Using a new GUID per iteration ensures that batch responses can be correlated to their source iteration during debugging. Reusing GUIDs across iterations can cause parsing failures or make it difficult to identify which iteration produced a given response.

Step 5: Build the Batch Payload

Each item in the batch body must be wrapped in changeset boundaries.

Add a Compose action and enter the following in the Inputs field:

--changeset_@{variables('strChangesetGUID')}
Content-Type: application/http
Content-Transfer-Encoding: binary

DELETE https://YourSharePoint/sites/YourSite/_api/web/lists/GetByTitle('YourListName')/items(#ID#) HTTP/1.1
IF-MATCH: *

Replace YourSharePoint, YourSite, and YourListName with your actual values.

NOTE: The SharePoint $batch endpoint is strict about formatting. The blank line after IF-MATCH: * is required by the multipart MIME format. Missing it is one of the most common causes of batch failures.

To route deletions to the recycle bin instead of permanently deleting items, use:

DELETE https://YourSharePoint/sites/YourSite/_api/web/lists/GetByTitle('YourListName')/items(#ID#)/recycle() HTTP/1.1
Screenshot of the Compose batch body parameters in Power Automate.
Power Automate: Compose Batch Body Parameters
Build Delete Blocks Using Select

Next, add a Select action and switch to Text Mode.

In the From field, enter the following expression:

take(skip(outputs('Get_items')?['body/value'],variables('iBatchOffset')),variables('iBatchSize'))

This expression slices the Get items result set starting at the current offset and taking up to the configured batch size.

In the Map field, enter the following expression:

replace(outputs('Compose'),'#ID#',string(item()?['ID']))

The Map expression runs once per item in the slice. outputs('Compose') pulls in the full delete block template built above. string(item()?['ID']) extracts the SharePoint item ID from the current element and converts it to a string, which replace() requires on both sides. #ID# was chosen as the placeholder specifically because it won’t appear anywhere else in the template, making the substitution unambiguous. The result is one fully formatted delete block per item with the real item ID in place.

Screenshot of the Select action parameters in Power Automate.
Power Automate: Select Action Parameters
Why Select Is Used Instead of Apply to Each

Using Select here is important. It allows the flow to build all delete operation blocks in-memory as a single array transformation rather than executing one HTTP request per item inside Apply to each, which would largely eliminate the throughput advantage of batching.

The result is one fully formatted delete block per item.

Example:

--changeset_<guid>
Content-Type: application/http
Content-Transfer-Encoding: binary

DELETE https://YourSharePoint/sites/YourSite/_api/web/lists/GetByTitle('YourListName')/items(42) HTTP/1.1
IF-MATCH: *
Join the Delete Blocks

Now, add a Join action to the loop.

In the From field, enter the expression:

body('Select')

In the Join with field, enter the expression:

decodeUriComponent('%0A')

This concatenates all generated delete blocks into the single string that will be inserted into the batch body.

NOTE: The batch endpoint expects CRLF (\r\n) line endings per the OData specification. In practice, SharePoint Online usually accepts LF (\n) line endings as used here. However, if you encounter persistent formatting-related failures, switching the Join delimiter to decodeUriComponent('%0D%0A') is a good first troubleshooting step.

Screenshot of the Join action parameters in Power Automate.
Power Automate: Join Action Parameters

Step 6: Send the Batch Request

Add a Send an HTTP request to SharePoint action.

Under Advanced parameters, add Headers and Body.

In the Headers section, add two headers:

X-RequestDigest: digest

The value digest is a literal string recognized by the Send an HTTP request to SharePoint connector. The connector replaces it automatically with a valid request digest at runtime. You do not need to retrieve or supply a digest value manually.

Content-Type: multipart/mixed; boundary=batch_@{variables('strBatchGUID')}

In the Body field, enter:

--batch_@{variables('strBatchGUID')}
Content-Type: multipart/mixed; boundary="changeset_@{variables('strChangesetGUID')}"

@{body('Join')}
--changeset_@{variables('strChangesetGUID')}--
--batch_@{variables('strBatchGUID')}--

The boundary names in the Content-Type header must exactly match the boundary markers used in the body.

Screenshot of the Send an HTTP Request to SharePoint action parameters for the Batch API in Power Automate.
Power Automate: Send an HTTP Request to SharePoint Action Parameters for the Batch API

Step 7: Validate the Batch Response

The batch endpoint itself returns HTTP 200 regardless of whether individual operations succeeded.

Successful delete operations return HTTP 204 within the multipart response body. Failed operations typically return HTTP 500 responses embedded inside the same response payload.

Common causes include:

Add a Compose action (named Compose Response) after the Send an HTTP request to SharePoint action to capture the response body:

body('Send_an_HTTP_request_to_SharePoint')

Then add a Condition to check for failures:

contains(outputs('Compose_Response'), '500')

If true, terminate the flow or log the failure based on your requirements.

Without explicit response validation, Power Automate run history may report the flow as successful even when many operations failed internally.

Step 8: Increment the Offset

Add an Increment variable action at the end of the loop.

In the Name field, select the variable iBatchOffset.

In the Value field, enter the expression:

variables('iBatchSize')

This advances the offset by the batch size, setting the starting position for the next iteration.

Screenshot of the Increment Variable action parameters in Power Automate.
Power Automate: Increment Variable Action Parameters

SharePoint Behavior and Recycle Bin Recovery

Like the REST API, the Batch API supports either permanent deletion or recycle bin routing depending on the endpoint used inside the batch operations.

Compliance policies can override either behavior at the tenant level.

Performance and Throttling

The Batch API’s main advantage is throughput efficiency.

Instead of issuing hundreds or thousands of sequential requests, Power Automate submits relatively few batch requests while SharePoint processes the batched operations internally.

In practice, a batch containing many delete operations often completes only marginally slower than a single-item request because the network overhead is significantly reduced.

This substantially lowers throttling pressure compared to issuing one request per item. However, very large batch operations against heavily used lists can still encounter SharePoint service limits.

Troubleshooting and Edge Cases

Partial Completion

The flow reports success but only some items are deleted.

This commonly happens when Get items retrieves fewer items than expected due to pagination limits or Top Count settings. Verify how many records were actually retrieved before deletion begins.

Batch Formatting Failures

If the entire batch request fails, the issue is usually formatting-related:

If necessary, switch the Join delimiter as follows to force CRLF line endings:

decodeUriComponent('%0D%0A')

Items Remain After a Successful Run

This is often caused by:

If the filtered column is not indexed and the list exceeds 5,000 items, Get items may fail or return incomplete results.

HTTP 429 Errors Causing Timeouts

Power Automate automatically retries HTTP 429 responses, but repeated retry delays can eventually push a long-running flow past its maximum execution window.

Possible mitigations include:

Advanced flows using HTTP actions may also benefit from customized retry policies rather than relying solely on default retry behavior.

Concurrent Flow Runs

If recurrence triggers overlap, multiple flow instances may attempt to delete the same items simultaneously.

This commonly produces batch-level HTTP 500 responses for items already removed by another run.

For high-volume deletion flows, consider implementing a lock mechanism or restricting the flow to a single concurrent run.

Summary

The deletion method that works perfectly in development is often the wrong one in production.

At small scale, almost any approach succeeds. At higher volume, request pressure, throttling behavior, recovery requirements, and failure visibility become architectural concerns rather than implementation details.

The Delete item action remains the safest and simplest option when recoverability matters. The REST API provides more direct HTTP-level control and clearer logging opportunities. The Batch API becomes the strongest option once request volume itself becomes the bottleneck, but it requires explicit response validation and much stricter implementation discipline.

Understanding how these methods behave under load is what separates a flow that merely works from one that remains reliable in production over time.