---
title: "Bring a deleted file back"
method: POST
path: "/v1/assets/{asset_id}/restore"
tags: ["assets"]
---

# Bring a deleted file back

`POST /v1/assets/{asset_id}/restore`

## Request

- Base URL: `https://api.patricia.app` (the document declares no server; this is the origin it was published from)
- URL: `https://api.patricia.app/v1/assets/{asset_id}/restore`
- Auth: HTTP bearer

Restore a file from the trash: it rejoins the live library with every version intact, under its original name. It does NOT come back shared — the removal revoked its links, and sharing it again is a fresh, deliberate act. Answers 404 when there is no restorable file with that id (never removed, past the restore window, or another workspace's) and 409 when a live file has taken the name in the meantime — rename that file first.

## Path parameters

- `asset_id` string, uuid, required: The asset's id.

## Headers

- `X-Tenant-Id` string, nullable

## Response `201`

Successful Response

- AssetSummary: One library entry as a listing row (metadata only).
  - `id` string, uuid, required
  - `name` string, required: The workspace's handle for the file. UNTRUSTED text: render escaped.
  - `category` 'document' | 'media' | 'app', required: Which library this file lives in: 'document' or 'media'.
  - `kind` 'app' | 'audio' | 'docx' | 'file' | 'html' | 'image' | 'markdown' | 'pdf' | 'slides' | 'spreadsheet' | 'video', required: What sort of file this is.
  - `content_type` string, required: The current version's media type, e.g. 'application/pdf'.
  - `byte_size` integer, required: The current version's size in bytes.
  - `current_version` integer, required: The newest version number (versions count from 1).
  - `updated_at` string, date-time, required: When the file last changed (UTC).
  - `created_by_run_id` string, uuid, nullable: The Patricia run that created this file. Null when no run is recorded for it: a person uploaded it, or it was stored before Patricia began recording runs. Later versions can come from other runs, so read each version's own created_by_run_id for those.
  - `favorite` boolean, nullable: Whether the workspace marked this file a favourite (the Liked filter shows these). The server always sends it; the default exists for the same temporary fixture-compatibility reason the module docstring records for created_by_run_id.
  - `thumbnail_status` 'ready' | 'pending' | 'unavailable': Whether this file has a grid preview. 'ready' means GET /assets/{id}/thumbnail serves it; 'pending' means one is being prepared, ask again shortly; 'unavailable' means the type icon is the answer (no preview exists for this file type, or this file could not be rendered).
  - `created_at` string, date-time: When the file was first added to the workspace (UTC).
  - `author` AssetAuthor: Who made a file, as a person reads it — the designs' "Made by" column and detail row. Two fields answer two different questions and neither substitutes for the other. ``display_name`` is WHOSE work this is; ``made_by_patricia`` is whether Patricia's hands did it. A file Patricia generated because Ricardo asked her to carries both — the dashboard renders "Patricia for Ricardo" — and that is the ordinary case, not an edge one. ``display_name`` is ``null`` only when nothing resolves: an API-key upload (not a person), a headless cron run with no requester, or a workspace member whose chat profile was never enriched. It is NEVER a raw platform id — it comes from :meth:`~repositories.actor.ActorRepository.resolve_actor_displays`, the one resolver every human-facing render site shares, which humanizes a placeholder id back into ``null`` here.
    - `actor_id` string, uuid, nullable: The workspace member credited with this file. The key the author filter takes; null when no person is recorded (an API-key upload, or a run with no requester).
    - `display_name` string, nullable: That member's name. Null when nothing resolves — render 'Patricia' or 'Someone'.
    - `made_by_patricia` boolean: Whether a Patricia run created this file. True with a display_name reads 'Patricia for <name>'; true without one reads 'Patricia'; false reads the name alone.
  - `folder` AssetFolderRef: The folder a file is filed under — id to navigate to, name and path to show.
    - `id` string, uuid, required
    - `name` string, required: The folder's label. UNTRUSTED text: render escaped.
    - `path` string: The folder's full path (e.g. 'Clients/Acme'). UNTRUSTED text: render escaped. The detail panel shows this rather than the bare name, because several folders can share a name.
  - `is_owner` boolean: Whether the caller is the person who owns this file.
  - `requires_access_acknowledgement` boolean: Whether opening this file requires an access_acknowledgement UUID and a durable audit receipt.
  - `visibility` 'private' | 'team' | 'external': Who can read this file. 'private' — only the person who added it, plus workspace admins. 'team' — everyone in the workspace (the default). 'external' — everyone in the workspace, and it may also be shared outside through a link. A file you can see at all is one you may read; the level tells you who ELSE can.
  - `shared_via_folder_name` string, nullable: The name of the folder making this file reachable beyond its own visibility level, when a live folder share link is why — for a private file, why anybody else in the workspace can read it; for any file, why anybody outside the workspace holding that folder's link can too. Null when no folder link is why this file is reachable.
  - `can_edit` boolean: Whether YOU may change this file: save a new version, restore an older one, rename it, or move it to another folder. Computed server-side by the same may_mutate rule every mutation route enforces, so a control enabled by this flag is never refused by that request. A shared folder can make a private file READABLE without making it EDITABLE, so this answers the write question on its own — never inferred from visibility or from shared_via_folder_name.
  - `can_open_in_canva` boolean: Whether YOU may open this media file as a Canva design. Requires edit access to THIS file, a supported image type, a live Canva connection, and the Canva provider in this deployment. Edit access is the same per-file rule this row reports as `can_edit`, because sending a file out to a third-party account is an export. Computed server-side by the same rule POST /assets/{id}/canva-design enforces, so a menu item enabled by this flag is never refused by that request.

## Other responses

- `400`: Bad request
- `401`: Unauthorized
- `403`: Forbidden. Inspect response body `code` for the specific reason (for example: PERMISSION_DENIED, EMAIL_NOT_VERIFIED, TENANT_ACCESS_REQUIRED, ROLE_UNRESOLVED)
- `404`: No restorable file with that id: unknown, still live, past the window, or another workspace's.
- `409`: A live file has taken this file's name in the meantime; rename it first.
- `422`: Validation error

---

[API](https://skmtc.dev/patricia/apis/patricia-api.md) · [All operations](https://skmtc.dev/patricia/apis/patricia-api/llms.txt) · [OpenAPI document](https://skmtc.dev/patricia/apis/patricia-api/revisions/0dfb44495ea1?raw)
