Vaulx uses a presigned-URL upload strategy: the server never touches your file bytes. Instead it issues a time-limited, pre-authorised URL pointing directly at the S3-compatible bucket. Your browser (or API client) then PUTs the data straight to storage. This keeps the Vaulx server lightweight and allows uploads to scale without any changes to the application layer. Two upload flows are available depending on file size. Both require an authenticated session with editor or admin role.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/noelzappy/vaulx/llms.txt
Use this file to discover all available pages before exploring further.
Small File Upload (Simple Presigned PUT)
For files of any size where you want a single-step flow, use the presigned PUT path. The upload zone in the Vaulx web UI drives this flow automatically, but you can also call it directly from your own tooling.Initialise the upload
POST /api/upload/init — creates a pending file record and returns a presigned PUT URL.Request body (JSON):Original filename (e.g.
report-q4.pdf). Vaulx sanitises it before using it as the S3 key suffix — non-alphanumeric characters other than ., -, and _ are replaced with _.File size in bytes. Must match the
Content-Length you send in the PUT request.MIME type (e.g.
image/png). Used to set the S3 Content-Type. Omit or pass an empty string for application/octet-stream.UUID of the destination folder. Omit or pass an empty string to upload to the root.
UUID of the newly created (pending) file record. Use this to confirm the upload in step 3.
Presigned S3 PUT URL. Valid for 15 minutes. You must set the exact
Content-Type and Content-Length headers when calling it.PUT the file bytes to S3
Upload the raw file bytes directly to the
upload_url returned in step 1. This request goes to your S3-compatible storage — not to the Vaulx server.The
Content-Type and Content-Length headers must exactly match the values you supplied to /api/upload/init. A mismatch will cause the presigned URL to reject the request with a 403 Forbidden.Confirm the upload
POST /api/upload/confirm/{fileID} — marks the file as active and makes it visible in the browser.Only the user who initiated the upload (or an admin) can call this endpoint. Confirming a file that is already active returns 404.Response (200 OK):Always
"ok" on success.UUID of the now-active file.
Full curl Example
Multipart Upload (Large Files)
For large files, Vaulx implements the S3 multipart upload API. The web UI uses Uppy with theAwsS3 plugin to drive this flow entirely from the browser. Parts are uploaded in parallel (up to 6 concurrent connections) with chunk sizes between 10 MB and 100 MB.
Create the multipart upload
POST /api/s3/multipart — registers a multipart upload with S3 and creates a pending file record.Request body (JSON):Original filename (e.g.
archive.tar.gz).MIME type of the file (e.g.
application/gzip).UUID of the destination folder. Pass an empty string for root.
S3 multipart upload ID. Required for all subsequent part operations.
The S3 object key that was assigned to this upload. Format:
uploads/<year>/<month>/<16-hex-bytes>/<sanitized-name>.UUID of the pending Vaulx file record.
Presign each part
GET /api/s3/multipart/{uploadId}/{partNumber}?key=<key> — returns a presigned URL for uploading one part.Part numbers are 1-indexed integers. Each presigned URL is valid for 1 hour.Response (200 OK):Presigned PUT URL for this part. PUT your chunk bytes directly to this URL.
PUT each part to its presigned URL
For each chunk, PUT the raw bytes to the corresponding presigned URL. S3 returns an
ETag header in the response — save it alongside the part number; you’ll need both in step 4.Complete the multipart upload
POST /api/s3/multipart/{uploadId}/complete — assembles all parts, activates the file record, and records an audit event.Request body (JSON):The S3 key returned in step 1.
The Vaulx file UUID returned in step 1.
Total file size in bytes.
Array of completed parts, each with
PartNumber (integer) and ETag (string) as returned by S3 during the PUT.The S3 object URL returned by the
CompleteMultipartUpload S3 API call.Additional Multipart Endpoints
| Endpoint | Method | Description |
|---|---|---|
GET /api/s3/multipart/{uploadId}?key= | GET | Lists already-uploaded parts. Useful for resuming an interrupted upload — compare the returned parts against your local chunks to determine which ones still need to be sent. |
DELETE /api/s3/multipart/{uploadId}?key= | DELETE | Aborts the multipart upload and discards all uploaded parts from S3. Returns 204 No Content. |
S3 Key Format
| Upload type | Key pattern |
|---|---|
| Simple presigned PUT | files/<16-hex-bytes>/<sanitized-name> |
| Multipart | uploads/<year>/<month>/<16-hex-bytes>/<sanitized-name> |
crypto/rand), giving 16 hex characters. This ensures that two uploads of identically named files never collide in storage.
Authorization
Both upload flows require:- A valid authenticated session cookie (
session=<token>). - The authenticated user must have the
editororadminrole. Users with theviewerrole receive403 Forbidden.
Vaulx automatically configures CORS on the S3 bucket at startup via
storage.EnsureCORS. This is what allows browser JavaScript to PUT directly to S3 from your Vaulx domain without cross-origin errors. If you are pointing Vaulx at an existing bucket that already has a restrictive CORS policy, the startup routine will overwrite it.