Zenfolio service supports two ways of uploading photos from the user's computer, both of them based on the HTTP POST request. The first method is the standard form-based file upload as described in RFC 1867. The second method uses a simplified POST request that is often easier to implement than a form-based upload.
Regardless of the method, the first step in uploading is to obtain the upload URL. Photos and videos are always uploaded into an existing gallery and the upload URL is specific to a gallery. To obtain the upload URL, obtain the PhotoSet snapshot with the LoadPhotoSet method. The upload URL for photos is returned in the UploadUrl field of the snapshot, the upload URL for videos can be found in the VideoUploadUrl field, and the upload URL for Raw files can be found in the RawUploadUrl field.
Note that the user need to opt in to using the Raw Storage feature before Raw files can be uploaded. See Raw Storage Opt-in section below for more detail.
When using form-based HTTP POST, the returned URL can be used "as is". When using the simplified POST method, a few additional parameters need to be added to the URL to describe the photo being uploaded.
When uploading files with a POST request, you need to prepare post data in the multipart/form-data format and submit it in the request body. As the name suggests, the data in this format consists of several parts, one of which is the actual file data. Below is an example of a form-based POST request.
POST /demouser/p340540780/upload.ushx HTTP/1.1<cr><lf> Host: up.zenfolio.com<cr><lf> User-Agent: Upload Sample Application<cr><lf> Content-Type: multipart/form-data; boundary=8a47a5f4dc58498da616<cr><lf> Content-Length: 1290606<cr><lf> X-Zenfolio-Token: 6cA3p2kbk1MvGplnQ-NgGtaKf1B3PaDPqOOCORpR/cnyAAKoeyGz=<cr><lf> <cr><lf> --8a47a5f4dc58498da616<cr><lf> Content-Disposition: form-data; name="file"; filename="test.jpg"<cr><lf> Content-Type: image/jpeg<cr><lf> <cr><lf> [binary file data]<cr><lf> --8a47a5f4dc58498da616<cr><lf> Content-Disposition: form-data; name="file_modified"<cr><lf> <cr><lf> Fri, 28 Jan 2005 13:15:04 GMT<cr><lf> --8a47a5f4dc58498da616--<cr><lf>
As you can see, the request body consists of two parts. The top part, which has to be named "file", contains the file data. The content type of this part should be set accordingly to the actual file type (image/jpeg in this example). The original file name has to be provided in the Content-Disposition header of this part.
The bottom part is optional. If present, it has to be named "file_modified" and it should contain the file modification time in the RFC 1123 format. If this part is omitted, the server tries to get the image modification date from the image metadata. However, if the file has no metadata, this part is the only way a server can know the file modification date, so it is advisable to include it.
Here are some tips and tricks regarding form-based POST requests:
With the simplified HTTP POST, file data constitute the entire request body and any additional information is passed as query string parameters. Below is an example of a simplified POST request (note that the first line of the request is wrapped for readability):
POST /demouser/p340540780/upload.ushx?filename=test.jpg &modified=Fri,+28+Jan+2005+13%3A15%3A04+GMT HTTP/1.1<cr><lf> Host: up.zenfolio.com<cr><lf> User-Agent: Upload Sample Application<cr><lf> Content-Type: image/jpeg<cr><lf> Content-Length: 1290221<cr><lf> X-Zenfolio-Token: 6cA3p2kbk1MvGplnQ-NgGtaKf1B3PaDPqOOCORpR/cnyAAKoeyGz=<cr><lf> <cr><lf> [binary file data]
Here are the important differences between the simplified POST requests and the form-based requests:
With both the form-based and the simplified POST requests, server response consists of a single line that specifies the identifier of the photo, video, or gallery file just uploaded, for example:
HTTP/1.1 200 Uploaded<cr><lf> Content-Type: text/plain<cr><lf> Content-Length: 11<cr><lf> <cr><lf> 327977501<cr><lf>
If upload fails, the server returns a standard or a non-standard HTTP response code. The following table lists non-standard HTTP response codes that can be returned by the Zenfolio server:
Video duration limit is exceeded
User storage quota is exceeded
The photo file size is greater than allowed by user's subscription plan
The photo dimensions are too big
The file format is invalid or not supported
The photo file size exceeds maximum value supported
Users need to opt in to using the Raw Storage feature before Raw files can be uploaded. In Zenfolio Edit View, this happens when a Raw file is first selected for uploading.
Applications can determine whether the user has already opted in for the Raw Storage feature by analyzing the RawStorageOptedIn field of the User snapshot. Note this field is only returned as part of the private profile, so the application needs to use the LoadPrivateProfile method to obtain the snapshot.
If RawStorageOptedIn is set to true, no further action is necessary and Raw files can be uploaded right away. Otherwise, the user should be navigated to the URL provided in the RawStorageOptInUrl field of the User snapshot. This will send the user to a Zenfolio page where they can read the terms and agree to using the feature.
Once the user returns to the application, the application should load user's private profile again to confirm that RawStorageOptedIn is now set to true.