Skip to content

Storage & clean-up

A workspace stores everything it generates and uploads, up to a limit set by its plan. The Storage endpoints let a workspace’s admins see what uses that space and free it from a script, the same as Settings > Storage in the app. Every operation needs the settings admin permission in the workspace.

Terminal window
curl https://api.app.layer.ai/api/v2/workspaces/$WORKSPACE_ID/storage \
-H "Authorization: Bearer $LAYER_TOKEN"

used_bytes and quota_bytes are live. The breakdown (files by origin, category, age, project and member, and the largest files) is computed in the background, nightly and on request, so it trails the live count: breakdown_computed_at says when it was computed. The first read of a workspace that never had one asks for one and returns is_breakdown_computing: true. POST …/storage/breakdown asks for a fresh one.

  1. List candidates. GET …/storage/cleanup-candidates?older_than_days=180&origin=generated returns the oldest files that match and that nothing depends on, oldest first. Page with cursor until next_cursor is null; a page can hold fewer than limit files and still have a next page.

  2. Delete them, up to 500 ids per request:

    Terminal window
    curl -X POST https://api.app.layer.ai/api/v2/workspaces/$WORKSPACE_ID/storage/delete \
    -H "Authorization: Bearer $LAYER_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{ "file_ids": ["…", "…"] }'
    # → { "deleted_files": 1, "deleted_bytes": 2500000, "skipped": [{ "file_id": "…", "message": "This file is used by the skill \"pixel-art\". …", "dependencies": [{ "kind": "skill", "owner_id": "…", "owner_name": "pixel-art" }] }] }

A file something depends on (a reference set’s training data, a workflow’s constant, a skill’s resource, a template’s example, a share into another workspace, a running export) is never deleted. It comes back in skipped, with what holds it, so you know what to remove first. Labeled, foldered, liked and pinned files are left out of the candidates unless you pass keep_labeled=false and so on.

Deleted files stay in the trash for 29 days. GET …/storage/trash lists them, most recently deleted first, and POST …/storage/trash/restore with { "file_ids": [...] } brings them back to the library where they were.

An enterprise workspace can set rules that run every night. Each rule picks files by age (7 days or more), origin and category, and keeps labeled, foldered, liked and pinned files unless told otherwise. A file any rule reaches is deleted into the trash; files in use are always kept.

  1. Preview the rules to see what they would delete now. Nothing is deleted:

    Terminal window
    curl -X POST https://api.app.layer.ai/api/v2/workspaces/$WORKSPACE_ID/storage/auto-delete/preview \
    -H "Authorization: Bearer $LAYER_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{ "rules": [{ "older_than_days": 180, "origin": "generated" }] }'
  2. Save them with PUT …/storage/auto-delete, is_enabled: true. Set notify_admins: true to email the workspace’s admins a summary after each run, and is_locked: true to make every workspace under this one follow the same rules.

  3. Run them now, if you don’t want to wait for the night: POST …/storage/auto-delete/runs answers 202 with the run, running. Read GET …/storage/auto-delete/runs to follow it. While one is running, another is refused with AUTO_DELETE_RUNNING.

A workspace without rules of its own follows those of the nearest workspace above it that has some. GET …/storage/auto-delete returns both the workspace’s own policy and the effective_policy that applies, with the workspace that set it.