Upload

The upload resource represents data in the state of being uploaded. It is nested under the scope of the resource the data belongs to, for example under a clip.

The following steps are necessary to perform an upload:

  1. Acquire the URI of the parent resource
  2. Create the resource (file or clip) you want to upload to
  3. Create the upload, passing the total size.
  4. Upload the first chunk using the update action.
  5. Repeat the last step until the entire data has been transferred

The step of splitting the data in chunks is optional. However it is recommended to do so for large files. The chunk size is up to the client application, reasonable chunk sizes are a couple of megabytes. The chunk size should not exceed 32 MB and all chunks, except the last one, must have the same size.
All uploads to the main webgate server are cancelled.

Attributes
total_size Integer 12345 create Total size of the upload in bytes.
chunk Integer 2 update Number of chunk provided. Defaults to 1
Actions
Create POST {resource_path}/upload necessary data: {"total_size": total upload size in bytes (int not string)}
Update PUT {resource_path}/upload?chunk=13 Header must contain: "Content-Type: application/octet-stream"

Both actions respond with data providing the current_size and total_size in the namespace flowuploader::upload E.g.

{ "status": 201,
  "status_message": "Created",
  "info": "",
  "data": { "flowuploader::upload": {
            "current_size": 0,
            "total_size": 13,
            "url":  "..." }
          } }

Example

The following requests demonstrate uploading the ASCII data "Hello World!!", nested under the fictional resource "/greetings/7" using a chunk size of 4.

Step 1: Create upload

Request:

POST /greetings/7/upload HTTP/1.1
Authorization: Bearer example-token
Content-Type: application/json

{"upload": {"total_size":13} }

Response:

HTTP/1.1 201 Created

{ "status": 201,
  "status_message": "Created",
  "info": "",
  "data": { "flowuploader::upload": {
            "current_size": 0,
            "total_size": 13,
            "url":  "..." }
          } }

Step 2: Upload first chunk

Request:

PUT /greetings/7/upload?chunk=1 HTTP/1.1
Authorization: Bearer example-token
Content-Type: application/octet-stream
Content-Length: 4

Hell

Response:

HTTP/1.1 200 OK

{ "status": 200,
  "status_message": "OK",
  "info": "",
  "data":  { "flowuploader::upload": {
              "current_size": 4,
              "total_size": 13,
              "url":  "..." }
           } }

Step 3: Upload second chunk

Request:

PUT /greetings/7/upload?chunk=2 HTTP/1.1
Authorization: Bearer example-token
Content-Type: application/octet-stream
Content-Length: 4

o Wo

Response:

HTTP/1.1 200 OK

{ "status": 200,
  "status_message": "OK",
  "info": "",
  "data": { "flowuploader::upload": {
            "current_size": 8,
            "total_size": 13,
            "url":  "..." }
          } }

Step 4: Upload third chunk

Request:

PUT /greetings/7/upload?chunk=3 HTTP/1.1
Authorization: Bearer example-token
Content-Type: application/octet-stream
Content-Length: 4

rld!

Response:

HTTP/1.1 200 OK

{ "status": 200,
  "status_message": "OK",
  "info": "",
  "data": { "flowuploader::upload": {
            "current_size": 12,
            "total_size": 13,
            "url":  "..." }
          } }

Step 5: Upload last chunk

Request:

PUT /greetings/7/uploadchunk=4 HTTP/1.1
Authorization: Bearer example-token
Content-Type: application/octet-stream
Content-Length: 1

!

Response:

HTTP/1.1 200 OK

{ "status": 200,
  "status_message": "OK",
  "info": "",
  "data": { "flowuploader::upload": {
            "current_size": 12,
            "total_size": 13,
            "url":  "..." }
          } }

Errors

The following error conditions are defined for uploads:

  • 404 in response to: PUT Attempted to upload data before the upload has been created.
  • 422 in response to: POST Invalid data passed to the create action (e.g. tried to create an upload of negative size).
  • 422 in response to: PUT Attempted to upload more data than specified during create.

Tutorial - Upload a clip into a new playlist

Step 1: Choose a project for the upload!

