# list_storage_files

Source: https://modulify.ai/docs/api/storage/list-storage-files

Browses a site's storage bucket one folder at a time, returning the folders and files directly under a path.

- Title: List storage files
- Scope: `data:read`
- Access: Read only
- Endpoint: `POST /v1/list_storage_files`

Each file comes back with its key, size, last modified date and visibility, and each folder with its visibility and whether it is mixed. Keys are what every other storage tool takes, so start here. It keeps working while a storage backup is being restored.

Read `visibility` to tell public from private, never the `url` field. Only image files carry a `url`: for a public image it is the permanent CDN address, or a signed link that works for 7 days while the CDN is still being provisioned, and for a private image it is a signed preview that expires after 15 minutes and must never be embedded in a page or stored. A public file without a `url` is still served at its CDN address, and a private file has no public address at all, so use `get_storage_file_url` for a link to any file.

A page holds up to 50 entries and comes back with a `nextToken`, which you pass as `token` to read the next page. If a token is refused with a `400`, list the folder again from the first page.

Pass `search` instead of `path` to scan the bucket for keys containing that text anywhere, folder path included, so a search for `invoices` also finds every file inside an `invoices` folder. It returns a flat list of up to 200 matches and no folders. That scan reads at most 5,000 objects, shared between public and private files, and sets `truncated` to true when it stopped before covering the whole bucket, so an empty result with `truncated` set is inconclusive rather than proof the file is absent, and browsing by path is the sure way to find it.

The `CMS` folder at the top level holds the files uploaded from CMS fields, and the CMS manages it. This tool lists it like any other folder, but nothing can be uploaded into it, deleted from it, moved in or out of it or changed in visibility, and a CMS file is deleted with the item that uses it. See [The CMS folder](https://modulify.ai/docs/data/storage#the-cms-folder).

## Request

Call it with a `POST` to `https://api.modulify.ai/v1/list_storage_files`, sending the inputs below as a JSON object. The token needs the `data:read` scope.

It only reads and changes nothing, so retrying it is safe.

```bash
curl -X POST https://api.modulify.ai/v1/list_storage_files \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"projectId":"PROJECT_ID"}'
```

Over MCP, the same method is the [list_storage_files tool](https://modulify.ai/docs/mcp/storage/list-storage-files).

## Inputs

| Input | Type | Required | Description |
| --- | --- | --- | --- |
| `projectId` | string | Yes | The site id, from `list_sites`. |
| `path` | string | No | The folder to list, such as `images/logos/`. Leave it out or pass an empty string for the top level of the bucket. |
| `token` | string | No | The `nextToken` from a previous response, to read the next page of the same folder. |
| `search` | string | No | Text to find anywhere in a file key, folder path included, across the whole bucket instead of listing one folder. Case insensitive, and `path` is ignored while it is set. |

## Response

Every call answers with the [JSON envelope](https://modulify.ai/docs/api/requests-and-responses#the-response) of `success`, `message`, `data`, `code` and `version`. `data` holds the result described above, and on a method that returns a total, `count` carries it. The [response headers](https://modulify.ai/docs/api/requests-and-responses#headers-on-every-method-call) carry the call's `X-Request-Id` and what is left of your per-minute budget in `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset`. [Errors](https://modulify.ai/docs/api/errors) explains every status code a call can answer with.