# GET /api/v2/drive-items

List drive items

- MCP id: drive-items.index
- Scope: api:read:project_drive
- Scope: api:read:customer_drive
- Scope: api:read:organization_drive
- Scope: api:read:user_drive
- Permission: project_drive::access
- Rate cost: 1 unit, read bucket. `view=detail` makes it 3. Adds: `with_total=1` +2, each include +1 (to-many +3), `q` +2.
- Cache-Control: private, no-store

Returns the drive items the caller may read: the rows plnnrly's file browser lists.

Access is decided per item (the permission for the owner type, the access inherited from its folder, then any per-item grant), and it applies before any filter you send, so this collection can be read across the whole organisation without leaking an item the caller cannot open. Narrow it to one drive with the `owner_type`/`owner_id` pair, which must be sent together, and to one folder with `filter[folder_id]`; the default `order_column` sort is only meaningful once you have, because positions are scoped per (`owner_type`, `owner_id`, `folder_id`) and an organisation-wide sort by it interleaves every drive. Pass `trashed=with` or `trashed=only` to see archived items; that needs only this endpoint's permission, never the restore ability. `total` is omitted unless you pass `with_total=1`. The declared permission is `project_drive::access`; `customer_drive`, `organization_drive` and `user_drive` apply by owner type, and a token covering any of the four is accepted.

## Parameters
- view (string, optional): Which field set to render.
- per_page (integer 1 to 100, optional): Rows per page. At most 25 when `include` names a to-many relation; a larger value is 400 invalid-query-parameter.
- cursor (string, optional): Opaque keyset cursor from a previous page's links.next. Never construct one by hand.
- with_total (boolean, optional): Whether meta.page.total is counted for this request.
- filter[archived_by] (integer, optional): The user who archived the item. Pair it with `trashed=only` for an archive view. Operators: = in null.
- filter[content_record_id] (integer, optional): Id of the document body. Must be sent together with `content_record_type`. Operators: = in null.
- filter[content_record_type] (string, optional): Type of body the item points at. `drive_document` is the only value. Must be sent together with `content_record_id`.
- filter[created_at] (timestamp (YYYY-MM-DDThh:mm:ssZ), optional): Creation timestamp. Pair with `sort=id` for a stable full export. Operators: = gte lt.
- filter[created_by] (integer, optional): Author of the item. Operators: = in null.
- filter[folder_id] (integer, optional): Folder the item sits in. Pass `null` to list the items at the drive root. Operators: = in null.
- filter[general_access] (string, optional): Baseline sharing tier, which applies only while `inherits_permissions` is `false`. Operators: = ne in.
- filter[inherits_permissions] (boolean, optional): Whether the item takes its permissions from its folder.
- filter[kind] (string, optional): What the item is. Operators: = ne in.
- filter[owner_id] (integer, optional): Id of the record whose drive this is, within the `owner_type` given. Must be sent together with `owner_type`. For `organization` it is your own organisation's id. Operators: = in.
- filter[owner_type] (string, optional): Which drive the item lives in: `project`, `customer`, `organization` or `user`. Must be sent together with `owner_id`.
- filter[source] (string, optional): Where the item came from. Operators: = ne in.
- filter[updated_at] (timestamp (YYYY-MM-DDThh:mm:ssZ), optional): Last-write timestamp. Use for incremental sync. Operators: = gte lt.
- filter[work_items.id] (integer, optional): The drive items linked to one work item, by its numeric id. A work item's `links.drive_items` points here: it lists every linked item you may open, where `include=drive_items` stops at 25. Using it also requires `project_management::manage_work_items`.
- q (string, optional): Free-text search over `title`. At most one substring match per request: `q` together with a `contains` filter is 400 invalid-query-parameter.
- sort (string, optional): Up to three keys, comma-separated, each optionally prefixed with `-` for descending.
- include (string, optional): Comma-separated names to inline, at most five.
- trashed (string, optional): Whether soft-deleted rows are included.
- X-Request-Id (header, optional): A correlation id of your own. It is recorded in our logs next to the server's request id but never returned: the response header always carries the server's id. A value that does not match the pattern is discarded silently, never rejected.
- If-None-Match (header, optional): The ETag a read is conditional on. A match is answered 304 with no body.

