Start an upload session
createUploadSession
POST /api/v1/uploads
files.writeRate cost: 2Open an upload straight to the share’s storage, for shares that offer it (Amazon S3 and compatible storage, Microsoft 365, Dropbox up to 150 MB)
Answers where and how to send the file; send it, then complete the session. Elsewhere 409 no-direct-upload: send the file through uploadFile instead. size is the file’s exact size: completing checks it. New files only: something already called that is never replaced. A session is kept until about an hour after its expires_at: one neither completed nor cancelled by then is gone (404), and a file sent to the storage for it is removed, never announced.
Request
Section titled “Request”curl -X POST "$FOLDR/api/v1/uploads" \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"share_id":"0191f2c4-8a1e-7b52-9d3a-5c1e0b7a4d21","path":"string","size":1}'$FOLDR is your site’s address (for example https://files.example.com) and $TOKEN is an access token. See Getting access.
Request body
Section titled “Request body”application/json, required: UploadSessionBody
| Field | Type | Description |
|---|---|---|
share_id | string (uuid) | Required. The id of the share. |
path | string | Required. The new file’s full path in the share, its name last. The folder it goes in must exist. |
size | integer | Required. The file’s exact size in bytes. Completing the session checks the storage holds exactly this many. |
on_conflict | string, one of fail, rename | What to do when something is already called that: “fail” (the default) answers 409 conflict; “rename” uploads it under the first free name. Nothing is ever replaced. |
content_type | string or null | The file’s media type, where the storage records one (default application/octet-stream). |
Example:
{ "share_id": "0191f2c4-8a1e-7b52-9d3a-5c1e0b7a4d21", "path": "string", "size": 1}Responses
Section titled “Responses”| Status | Meaning | Body |
|---|---|---|
| 201 | The session: where and how to send the file. | application/json: UploadSession |
201 response
Section titled “201 response”| Field | Type | Description |
|---|---|---|
id | string | Required. The session’s id, for complete and cancel. |
mode | string | Required. How the file is sent: direct, straight to the storage. Known values: direct. Clients must accept values not listed here. |
share_id | string (uuid) | Required. The id of the share. |
path | string | Required. The canonical path the file will have (on_conflict “rename” may have given it a new name). |
size | integer | Required. The size declared, in bytes. |
url | string (uri) | Required. Where to send the file. |
method | string | Required. The HTTP method to send it with (PUT or POST). |
headers | map of string | Required. Headers to send with it, exactly as given. |
chunk_size | integer or null | Required. Where set, send the file in pieces of at most this many bytes (a multiple of it, except the last), each with a Content-Range header; null: send it whole in one request. |
expires_at | string or null (date-time) | Required. Send the file before this time (RFC 3339, UTC); then the url stops working. Complete the session afterwards. |
Example:
{ "id": "string", "mode": "string", "share_id": "0191f2c4-8a1e-7b52-9d3a-5c1e0b7a4d21", "path": "string", "size": 1, "url": "https://files.example.com/", "method": "string", "headers": {}, "chunk_size": 1, "expires_at": "2026-11-04T09:30:00Z"}Errors
Section titled “Errors”Every error is an application/problem+json document (ProblemDetails); branch on its type or code. See Errors.
| Status | Problem types | When |
|---|---|---|
| 400 | invalid-pathinvalid-request | One of: Invalid path (invalid-path); Invalid request (invalid-request). |
| 401 | invalid-token | Invalid token (invalid-token). |
| 403 | insufficient-scopewrite-not-allowed | One of: Insufficient scope (insufficient-scope); Not allowed for this app (write-not-allowed). |
| 404 | not-found | Not found (not-found). |
| 409 | ambiguous-pathconflictno-direct-uploadnot-a-folderstorage-account-not-connected | One of: Ambiguous path (ambiguous-path); Conflict (conflict); No direct upload (no-direct-upload); Not a folder (not-a-folder); Storage account not connected (storage-account-not-connected). |
| 413 | too-large | Too large (too-large). |
| 429 | daily-write-limitrate-limited | One of: Daily write limit reached (daily-write-limit); Too many requests (rate-limited). |
| 500 | internal-error | Internal error (internal-error). |
| 503 | share-unavailableshare-unreachablewrite-failed | One of: Share unavailable (share-unavailable); Share unreachable (share-unreachable); Write failed (write-failed). |