Files
Uploaded files are records of njin's own file model. Models refer to them with file() and multiFile() fields. See Files and uploads.
| Request | What it does |
|---|---|
POST /api/file |
Upload a file |
GET /api/file |
List files |
DELETE /api/file/:id |
Delete a file |
GET /uploads/* |
The file's bytes. Public |
These endpoints need a credential and the file permissions. See Authentication.
Uploading
Send a multipart/form-data request with the file in a field named file:
curl -X POST http://localhost:3000/api/file \
-H "Authorization: Bearer $TOKEN" \
-F "[email protected]"The response holds the created file record in an array with one element:
{
"data": [
{
"id": "01a1aaf9-955d-71c4-8028-ae79455ee666",
"name": "photo_wrbgtk8wo5.jpg",
"size": 48213,
"type": "image/jpeg",
"url": "/uploads/photo_wrbgtk8wo5.jpg",
"meta": null,
"createdAt": "2026-11-05T09:10:45.853Z",
"updatedAt": "2026-11-05T09:10:45.853Z",
"createdBy": "01a1aaf9-9469-731b-a4e1-de525d7171aa"
}
]
}idis what you write into afile()field of a model.nameis the stored name. njin makes it safe and adds a random suffix, so uploading the same file name twice never overwrites.urlis where the file is served. With the default filesystem adapter it is a relative path. With the S3 adapter it is an absolute address on the storage service.
On the default filesystem adapter, files with these extensions are refused with 422, because a browser would run them from your site's own address: html, htm, xhtml, shtml, js, mjs and xml.
Listing
GET /api/file returns { data, meta } like a model list. It accepts search, page, limit, sort and order, but not filters. See Filtering and pagination.
Deleting
DELETE /api/file/:id deletes the file record and the stored file, and returns the record as { "data": record }.
Model records that still refer to the deleted file are not updated, and will point at nothing. Check where a file is used before you delete it.
Serving files
With the default filesystem adapter, GET /uploads/* returns the file's bytes. It needs no authentication, so the URLs can be used directly in pages and shared. These responses carry X-Content-Type-Options: nosniff and a Content-Security-Policy: sandbox header, so a file that a browser could render, such as an SVG, runs without scripts.
The route exists only when the configured file adapter has a dir. With S3, files are served from the storage service's own URL instead.