Request:

GET /api/projects HTTP/1.1
Authorization: Bearer example-token

Response:

HTTP/1.1 200 OK

{
  "status": 200,
  "status_message": "OK",
  "info": "",
  "data": {"array":[{"id":6,"name":"Philipp's Project","starts_at":"2013-07-17","ends_at":"2015-01-08"},
                    {"id":8,"name":"project 3","starts_at":"2011-07-07","ends_at":"2055-01-01"}]}
}

Step 2: Choose a folder for the upload!

Request:

GET /api/projects/6/folders HTTP/1.1
Authorization: Bearer example-token

Response:

HTTP/1.1 200 OK

{
  "status": 200,
  "status_message": "OK",
  "info": "",
  "data": {"array":[{"id":1,"name":"philipp","project_id":6,"parent_id":null},
                    {"id":7,"name":"test 2","project_id":6,"parent_id":null},
                    {"id":8,"name":"test 3","project_id":6,"parent_id":null},
                    {"id":129,"name":"Dailies","project_id":6,"parent_id":null},
                    {"id":257,"name":"another useless folder","project_id":6,"parent_id":null},
                    {"id":258,"name":"another useless folder","project_id":6,"parent_id":null}]}
}

Step 3: (optional) List child folders of "philipp" (id=1)

Request:

GET /api/projects/6/folders?parent_id=1 HTTP/1.1
Authorization: Bearer example-token

Response:

HTTP/1.1 200 OK

{
  "status": 200,
  "status_message": "OK",
  "info": "",
  "data": {"array":[{"id":157,"name":"metadata","project_id":6,"parent_id":1},
                    {"id":158,"name":"flickr","project_id":6,"parent_id":1},
                    {"id":163,"name":"file_mass","project_id":6,"parent_id":1},
                    {"id":223,"name":"galleries","project_id":6,"parent_id":1},
                    {"id":255,"name":"another useless subfolder","project_id":6,"parent_id":1}]}
}

Step 4: Create a playlist in e.g. "metadata" (id=157)

Request:

POST /api/projects/6/folders/157/playlists HTTP/1.1
Authorization: Bearer example-token
Content-Type: application/json

data: {"name":"how-to-upload"}

Response:

HTTP/1.1 201 Created

{
  "status": 201,
  "status_message": "Created",
  "info": "",
  "data": {"playlist":{"id":61441,"name":"how-to-upload","folder_id":157}}
}

Step 5: Create a playlist item in "how-to-upload" (id=61437)

Request:

POST /api/projects/6/folders/157/playlists/61441/items HTTP/1.1
Authorization: Bearer example-token
Content-Type: application/json

data: {"playlist_id":61441}

Response:

HTTP/1.1 201 Created

{
  "status": 201,
  "status_message": "Created",
  "info": "",
  "data": {"playlistitem":{"id":1371,"playlist_id":61441,"clip_id":1173,"position":1}}
}

Step 6: Create an upload

Note: To upload the clip, the resource path for the upload is /api/projects/6/clips/1173 and NOT /api/projects/6/folders/157/playlists/61441/items/1371

Request:

POST /api/projects/6/clips/1167/upload HTTP/1.1
Authorization: Bearer example-token
Content-Type: application/json

upload: {"total_size":29533258}

Response:

HTTP/1.1 201 Created

{
  "status": 201,
  "status_message": "Created",
  "info": "",
  "data": {"flowuploader::upload":{"current_size":0,"total_size":29533258}}
}

Step 7: Upload the video file

Request:

PUT /api/projects/6/clips/1167/upload HTTP/1.1
Authorization: Bearer example-token
Content-Type: application/octet-stream



cURL example:
curl -X PUT localhost:3000/api/projects/6/clips/1169/upload -H "Authorization: Bearer example-token"
-H "Content-Type: application/octet-stream" -T "/path/to/video.mp4"

Response:

HTTP/1.1 200 OK

{
  "status": 200,
  "status_message": "OK",
  "info": "",
  "data": {"flowuploader::upload":{"current_size":29533258,"total_size":29533258}}
}