Skip to content

Delete a file or folder

deleteItem

DELETE /api/v1/shares/{share_id}/items

Scope: files.deleteRate cost: 5

Delete a file, or a folder with everything in it (at most 1,000 items: 409 folder-too-large beyond that)

Send If-Match with the item’s ETag as you last read it (428 without, 412 stale). Needs files.delete, allowed for your app on this share. Refused for anything checked out by someone else (423), under a legal hold (403), published (409 published), or the document of a signing still out (409). Where the share’s storage keeps no bin an administrator may refuse apps deletions there (409 not-recoverable-here). Answers 200 with what was deleted and where its storage keeps it now (recoverable, destination, where), so you can tell your user whether it can be brought back; a folder counts every item in it against your app’s daily allowance. Send an Idempotency-Key: the same request sent again with it answers the first answer. For an app whose administrator requires approval for its changes, it is not made at once: once every check has passed (and the items are counted against the allowance) it is answered 202 with an operation in state pending_approval, held for someone other than the person to approve in Foldr, then made as the person; poll it at its Location (getOperation). Refused 409 no-approver when nobody else could approve it. Once approved and made, the operation’s deletion says what was deleted and where it is now.

Terminal window
curl -X DELETE "$FOLDR/api/v1/shares/$SHARE_ID/items?path=%2FReports%2Fq3.pdf" \
-H "Authorization: Bearer $TOKEN" \
-H "If-Match: $ETAG" \
-H "Idempotency-Key: $(uuidgen)"

