> ## 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.

# File handling overview

> Learn how PocketBase handles file uploads, storage, and retrieval

PocketBase provides a robust file handling system that supports both local filesystem and S3-compatible cloud storage. The file system automatically manages uploads, downloads, and thumbnail generation for images.

## File field type

The file field type allows you to store one or more files in your records. Files are stored with automatically generated unique names and can be protected or publicly accessible.

### Key features

* Single or multiple file uploads per field
* MIME type validation
* File size limits (default: 5MB per file)
* Automatic thumbnail generation for images
* Protected file access with token authentication
* Support for local and S3 storage backends

## How files are stored

When you upload a file to a record, PocketBase:

1. Validates the file against the field's constraints (size, MIME type)
2. Generates a unique filename with a random suffix
3. Stores the file in the record's directory: `{collection}/{recordId}/{filename}`
4. Saves only the filename in the database record field
5. Generates thumbnails if the file is an image and thumbs are configured

<Note>
  File names are automatically normalized and sanitized. PocketBase appends a random 10-character suffix to prevent filename collisions and enhance security.
</Note>

## File field configuration

You can configure file fields with the following options:

```go theme={null}
type FileField struct {
    Name         string   // Field name
    MaxSize      int64    // Maximum file size in bytes (default: 5MB)
    MaxSelect    int      // Max number of files (1 for single, >1 for multiple)
    MimeTypes    []string // Allowed MIME types (empty = all)
    Thumbs       []string // Thumbnail sizes for images
    Protected    bool     // Require token for access
    Required     bool     // At least one file required
}
```

### Example configuration

```go theme={null}
field := &core.FileField{
    Name:      "avatar",
    MaxSize:   2 << 20, // 2MB
    MaxSelect: 1,
    MimeTypes: []string{"image/png", "image/jpeg", "image/webp"},
    Thumbs:    []string{"100x100", "200x200"},
    Protected: false,
    Required:  false,
}
```

## File URL structure

Files are served through the API endpoint:

```
GET /api/files/{collection}/{recordId}/{filename}
```

### Query parameters

* `thumb` - Request a specific thumbnail size (e.g., `?thumb=100x100`)
* `token` - File access token (required for protected files)
* `download` - Force download instead of inline display (e.g., `?download=1`)

### Example URLs

```bash theme={null}
# Original file
https://your-app.com/api/files/users/abc123/avatar_kj3n4k5l6m.png

# Thumbnail
https://your-app.com/api/files/users/abc123/avatar_kj3n4k5l6m.png?thumb=100x100

# Protected file with token
https://your-app.com/api/files/users/abc123/document_x9y8z7w6v5.pdf?token=eyJ...

# Force download
https://your-app.com/api/files/users/abc123/report_m2n3b4c5d6.pdf?download=1
```

## Thumbnail sizes

For image files, you can configure automatic thumbnail generation using these formats:

* `WxH` (e.g., `100x300`) - Crop to WxH from center
* `WxHt` (e.g., `100x300t`) - Crop to WxH from top
* `WxHb` (e.g., `100x300b`) - Crop to WxH from bottom
* `WxHf` (e.g., `100x300f`) - Fit inside WxH without cropping
* `0xH` (e.g., `0x300`) - Resize to height, preserve aspect ratio
* `Wx0` (e.g., `100x0`) - Resize to width, preserve aspect ratio

<Info>
  Thumbnails are generated on-demand on first request and cached for subsequent requests. The default thumbnail size is `100x100`.
</Info>

## Protected files

When `Protected` is set to `true`, users need to provide a file token to access the file:

<Steps>
  <Step title="Authenticate the user">
    The user must be authenticated to request a file token.
  </Step>

  <Step title="Request a file token">
    Call `POST /api/files/token` to get a temporary file access token.
  </Step>

  <Step title="Access the file">
    Append the token to the file URL as a query parameter: `?token=...`
  </Step>
</Steps>

```javascript theme={null}
// Example: Get file token
const token = await pb.files.getToken();

// Use token to access protected file
const fileUrl = `${pb.files.getUrl(record, 'document')}?token=${token}`;
```

<Warning>
  Protected files still respect the collection's view rules. Even with a valid token, users can only access files from records they have permission to view.
</Warning>

## Storage backends

PocketBase supports two storage backends:

* **Local filesystem** - Default, stores files in `pb_data/storage/`
* **S3-compatible storage** - AWS S3, MinIO, DigitalOcean Spaces, etc.

The storage backend is configured in your application settings and applies globally to all file fields.

## Next steps

<CardGroup cols={3}>
  <Card title="File upload" icon="upload" href="/files/upload">
    Learn how to upload files to records
  </Card>

  <Card title="File download" icon="download" href="/files/download">
    Understand the file download workflow
  </Card>

  <Card title="S3 storage" icon="cloud" href="/files/s3-storage">
    Configure S3-compatible storage
  </Card>
</CardGroup>
