Uploading files

To upload files, you must first add a file type field to your collection:

File field screenshot

Once added, you could create/update a Record and upload "documents" files by sending a multipart/form-data request using the Records create/update APIs.

The client SDK makes things a little easier and auto detect the request content type based on the parameters that you provide. Here is an example how to create a new Record and upload multiple files to the demo file field "documents" using the SDKs:

// Example HTML: // <input type="file" id="fileInput" /> import PocketBase from 'pocketbase'; const client = new PocketBase('http://127.0.0.1:8090'); ... const formData = new FormData(); const fileInput = document.getElementById('fileInput'); // listen to file input changes and add the selected files to the form data fileInput.addEventListener('change', function () { for (let file of fileInput.files) { formData.append('documents', file); } }); // set some other regular text field value formData.append('title', 'Hello world!'); ... // upload and create new record const createdRecord = await client.records.create('demo', formData);
import 'package:pocketbase/pocketbase.dart'; import 'package:http/http.dart' as http; final client = PocketBase('http://127.0.0.1:8090'); ... // create a new record and upload multiple files final record = await client.records.create('demo', body: { 'title': 'Hello world!', // some regular text field }, files: [ http.MultipartFile.fromString( 'document', 'demo content 1...', filename: 'file1.txt', ), http.MultipartFile.fromString( 'document', 'demo content 2...', filename: 'file2.txt', ), ], );

Each uploaded file will be stored with the original filename (sanitized) and suffixed with a random (10 chars) part (eg. test_52iWbGinWd.png).

When you upload a new file to a single file upload field (aka. Max Files option is 1) PocketBase will automatically delete the previous uploaded file (if any) and upload the new one in its place.

When you upload a new file to a multiple file upload field (aka. Max Files option is > 1) the new file will be appended to the existing field values (as long as the Max Files limit is not reached, otherwise an error will be thrown).

Deleting files

To delete uploaded file(s), you could either edit the Record from the admin UI, or use the API and set the file field to a zero-value
(null, [], empty string, etc.).

If you want to delete only a single file from a multiple file upload field, you could provide the index or the filename of the file to delete. Here are some examples using the SDKs:

import PocketBase from 'pocketbase'; const client = new PocketBase('http://127.0.0.1:8090'); ... // delete all "documents" files await client.records.update('demo', 'RECORD_ID', { 'documents': null, }); // delete individual files by their index or filename await client.records.update('demo', 'RECORD_ID', { 'documents.0': null, 'documents.2': null, 'documents.text_abcd.pdf': null, });
import 'package:pocketbase/pocketbase.dart'; final client = PocketBase('http://127.0.0.1:8090'); ... // delete all "documents" files await client.records.update('demo', 'RECORD_ID', body: { 'documents': null, }); // delete individual files by their index or filename await client.records.update('demo', 'RECORD_ID', body: { 'documents.0': null, 'documents.2': null, 'documents.text_abcd.pdf': null, });

The above examples use the JSON object data format, but you could also use FormData instance for multipart/form-data requests.

File URL

Each uploaded file could be accessed by requesting its file url:
http://127.0.0.1:8090/api/files/COLLECTION_ID_OR_NAME/RECORD_ID/FILENAME

If your file field has Thumb sizes option, you can get a thumb of an image file (jpg, png) by just adding the thumb query parameter to the url like this: http://127.0.0.1:8090/api/files/COLLECTION_ID_OR_NAME/RECORD_ID/FILENAME?thumb=100x300

The following thumb formats are currently supported:

  • WxH (eg. 100x300) - crop to WxH viewbox (from center)
  • WxHt (eg. 100x300t) - crop to WxH viewbox (from top)
  • WxHb (eg. 100x300b) - crop to WxH viewbox (from bottom)
  • WxHf (eg. 100x300f) - fit inside a WxH viewbox (without cropping)
  • 0xH (eg. 0x300) - resize to H height preserving the aspect ratio
  • Wx0 (eg. 100x0) - resize to W width preserving the aspect ratio

The original file would be returned, if the requested thumb size is not found or the file is not an image!

If you already have a Record model instance, the SDKs provide a convenient method to generate a file url by its name.

import PocketBase from 'pocketbase'; const client = new PocketBase('http://127.0.0.1:8090'); ... const record = await client.records.getOne('demo', 'RECORD_ID'); // get only the first filename from "documents" // // note: // "documents" is an array of filenames because // the "documents" field was created with "Max Files" option > 1; // if "Max Files" was 1, then the result property would be just a string const firstFilename = record.documents[0]; // returns something like: // http://127.0.0.1:8090/api/files/demo/kfzjt5oy8r34hvn/test_52iWbGinWd.png?thumb=100x250 const url = client.records.getFileUrl(record, firstFilename, {'thumb': '100x250'});
import 'package:pocketbase/pocketbase.dart'; final client = PocketBase('http://127.0.0.1:8090'); ... final record = await client.records.getOne('demo', 'RECORD_ID'); // get only the first filename from "documents" // // note: // "documents" is an array of filenames because // the "documents" field was created with "Max Files" option > 1; // if "Max Files" was 1, then the result property would be just a string final firstFilename = record.getListValue<String>('documents')[0]; // returns something like: // http://127.0.0.1:8090/api/files/demo/kfzjt5oy8r34hvn/test_52iWbGinWd.png?thumb=100x250 final url = client.records.getFileUrl(record, firstFilename, query: { 'thumb': '100x250' });

Storage options

By default PocketBase uses the local file system to store uploaded files (aka. in the pb_data/storage directory).

If you have limited disk space, you could use a S3 compatible storage (AWS S3, MinIO, Wasabi, DigitalOcean Spaces, Vultr Object Storage, etc.). The easiest way to setup the connection settings is from the admin UI (Settings > Files storage):

Files storage settings screenshot