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

LimitDefaultVariable
Per file2048 MBNUXT_MAX_FILE_SIZE_MB
Files per transfer50NUXT_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.