Path parameters
| Parameter | Description | |
|---|---|---|
uploadUrlstring |
required | The uploadUrl from Create Upload, used exactly as returned. |
Header parameters
| Parameter | Description | |
|---|---|---|
Content-Lengthinteger |
required | The size of the body in bytes. HTTP clients set it when the body is a file or a buffer. |
Content-Rangestring |
optional | Only when sending in pieces: bytes {first}-{last}/{size}, for example bytes 52428800-104857599/120000000. A piece starts at a multiple of chunkSize and is chunkSize bytes long, except the last. Leave it out when the whole file is one piece. |
Content-MD5string |
optional | The piece's MD5, base64-encoded. AWS S3 and Azure Blob check it; SharePoint and Google Drive refuse it. |
Request body
| Parameter | Description | |
|---|---|---|
(body)binary |
required | The raw bytes of the file or the piece. Not a form and not base64. |
Example request
# The second 50 MB piece of a 120,000,000-byte file, saved as piece2.bin curl --request PUT "$UPLOAD_URL" \ --header 'Content-Range: bytes 52428800-104857599/120000000' \ --data-binary @piece2.bin
Response body
| Status | When |
|---|---|
202 Accepted | The piece is stored; nextExpectedRanges lists what is still missing. An empty list means the file is being put together: GET the upload URL after a few seconds. |
201 Created | This piece finished the upload. The answer carries file. |
200 OK | The upload was already finished, for example when you resend the last piece after its answer was lost. Same file as the 201. |
A 201 or 200 looks like this. file.id works with every file endpoint, and file.fullName is the stored name.
{
"id": "upl_66f3c1a2b4d5e6f708192a3b",
"status": "completed",
"library": "s3",
"driveId": "workspace",
"name": "Q3-report.pdf",
"size": 120000000,
"chunkSize": 52428800,
"chunkCount": 3,
"maxConcurrency": 4,
"bytesReceived": 120000000,
"nextExpectedRanges": [],
"expiresAt": "2026-09-25T11:05:09.000Z",
"fileId": "66f3c1b9b4d5e6f708192a40",
"file": {
"id": "66f3c1b9b4d5e6f708192a40",
"name": "Q3-report",
"fullName": "Q3-report.pdf",
"type": "file",
"extension": "pdf",
"source": "INTERNAL",
"size": 120000000,
"createdAt": "2026-09-25T10:05:12.000Z",
"updatedAt": "2026-09-25T10:05:12.000Z",
"createdBy": "Priya Shah",
"driveId": "workspace",
"library": "s3",
"parent": {
"id": "66f3c1a2b4d5e6f708192a32",
"type": "folder",
"driveId": "workspace"
},
"path": "Contracts/2026/Q3-report.pdf"
}
}Errors
| Status | errorCode | What it means |
|---|---|---|
| 400 | UPLOAD/INVALID_RANGE | Content-Range or the body's length does not match the upload. message says how. |
| 404 | UPLOAD/NOT_FOUND | No upload at this URL. |
| 409 | UPLOAD/OUT_OF_ORDER | SharePoint and Google Drive take pieces in order. GET the upload URL and send the first missing piece. |
| 409 | UPLOAD/NOT_ACCEPTING_CHUNKS | The upload was cancelled or ended by an error. Create a new one. |
| 410 | UPLOAD/EXPIRED | The upload expired. Create a new one. |
| 411 | UPLOAD/LENGTH_REQUIRED | The request had no Content-Length. |
| 429 | UPLOAD/CHUNKS_IN_FLIGHT | Too many pieces at once. Send it again after Retry-After seconds. |
| 503 | UPLOAD/STORAGE_UNAVAILABLE | The storage was busy. Send it again after Retry-After seconds. |
Upload Errors lists every code and what to do.