Skip to content

Soft-delete an asset

DELETE
/assets/{id}

Marks the asset deleted (sets deleted_at). The storage pin is removed; the GC sweeper later collects bytes that are no longer pinned by anyone.

Accepts optional {reason} body captured into deleted_reason for the admin recovery-window audit.

AUTHORISATION is the same gate as PATCH /assets/{id}: the owner, a holder of assets.admin (global or scoped to the asset’s team or an ancestor of it), or system.admin. Anyone else gets 403 and the row is not touched. Until #930 this checked only that the caller was signed in, so any account could delete any asset while only system.admin could restore.

The caller is recorded in deleted_by_user_ref, which is what POST /admin/assets/{id}/restore then lets them undo.

id
required
string format: uuid

Optional body on DELETE endpoints that soft-delete an entity. The reason free-text string is captured verbatim into the entity’s deleted_reason column so admin recovery-window audits carry operator context.

The body itself is optional — a bare DELETE with no body is still valid + writes deleted_reason = NULL. When present, an empty-string reason is treated the same as missing.

object
reason

Free-text explanation of why the entity was deleted. Max 500 characters; validated at the handler.

string
<= 500 characters

Deleted

Malformed request

object
error
required

Human-readable error summary

string
Example
the request could not be completed

Authentication required, missing, or invalid

object
error
required

Human-readable error summary

string
Example
the request could not be completed
Example
{
"error": "authentication required: sign in and retry with a valid session or API token"
}

Authenticated but missing required capabilities

object
error
required

Human-readable error summary

string
Example
the request could not be completed

Resource not found

object
error
required

Human-readable error summary

string
Example
the request could not be completed