# Uploading a file This page documents how to upload a file through the FarmMaps API. The FarmMaps file upload API follows the [Google Drive API](https://developers.google.com/drive/api/v3/manage-uploads#resumable) loosely. Files smaller than 2 MB are uploaded in a single part, larger files need to be split into parts of 1 MB. The workflow for uploading a file is as follows: * Register the file for upload. * Uploading the file chunks * Downloading the file to check (optional) **Prerequisites** - To be able to perform requests, make sure you have an [access token](/wiki/Create-access-token). ### Registering the upload Before a file can be uploaded it needs to be registered. Files smaller than 2 MB can be uploaded in one chunk. Bigger files need to be uploaded in chunks of 1 MB. The uploaded files are structured in a hierarchy, so we'll specify a `parentCode` to identify its parent. We'll first retrieve this parentcode using a GET request to the "my_drive" (root)folder. **Request** Replace `` with your actual token. ```http GET https://farmmaps.awacc.nl/api/v1/folders/my_drive? HTTP/1.1 Host: farmmaps.awacc.nl Accept: application/json Authorization: Bearer ``` **Response** The response will be something similar to: ```http HTTP/1.1 200 OK Server: nginx/1.14.0 (Ubuntu) Date: Tue, 21 Apr 2020 09:57:07 GMT Content-Type: application/json; charset=utf-8 Transfer-Encoding: chunked Connection: keep-alive Cache-Control: no-store,no-cache Pragma: no-cache Content-Encoding: br Vary: Accept-Encoding { "url":"/api/v1/folders/f25d8765a1cd407cb235961c73c268cf:USER_FILES", "code":"f25d8765a1cd407cb235961c73c268cf:USER_FILES", "name":"My Drive", "created":"2019-09-25T19:39:33.841835", "updated":"2019-09-25T19:39:33.841835", "itemType":"ROOT_FOLDER", "size":0, "state":0, "thumbnail":false } ``` So the `parentcode` we need is **"f25d8765a1cd407cb235961c73c268cf:USER_FILES"** We can now register the file. In the request to register the upload, we specify its parent (`parentCode`), the filename (`name`), and the size in bytes (`size`) in the body. **Request** ```http POST /api/v1/file HTTP/1.1 Accept: application/json Authorization: Bearer Content-Type: application/json Cache-Control: no-cache Host: farmmaps.awacc.nl Accept-Encoding: gzip, deflate, br Connection: keep-alive Content-Length: 115 { "parentCode": "f25d8765a1cd407cb235961c73c268cf:USER_FILES", "name": "example.csv", "size": 67351 } ``` **Response** If all went well, we should recieve a response with status code 201, indicating that a new file was registered. ```http HTTP/1.1 201 Created Server: nginx/1.14.0 (Ubuntu) Date: Tue, 21 Apr 2020 10:08:56 GMT Content-Type: application/json; charset=utf-8 Transfer-Encoding: chunked Connection: keep-alive Cache-Control: no-store,no-cache Pragma: no-cache Content-Encoding: br Location: /api/v1/file/147357a252044a098788492729c4d551 Vary: Accept-Encoding { "code":"147357a252044a098788492729c4d551", "chunks":1, "parentCode":"f25d8765a1cd407cb235961c73c268cf:USER_FILES", "name":"example.csv", "size":67351, "chunkSize":67351, "data":{} } ``` For files larger than 2 MB we also need to specify the chunksize (`chunkSize`): ```http POST /api/v1/file HTTP/1.1 Accept: application/json Authorization: Bearer Content-Type: application/json Cache-Control: no-cache Host: farmmaps.awacc.nl Accept-Encoding: gzip, deflate, br Connection: keep-alive Content-Length: 147 { "parentCode": "f25d8765a1cd407cb235961c73c268cf:USER_FILES", "name": "sampledata2.csv", "size": 7265743, "chunkSize": 1048576 } ``` **Response** The response now shows the amount of chunks that we'll need to send ("chunks":7). ```http HTTP/1.1 201 Created Server: nginx/1.14.0 (Ubuntu) Date: Tue, 21 Apr 2020 14:27:05 GMT Content-Type: application/json; charset=utf-8 Transfer-Encoding: chunked Connection: keep-alive Cache-Control: no-store,no-cache Pragma: no-cache Content-Encoding: br Location: /api/v1/file/f319e9c6bfe3493cba1a888f6292f00a Vary: Accept-Encoding { "code":"f319e9c6bfe3493cba1a888f6292f00a", "chunks":7, "parentCode":"f25d8765a1cd407cb235961c73c268cf:USER_FILES", "name":"sampledata2.csv", "size":7265743, "chunkSize":1048576, "data":{} } ``` ### Uploading the chunks The upload URL contains the registration code, and ends with the chunk number. The body of the request contains the data of the chunk. For uploading the first chunk, we can use the request below. Subsequent chunks can be uploaded by increading the chunk number at the end and adding the next chunk in the body. **Request** ```http POST /api/v1/file/9c27d92fd44e43cf975275a2bec5c5f5/chunk/1 HTTP/1.1 Accept: application/json Authorization: Bearer Cache-Control: no-cache Host: farmmaps.awacc.nl Accept-Encoding: gzip, deflate, br Connection: keep-alive Content-Type: multipart/form-data; boundary=--------------------------272838473781934324854095 Content-Length: 1048788 ----------------------------272838473781934324854095 Content-Disposition: form-data; name="Chunk"; filename="sampledata2_1.csv" ----------------------------272838473781934324854095-- ``` **Response** The response should show a 200 status code, confirming that the chunk was recieved succesfully: ```http HTTP/1.1 200 OK Server: nginx/1.14.0 (Ubuntu) Date: Tue, 21 Apr 2020 15:07:19 GMT Content-Length: 0 Connection: keep-alive Cache-Control: no-store,no-cache Pragma: no-cache ``` When uploading the final chunk of the file a 201 status code should be returned. This indicates all chunks have been uploaded. The file will now be ready for further processing. ```http HTTP/1.1 201 Created Server: nginx/1.14.0 (Ubuntu) Date: Tue, 21 Apr 2020 15:21:01 GMT Content-Type: application/json; charset=utf-8 Transfer-Encoding: chunked Connection: keep-alive Cache-Control: no-store,no-cache Pragma: no-cache Content-Encoding: br Location: /api/v1/item/9c27d92fd44e43cf975275a2bec5c5f5 Vary: Accept-Encoding ``` ### Downloading the uploaded file To verify that your file was uploaded and re-assembled correctly you can download the file using a simple GET request. ```http GET /api/v1/items/9c27d92fd44e43cf975275a2bec5c5f5/data HTTP/1.1 Accept: application/json Authorization: Bearer Cache-Control: no-cache Host: farmmaps.awacc.nl Accept-Encoding: gzip, deflate, br Connection: keep-alive ``` This will return the file as an attachment: ```http HTTP/1.1 200 OK Server: nginx/1.14.0 (Ubuntu) Date: Tue, 21 Apr 2020 16:05:25 GMT Content-Type: application/octet-stream Content-Length: 0 Connection: keep-alive Cache-Control: no-store,no-cache Pragma: no-cache Content-Disposition: attachment; filename=sampledata2.csv; filename*=UTF-8''sampledata2.csv ``` **Troubleshooting** |Status code|Description| |---|---| |200|Chunk was uploaded| |201|All chunks from file have been uploaded| |400|Error: the chunk number exceeds the total number of chunks calculated earlier| |401|Error: not authenticated| |404|Error: the chunk cannot be added to a registered file (not found)|