> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/pocketbase/pocketbase/llms.txt
> Use this file to discover all available pages before exploring further.

# Files

> Upload, download, and manage files

The Files API allows you to upload files as part of record operations and download files with optional thumbnail generation.

## Upload files

Files are uploaded as part of record create/update operations using `multipart/form-data`.

### Create record with file

```bash theme={null}
POST /api/collections/{collection}/records
```

Use `multipart/form-data` to upload files with record data.

<CodeGroup>
  ```bash Single file theme={null}
  curl -X POST http://127.0.0.1:8090/api/collections/posts/records \
    -H "Authorization: Bearer YOUR_TOKEN" \
    -F "title=My Post" \
    -F "content=Post content" \
    -F "image=@/path/to/image.jpg"
  ```

  ```bash Multiple files theme={null}
  curl -X POST http://127.0.0.1:8090/api/collections/posts/records \
    -H "Authorization: Bearer YOUR_TOKEN" \
    -F "title=Gallery Post" \
    -F "images=@/path/to/image1.jpg" \
    -F "images=@/path/to/image2.jpg" \
    -F "images=@/path/to/image3.jpg"
  ```
</CodeGroup>

### Update record files

```bash theme={null}
PATCH /api/collections/{collection}/records/{id}
```

**Replace files:**

```bash theme={null}
curl -X PATCH http://127.0.0.1:8090/api/collections/posts/records/RECORD_ID \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -F "image=@/path/to/new-image.jpg"
```

**Append files (using + modifier):**

```bash theme={null}
curl -X PATCH http://127.0.0.1:8090/api/collections/posts/records/RECORD_ID \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -F "images+=@/path/to/another-image.jpg"
```

**Prepend files (using + prefix):**

```bash theme={null}
curl -X PATCH http://127.0.0.1:8090/api/collections/posts/records/RECORD_ID \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -F "+images=@/path/to/first-image.jpg"
```

**Remove specific files (using - modifier):**

```bash theme={null}
curl -X PATCH http://127.0.0.1:8090/api/collections/posts/records/RECORD_ID \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -d '{
    "images-": ["existing_filename.jpg", "another_file.png"]
  }'
```

## Download files

Download files from file field records.

```bash theme={null}
GET /api/files/{collection}/{recordId}/{filename}
```

<ParamField path="collection" type="string" required>
  The collection name or ID
</ParamField>

<ParamField path="recordId" type="string" required>
  The record ID containing the file
</ParamField>

<ParamField path="filename" type="string" required>
  The name of the file to download
</ParamField>

<ParamField query="thumb" type="string">
  Thumbnail size (e.g., `100x100`, `300x200`). Only works for images.
</ParamField>

<ParamField query="token" type="string">
  File token for accessing protected files (see Generate file token)
</ParamField>

**Authentication:** Required for protected files (when field has `protected: true`)

### Response

Returns the file with appropriate `Content-Type` header.

<CodeGroup>
  ```bash Download file theme={null}
  curl http://127.0.0.1:8090/api/files/posts/RECORD_ID/image.jpg \
    --output image.jpg
  ```

  ```bash Download thumbnail theme={null}
  curl http://127.0.0.1:8090/api/files/posts/RECORD_ID/image.jpg?thumb=100x100 \
    --output thumb.jpg
  ```

  ```bash Protected file theme={null}
  curl "http://127.0.0.1:8090/api/files/posts/RECORD_ID/document.pdf?token=FILE_TOKEN" \
    --output document.pdf
  ```
</CodeGroup>

## Generate file token

Generate a token to access protected files.

```bash theme={null}
POST /api/files/token
```

**Authentication:** Required (must be authenticated)

### Response

<ResponseField name="token" type="string">
  File access token (valid for the authenticated user's session)
</ResponseField>

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST http://127.0.0.1:8090/api/files/token \
    -H "Authorization: Bearer YOUR_AUTH_TOKEN"
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('http://127.0.0.1:8090/api/files/token', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer ' + authToken
    }
  });
  const data = await response.json();
  const fileToken = data.token;

  // Use token to access protected file
  const fileUrl = `http://127.0.0.1:8090/api/files/posts/${recordId}/${filename}?token=${fileToken}`;
  ```
</CodeGroup>

## Thumbnail generation

PocketBase automatically generates thumbnails for image files on-demand.

### Supported formats

Thumbnails are generated for:

* PNG (`.png`)
* JPEG (`.jpg`, `.jpeg`)
* GIF (`.gif`)
* WebP (`.webp`)

### Default sizes

The default thumbnail size is `100x100`, but you can configure custom sizes in the collection's file field settings.

### Thumbnail sizes

Specify thumbnail dimensions using `{width}x{height}` format:

```bash theme={null}
# Square thumbnail
curl http://127.0.0.1:8090/api/files/posts/RECORD_ID/photo.jpg?thumb=100x100

