# GET /api/v2/drive-folders

List drive folders

- MCP id: drive-folders.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, `q` +2.
- Cache-Control: private, no-store

Returns the drive folders the caller may read: the tree plnnrly's file browser draws.

Access is decided per folder (the permission for the owner type, the access inherited from the nearest ancestor that does not inherit, then any per-folder grant), and it applies before any filter you send, so this collection can be read across the whole organisation without leaking a folder the caller cannot open. Narrow it to one drive with the `owner_type`/`owner_id` pair, which must be sent together, and to one level with `filter[parent_id]`; `filter[parent_id][null]=true` is the drive root, and a bare id is that folder's direct children, which is how a client walks the tree. The default name sort is stable across the organisation; the `order` sort is only meaningful once you have narrowed to one drive and one level, because positions are scoped per (`owner_type`, `owner_id`, `parent_id`). A folder is hard-deleted, so there is no trashed parameter. `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, a token covering any of the four is accepted, and the per-folder rule is what actually decides.

## 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[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 folder. Null on legacy rows. 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 folder takes its permissions from its parent.
- 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 folder lives in: `project`, `customer`, `organization` or `user`. Must be sent together with `owner_id`.
- filter[parent_id] (integer, optional): Folder this one sits in. Pass `null` to list the folders at the drive root, or an id to list one level of the tree. Operators: = in null.
- filter[updated_at] (timestamp (YYYY-MM-DDThh:mm:ssZ), optional): Last-write timestamp. Use for incremental sync. Operators: = gte lt.
- q (string, optional): Free-text search over `name`. 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.
- 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.
- name (string ≤ 255, required): Folder name as shown in the drive tree.
- parent_id (integer or null, required): Folder this one sits in, or `null` at the drive root.
- parent_folder (Ref or DriveFolderSummary or null, required): The folder this one sits in; absent for folders 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 folder lives in. An organisation-owned folder renders as a bare {"id": N} reference.
- order (integer, required, server-assigned): Sort position within the drive and level, as shown in the drive tree. Positions count per drive and level, so the sequence is only meaningful once the collection is narrowed to one drive and one level. It is not assigned on create, so a folder created through the API stays at 0 until it is positioned in plnnrly; 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.
- inherits_permissions (boolean, required): Whether this folder takes its permissions from its parent.
- 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 folder, after the permission for the owner type, the access inherited from folders and any per-folder 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.
- drive_items_count (integer ≥ 0, required): Live drive items directly in this folder that the caller may see. Archived items are not counted, and neither are items in subfolders.
- links (DriveFolderLinks, required)
  - self (url, required): The canonical URI of this record.
  - drive_items (url, required): Drive items directly in this folder.

## 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-folders' \
  --data-urlencode 'filter[owner_type]=project' \
  --data-urlencode 'filter[owner_id]=1' \
  --data-urlencode 'filter[parent_id][null]=true' \
  --data-urlencode 'include=owner' \
  --data-urlencode 'with_total=1' \
  -H 'Authorization: Bearer <token>' \
  -H 'Accept: application/json'
```
