File Upload
In order to make file uploading as easy and flexible as possible we support several scenarios for this procedure.
Two-step upload
With Files API you can first upload files separately and then "attach" them to appropriate resources.
File
resource handling fields, that end with _file_id
(for single file) or with _file_ids
(for multiple files).
With this scenario you can also re-use uploaded files (i.e. "attach" the same file to different resources).
Upload to File resource
During the first step you upload files to the File
resource using the POST
HTTP method as described here.
POST /api/v1/files.json HTTP/1.1
Host: brewfictus.kayako.com
Content-Disposition: attachment; filename="coffee.png"
Content-Length: 2347
Content-Type: image/png
...
This is, in fact, the single-step upload to the File
resource.
Associate file with resource
For each uploaded file Files API generates unique ID, that can be used to associate the file with a resource during the second step. To do this pass the ID as a value for a resource's file handling field.
PUT /api/v1/profile.json HTTP/1.1
Host: brewfictus.kayako.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 17
avatar_file_id=19
Single-step upload
The single-step upload technique is used to upload files to resources directly.
Upload file content as request body
This is the simplest uploading technique from the low-level technical perspective.
To upload a file you can just pass its contents as the request body.
File name
To specify the name of the uploaded file (required in most cases) use the Content-Desposition
HTTP header:
POST /api/v1/files.json HTTP/1.1
Host: brewfictus.kayako.com
Content-Disposition: attachment; filename="coffee.png"
Alternatively, you can use the _filename
argument:
/api/v1/files.json?_filename=coffee.png
Field name
If the API end point expects a field name for the uploaded file (e.g. if multiple target fields are supported) use the Content-Desposition
HTTP header as follows:
POST /api/v1/files.json HTTP/1.1
Host: brewfictus.kayako.com
Content-Disposition: attachment; name="avatar"; filename="coffee.png"
Alternatively, you can use the _field
argument:
/api/v1/files.json?_field=avatar&_filename=coffee.png
File size
We strongly recommend to always specify the file size in the Content-Length
HTTP header of the request.
POST /api/v1/files.json HTTP/1.1
Host: brewfictus.kayako.com
Content-Length: 2347
This way you also ensure that an incomplete file won't be accepted by the server.
Checksum
To ensure, that content of the file was not damaged during the network transfer include the Content-MD5
header with the MD5 hash of the file into your request:
POST /api/v1/files.json HTTP/1.1
Host: brewfictus.kayako.com
Content-MD5: f9e590b40fe31ecd4e0c4fc3f3c0b9fd
Alternatively, you can use the _md5
argument:
/api/v1/files.json?_md5=f9e590b40fe31ecd4e0c4fc3f3c0b9fd
Complete example
Here is the complete example of the request headers, which can be used for uploading files using this technique:
POST /api/v1/files.json HTTP/1.1
Host: brewfictus.kayako.com
Content-Disposition: attachment; name="avatar"; filename="coffee.png"
Content-MD5: f9e590b40fe31ecd4e0c4fc3f3c0b9fd
Content-Length: 2347
Content-Type: image/png
...
CURL
Here is the example of the CURL command used for uploading files with this technique.
curl -X POST \
-H 'Content-Type: image/png' \
-d @coffee.png 'https://brewfictus.kayako.com/api/v1/files.json?_filename=coffee.png'
By default CURL always adds Content-Type: application/x-www-form-urlencoded
, what makes the API server think, that the body contains parameters.
So, to upload files as the body always specify the Content-Type, e.g. application/octet-stream
.
The special CURL file uploading mode is also supported:
curl -X POST \
-T coffee.png 'https://brewfictus.kayako.com/api/v1/files.json?_filename=coffee.png'
Using multi-part form data
This is the most commonly used uploading technique, which is used by web browsers to upload files to HTTP servers by default. This is also the only technique, that allows to upload files and to send parameters in a single request body. Additionally, this technique can be used to upload multiple files at once.
This technique is identified by the Content-Type
HTTP request header, which must be set to multipart/form-data
.
POST /api/v1/files.json HTTP/1.1
Host: brewfictus.kayako.com
Content-Type: multipart/form-data; boundary="1modcYGLAATJpapo8jhD4UwHbF5asu4u"
Here, the boundary is a special unique string, that is used to split the request body into "parts".
The request body and each its part must start with the special line:
--<boundary>
The last line of the request body must be:
--<boundary>--
Like a HTTP request each part of the multi-part request must start with HTTP headers, that describe this part, following by an empty line and the contents.
The following HTTP headers are supported for parts of the multi-part request:
Content-Disposition
is required and must be set toform-data
. Additionally, it may include thename
(field name) and thefilename
.Content-Length
is strongly recommended and must be set to the size of the content delivered inside the part.Content-MD5
can be specified to ensure that data won't be saved in a damaged state.Content-Type
can be used to specify the MIME type of the file.Content-Transfer-Encoding
to specify encoding of the content. Thebinary
encoding is recommended.
See also RFC 2388 for details.
Complete example
Here is the complete example of the request, that uses this format:
POST /api/v1/files.json HTTP/1.1
Host: brewfictus.kayako.com
Content-Type: multipart/form-data; boundary="1modcYGLAATJpapo8jhD4UwHbF5asu4u"
--1modcYGLAATJpapo8jhD4UwHbF5asu4u
Content-Disposition: form-data; filename="coffee.png"
Content-Type: image/png
Content-Transfer-Encoding: binary
...
--1modcYGLAATJpapo8jhD4UwHbF5asu4u
Content-Disposition: form-data; filename="cappuccino.png"
Content-Type: image/png
Content-Transfer-Encoding: binary
...
--1modcYGLAATJpapo8jhD4UwHbF5asu4u--
CURL
Here is the example of the CURL command, that uses this format:
curl -X POST \
-F "files[]=@coffee.png" \
-F "files[]=@cappuccino.png" 'https://brewfictus.kayako.com/api/v1/files.json'