Skip to main content

File Endpoints

POST /files/upload

Upload a file.

Auth: Optional (identity from JWT Authorization header)

Request: multipart/form-data

FieldTypeRequiredDescription
filefileYesThe file to upload
visibilitystringNo"public" (default) or "private"

Response 201:

{
"data": {
"id": "uuid",
"original_name": "photo.jpg",
"stored_name": "uuid.jpg",
"mime_type": "image/jpeg",
"size_bytes": 204800,
"visibility": "public",
"uploader_id": "user-uuid",
"created_at": "2026-03-06T12:00:00.000Z"
}
}

Errors:

CodeReason
400No file provided, invalid visibility
413File exceeds size limit or per-user quota

GET /files

List files. Admins see all files; other users see only their own.

Response 200:

{
"data": [
/* array of file metadata objects */
],
"meta": { "total": 5 }
}

GET /files/:id

Get metadata for a single file.

Errors:

CodeReason
403Not the owner and not admin
404File not found

GET /files/:id/download

Download a file. Public files are accessible directly. Private files require a signed URL.

Query Parameters (private files only):

ParameterDescription
tokenHMAC token from the signed URL
expiresUnix timestamp from the signed URL

Response: File stream with appropriate Content-Type and Content-Disposition headers.

Errors:

CodeReason
403Private file accessed without valid signed URL
404File not found

GET /files/:id/signed-url

Generate a time-limited signed URL for a private file.

Auth: Must be the file owner or admin.

Response 200:

{
"data": {
"url": "http://localhost:3000/files/uuid/download?token=abc123&expires=1741300000",
"expires": 1741300000
}
}

Errors:

CodeReason
400File is not private
403Not the owner and not admin
404File not found

DELETE /files/:id

Delete a file from disk and database.

Auth: Must be the file owner or admin.

Response: 204 No Content