---
title: "Read one file and its version history"
method: GET
path: "/v1/assets/{asset_id}"
tags: ["assets"]
---

# Read one file and its version history

`GET /v1/assets/{asset_id}`

## 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}`
- Auth: HTTP bearer

One live asset plus every version stored for it, newest first. Answers 404 when the file does not exist, has been deleted, or belongs to another workspace.

## Path parameters

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

## Query parameters

- `access_acknowledgement` string, uuid, nullable: A UUID for one deliberate private-file opening. Reuse across requests for the same opening.

## Headers

- `X-Tenant-Id` string, nullable

## Response `200`

Successful Response

- AssetDetail: One asset plus its version history: the detail panel's payload.
  - `asset` AssetSummary, required: 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.
  - `versions` AssetVersionSummary[], required: Stored versions, newest first, capped at the most recent 200.
    - `version` integer, required
    - `content_type` string, required
    - `byte_size` integer, required
    - `created_at` string, date-time, required: When this version was stored (UTC).
    - `created_by_run_id` string, uuid, nullable: The Patricia run that wrote this version. Null when no run is recorded for it. This is what answers 'which run replaced the file', version by version.
    - `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.
    - `generation` AssetGenerationInfo: How a run generated one version — the detail panel's prompt / settings / brand-kit rows. Everything here is what Patricia herself recorded at dispatch time; ``prompt`` is model-written UNTRUSTED text (render escaped), and ``settings`` values are short scalars by construction (``agent.image_generation._scalar_settings``).
      - `prompt` string, nullable: The prompt as it was actually sent. UNTRUSTED text.
      - `model` string, nullable: The generation model's catalog key.
      - `settings` object, nullable: The scalar dispatch settings (aspect ratio, resolution, seed, ...).
      - `brand_assets` string[], nullable: The brand-kit logo names placed into the generation, when any were.
  - `source` AssetSource: Where a file came from: the detail panel's provenance block. ``kind`` is DERIVED from ``created_by_run_id``, not stored: a run wrote it, or a person uploaded it, and there is no third write path into this library today. That is deliberate over a ``source`` column duplicating a fact the row already carries — two copies of one fact drift, and the first thing that drifts is the one nobody reads. The day an inbound chat attachment can be saved to the library, that path IS indistinguishable from a dashboard upload here and needs a real column; this docstring is where that gets noticed.
    - `kind` 'generated' | 'uploaded', required: 'generated' — a Patricia run produced this file. 'uploaded' — a person added it directly. Derived from whether a run is recorded, so it can never disagree with run_id.
    - `run_id` string, uuid, nullable: The run that created it, when one did — opens /runs/{id} in the dashboard.
    - `conversation` AssetSourceConversation: The chat conversation a file came out of — the detail panel's "From" row. Carries the platform's own coordinates rather than a ready-made URL. Building a Slack permalink needs an API call per file (``chat.getPermalink``), which a detail read must not make, and the dashboard already holds the workspace's team id from its Slack connection — so it composes the deep link from these three values with the builder it already uses for "Open Slack". A server-side permalink would arrive later as one more optional field here.
      - `platform_code` string, required: Which chat platform, e.g. 'slack'.
      - `channel_ref` string, required: The platform's own id for the channel or DM.
      - `thread_ref` string, nullable: The thread this happened in, when it was in a thread rather than the channel.
      - `title` string, nullable: The channel or conversation name, when known. UNTRUSTED text: render escaped.
  - `can_change_visibility` boolean: Whether YOU may change this file's visibility: your role carries assets:edit, AND you added the file or are a workspace admin. Both halves are what the PUT /assets/{id}/visibility route checks for itself, so a picker enabled by this flag is never refused by that request.
  - `can_share` boolean: Whether YOU may create this file's link. Requires assets:edit. A link is the file's ADDRESS and publishes nothing: who can open it stays the file's own visibility, tested against whoever asks, so a file set to 'Only me' has a link too and only you can open it. Changing who can see a file is a separate act with its own permission, can_change_visibility. Computed server-side from the same rules POST /assets/{id}/share-links enforces, so a button 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`: Not found
- `422`: Validation error
- `503`: The private access audit is unavailable.

---

[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)