$FOLDR is your site’s address (for example https://files.example.com) and $TOKEN is an access token. See Getting access.

NameInTypeRequiredDescription
share_idpathstringYesThe share’s id.
pathquerystringYesThe path of the file or folder to delete. The top of a share cannot be deleted.
If-MatchheaderstringYesThe item’s ETag as you last read it. ”*” is refused.
Idempotency-KeyheaderstringYesA value of your own, 1 to 255 visible ASCII characters, new for each new request. The same key with the same request within 24 hours answers the first answer again (what was deleted) and deletes nothing more; with a different request it is refused (422).
StatusMeaningBody
200What was deleted, and where it is now.application/json: Deletion
202Held for an approver (the app’s administrator requires approval for its changes): the operation, state pending_approval. Poll its Location after Retry-After seconds.application/json: Operation

Deletion:

FieldTypeDescription
deletedItemRequired. The item that was deleted, as it was (its path names nothing now).
itemsintegerRequired. How many files and folders went: 1 for a file; a folder and everything in it.
recoverablestring, one of bin, snapshot, noneRequired. “bin”: the storage keeps it in a recycle bin, a trash or its earlier versions, so it can be brought back there; “snapshot”: only the server’s shadow copies hold it, as of the last one; “none”: as far as Foldr can tell it is gone for good.
destinationstring or nullRequired. Where it is, as a stable name: microsoft-365-recycle-bin, google-drive-trash, box-trash, dropbox-deleted-files, foldr-deleted-files, bucket-versions, azure-soft-delete, shadow-copies, shadow-copies-if-enabled, or unknown (Foldr cannot tell whether this storage keeps deleted items). Null where it is certainly gone.
wherestring or nullRequired. The same, in words for a person (“the Microsoft 365 recycle bin”). Bins belong to the share’s storage account, not the person: getting something back is usually for whoever manages it.

Example:

{
"deleted": {
"share_id": "0191f2c4-8a1e-7b52-9d3a-5c1e0b7a4d21",
"path": "string",
"name": "string",
"kind": "file",
"size": 1,
"modified": "2026-11-04T09:30:00Z",
"mime_type": "string",
"export": {},
"etag": "string",
"read_only": false,
"checked_out": {}
},
"items": 1,
"recoverable": "bin",
"destination": "string",
"where": "string"
}
HeaderDescription
LocationWhere to poll the operation: GET it until it answers anything but 202.
Retry-AfterSeconds to wait before polling again.

Operation:

FieldTypeDescription
idstring (uuid)Required. The operation’s id.
kindstringRequired. What it does: copy, move (to another share, or held for approval within one), delete or restore (a version restore). delete and restore are only ever operations held for approval. Known values: copy, move, delete, restore. Clients must accept values not listed here.
statestring, one of pending_approval, queued, running, cancelling, succeeded, failed, cancelled, declined, expiredRequired. Where it has got to. pending_approval: held for an approver, nothing changed yet (approval says until when); queued: waiting to start; running: under way; cancelling: asked to stop, stopping at its next item; succeeded: done, result is what was made; failed: ended with the problem getOperation answers; cancelled: stopped, and what it had made removed (or, held for approval, withdrawn, nothing changed); declined: an approver said no, nothing changed; expired: nobody approved it in time, nothing changed.
phasestring or nullRequired. A move’s phase: copying (every item is copied first; nothing has been removed from where it was, and a cancel removes the partial copy), then deleting (the copy is whole and proven, and the originals are being removed: too late to cancel). Null for a copy. Known values: copying, deleting. Clients must accept values not listed here.
created_atstring (date-time)Required. When it was asked for (RFC 3339, UTC).
started_atstring or null (date-time)Required. When a worker first started it; null while queued.
finished_atstring or null (date-time)Required. When it finished; null until then.
sourceOperationSourceRequired. What is being copied, moved, deleted or restored.
targetOperationTarget or nullRequired. Where it was asked to go: the path asked for. result.path is where it landed (on_conflict “rename” may have given it another name). Null for a delete or a restore.
version_idstring or nullRequired. For a restore: the version asked for (one of listVersions’ ids). Null otherwise.
progressOperationProgressRequired. How far it has got.
resultItem or nullRequired. Once it has succeeded, what it made (the copy, the moved item at its new place, the restored file), at its canonical path; null until then, and for a delete (see deletion). A move that ended source-remains also has it: the whole copy it made.
deletionDeletion or nullRequired. A delete held for approval, once it has succeeded: what was deleted and where its storage keeps it now, as deleteItem answers. Null otherwise.
approvalOperationApproval or nullRequired. For an operation held for an approver: how its approval stands. Null for one that never waited for approval.
failuresarray of OperationFailureRequired. At most 100 items (failures_truncated says when there were more): for a copy that ended copy-incomplete, those it could not copy; for a move that ended source-remains, those still at the source. Empty otherwise.
failures_truncatedbooleanRequired. True when more items failed than failures lists.

Example:

{
"id": "0191f2c4-8a1e-7b52-9d3a-5c1e0b7a4d21",
"kind": "string",
"state": "pending_approval",
"phase": "string",
"created_at": "2026-11-04T09:30:00Z",
"started_at": "2026-11-04T09:30:00Z",
"finished_at": "2026-11-04T09:30:00Z",
"source": {
"share_id": "0191f2c4-8a1e-7b52-9d3a-5c1e0b7a4d21",
"path": "string",
"kind": "file"
},
"target": {
"share_id": "0191f2c4-8a1e-7b52-9d3a-5c1e0b7a4d21",
"path": "string"
},
"version_id": "string",
"progress": {
"items_done": 1,
"items_total": 1,
"bytes_done": 1,
"bytes_total": 1
},
"result": {
"share_id": "0191f2c4-8a1e-7b52-9d3a-5c1e0b7a4d21",
"path": "string",
"name": "string",
"kind": "file",
"size": 1,
"modified": "2026-11-04T09:30:00Z",
"mime_type": "string",
"export": {
"mime_type": "string",
"extension": "string"
},
"etag": "string",
"read_only": false,
"checked_out": {
"by": {},
"since": "2026-11-04T09:30:00Z"
}
},
"deletion": {
"deleted": {},
"items": 1,
"recoverable": "bin",
"destination": "string",
"where": "string"
},
"approval": {
"status": "string",
"expires_at": "2026-11-04T09:30:00Z",
"decided_at": "2026-11-04T09:30:00Z"
},
"failures": [
{
"path": "string",
"code": "string"
}
],
"failures_truncated": false
}

Every error is an application/problem+json document (ProblemDetails); branch on its type or code. See Errors.

StatusProblem typesWhen
400invalid-path
invalid-request
One of: Invalid path (invalid-path); Invalid request (invalid-request).
401invalid-tokenInvalid token (invalid-token).
403change-declined
insufficient-scope
legal-hold
write-not-allowed
One of: Change declined (change-declined); Insufficient scope (insufficient-scope); Legal hold (legal-hold); Not allowed for this app (write-not-allowed).
404not-foundNot found (not-found).
409ambiguous-path
change-expired
envelope-source
folder-too-large
no-approver
not-recoverable-here
operation-cancelled
published
requester-not-connected
storage-account-not-connected
One of: Ambiguous path (ambiguous-path); Change not approved in time (change-expired); Out for signature (envelope-source); Folder too large (folder-too-large); No approver (no-approver); Not recoverable here (not-recoverable-here); Operation cancelled (operation-cancelled); Published (published); Not connected when approved (requester-not-connected); Storage account not connected (storage-account-not-connected).
412changed-since-requested
precondition-failed
One of: Changed since requested (changed-since-requested); Precondition failed (precondition-failed).
422idempotency-key-reusedIdempotency key reused (idempotency-key-reused).
423checked-outChecked out (checked-out).
428precondition-requiredPrecondition required (precondition-required).
429destructive-budget
rate-limited
One of: Daily limit of removals reached (destructive-budget); Too many requests (rate-limited).
500internal-errorInternal error (internal-error).
503share-unavailable
share-unreachable
write-failed
One of: Share unavailable (share-unavailable); Share unreachable (share-unreachable); Write failed (write-failed).