# Rectangle thumbnail
curl http://127.0.0.1:8090/api/files/posts/RECORD_ID/photo.jpg?thumb=300x200

# Custom size (if configured in field settings)
curl http://127.0.0.1:8090/api/files/posts/RECORD_ID/photo.jpg?thumb=500x500
```

<Note>
  Thumbnails are generated on first request and cached. The original file is served if thumbnail generation fails.
</Note>

### Custom thumbnail sizes

Define custom thumbnail sizes in your collection's file field configuration:

```json theme={null}
{
  "name": "image",
  "type": "file",
  "options": {
    "maxSelect": 1,
    "maxSize": 5242880,
    "thumbs": ["100x100", "300x200", "800x600"]
  }
}
```

## Protected files

Mark file fields as protected to require authentication for access.

### Field configuration

```json theme={null}
{
  "name": "document",
  "type": "file",
  "options": {
    "protected": true
  }
}
```

### Accessing protected files

Protected files require either:

1. **File token** (recommended for client-side access)
2. **Direct auth** (collection's `viewRule` is checked)

<CodeGroup>
  ```javascript Using file token theme={null}
  // 1. Generate file token
  const tokenResponse = await fetch('http://127.0.0.1:8090/api/files/token', {
    method: 'POST',
    headers: { 'Authorization': 'Bearer ' + authToken }
  });
  const { token } = await tokenResponse.json();

  // 2. Use token to access file
  const fileUrl = `http://127.0.0.1:8090/api/files/documents/${recordId}/file.pdf?token=${token}`;
  ```

  ```bash Using auth header theme={null}
  curl http://127.0.0.1:8090/api/files/documents/RECORD_ID/file.pdf \
    -H "Authorization: Bearer YOUR_AUTH_TOKEN"
  ```
</CodeGroup>

## File field options

When defining file fields in collections, you can configure:

<ParamField name="maxSelect" type="number" default="1">
  Maximum number of files (1 for single file, >1 for multiple)
</ParamField>

<ParamField name="maxSize" type="number" default="5242880">
  Maximum file size in bytes (default 5MB)
</ParamField>

<ParamField name="mimeTypes" type="array">
  Allowed MIME types (e.g., `["image/png", "image/jpeg"]`)
</ParamField>

<ParamField name="thumbs" type="array">
  Thumbnail sizes to generate (e.g., `["100x100", "300x200"]`)
</ParamField>

<ParamField name="protected" type="boolean" default="false">
  Whether files require authentication to access
</ParamField>

## File URLs

File URLs follow this pattern:

```
http://127.0.0.1:8090/api/files/{collection}/{recordId}/{filename}
```

You can construct file URLs from record data:

```javascript theme={null}
const record = {
  id: 'RECORD_ID',
  collectionName: 'posts',
  image: 'filename.jpg'
};

const fileUrl = `http://127.0.0.1:8090/api/files/${record.collectionName}/${record.id}/${record.image}`;
```

## View collection files

For view collections, files are served from the original collection record:

```bash theme={null}
GET /api/files/{viewCollection}/{viewRecordId}/{filename}
```

PocketBase automatically resolves the file to the original collection's record.

## Best practices

<Note>
  * Use appropriate MIME type restrictions for security
  * Set reasonable `maxSize` limits
  * Use protected files for sensitive documents
  * Generate thumbnails only for sizes you need
  * Consider CDN caching for public files
</Note>

### File naming

PocketBase automatically handles file naming:

* Generates unique filenames to prevent collisions
* Preserves file extensions
* Sanitizes filenames for safe storage

### Storage

Files are stored in:

```
pb_data/storage/{collectionId}/{recordId}/
```

Thumbnails are stored in:

```
pb_data/storage/{collectionId}/{recordId}/thumbs_{filename}/
```

## Common errors

| Code | Description                                 |
| ---- | ------------------------------------------- |
| 400  | Invalid file type or size exceeds limit     |
| 403  | Insufficient permissions for protected file |
| 404  | File, record, or collection not found       |
| 500  | File system error                           |
