Skip to content

Move a file or folder

moveItem

POST /api/v1/shares/{share_id}/move

Scope: files.moveRate cost: 5

Move a file or a folder (with everything in it) to another folder, in the same share or in another of the person’s shares (to_share), keeping its name or giving it a new one

to_path is its full new path; the folder it goes in must exist. Something already there is never replaced (on_conflict “fail”: 409; “rename”: the first free name, so read the answer’s path). Send If-Match with the item’s ETag as you last read it (428 without, 412 stale). Needs files.move, allowed for your app on this share (and, for another share, on that one too). Refused for anything checked out by someone else (423), under a legal hold (403), published (409 published: an app never moves a published file, or a folder holding one), or the document of a signing still out (409), and for a folder of more than 1,000 items (409 folder-too-large). A folder counts every item in it against your app’s daily allowance. Within a share the storage moves it in one step. To another share it is copied, the copy proven whole, and only then is the original removed: refused for a file a label keeps in its share (403 download-blocked), and for a folder nested more than 64 deep. A small file is moved in the request (200, the item at its new place). A folder, a file whose source or destination is in Microsoft 365, a file over 64 MiB, or any move to another share sent with Prefer: respond-async, is moved by Foldr afterwards: answered 202 with an operation (kind move) to poll at its Location (getOperation): it copies every item first and removes the originals only once the whole copy is proven; cancelled while copying, its partial copy is removed and the original left as it was; once it is removing the originals it is too late to cancel. If the copy is whole but an original could not be removed, the move ends 409 source-remains: the item is in both places, nothing is lost, and the answer says where. Send an Idempotency-Key: the same request sent again with it answers the first answer (for a move made afterwards, the same operation) and moves nothing more. 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.

Terminal window
curl -X POST "$FOLDR/api/v1/shares/$SHARE_ID/move" \
-H "Authorization: Bearer $TOKEN" \
-H "If-Match: $ETAG" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"path":"string","to_path":"string"}'

$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.
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 (for a move made afterwards, the same operation) and moves nothing more; later, an operation still under way is answered 202 again and a finished one its final answer (200 with the item, or the problem it ended with); with a different request it is refused (422).
PreferheaderstringNorespond-async: for a move to another share, move it afterwards and answer 202 with an operation, whatever the size (Preference-Applied says it was). Without it, small files are moved in the request. A move within a share is always made in the request.

application/json, required: MoveBody

FieldTypeDescription
pathstringRequired. The path of the file or folder to move.
to_pathstringRequired. Its full new path, its name last (the same name, or a new one), in the same share or in to_share. The folder it goes in must exist.
to_sharestring or null (uuid)The id of the share it goes to, when that is another share; absent (or this share’s id) moves it within this share.
on_conflictstring, one of fail, renameWhat to do when something is already called that: “fail” (the default) answers 409 conflict; “rename” gives it the first free name (“Q3 copy.xlsx”). Nothing is ever replaced.

Example:

{
"path": "string",
"to_path": "string"
}
StatusMeaningBody
200The item, at its new canonical path.application/json: Item
202A move to another share Foldr will make, or any move held for an approver (state pending_approval): the operation. Poll its Location after Retry-After seconds.application/json: Operation
HeaderDescription
ETagThe entity tag of what was answered. Send it back as If-None-Match for a 304 while it is unchanged, or as If-Match to change it only while it is unchanged.

Item:

FieldTypeDescription
share_idstring (uuid)Required. The id of the share the item is in.
pathstringRequired. The canonical path: as the storage holds it (its case), Unicode NFC, always starting with ”/”. ”/” is the top of the share. Send this form back in later calls.
namestringRequired. The item’s name (the last segment of its path; the share’s name for the top).
kindstring, one of file, folderRequired. file or folder.
sizeinteger or nullRequired. Size in bytes; null for a folder, and null when the item has no fixed byte size (a native Google document, exported on download: see export).
modifiedstring or null (date-time)Required. Last modified (RFC 3339, UTC), where the storage reports it.
mime_typestring or nullRequired. The item’s own media type, as the storage reports it or guessed from the name; null for a folder. A native Google document has Google’s own type here (application/vnd.google-apps.document for a Doc); export says what it downloads as.
exportExport or nullRequired. For a native Google document that can be downloaded, what content delivers: its media type and the extension the download is named with. Null for everything else, including a native Google type that cannot be downloaded (a Form: content answers 409 not-downloadable).
etagstring or nullRequired. The item’s entity tag: the storage’s own where it has one, else a weak tag over size and modified time (over modified time alone for a native Google document, whose export is made afresh each time). Null on a search hit, which comes from the index; GET …/item for the live one.
read_onlybooleanRequired. True when the person cannot change things in this share.
checked_outCheckout or nullRequired. Who has the item checked out, or null. Null on a search hit.

Example:

{
"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"
}
}
HeaderDescription
LocationWhere to poll the operation: GET it until it answers anything but 202.
Preference-Appliedrespond-async: sent when the request’s Prefer: respond-async is why this is an operation rather than an answer in the request (RFC 7240). Absent when Foldr chose the operation itself (a folder, a large file, Microsoft 365).
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
move-into-itself
One of: Invalid path (invalid-path); Invalid request (invalid-request); Move into itself (move-into-itself).
401invalid-tokenInvalid token (invalid-token).
403change-declined
download-blocked
insufficient-scope
legal-hold
write-not-allowed
One of: Change declined (change-declined); Download blocked (download-blocked); Insufficient scope (insufficient-scope); Legal hold (legal-hold); Not allowed for this app (write-not-allowed).
404not-foundNot found (not-found).
409ambiguous-path
approved-version-unavailable
change-expired
conflict
envelope-source
folder-too-large
no-approver
not-a-folder
operation-cancelled
published
requester-not-connected
source-remains
storage-account-not-connected
One of: Ambiguous path (ambiguous-path); Approved version unavailable (approved-version-unavailable); Change not approved in time (change-expired); Conflict (conflict); Out for signature (envelope-source); Folder too large (folder-too-large); No approver (no-approver); Not a folder (not-a-folder); Operation cancelled (operation-cancelled); Published (published); Not connected when approved (requester-not-connected); Moved, but the original remains (source-remains); 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).
413copy-too-large
too-large
One of: Copy too large (copy-too-large); Too large (too-large).
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).
503copy-interrupted
share-unavailable
share-unreachable
write-failed
One of: Copy interrupted (copy-interrupted); Share unavailable (share-unavailable); Share unreachable (share-unreachable); Write failed (write-failed).