## Response 200
- id (integer, required): Unique identifier.
- title (string ≤ 255, required): Item title.
- group (string or null ≤ 255, required): Free-text grouping label shown in the drive tree.
- kind (string, required): What this item is. Everything created through the API is a `document`; the other kinds come from uploads in plnnrly.
- source (string, required): Where the item came from: `builtin` for an editor document, `upload` for a file uploaded in plnnrly.
- folder_id (integer or null, required): Folder this item sits in, or `null` at the drive root.
- drive_folder (Ref or DriveFolderSummary or null, required): The folder this item sits in; absent for items at the drive root.
- owner_type (string, required): The kind of record `owner` points at; it says which branch of `owner` applies.
- owner_id (integer, required): The id of the record `owner` points at.
- owner (Ref or ProjectSummary or CustomerSummary or UserSummary, required): The project, customer, organisation or user whose drive this item lives in. An organisation-owned item renders as a bare {"id": N} reference.
- content_record_type (string or null, required): The kind of record `content_record` points at; it says which branch of `content_record` applies.
- content_record_id (integer or null, required): The id of the record `content_record` points at.
- content_record (Ref or null, required): The body this item points at: a drive document for an editor document, `null` for an item with no body yet. Renders as a bare {"id": N} reference; read the body from `GET /api/v2/drive-documents/{drive_document}`.
- order_column (integer, required, server-assigned): Sort position, assigned by the server. Positions count per drive and folder, so the sequence is only meaningful once the collection is narrowed to one drive and one folder. Reordering is not exposed in v2.0.
- created_by (integer or null, required, server-assigned): Author; always the authenticated user at create time. Null on legacy rows and where the author has since been deleted.
- archived_by (integer or null, required, server-assigned): The user who archived this item; set on delete and cleared on restore.
- inherits_permissions (boolean, required): Whether this item takes its permissions from its folder.
- general_access (string, required): Baseline sharing tier, consulted only while `inherits_permissions` is `false`.
- access (string or null, required): The calling user's effective access level on this item, after the permission for the owner type, the access inherited from folders and any per-item grant.
- created_at (timestamp (YYYY-MM-DDThh:mm:ssZ), required): Creation timestamp.
- updated_at (timestamp (YYYY-MM-DDThh:mm:ssZ), required): Last-write timestamp; use for incremental sync.
- deleted_at (timestamp (YYYY-MM-DDThh:mm:ssZ) or null, required): When this item was archived, or `null` while it is live.
- comments_count (integer ≥ 0, required): Comments on this item.
- files_count (integer ≥ 0, required): Files attached to this item, counting the attachments list in plnnrly, the single uploaded file and the images embedded in the document body.
- tags_count (integer ≥ 0, required): Tags on this item.
- links (DriveItemLinks, required)
  - self (url, required): The canonical URI of this record.
  - comments (url, required): Comments on this drive item.
  - files (url, required): Files stored on this drive item.
- tags (array of TagSummary ≤ 50, optional, only with include): Tags on this item. An item takes at most 50 tags, so the include lists them all. `tag_ids` replaces the whole set. Wrapped in `{ data, meta }`; `meta.truncated` says whether the cap was hit and `meta.count` is the full count.
  - id (integer, required): Unique identifier.
  - title (string ≤ 255, required): Tag title as shown in the UI.

## Errors
- 403 forbidden-by-policy | insufficient-permission | insufficient-token-scope: Forbidden.
- 304 : Not modified.
- 400 idempotency-key-required | invalid-cursor | invalid-query-parameter | malformed-request | unsupported-parameter: Bad request.
- 401 token-expired | unauthenticated: Unauthenticated.
- 404 endpoint-not-found | resource-not-found: Not found.
- 406 not-acceptable: Not acceptable.
- 429 rate-limit-exceeded: Too many requests.
- 500 internal-error: Server error.
- 503 tenant-unavailable: Service unavailable.

## Example
```bash
curl -G \
  'https://<your-url>/api/v2/drive-items' \
  --data-urlencode 'filter[owner_type]=project' \
  --data-urlencode 'filter[owner_id]=1' \
  --data-urlencode 'filter[folder_id][null]=true' \
  --data-urlencode 'include=owner,tags' \
  --data-urlencode 'with_total=1' \
  -H 'Authorization: Bearer <token>' \
  -H 'Accept: application/json'
```
