# createTempUploads

## Overview

This endpoint can be used for creating a collection of temporary upload endpoints, allowing for the performant and robust transfer of files to Redivis. Larger uploads can specify the *resumable* option, which allows for upload progress recovery in the case of intermittent network failures.

These temporary uploads can then be used both by either [upload.post](https://docs.redivis.com/api/rest-api/uploads/post) to upload a tabular file to a table, or [file.post](https://docs.redivis.com/api/rest-api/files/post) to add non-tabular files to a file index table.

{% hint style="info" %}
Data uploads can be quite complex. It is highly recommended to use one of the client libraries to upload your files (and handle resumable uploads for you), rather than calling this endpoint directly.
{% endhint %}

## HTTP Request

```http
POST /api/v1/tables/:tableReference/tempUploads
```

## Path parameters

| Parameter      |                                                                                                                                           |
| -------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| tableReference | A qualified reference to the table. See [referencing resources](https://docs.redivis.com/api/referencing-resources) for more information. |

## Request body

<table><thead><tr><th>Parameter</th><th width="185">Type</th><th>Description</th></tr></thead><tbody><tr><td>tempUploads</td><td><strong>Array&#x3C;object></strong></td><td><strong>Required.</strong> An array of objects, where each object corresponds to a single temp upload.</td></tr><tr><td>tempUploads[].size</td><td><strong>integer</strong></td><td><strong>Required.</strong> The size of the upload, in bytes.</td></tr><tr><td>tempUploads[].resumable</td><td><strong>bool</strong></td><td>Optional, default false. If specified, the created temp upload will be a resumable upload(see below). <br><br>Resumable uploads have some minor overhead, and are generally only recommended for larger files (> 100MB)</td></tr></tbody></table>

{% hint style="info" %}
This endpoint extends the [general API structure](https://docs.redivis.com/api/rest-api/general-structure).
{% endhint %}

## Authorization

Edit access to the table's dataset is required. Your access token must have one of the following scopes:

* data.edit

[Learn more about authorization.](https://docs.redivis.com/api/rest-api/authorization)

The request body must be empty.

## Response body

Returns an object whose `results` attribute is a list of temp uploads. The order of `results` will always correspond to the order of the `tempUploads` array in the request body.

```javascript
{
    "kind": "tempUploadList",
    "results": [
        {
            "kind": "tempUpload",
            "id": string,
            "url": string,
            "size": string,
            "resumable": bool
        },
        ...
    ]
    
}
```

## Performing non-resumable uploads

```bash
PUT <tempUpload.url>
```

To perform a temp upload where `resumable=false`, simply `PUT` the upload contents to the URL returned on the tempUpload.

## Performing resumable uploads

First, initiate the resumable upload by submitting a POST request with an empty body to the `tempUpload.url`. This post request must specify two-headers:

* `x-upload-content-length`: The size, in bytes, of the upload
* `x-goog-resumable`: `"start"`

If successful, the response from this initial request will include a `Location` header, which specifies the URL for all subsequent requests.

Next, perform the resumable upload. The general process for performing a resumable upload is to send the file in a series of chunks, via `PUT` requests to the url returned when creating the resumable upload. For each request, specify the `Content-Range` header to inform which chunk is currently being uploaded, and provide the content of the chunk in the request body.

If an error occurs when uploading a chunk, you can retry the upload [as specified below.](#resuming-an-interrupted-upload)

Resumable uploads expire after 24 hours.

### Request headers

<table><thead><tr><th width="249.9047078894614">Header</th><th>Description</th></tr></thead><tbody><tr><td><strong>Content-Range</strong></td><td><p>Set to show which bytes in the file you are uploading. </p><p></p><p>For example, <code>Content-Range: bytes 0-524287/2000000</code> shows that you are uploading the first 524,288 bytes (256 x 1024 x 2) in a 2,000,000 byte file.</p><p></p><p>If the total file size isn't known beforehand (for example, during streaming uploads that might perform processing on the stream), you can specify an unknown total size as: <code>Content-Range: bytes 0-524287/*</code> <br></p><p>If you are resuming an interrupted upload and want to know its progress, set the left part of the range to a <code>*</code> to signal that it is unknown. E.g., <code>Content-Range: bytes */2000000</code></p></td></tr></tbody></table>

### Request body

You should provide the current chunk content in the request body.

### Response body

Upon successfully transferring a chunk, the response body will be empty with a status of 200.

### Resuming an interrupted upload

If an upload request is terminated before receiving a response, or if you receive a `503` or `500` Service Unavailable response, then you need to resume the interrupted upload. To resume an interrupted upload:

1. To request the upload status, create an empty PUT request to the resumable session URI. <br>
2. Add a Content-Range header indicating that the current position in the file is unknown.\
   \
   For example, set the `Content-Range` to `*/2000000` if your total file length is 2,000,000 bytes.\
   \
   If you don't know the full size of the file, set the `Content-Range` to `*/*`.<br>
3. Send the request.<br>
4. Process the response.

   \
   A 200 OK or 201 Created response indicates that the upload was completed, and no further action is necessary. \
   \
   A 308 Resume Incomplete response indicates that you need to continue uploading the file.<br>
5. &#x20;If you received a 308 Resume Incomplete response, process the response's Range header, which specifies which bytes Cloud Storage has received so far. You will use this number in the next step. The response does not have a Range header if Cloud Storage has not yet received any bytes.\
   \
   For example, a Range header of bytes=0-42 indicates that the first 43 bytes of the file have been received.<br>
6. Now that you know where to resume the upload, continue uploading the file, either by sending the remaining data or by sending the next chunk. Include a Content-Range header indicating which portion of the file you are sending.\
   \
   For example, Content-Range: bytes 43-1999999/2000000 indicates that you are sending bytes 43 through 1,999,999.
