> For the complete documentation index, see [llms.txt](https://documentation.dnanexus.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://documentation.dnanexus.com/developer/api/data-containers/folders-and-deletion.md).

# Folders and Deletion

Data containers organize objects into folders. Each data object or folder can exist within one parent folder, and the system prevents circular references. The root folder, identified by the path `/`, serves as the default location for new objects and cannot be moved, cloned, or removed.

The system treats consecutive `/` characters as a single `/` and ignores trailing `/` characters in folder paths. You can rename, move, and remove folders as needed.

## Folder Naming Requirements

Individual **folder names** have the following requirements:

* Must contain between 1 and 2,048 characters in UTF-8 encoding.
* Cannot be `.` or `..`.
* Cannot include [control characters](https://en.wikipedia.org/wiki/Control_character#In_ASCII) (matching the regular expression `[\x00-\x1F]`).

Complete **folder paths** have the following requirements:

* Must be under 10,240 characters total.
* Cannot exceed 128 nested folder levels. That is the root folder `/` with up to 128 subfolders.

## Deletion of Data

When you remove data objects, the system automatically removes any hidden linked objects that can no longer be reached from other visible objects in the same data container through one or more links. For detailed information about object details, links, and visibility, see [Details and Links](/developer/api/data-object-lifecycle/details-and-links.md) and [Visibility](/developer/api/data-object-lifecycle/visibility.md).

You can remove objects in any state. Unless the project has [data retention](#recycle-bin) turned on, removal cannot be undone. Removing open objects may cause additional effects, such as making upload URLs invalid. To remove objects, use either the [`/class-xxxx/removeFolder`](#api-method-class-xxxx-removefolder) or [`/class-xxxx/removeObjects`](#api-method-class-xxxx-removeobjects) API methods.

## Recycle Bin

{% hint style="info" %}
A license is required to use data retention. [Contact DNAnexus Sales](mailto:sales@dnanexus.com) for more information.
{% endhint %}

When a project has data retention turned on, `/class-xxxx/removeObjects` and `/class-xxxx/removeFolder` move data objects into the project's recycle bin. Objects in the recycle bin can be recovered until their retention period ends, after which they are permanently deleted. Data retention applies only to projects. Removing objects from containers that are not projects, such as job workspaces, is always permanent.

{% hint style="success" %}
For how data retention works in the UI, see [Data Retention](/user/objects/data-retention.md).
{% endhint %}

The project's `deletionRetentionEnabled` flag, set with [`/project/new`](/developer/api/data-containers/projects.md#api-method-project-new) or [`/project-xxxx/update`](/developer/api/data-containers/projects.md#api-method-project-xxxx-update), turns data retention on, and the billing org's `deletionRetentionPeriod` and `deletionRetentionEnforced` [org policies](/developer/api/organizations.md#org-policies) set the retention period and whether data retention is enforced.

Each project with data retention turned on has a recycle bin at the reserved path `/.recycle_bin`. Every deleted object is stored directly in the recycle bin, regardless of the folder it was deleted from. The recycle bin does not appear in [`/class-xxxx/listFolder`](#api-method-class-xxxx-listfolder) output or in the `folders` field of project describe output. To list its contents, use [`/project-xxxx/listRecycleBin`](/developer/api/data-containers/projects.md#api-method-project-xxxx-listrecyclebin).

Objects in the recycle bin cannot be described, downloaded, modified, or used as execution inputs, and they do not appear in [`/system/findDataObjects`](/developer/api/search.md#api-method-system-finddataobjects) results. Requests that reference them return `ResourceNotFound`. Objects in the recycle bin count towards the project's storage until they are permanently deleted.

### Recycle Bin Metadata

When an object moves into the recycle bin, the platform records the following metadata on it:

* `deletedAt` - The time the object was deleted.
* `purgeAt` - The time after which the object is permanently deleted, calculated from the billing org's `deletionRetentionPeriod` at deletion time. Later changes to the policy do not affect objects already in the recycle bin.
* `previousFolder` - The folder the object was deleted from. Recovery restores the object to this folder.

After `purgeAt`, an object can no longer be recovered, and it no longer appears in `/project-xxxx/listRecycleBin` output.

### Removing Objects with Data Retention

Data retention changes how `/class-xxxx/removeObjects` and `/class-xxxx/removeFolder` behave:

* Hidden linked objects that the removal orphans move into the recycle bin with the objects that linked to them.
* `/class-xxxx/removeFolder` removes the folders themselves. Only the data objects they contain move to the recycle bin.
* A single call can move at most 10,000 objects, counting hidden linked objects.
* Objects removed with `overrideProjectAccess` also move to the recycle bin.

Purging a retained object permanently removes that project's link to the object. Other copies in other containers remain unaffected. The underlying file data is permanently deleted from platform storage only when the purged object is the last remaining link. For more information about how data objects and copies share platform data, see [Platform IDs and Data Objects in Projects](/user/platform-ids.md#platform-ids-and-data-objects-in-projects), [Data Containers](/developer/api/data-containers.md#data-containers), and [Cloning](/developer/api/data-containers/cloning.md).

To restore objects from the recycle bin, use [`/project-xxxx/recoverObjects`](/developer/api/data-containers/projects.md#api-method-project-xxxx-recoverobjects). To purge them before their `purgeAt` time, use [`/project-xxxx/purgeRecycleBinObjects`](/developer/api/data-containers/projects.md#api-method-project-xxxx-purgerecyclebinobjects).

### Operations That Require an Empty Recycle Bin

The following operations fail with `InvalidState` while the project's recycle bin is not empty:

* Changing the project's `billTo` with `/project-xxxx/update`.
* Transferring the project with [`/project-xxxx/transfer`](/developer/api/data-containers/project-permissions-and-sharing.md#api-method-project-xxxx-transfer) or [`/project-xxxx/acceptTransfer`](/developer/api/data-containers/project-permissions-and-sharing.md#api-method-project-xxxx-accepttransfer).
* Setting `deletionRetentionEnabled` to `false` with `/project-xxxx/update`.
* Destroying the project with [`/project-xxxx/destroy`](/developer/api/data-containers/projects.md#api-method-project-xxxx-destroy).

To run these operations, first recover or purge the recycle bin contents. When the recycle bin holds only objects past their `purgeAt` time, these operations fail until the system permanently deletes those objects.

Cloning an object into a project whose recycle bin holds a copy of that object also fails with `InvalidState`. For details, see [`/class-xxxx/clone`](/developer/api/data-containers/cloning.md#api-method-class-xxxx-clone).

## API Methods

### API method: `/class-xxxx/newFolder`

#### Specification

Creates a new folder in the data container using the given path.

#### Inputs

* `folder` **string** (required) The new folder to be created in the data container. Must meet the [folder naming requirements](#folder-naming-requirements).
* `parents` **boolean** (optional) Whether to create the parent folders if they do not exist. Defaults to `false`.

#### Outputs

* `id` **string** ID of the manipulated data container.

#### Errors

* `InvalidInput`
  * The input is not a hash.
  * `folder` is missing or is not a nonempty string starting with "/".
  * `parents` is present but is not a boolean.
* `ResourceNotFound`
  * The specified data container does not exist.
  * `parents` is false but the parent folder of the folder specified in `folder` does not yet exist.
* `InvalidState`
  * A folder with the given path already exists and `parents` was not set to true.
  * `folder` is `/.recycle_bin` or a path beneath it. This path is reserved for the [recycle bin](#recycle-bin).
* `PermissionDenied`
  * UPLOAD access is required.

### API method: `/class-xxxx/renameFolder`

#### Specification

Renames a current folder in the data container with the given name.

#### Inputs

* `folder` **string** (required) Folder to be renamed.
* `name` **string** (required) The new name of the folder (to replace the string after the last "/" in `folder`). Must meet the [folder naming requirements](#folder-naming-requirements).

#### Outputs

* `id` **string** ID of the manipulated data container.

#### Errors

* `InvalidInput`
  * The input is not a hash.
  * `folder` is missing or is not a nonempty string starting with "/".
  * `folder` is "/".
  * `name` is missing or is not a nonempty string with no "/".
* `ResourceNotFound`
  * The specified data container does not exist.
  * The specified folder does not exist.
* `InvalidState`
  * A folder with the given path already exists.
  * `folder` is `/.recycle_bin` or a path beneath it. This path is reserved for the [recycle bin](#recycle-bin).
* `PermissionDenied`
  * CONTRIBUTE access is required.

### API method: `/class-xxxx/listFolder`

#### Specification

Lists the contents of a given data container's folder. Only folders or only objects can be specified to be returned, though this method returns both folders and objects by default. This method does not return hidden objects unless `includeHidden` is set to true.

#### Inputs

* `folder` **string** (optional) The folder to be listed. Defaults to `"/"`.
* `describe` **boolean or mapping** (optional) Controls whether additional metadata is retrieved with data object results. Defaults to `false`. If `true`, equivalent to passing an empty mapping.
  * If a **mapping**, represents input used when calling the result's corresponding describe method.
* `only` **string** (optional) Indicates what type of contents to return. Defaults to `"all"`.
  * Must be one of `"folders"`, `"objects"`, or `"all"`.
* `includeHidden` **boolean** (optional) Whether to return hidden objects in `objects`. Applicable only if `only` is set to `"objects"` or `"all"`. Defaults to `false`.
* `hasSubfolderFlags` **boolean** (optional) Whether to include subfolder flags in the output. Defaults to `false`.

#### Outputs

* `objects` **array of mappings** List of metadata for all data objects in the specified folder. Each mapping contains:
  * `id` **string** The object ID.
  * `describe` **mapping** The output of the result's corresponding describe method.
    * Only present when `describe` was set in the input.
* `folders` **array of strings** or **array of arrays** List of all folders directly under the specified folder.
  * If `hasSubfolderFlags` is `false` (default), an array of folder name strings.
  * If `hasSubfolderFlags` is `true`, each element is a two-element array containing the folder name (string) and whether it has subfolders (boolean).

#### Errors

* `InvalidInput`
  * The input is not a hash.
  * `folder` is not a nonempty string starting with "/".
  * `only` is given but is not one of "folders", "objects", and "all".
  * `includeHidden` is present but is not a boolean.
* `ResourceNotFound`
  * The specified data container does not exist.
  * A folder with the given path does not exist.
* `PermissionDenied`
  * VIEW access is required.

### API method: `/class-xxxx/removeFolder`

#### Specification

Removes the given folder in the data container using the given path. The folder must contain no visible data objects to be removed unless `recurse` is set to true. Removing the root folder "/" with `recurse` set to true removes **ALL** the contents in the data container. Use `recurse=true` with caution to prevent accidental deletion of data. Removing a folder removes all the visible objects contained in it and all their orphaned hidden links. Any remaining hidden objects that are not removed by this process are placed in the root folder. In particular, if `recurse` is false and the folder to be removed only contains hidden objects, then these objects are similarly placed in the root folder, and the specified folder `folder` is removed.

The API call has a limit of 10,000 data objects that can be removed regardless of visibility. If a folder's contents go above this threshold, one can set `partial` to true to allow for a partial removal of the folder's contents up to this limit. A `completed` flag in the output indicates whether the folder was fully removed. If `completed` is false, reissue the API call with the `partial` flag to continue removing the folder.

When the project has [data retention](#recycle-bin) turned on, this method moves the contained data objects into the project's recycle bin and removes the folders.

#### Inputs

* `folder` **string** (required) The folder to be removed from the data container.
* `recurse` **boolean** (optional) Whether to propagate the folder removal to its contained subfolders and objects. Defaults to `false`.
* `force` **boolean** (optional) If `true`, this operation does not throw an error even if the given folder does not exist. Defaults to `false`.
* `partial` **boolean** (optional) If `true`, this operation attempts to remove objects from the folder even if the folder contains more objects than can be deleted at one time. Defaults to `false`.

#### Outputs

* `id` **string** ID of the manipulated data container.
* `completed` **boolean** Whether all objects, subfolders, and the specified folder have been removed. If `false`, reissue the API call to continue removal.
  * Only present when `partial` was set to `true`.

#### Errors

* `InvalidInput`
  * The input is not a hash.
  * `folder` is missing.
  * `folder` is not set to a nonempty string starting with "/".
  * `folder` is set to "/" but `recurse` is not specified or is false.
  * `recurse` is provided and is not a boolean.
* `ResourceNotFound`
  * The specified data container does not exist.
  * A folder with the given path does not exist and `force` was not set to true.
* `PermissionDenied`
  * CONTRIBUTE access is required.
* `InvalidState`
  * The project contains a DBCluster in a non-terminal state.
  * `recurse` is false and the specified folder contains either subfolders or visible objects.
  * `partial` is false and the specified folder contains more objects than can be deleted in one API call. For more information, see [Service Limits](/developer/api/service-limits.md).
  * `folder` is `/.recycle_bin` or a path beneath it. This path is reserved for the [recycle bin](#recycle-bin).
  * The project has data retention turned on, and the folder contains more than 10,000 objects, counting hidden linked objects. To remove the folder, remove its subfolders first.

### API method: `/class-xxxx/move`

#### Specification

Moves the specified objects or folders into the specified folder. Objects and folders can be moved from any state and any folder in the data container. Objects and folders in a folder listed in `folders` remain in the (moved) folder unless explicitly listed in `objects` or `folders`. In that case, they are removed from their parent folder and moved to the destination folder described in `destination`. Objects explicitly listed in `objects` also move any linked hidden objects to the folder indicated as `destination`.

#### Inputs

* `objects` **array of strings** (optional) List of data object IDs to be moved.
* `folders` **array of strings** (optional) List of folders to be moved.
* `destination` **string** (required) The destination folder.

#### Outputs

* `id` **string** ID of the manipulated data container.

#### Errors

* `InvalidInput`
  * The input is not a hash.
  * `objects` (if provided) is not an array of nonempty strings.
  * `folders` (if provided) is not an array of nonempty strings starting with "/".
  * Two of the folders in `folders` have the same name but different paths.
  * `destination` is missing or is not a nonempty string starting with "/".
  * `destination` is `/.recycle_bin` or a path beneath it. Moving objects directly into the recycle bin is not allowed. Use [`/class-xxxx/removeObjects`](#api-method-class-xxxx-removeobjects) or [`/class-xxxx/removeFolder`](#api-method-class-xxxx-removefolder) instead.
* `ResourceNotFound`
  * The specified data container does not exist.
  * One of the specified objects or folders does not exist in the specified data container.
  * The destination folder does not exist.
* `PermissionDenied`
  * CONTRIBUTE access is required.
* `InvalidState`
  * A folder listed in `folders` is or contains the destination folder.
  * A folder listed in `folders` is `/.recycle_bin` or a path beneath it. To restore objects from the recycle bin, use [`/project-xxxx/recoverObjects`](/developer/api/data-containers/projects.md#api-method-project-xxxx-recoverobjects).

### API method: `/class-xxxx/removeObjects`

#### Specification

Removes the specified objects from the data container. When you remove objects, the system also removes any hidden linked objects that can no longer be reached from other visible objects in the same data container through one or more links. You can remove objects in any state. Unless the project has data retention turned on, removal cannot be undone.

Removing open objects may cause additional effects, such as making upload URLs invalid. To restore a removed object to the data container, you must have a copy in another data container and the proper permissions to clone it back. When cloning an object back, any previously set custom metadata is lost and replaced with metadata from the source data container. For more information, see [Cloning](/developer/api/data-containers/cloning.md).

When the project has [data retention](#recycle-bin) turned on, this method moves the objects into the project's recycle bin. To restore them before their retention period ends, use [`/project-xxxx/recoverObjects`](/developer/api/data-containers/projects.md#api-method-project-xxxx-recoverobjects).

#### Inputs

* `objects` **array of strings** (required) List of object IDs to be removed from the data container.
* `force` **boolean** (optional) If `true`, this operation does not throw an error even if the given object does not exist. Defaults to `false`.
* `overrideProjectAccess` **boolean** (optional) If `true`, removes objects from any project or container billed to an organization for which the requesting user has the [`dataDeletion`](/developer/api/organizations.md#org-permission-flags) permission, regardless of project or container membership. Defaults to `false`.

#### Outputs

* `id` **string** ID of the manipulated data container.

#### Errors

* `InvalidInput`
  * The input is not a hash.
  * `objects` is missing or is not an array of nonempty strings.
* `ResourceNotFound`
  * The specified data container does not exist.
  * An object with the given ID does not exist or does not exist in the specified data container and `force` was not set to `true`.
* `PermissionDenied`
  * CONTRIBUTE or ADMINISTER access is required, depending on the PROTECTED flag.
  * `overrideProjectAccess` is `true` but the requesting user does not have the `dataDeletion` permission for an organization that bills the data container.
* `InvalidState`
  * One of the objects is a DBCluster in a non-terminal state.
  * The project has data retention turned on, and the request covers more than 10,000 objects, counting hidden linked objects. To remove them, split the request into smaller batches.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://documentation.dnanexus.com/developer/api/data-containers/folders-and-deletion.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
