# Files

The file browser API: see, upload, link to and delete the files of any environment of a project. The dashboard's file browser uses it. Your app's own users go through [`/storage/*` on the app](../apps/storage.md) instead, under bucket rules; these routes are for the team and act without them.

Files are your app users' data, so reading them needs `data:read` (owners, admins, developers, and tokens with that scope) and changing them needs `data:write` (owners, admins, and tokens with that scope). Viewers can't see files.

Every route takes `environment` (default `production`, or `preview/<name>`) and, except `buckets` and `usage`, a `bucket`.

| Request | Needs | What it does |
| --- | --- | --- |
| `GET /v1/projects/{projectId}/storage/buckets?environment=` | `data:read` | `{ buckets }`: `public`, `private`, and any other bucket that holds files. |
| `GET /v1/projects/{projectId}/storage/files?bucket=&prefix=&cursor=&limit=&delimiter=true` | `data:read` | `{ files, prefixes, cursor }`. Each file has `key`, `size` (bytes), `contentType`, `etag` and `uploadedAt`. |
| `GET /v1/projects/{projectId}/storage/usage` | `data:read` | `{ bytes, files }` across the project's environments. |
| `POST /v1/projects/{projectId}/storage/uploads` | `data:write` | `{ bucket, key, size, contentType? }`. Returns an upload ticket, as in [Uploading](../apps/storage.md#uploading). |
| `POST /v1/projects/{projectId}/storage/uploads/complete` | `data:write` | `{ bucket, key, uploadId, parts }`. Finishes a multipart upload; returns the file. |
| `POST /v1/projects/{projectId}/storage/uploads/abort` | `data:write` | `{ bucket, key, uploadId }`. |
| `POST /v1/projects/{projectId}/storage/download-url` | `data:read` | `{ bucket, key, expiresIn? }` (seconds, default 3600, at most 7 days). Returns `{ url, method, expiresAt }`: the "copy URL" link. |
| `DELETE /v1/projects/{projectId}/storage/files` | `data:write` | `{ bucket, keys, confirm: true }`, up to 1,000 keys. Without `confirm: true` it answers `400 confirmation_required` and deletes nothing. Returns `{ deleted }`. |

Uploads, download links and deletes are written to the audit log (`storage.upload_started`, `storage.upload_completed`, `storage.upload_aborted`, `storage.download_url_created`, `storage.files_deleted`).

A project in another account, or an environment a deploy token wasn't made for, answers `404 not_found`. Uploads answer `507 file_storage_full` when the account's file storage is full.