Skip to content

Uploads

Upload files of any size with signed URLs, in one request or in parts, with checksums and versions.

Bytes go straight to storage through signed URLs, so large files never pass through the API.

Method and path Scope What it does
POST /uploads files:write Start an upload and get signed URLs
GET /uploads/{id} files:write See where an upload stands
POST /uploads/{id}/parts files:write Get fresh signed URLs for parts
POST /uploads/{id}/complete files:write Finish the upload and get the file
DELETE /uploads/{id} files:write Abort an unfinished upload

Flow

  1. Start. POST /uploads with { "name", "size", "folder_id"?, "content_type"?, "sha256"?, "on_conflict"?, "modified_at"? }. The answer is 201 with signed URLs.
  2. Send the bytes. In mode single, PUT the whole file to uploads[0].url. In mode multipart, PUT part N to its URL. Each part is part_size bytes. Ask for more URLs with POST /uploads/{id}/parts and { "from_part": 1, "count": 100 } (up to 100 at a time).
  3. Complete. POST /uploads/{id}/complete. It answers 409 incomplete with details.missing_parts until every part is stored. It is safe to repeat.

Same name already there

The same rules as the app apply. Free renames the new file to name (2). Pro saves a new version of the existing file: the answer has kind: "version" and file_id, and complete returns the file with version_created. A clash the app would ask about is 409 conflict with the choices in details. Identical content answers 200 with skip. Send on_conflict to choose.

Checksums and times

complete takes an optional body { "sha256", "modified_at", "multipart_id" }. Up to 100 MiB the server hashes the stored object. A match is stored as sha256_source: server. A mismatch is 422 integrity_mismatch and the file moves to the bin, so upload it again. Above 100 MiB your claim is stored as client.

Empty files

size: 0 creates the empty file at once and answers 201 with { "action": "created", "kind": "empty", "file": { ... } }. There is no upload step. An empty file cannot become a new version (409 empty_version_not_supported), so send on_conflict as separate or skip.

Limits

Storage and plan limits apply as in the app: 413 storage_full, 413 file_too_large. A transfer-held item follows the same transfer rules. Uploads count against the files rate limit (600 a minute per token).

Type to search…

↑↓ navigate↵ selectEsc close