23 June, 2026
This release adds named file downloads and automatic cleanup of orphaned files.
Named File Downloads
Presigned download URLs for File fields now include the file's real filename in the Content-Disposition header. Browsers save files with their proper name instead of a generic one.
This works automatically for file URLs returned from actions. In custom functions, getPresignedUrl() now accepts an optional options bag to control the download behaviour:
// Default: inline preview with the file's own filename
const url = await file.getPresignedUrl();
// Force a download (Save As dialog) with the file's own filename
const url = await file.getPresignedUrl({ contentDisposition: "attachment" });
// Force a download with a custom suggested filename
const url = await file.getPresignedUrl({
contentDisposition: "attachment",
filename: "2026-invoice.pdf",
});Automatic File Cleanup
Keel now automatically removes orphaned files from storage when a File field is set to null, replaced with a different file, or the row is deleted. This applies to both built-in actions and the models API in custom functions.
Previously, updating a file field or deleting a row left the old file sitting in storage. Now cleanup is handled for you.
Fixes and Improvements
- Flow stability: fixed duplicate step creation when a step is already running, allowed more than 16 back-to-back flow steps.
- Seeding:
keel generatenow emits primary-key IDs in seed data so required foreign keys resolve correctly.
For any issues or feedback, please contact us at help@keel.so.
Thank you for using Keel!