## Deleting Objects

### Delete Cascades

When deleting objects, the deletion may cascade to child items as well; for example, deleting a Tenant will also result in deleting all of that Tenant's subscriptions.

To determine the impact of a delete operation before performing the delete, you may call the `GET DeleteCascade` API related to the delete operation. For example, before doing `DELETE Tenants([id])`, use `GET Tenants([id])/DeleteCascade`. The result is a DeleteCascadeModel that lists all objects that will also be deleted if you proceed with the original delete.

### Two-Phase Deletes

Due to App Orchestration's Desired State nature, deleting an item may sometimes require the system to perform some operations in the various products and components distributed throughout the deployment. When this is necessary, the deleted item performs a Two Phase Delete.

During the first phase, the item is marked for deletion. The deletion may cascade to child items as well; for example, deleting a Tenant will also result in deleting all of that Tenant's subscriptions. The system schedules workflows to execute in order to clean up the configuration across the deployment.

Once all of the workflows have completed, the second phase of the delete happens. In this phase, the objects themselves are truly deleted from the App Orchestration configuraiton database.

When querying for collections of objects from the API, the default is to hide objects which are in the process of deletion. This is the most typical use case for callers, who may be attempting to perform operations on the items returned. However, there are many use cases where it is necessary to see all of the objects in the system, regardless of whether they are currently being deleted. To do so, you must specify a Filter of All when issuing the API query.

When using the All filter, you must inspect the `ObjectDeleteState` property of the items returned. This has one of three values:

- `NotDeleted`: The item is not undergoing the process of deletion.
- `InProgress`: The item is undergoing the process of deletion. It may take some time for the deletion process to finish. You cannot change properties of the item or associate it with other items while deletion is in progress.
- `DeleteFailed`: The item was deleted, but one or more of the workflows scheduled to clean up the deployment have failed. The administrator may correct the problem(s) and retry, or may force the object deletion to complete. You cannot change properties of the item or associate it with other items.

### Forcing Deletion

Forcing a deletion to complete is not recommended in any but the most extreme cases. It causes App Orchestration to delete the item from its configuration database, but without scheduling any clean-upo workflows to execute. This can be helpful if there is a major system problem that may prevent the workflows from ever completing successfully; however, it can be dangerous if it leaves unmanaged configuration lingering in the products and components deployed in your environment. For example, if a subscription is force-deleted, access to the app or desktop may not actually be revoked from the end user.

Because of the dangers inherent in force-delete, App Orchestration only allows an item to be force-deleted if a "normal" delete has been attempted and the workflows for deleting the item have failed or been canceled. So, to truly force an unsafe deletion, it may be necessary to delete the item without forcing it, then cancel the task associated with the deletion, and then finally force the object deletion.

To force an object deletion, specify the `force` query parameter as `true` on the delete operation; for example:

        DELETE Tenants([id])?force=true