Buckets & files
Buckets are named file containers — the equivalent of PocketBase buckets and Supabase Storage buckets.
Buckets
{
"name": "avatars",
"is_public": true,
"created_at": "...",
"updated_at": "..."
}
is_publicis stored on the bucket and surfaced in the API. Note thatdownload_filecurrently requires a valid JWT for all buckets — treatis_publicas metadata until public-download enforcement is added.- Deleting a bucket deletes its file metadata (verify filesystem cleanup in your deployment if you rely on it).
Uploading
POST /api/buckets/{name}/files accepts multipart/form-data with a single
file field (any field name; the handler reads the first field):
curl -X POST http://localhost:8080/api/buckets/avatars/files \
-H "Authorization: Bearer $TOKEN" \
-F 'file=@avatar.png'
Response 201:
{
"id": "...",
"bucket": "avatars",
"filename": "avatar.png",
"mime_type": "image/png",
"size": 1024,
"created_at": "...",
"updated_at": "..."
}
Request bodies are capped at 10 MiB by the global body limit.
Listing & pagination
GET /api/buckets/{name}/files?page=1&per_page=20 returns:
{
"files": [...],
"total": 1, "page": 1, "per_page": 20, "total_pages": 1
}
Download & delete
GET /api/buckets/{name}/files/{id} → file bytes (Content-Type from mime_guess)
DELETE /api/buckets/{name}/files/{id} → 204
Thumbnails
For image files, a JPEG thumbnail can be generated on demand:
GET /api/buckets/{name}/files/{id}/thumb
image::generate_thumbnail decodes the stored file, scales it to fit a
bounded box, and returns JPEG bytes — handy for avatar grids without a
separate image pipeline.