Skip to main content
File uploads are handled via presigned URLs to MinIO. The API exposes two main steps:
  • POST /api/v1/initiate-upload – create an upload session and receive presigned URLs.
  • POST /api/v1/complete-upload – finalize the upload and register the file for operations.
Single-part vs multipart: For objects 5 GiB (5 × 2³⁰ bytes) or smaller, you can upload the whole file in one presigned PUT (parts: 1). For files larger than 5 GiB, you must use multipart upload: set parts to the number of chunks you will upload (each chunk is uploaded with its own presigned URL), PUT each part separately, collect each response’s ETag, then call complete-upload with every (etag, part_number) pair. This matches S3‑compatible limits: a single PUT cannot exceed 5 GiB per object part.

Initiate upload

  • file_name (required) – original file name including extension.
  • size (required) – file size in bytes.
  • mime_type (required) – MIME type (e.g. application/pdf).
  • parts (optional) – number of multipart parts; defaults to 1 when omitted or zero. Use 1 for files ≤ 5 GiB. For > 5 GiB, set parts to how many pieces you will upload (see Multipart upload example).
Response (ExternalUploadResponse):
  • file_key – stable key to reference this file in later operations.
  • object_name – internal object name in MinIO.
  • upload_id – underlying multipart upload id (if applicable).
  • presigned_urls – list of PUT URLs to upload file parts.

Upload file contents

Use the provided presigned_urls to upload file data directly to MinIO. For single‑part uploads there will be exactly one URL. For multipart uploads there is one URL per part, in order (index 0part_number 1, and so on).

Getting ETag values for complete-upload

After each successful presigned PUT:
  1. Read the ETag HTTP response header (not the request body).
  2. Remove surrounding double quotes if present (S3 and MinIO often return "abc123...").
  3. Send that string as parts[i].etag with part_number equal to the 1‑based part index (first URL → 1, second → 2, …).
If you omit a part or scramble part_number order, complete-upload can fail when the storage backend completes the multipart upload.

Multipart upload example (files larger than 5 GiB)

Why multipart: S3‑compatible storage allows at most 5 GiB per single PUT. Objects larger than 5 GiB must be split into multiple parts: each part is uploaded with its own presigned URL, and you pass every part’s ETag into complete-upload. Flow:
  1. Decide how many parts N you need (each uploaded part’s body must be ≤ 5 GiB; size the ranges so the whole file is covered).
  2. POST /api/v1/initiate-upload with parts: N, size: total file size in bytes, plus file_name and mime_type. The response includes N entries in presigned_urls (in order: part 1, part 2, …).
  3. For each index i from 0 to N - 1, PUT the corresponding byte range of your file to presigned_urls[i]. After each successful PUT, read ETag from the response headers and strip double quotes (see Getting ETag values for complete-upload).
  4. POST /api/v1/complete-upload with parts listing all N parts, each with the correct part_number (1N) matching the presigned URL order.
Example: three parts — initiate with "parts": 3, upload three ranges, then complete with three { "etag", "part_number" } objects.
In application code, the pattern is the same as the official SDKs: loop over presigned_urls, PUT each chunk, push { etag: strippedETag, part_number: i + 1 }, then POST the array to complete-upload.

Complete upload

POST /api/v1/complete-upload finalizes the multipart upload in storage and registers the file so it can be referenced by file_key in /api/v1/do and related APIs. Call it only after every part has been uploaded successfully via the presigned PUT URLs. Authentication: same as other Business API routes — Authorization: Bearer <your-api-key> and Content-Type: application/json.

Request body

JSON body (CompleteUploadRequest):
  • file_key (required) – from initiate-upload response.
  • object_name (required) – from initiate-upload response.
  • upload_id (required) – from initiate-upload response.
  • parts (required) – one entry per uploaded part, in order:
    • etag (required) – value of the ETag header from the corresponding presigned PUT response. If the header includes double quotes (common for S3‑compatible storage), strip them before sending.
    • part_number (required) – 1‑based index matching the part and presigned URL order from initiate upload.
For multipart uploads, include every part; for a single‑part upload, parts is a one‑element array.

Response

On success, HTTP 200 with a JSON body (CompleteUploadResponse):
  • message – status text from the server (typically includes the stored object ETag after a successful complete). If the upload was already finalized, the message may instead be a short confirmation such as file upload completed.
  • file_key – echoes the key you sent; use this key in operations.
On success, the server persists metadata and the file becomes available for /api/v1/do operations.