Uploading files
POST /api/transfers/:id/files
Content-Type: multipart/form-data
One file per request, sent as a file field:
curl -X POST "$BASE/api/transfers/$ID/files" \
-H "x-api-key: $KEY" \
-F "file=@build.zip"
{
"data": {
"id": 41,
"filename": "build.zip",
"mimeType": "application/zip",
"size": 48213004
}
}
Why one file per request
The body is piped straight to disk rather than read into memory. For a service whose job is multi-gigabyte files, that is the difference between working and running the process out of memory on the first real transfer.
One file per request also means the client gets true per-file progress, a failure costs only that file, and the size limit can be enforced mid-stream rather than after everything has already arrived.
Limits
| Limit | Default | Variable |
|---|---|---|
| Per file | 2048 MB | NUXT_MAX_FILE_SIZE_MB |
| Files per transfer | 50 | NUXT_MAX_FILES_PER_TRANSFER |
Exceeding the size limit aborts the stream and removes the partial file, so nothing is left occupying disk under a row that was never written.
Only into a draft
A transfer accepts files only while its status is draft. Once sent, the file
list is what the recipient was told they are getting, so a further upload
answers 409 TRANSFER_ALREADY_SENT.
Someone else's transfer answers 404.
Filenames
The name you send is stored in the database and reattached in the
Content-Disposition header on the way out. On disk the file gets a random
name.
That removes path traversal, reserved Windows names, unicode normalisation collisions and case-insensitive overwrites as a class of problem, rather than trying to sanitise them one by one.