About
Deleted projects, dataset versions, trainings, and workflows are moved to your workspace Trash for 30 days before they are permanently removed. You can restore an item from Trash at any time within the 30-day retention window, or permanently delete it immediately if you are certain you do not need it.
Web App
Open the Trash
Navigate to Settings in your workspace and select Trash from the sub-navigation. The page lists every deleted project, version, training, and workflow grouped by type, along with who deleted each item, when it was deleted, and how many days remain before permanent cleanup.
Restore an item
Click Restore on a single row to restore that item, or use the checkboxes to select multiple items and click Restore to restore them all at once. Restore All restores every item in the workspace Trash.
Restored items immediately reappear in the workspace in the same location they were deleted from. Dataset versions can only be restored while their parent project is still active. If the parent project is also in Trash, restore the project first and then restore its versions. The same applies to trainings: restore the parent project and version first.
Delete an item permanently
To skip the 30-day retention window and remove an item right away, click Delete Permanently on a single row, or select multiple items and click Delete Permanently. Empty Trash removes everything in the workspace Trash at once. Permanent deletion cannot be undone.
Permanent deletion is available only from this page in the web app. It is not exposed on the REST API, Python SDK, or CLI so that a stray script or automation cannot irrecoverably destroy data.
What happens when you delete
When a project, version, training, or workflow is deleted:
- The item is hidden from the workspace and from all API listings.
- Any in-flight training jobs for the item are cancelled automatically so you do not keep spending credits on something you are deleting.
- For projects, the version's trained models stop serving.
- For trainings, the models produced by that run are hidden too, and the version's
{project}/{version}model ID may switch to another model. - Storage for the item still counts toward your workspace plan until the 30-day retention window expires or you permanently delete it.
If you checked "Also delete images from Asset Library" when deleting a project, an amber indicator on the Trash row shows that images belonging only to that project will also be removed when the project is permanently cleaned up. Images shared with other projects are always preserved.
Who can use the Trash
Access to the Trash and its actions is controlled by role-based access control. The default Owner role grants all trash permissions. You can assign individual trash permissions (view_trash, trash_dataset, restore_dataset, trash_version, restore_version, trash_training, restore_training, delete_training, trash_workflow, restore_workflow) to custom roles from your workspace's Role-Based Access Control settings.
HTTP API
Projects and dataset versions moved to Trash are retained for 30 days before being permanently cleaned up. You can delete, list, and restore items through the REST API; permanent deletion is web-UI only (see the Permanent Deletion note at the bottom).
In-flight training jobs for a project or version are automatically cancelled when the item is moved to Trash.
Delete a Project
Move a project to Trash:
https://api.roboflow.com/:workspace/:projectcurl "https://api.roboflow.com/my-workspace/my-detector?api_key=$ROBOFLOW_API_KEY" \
-X DELETEExample response:
{
"deleted": true,
"type": "project",
"workspace": "my-workspace",
"project": "my-detector",
"projectId": "d_abc123",
"trash": true
}The calling API key must have the project:update scope.
Delete a Version
Move a single dataset version to Trash:
https://api.roboflow.com/:workspace/:project/:versioncurl "https://api.roboflow.com/my-workspace/my-detector/3?api_key=$ROBOFLOW_API_KEY" \
-X DELETEExample response:
{
"deleted": true,
"type": "version",
"workspace": "my-workspace",
"project": "my-detector",
"projectId": "d_abc123",
"version": "3",
"trash": true
}The calling API key must have the version:update scope.
Delete a Workflow
Move a workflow to Trash:
https://api.roboflow.com/:workspace/workflows/:workflowUrlcurl "https://api.roboflow.com/my-workspace/workflows/slow-webhooks?api_key=$ROBOFLOW_API_KEY" \
-X DELETEExample response:
{
"deleted": true,
"type": "workflow",
"workspace": "my-workspace",
"workflow": "slow-webhooks",
"workflowId": "wf_abc123",
"trash": true
}The calling API key must have the workflow:update scope.
List Items in Trash
List everything currently in the workspace Trash:
https://api.roboflow.com/:workspace/trashcurl "https://api.roboflow.com/my-workspace/trash?api_key=$ROBOFLOW_API_KEY"Example response:
{
"items": [
{
"type": "project",
"id": "d_abc123",
"name": "My Detector",
"url": "my-detector",
"deletedAt": "2026-04-20T17:05:33.000Z",
"scheduledCleanupAt": "2026-05-20T17:05:33.000Z",
"deletedBy": "uid-of-user",
"deletedByName": "Alice"
},
{
"type": "version",
"id": "3",
"name": "augmented-416",
"parentId": "d_xyz789",
"parentName": "My Other Project",
"parentUrl": "my-other-project",
"parentInTrash": false,
"deletedAt": "2026-04-21T12:14:02.000Z",
"scheduledCleanupAt": "2026-05-21T12:14:02.000Z"
}
],
"sections": {
"projects": [ ... ],
"versions": [ ... ],
"workflows": [ ... ],
"trainings": [ ... ]
}
}Each item includes a scheduledCleanupAt timestamp - the point at which the item is eligible for permanent cleanup. Projects also carry a cleanupDeleteImages boolean indicating whether images exclusive to the project will be deleted along with it when cleanup runs.
The calling API key must have the project:read scope.
Restore an Item
Restore a project, version, training, or workflow from Trash:
https://api.roboflow.com/:workspace/trash/restorecurl "https://api.roboflow.com/my-workspace/trash/restore?api_key=$ROBOFLOW_API_KEY" \
-X POST \
-H "Content-Type: application/json" \
-d '{"type": "project", "id": "d_abc123"}'For versions, you must also include the parent project id:
curl "https://api.roboflow.com/my-workspace/trash/restore?api_key=$ROBOFLOW_API_KEY" \
-X POST \
-H "Content-Type: application/json" \
-d '{"type": "version", "id": "3", "parentId": "d_abc123"}'Restoring a version requires the parent project to still be active (not itself in Trash). If the parent is also in Trash, restore it first. Restoring a training requires both its project and its version to be active.
type must be one of project, version, training, or workflow. The required API-key scope is per-type - the request fails with 401 if the key doesn't carry the right scope for the item being restored:
type | Required scope |
|---|---|
project | project:update |
version | version:update |
training | version:update |
workflow | workflow:update |
The endpoint also verifies that targetItem.owner === :workspace before delegating, so a key valid in workspace A cannot restore an item that lives in workspace B.
Permanent Deletion
Permanent deletion is intentionally not available on the REST API. The actions to empty Trash and to immediately delete a single Trash item destroy data irrecoverably, and we don't want a stray curl or automation to be able to trigger them. These actions are available only through the Trash view in the Roboflow web app.
Items left in Trash are cleaned up automatically after the 30-day retention window.
Python SDK
Projects and dataset versions deleted through the Python SDK are moved to the workspace Trash and retained for 30 days before being permanently cleaned up. Within the retention window you can restore them back to the workspace.
Any in-flight training jobs for a project or version are cancelled automatically when it is moved to Trash, so you don't continue spending credits.
Delete a Project
import roboflow
rf = roboflow.Roboflow(api_key="YOUR_API_KEY")
project = rf.workspace().project("my-detector")
project.delete()The project is immediately hidden from the workspace project list and appears in the Trash view under Settings → Trash.
Restore a Project
If you still have a reference to the Project object, call restore() on it:
project.restore()The SDK looks up the project in the workspace Trash by its slug and restores it. RuntimeError is raised if the project isn't currently in Trash.
Delete a Version
Move a single dataset version to Trash. Any in-flight training on the version is cancelled.
import roboflow
rf = roboflow.Roboflow(api_key="YOUR_API_KEY")
project = rf.workspace().project("my-detector")
version = project.version(3)
version.delete()Restore a Version
version.restore()The parent project must still be active (not itself in Trash) to restore a version. Restore the project first if necessary.
List Items in Trash
Use Workspace.trash() to see what's currently in the workspace Trash:
import roboflow
rf = roboflow.Roboflow(api_key="YOUR_API_KEY")
ws = rf.workspace()
trash = ws.trash()
for item in trash["items"]:
print(item["type"], item["name"], "cleanup:", item["scheduledCleanupAt"])trash["sections"] groups the same items by projects, versions, and workflows for convenience.
Restore by ID
If you don't already have a Project or Version handle (for example, you're restoring something that was deleted in a previous session), use Workspace.restore_from_trash() with the id returned by trash():
trash = ws.trash()
project_in_trash = trash["sections"]["projects"][0]
ws.restore_from_trash("project", project_in_trash["id"])For versions, pass the parent project id:
version_in_trash = trash["sections"]["versions"][0]
ws.restore_from_trash(
"version",
version_in_trash["id"],
parent_id=version_in_trash["parentId"],
)Workflows
The SDK doesn't currently expose a Workflow object, but you can soft-delete a workflow via the low-level rfapi helper and restore it with Workspace.restore_from_trash("workflow", ...):
from roboflow.adapters import rfapi
# Soft-delete - moves the workflow to Trash for 30 days.
rfapi.delete_workflow(api_key, ws.url, "slow-webhooks")
# Restore - look up the workflow's id in Trash first.
trash = ws.trash()
wf = next(w for w in trash["sections"]["workflows"] if w["url"] == "slow-webhooks")
ws.restore_from_trash("workflow", wf["id"])Permanent Deletion
Permanent deletion is intentionally not available from the SDK - the actions to empty Trash and to immediately delete a single Trash item destroy data irrecoverably, and we don't want a stray script to be able to trigger them. These actions are available only through the Trash view in the Roboflow web app, which has an explicit confirmation dialog.
Items left in Trash are cleaned up automatically after the 30-day retention window, so you rarely need to act on them manually.
CLI
Projects, dataset versions, and workflows can all be moved to the workspace Trash, where they are retained for 30 days before being permanently cleaned up. Within the retention window you can restore them back to the workspace.
Any in-flight training jobs associated with a project or version are cancelled automatically when it is moved to Trash, so you don't continue spending credits on an item you're deleting.
Delete a Project
Move a project to Trash:
roboflow project delete <workspace>/<project>Example:
roboflow project delete my-workspace/my-detectorThe command prompts for confirmation before moving the project. Pass --yes (or -y) to skip the prompt for scripted use:
roboflow project delete my-workspace/my-detector --yesRestore a Project
roboflow project restore <workspace>/<project>Example:
roboflow project restore my-workspace/my-detectorThe CLI looks the project up in the workspace Trash by its slug and restores it. If the project isn't currently in Trash, the command exits with an error.
Delete a Version
Move a single dataset version to Trash. Any in-flight training on the version is cancelled.
roboflow version delete <workspace>/<project>/<version>Example:
roboflow version delete my-workspace/my-detector/3Pass --yes to skip confirmation.
Restore a Version
roboflow version restore <workspace>/<project>/<version>Example:
roboflow version restore my-workspace/my-detector/3The parent project must still be active (not itself in Trash) - restore the project first if necessary.
Delete a Workflow
Move a workflow to Trash:
roboflow workflow delete <workflow>Example:
roboflow workflow delete slow-webhooksPass --yes (or -y) to skip the confirmation prompt. You can pass either the workflow URL slug or its Firestore id.
Restore a Workflow
roboflow workflow restore <workflow>Example:
roboflow workflow restore slow-webhooksList Items in Trash
List everything currently in the workspace Trash:
roboflow trash listTYPE ID NAME DELETED CLEANUP_AT BY
dataset d_abc123 My Detector 2026-04-20 2026-05-20 Alice
version 3 My Detector - augmented-416 (v3) 2026-04-21 2026-05-21 Bob
workflow wf_def456 Preprocessing Pipeline 2026-04-19 2026-05-19 AliceFor structured output suitable for scripting:
roboflow --json trash listPermanent Deletion
Permanent deletion is intentionally not available from the CLI or SDK - emptying Trash and immediately deleting a single Trash item destroy data irrecoverably, and we don't want a stray script or typo to be able to trigger them. These actions are available only through the Trash view in the Roboflow web app, which has an explicit confirmation dialog.
Items left in Trash are cleaned up automatically after the 30-day retention window, so you rarely need to act on them manually.
MCP Server
Connect your AI agent to the MCP Server and it can restore something you deleted with these tools:
| Tool | Description |
|---|---|
trash_list | List soft-deleted items currently in the workspace Trash. |
trash_restore_project | Restore a deleted project. |
trash_restore_version | Restore a deleted dataset version. |
trash_restore_workflow | Restore a deleted Workflow. |
trash_restore_training | Restore a deleted training run. |