Resumable Upload
The Resumable Upload feature lets you resume an upload operation after network interruption or other transmission failure, saving time and bandwidth in the event of network failures.
It is especially useful in any of the following cases:
- You are transferring larges files.
- The probability of a network interruption is high.
- Uploads are originating from a device with a low-bandwidth connection, such as a mobile phone.
This page explains the sequence of HTTP requests required to upload files using the resumable upload process.
If you don't want to implement this part on your own, feel free to check our SDKs instead. It'll make the process a whole lot easier for you.
1. Sending metadata
The first step required to use the Resumable Upload protocol is to send a POST request to the following URL. This first step will let us send file metadata, such as the desired filename, its description ...
POST /files
Request Headers
The following request headers must be set.
Content-Type: application/json; charset=utf-8
X-Upload-Content-Length => 9999,
X-Upload-Content-Type => application/octet-stream
X-Api-Key: your_api_key
X-Upload-Content-Lengthdefines the number of bytes that will be uploaded in subsequent requests. Its value must be equal to the size of the file you are uploading.X-Upload-Content-Typedefines the MIME type of the file that you are uploading. It can also be set toapplication/octet-streamby default.
Request Body
Then, here is the request body. That's where you are able to specify file metadata.
visibility attribute is not required as it defaults to public.
{
"filename": "your_file.exe",
"description": "Hello world.",
"visibility": "public"
}
Response
If the request succeeds, the API will respond with a 201 Created status code, and the response will include a Location header that specifies the URL for the resumable upload endpoint. This is the URL that you will use to upload the actual file (in other words, its content).
Location: {uploadUrl}
2. Sending the actual file
After receiving the resumable upload URL from the previous request, you will then need to upload the actual file contents by sending a PUT request to that specific location.
PUT {uploadUrl}
Request Headers
The following request headers must be set.
Content-Length: 9999
Content-Type: application/octet-stream
X-Api-Key: your_api_key
Content-Lengthdefines the size of the file that you are uploading. Its value should be the same as the value of theX-Upload-Content-Lengthrequest header used in the previous request.Content-Typedefines the MIME type of the file that you are uploading. Its value must be the same as the value of theX-Upload-Content-Typerequest header used in the previous request.
Request Body
The body of the request is the actual file content.
Response
The request can lead to one of the following responses:
- The file has been uploaded successfully.
If the request succeeds, the API will respond with a 201 Created status code, and the response will include a Location header that specifies the file URL. This means that the upload is complete and successful.
- The upload did not succeed, but it can be resumed.
If the connection between the API and your application is lost, you should be able to resume the upload process by following the instructions for 2.1. Checking upload's status and 2.2. How to resume an upload below.
- The upload did not succeed and it cannot be resumed.
The API may respond with an error message. This message helps to explain the cause of the failure. There are several cases of failure. It could also be due to the fact that your upload URL has expired.
2.1. Checking upload's status
If you want to check the status of a resumable upload, just send a PUT request to the upload URL that you received in 2. Sending the actual file.
PUT {uploadUrl}
Request Headers
In your request, set the Content-Range header value to bytes */{contentLength}, where {contentLength} is the total size of the file you are uploading.
Content-Length: 0
Content-Range : bytes */{contentLength}
X-Api-Key: your_api_key
Request Response
If the upload is already completed, the API will return the same response that it sent when the upload originally completed.
Otherwise, if the upload was interrupted or is still in progress, the response will have an 308 Resume Incomplete status code. In this response, the Range header specifies how many bytes of the file have already been successfully uploaded.
Here is an example:
308 Resume Incomplete
Content-Length: 0
Range: bytes=0-9999
Here, the Range header value is indexed from 0. This means that the first 10,000 bytes of the file have already been uploaded.
2.2 How to resume an upload
To resume an upload, you will need to send a PUT request to the upload URL received in 2. Sending the actual file.
PUT {uploadUrl}
Request Headers
Content-Length: {remainingContentLength}
Content-Range: bytes {firstByte}-{lastByte}/{contentLength}
X-Api-Key: your_api_key
Content-Lengthdefines the size (in bytes) of the content that has not yet been uploaded.Content-Rangedefines the portion of the file that you are uploading. The header value contains three very specific numbers:{firstByte}The 0-based numeric index of the byte number from which you are resuming the upload. Its value is one number higher than the second number in theRangeheader retrieved in the previous step. In the previous example, theRangeheader value was0-9999, so the first byte in a subsequent resumed upload request would be10000.{lastByte}The 0-based numeric index of the last byte of the binary file that you are uploading. Thus, it can be the last byte in the file. This means that if the file size was50000bytes, the last byte in the file would be49999.{contentLength}The total size of the file in bytes. Its value is the same as theX-Upload-Content-Lengthheader specified in the first upload request.
Request Body
Set the request body to the binary code for the portion of the file that has not yet been uploaded. The portion is defined in the request headers above.
Sending file in chunks
Instead of trying to upload an entire file and resuming the upload in event of a network interruption, your application can break the file into chunks and send a series of requests to upload the chunks in sequence.
The instructions for uploading a file in chunks are identical to the process explained above (2.2 How to resume an upload). However, the requests to start uploading a file (2. Sending the actual file) and to resume an upload (2.2 How to resume an upload) both set the Content-Length and Content-Range header values differently when a file is being uploaded in chunks.
Request Headers
Content-Length: 10000
Content-Type: application/octet-stream
Content-Range: bytes 0-9999/1000000
X-Api-Key: your_api_key
- The
Content-Lengthheader value specifies the size of the chunk that the request is sending. -
The
Content-Rangeheader specifies the bytes in the file that the request is uploading. The instructions for setting the Content-Range header in 2.2. How to resume an upload are applicable when setting this value.Based on the example above, a value of
bytes 0-9999/1000000shows that the request is sending the first 10,000 bytes in a 1,000,000 byte file.
Request Body
Set the request body to the binary code for the portion of the file that you are uploading.
Response
The request can lead to one of the following responses:
- The entire file has been uploaded. The API responds with a
201 Createdstatus code and returns the file URL in theLocationheader. -
Alternatively, if the request other than the final succeeds, the API responds with a
308 Resume Incompletestatus code. The response format is the same as the one described in 2.2 How to resume an upload above.Then, just use the upper value returned in the response's
Rangeheader to determine where to start the next chunk.