---
title: "List the workspace's files"
method: GET
path: "/v1/assets"
tags: ["assets"]
---

# List the workspace's files

`GET /v1/assets`

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

One page of live assets, most recently changed first. Narrow with `category` (document | media | app), `kind` (pdf, image, …) and `search` (case-insensitive substring of the name). `total` is the true number of matches across all pages, not the number returned, so a truncated page can never read as a complete library. Deleted files are never listed. Dashboards (category=app) list newest first by creation unless `sort` says otherwise, take `scope`, `source` and `sort`, and carry `app_facets`, the filter options for the same reader.

## Query parameters

- `category` string, nullable: Narrow to 'document', 'media' or 'app'.
- `kind` string, nullable: Narrow to one kind, e.g. 'pdf' or 'image'.
- `search` string, nullable: Case-insensitive name substring.
- `folder_id` string, uuid, nullable: Narrow to one folder. Omit for no folder narrowing: every file, filed or not, unless unfiled=true also narrows to the unfiled ones.
- `author_actor_id` string, uuid, nullable: Narrow to files one workspace member is credited with.
- `favorite` boolean, nullable: True narrows to favourites (the Liked filter). False and unset both mean all.
- `unfiled` boolean: Narrow to files in no folder — the dashboard's top level. Cannot combine with folder_id.
- `scope` 'all' | 'mine' | 'shared', nullable: Dashboards only (category=app). 'all' (the default) lists every dashboard the caller can open, 'mine' the ones the caller made, 'shared' the rest.
- `source` string[], nullable: Dashboards only (category=app). Repeat to narrow to dashboards that read from ANY of these provider keys. At most 50 values of 1 to 255 characters. An unknown key matches nothing.
- `sort` 'newest' | 'name_asc' | 'name_desc', nullable: Dashboards only (category=app). 'newest' (the default), 'name_asc' or 'name_desc'.
- `limit` integer
- `offset` integer

## Headers

- `X-Tenant-Id` string, nullable

## Response `200`

Successful Response

- AssetPage: One page of the library plus the TRUE number of matches for the same filter. ``total`` is a real count, not ``len(items)``: the dashboard uses it for "Showing N of M" and to decide whether a next page exists, and a page-length stand-in would make a truncated library read as a complete one.
  - `items` AssetSummary[], required
    - `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.
  - `total` integer, required: Live assets matching the filter, across all pages.
  - `limit` integer, required: The page size actually applied.
  - `offset` integer, required: The offset actually applied.
  - `app_facets` AppListFacets: The dashboard list's filter options, counted for this reader. Each option list applies every active filter except its own, so choosing one option never hides the others. A source on a teammate's personal connection is never offered.
    - `created_by` AppCreatorOption[], required
      - `actor_id` string, uuid, required: The value the ``author_actor_id`` filter takes.
      - `display_name` string, nullable: That member's name. Null when nothing resolves; render 'Someone'.
    - `sources` AppSourceOption[], required
      - `key` string, required: The provider key the ``source`` filter takes.
      - `label` string, required: The app's name, for the option label.
      - `count` integer, required: Dashboards this source filter would match. Always positive.
    - `available_total` integer, required: Dashboards the reader can open before search and filters. Zero means an empty library; a positive value with zero items means nothing matches the filters.

## 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)
- `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)
