Contact Us

If you still have questions or prefer to get help directly from an agent, please submit a request.
We’ll get back to you as soon as possible.

Please fill out the contact form below and we will reply as soon as possible.

  1. Fotoware Alto
    • 11.14 Schreckhorn
    • Terminology
    • Solutions
    • User Guide - Deutsch
    • User Guide - English
    • API Changelog
  2. Fotoware Veloz
    • Managing users and groups
    • Configuring archives
    • Configuring workflows
    • Configuring site behavior
    • Navigating and searching to find your assets
    • Working with your assets
    • Editing asset metadata
    • Uploading files
    • Version Control in Fotoware
    • Albums - Creating and sharing collections
    • Placing assets in a CMS
    • Working with the Fotoware Pro interface
    • Using the Fotoware plugins
    • Consent management
    • User guide to FotoWeb for iPad (Legacy)
    • Picture conferencing with FotoWeb Screens (Legacy)
    • What's what in Fotoware
    • GDPR
    • Fotoware Veloz releases
    • Activity Exports
    • Fotoware Example Workflows
  3. Fotostation
    • Getting started with Fotostation
    • Viewing, selecting and sorting files
    • Managing your assets with archives
    • Adding metadata to assets
    • Searching for assets
    • Working with your assets
    • Version Control in Fotostation
    • Automating tasks with Actions
    • Configuring metadata fields and editors
    • Configuring Fotostation
    • Configuring Fotostation for multi-user environments
    • Troubleshooting Fotostation
  4. Fotoware Flow
    • What is Flow?
    • Getting started
    • Flow dictionary
  5. Fotoware On-Premises
    • Getting started
    • Index Manager
    • FotoWeb
    • Color Factory
    • Connect
    • Operations Center Guide
  6. Integrations and APIs
    • The Fotoware API
    • Creating integrations using embeddable widgets
    • Authorizing applications using OAuth
    • Auto-tagging
    • FotoWeb Drag and Drop export
    • Integration using webhooks
    • Optimizely and Episerver plugin documentation
    • User Interface Integrations
  7. Fotoware Mobile
    • User guide for Fotoware Mobile for iPhone and Android
    • User guide to FotoWeb for iPad (Legacy)
    • User guide to FotoWeb for iPhone and Android (Legacy)

Contact Us

If you still have questions or prefer to get help directly from an agent, please submit a request.
We’ll get back to you as soon as possible.

Please fill out the contact form below and we will reply as soon as possible.

  • Support

Table of Contents

Required permissions Upload procedure 1. Send initial upload request 2. Send file data 3. Send XMP sidecar file (if required) 4. Poll status for completion Send initial upload request Request syntax Applying metadata to fields during upload Example: Applying metadata to non-bag fields Example: Applying metadata to a bag field A special case: Metadata in PDF files Metadata fields that are automatically set Order in which metadata is applied Changing the file attributes during upload Example: Preserving the modification date/time of uploaded assets Full example of an initial upload request Response: 200 OK Response: 400 Bad Request Response: 403 Forbidden Send file data Request syntax Response: 204 No Content Response: 404 Not Found Response: 415 Unsupported Media Type Response: 400 Bad Request Response: 409 Conflict Send XMP sidecar file (optional) Response: 204 No Content Response: 404 Not Found Response: 415 Unsupported Media Type Response: 400 Bad Request Response: 409 Conflict Poll status for completion Response: 200 OK Response: 403 Forbidden Using the Upload API for Version Control
  • Home
  • Integrations and APIs
  • The Fotoware API
  • Fotoware API Overview

Upload API

Applications and integrations can ingest assets into Fotoware by using the Upload API to transfer a file by sending it in a series of chunks.

15. May 2025

Elaine Foley

Table of Contents

Required permissions Upload procedure 1. Send initial upload request 2. Send file data 3. Send XMP sidecar file (if required) 4. Poll status for completion Send initial upload request Request syntax Applying metadata to fields during upload Example: Applying metadata to non-bag fields Example: Applying metadata to a bag field A special case: Metadata in PDF files Metadata fields that are automatically set Order in which metadata is applied Changing the file attributes during upload Example: Preserving the modification date/time of uploaded assets Full example of an initial upload request Response: 200 OK Response: 400 Bad Request Response: 403 Forbidden Send file data Request syntax Response: 204 No Content Response: 404 Not Found Response: 415 Unsupported Media Type Response: 400 Bad Request Response: 409 Conflict Send XMP sidecar file (optional) Response: 204 No Content Response: 404 Not Found Response: 415 Unsupported Media Type Response: 400 Bad Request Response: 409 Conflict Poll status for completion Response: 200 OK Response: 403 Forbidden Using the Upload API for Version Control

Required permissions

Upload requests require the following:

  • If non-interactive application authorization is used, then the client can upload assets to any location where upload is supported.
  • If the client is impersonating a specific user, then that user must have upload permission on the upload location.

Note: The maximum file size for upload is 25 GB.

Upload procedure

An asset is uploaded using the following 4-step process:

1. Send initial upload request

POST /fotoweb/api/uploads/


Client makes a request to start an upload and specifies all the parameters (e.g. destination, filename, file size). If successful, the server creates an upload task and returns the upload details that the client uses in further requests.

2. Send file data

POST /fotoweb/api/uploads/<UPLOAD_ID>/chunks/<CHUNK_INDEX>


Client sends a file in one or more chunks based on the details returned by the initial upload request.
Server checks if all chunks have been received, based on file size.

3. Send XMP sidecar file (if required)

POST /fotoweb/api/uploads/<UPLOAD_ID>/xmp


Client sends a XMP sidecar file based on the details returned by the initial upload request.

4. Poll status for completion

GET /fotoweb/api/uploads/<UPLOAD_ID>/status


Client repeatedly polls the status of the upload task to monitor the progress and completion of the upload.
Upload is finished when post-processing is finished on the server.

 

Send initial upload request

The initial upload request begins the process of uploading a single asset by setting up an upload task with a unique Upload ID, which is used in all following API requests. The Upload ID is not a credential, and the API requests still use regular authentication and permission checking, which means each user can only access their own uploads.

Metadata can be specified in this step.

The destination parameter of the initial upload request determines where the asset will be uploaded to. To upload a new asset to an archive, set the destinationto the URL of the collection. For On-Premises systems, it is possible to upload an asset to the Upload Area by setting the destination to null.

Metadata fields can be overwritten, extended, or deleted using metadata patch instructions in the metadata parameter. Metadata patch instructions are applied relative to the existing XMP metadata in the uploaded asset. 

Metadata of the uploaded asset is applied as follows:

  • If an XMP sidecar file is uploaded, then the metadata in the XMP sidecar file is used. Any embedded metadata in the asset file itself is ignored.
  • Otherwise, embedded XMP metadata in the asset file is used, if present (and if the file format supports it).
  • Finally, metadata patch instructions, provided in the metadata attribute of the initial upload request, are applied relative to the provided XMP metadata. See the section about applying metadata for details.

Request syntax

POST /fotoweb/api/uploads/
Content-Type: application/json
Accept: application/json

with a request body containing the upload request parameters in JSON format:

01

02

03

04

05

06

07

08

09

10

11

12

13

{

"destination": "/fotoweb/archives/5000/DocFolder/SubFolder/",

"folder": "NewFolder1/NewSubFolder2/" | null

"filename": "image.jpeg" | null

"hasXmp": true | false,

"fileSize": 3145728,

"checkoutId": "..." | null,

"metadata": {

fields: [...],

attributes: [...]

} | null

"comment": "..." | null

}

Initial upload request parameters:

Parameter Type Description
destination URL (String)

The destinationcan be one of the following:

  • URL of the collection (e.g. archive or folder) to upload to.
    Folders can only be used on archives which have the Copy / Move / Upload to archive option set to User selection. The destination folder must be able to contain files, for instance, a document folder, but not a union member. Use the folder parameter (see below) to create new folders.
  • URL of the asset to upload a new revision.
  • null to upload to the On-Premises Upload Area.

Note: The collection or asset MUST exist!

folder URL (String)

The folderparameter is optional and is used to create new folders during an upload only when the destination is a collection URL for an archive with the Copy / Move / Upload to archive option set to User selection, otherwise the request will return 400 Bad Request. Also, the canCreateFoldersflag must be true for the destinationcollection. For more information, see Ingestion.

This must be set to nullwhen using an asset URL destination or an On-Premises Upload Area destination. If the folderparameter is not present the files will be uploaded to the location specified by the destinationcollection URL.

To create folders, set the folder parameter to a list of nested folders separated by forward-slashes (e.g. "NewFolder1/NewSubFolder2") which will be created relative to the location given in the destination collection URL. Leading and trailing slashes in the folder path are ignored, and multiple slashes are treated as single slashes (e.g. "/folder1//folder2/" is interpreted as "folder1/folder2"). The special folder names . and .. are treated as invalid, as are all other invalid folder names, e.g. names containing invalid characters such as ?*.

  • Using this folderparameter is the only way of creating new folders during upload.
  • The folder specified by the destination collection URL must already exist, or the request will fail.
  • Folder names are expected to be encoded in UTF-8 and must be specified "plain text" without any escaping (such as "percent-encoding" or "HTML-encoding") of any characters.
  • Each folder name must be a valid Windows folder name. Folder names are case-insensitive. The server may make adjustments to the name, such as normalization of accented characters.
  • The folder may or may not exist, and is created if it does not exist.
  • All files will be uploaded to the innermost folder.
filename String Filename of the file being uploaded and MUST be given when uploading to a folder.

If destinationis an existing asset URL, then this parameter SHOULD be null when the filename of the asset is not meant to change. When uploading a new revision of an existing asset which also changes the filename or extension, then the filename parameter specifies the new filename.
hasXmp Boolean

This boolean value specifies whether an XMP sidecar file is to be uploaded.

  • true: An XMP sidecar file with metadata is uploaded along with the asset.
  • false: No XMP sidecar file is uploaded.

If set to true, the XMP sidecar file must be sent using the Send XMP sidecar file command before the upload can be finalized.

fileSize Integer Exact size of the file in bytes.
checkoutId String This parameter MUST be set to null.

Used by internal Fotoware plug-ins to upload a new version of a checked-out file.
metadata Object

The metadataparameter contains metadata patch instructions which are used to change the metadata of the uploaded file. See Applying metadata to fields during upload below for more details.

  • fieldsJSON object containing the metadata patch instructions.
  • attributesJSON object containing the attribute patch instructions. This can be used for preserving modification date on upload.
comment String Comment to add to the revision. Set comment to nullwhen not required.

When uploading a new revision of a file that already exists, this becomes the comment of the new revision.

 

Applying metadata to fields during upload

Metadata can be applied to an asset during upload. This ensures strong metadata consistency in Fotoware archives. If a client uploaded an asset and applied metadata later in a separate request, then these assets might be without metadata, without consistent metadata or without required metadata fields for a short period of time after the upload. Applying metadata during upload ensures that all assets in the Fotoware systems always have fully consistent metadata.

Metadata can be applied to an asset in an upload request. This is done by adding a metadata parameter to the request body to apply fieldspatch instructions to the asset:

01

02

03

04

05

06

07

08

09

10

11

12

{

...

"metadata": {

"fields": [

{"id": 5, "value": "Roadrunner"},

{"id": 80, "value": "Wyle E. Coyote", "action": "add"},

{"id": 25, "action": "erase"},

{"id": 25, "action": "add", "value": ["chicken", "food"]}

]

}

...

}

Metadata patch instructions

In the JSON body, fields is an array of metadata patch instructions where each instruction has the following parameters:

Parameter Type Description
id Integer Numeric ID of the destination metadata field.

This parameter is required.
action String Metadata action to perform, as described below.

This parameter is optional. If omitted, the default action is "add".
value String, Array(String) Metadata value(s) to set or add.

This parameter is optional or required, depending on the action, as described below.

Depending on the action and field type, this can be a single value (given as a string) or zero or multiple values (given as an array of strings).

The action parameter defines what the metadata patch instruction does:

action Description
"add"

Set the field to the given value or values.

The value parameter is required.

If the destination field is a bag field, then either a single value or multiple values may be given and will be added to the existing items in the destination bag field. Otherwise, at most one value may be given (either as a string or as an array containing a single string element). If an empty array is given, then this action does nothing.

Example:

// If the field is a non-bag field:
"value": "foo" // Replaces existing value with "foo"
"value": ["foo"] // Replaces existing value with "foo"
"value": [] // valid, but does nothing
"value": ["foo", "bar"] // INVALID, because at most one value may be given
// If the field is a bag field:
"value": "foo" // Adds "foo" to existing values
"value": ["foo"] // Adds "foo" to existing values
"value": ["foo", "bar"] // Adds "foo" and "bar" to existing values
"value": [] // valid, but does nothing
"append"

Append the given valueto the existing value of the destination field. If the field does not have a value, then this action is equivalent to "add".

If the field is a bag field, then the given value is appended to the first value of the existing array of values of the field.

The value parameter is required and must be a string containing a single value.

"prepend"

Prepend the given value to the existing value of the destination field. If the field does not have a value, then this action is equivalent to "add".

If the field is a bag field, then the given value is prepended to the first value of the existing array of values of the field.

The value parameter is required and must be a string containing a single value.

"erase"

Remove the given field from the metadata.

If the field is a bag field, then all values in the bag are removed.

Example: Applying metadata to non-bag fields 

The following metadata patch instructions:

1

2

3

4

5

6

7

8

{

"fields": [

{"id": 500, "value": "V1"},

{"id": 501, "action": "erase"},

{"id": 502, "action": "append", "value": "V3"},

{"id": 503, "action": "prepend", "value": "V4"}

]

}

modifies the existing metadata as follows:

Field Existing value Final value
500 E1 V1
501 E2 (empty)
502 E3 E3V3
503 E4 V4E4

Example: Applying metadata to a bag field

The following metadata patch instructions:

1

2

3

4

5

6

7

{

"fields": [

{"id": 25, "action": "erase"},

{"id": 25, "action": "add", "value": ["food", "chicken"]},

{"id": 80, "action": "add", "value": "Wyle E. Coyote"}

]

}

modifies the following existing metadata as follows:

Field Existing values Final values
25

foo

bar

food

chicken

80 Roadrunner

Roadrunner

Wyle E. Coyote

Note:  To replace all values in a bag field with new values, use the erase action before adding new values with the add action.

A special case: Metadata in PDF files

When uploading PDF files to Fotoware, any metadata that is added to the PDF during upload will be committed to storage as an XMP sidecar that accompanies the PDF. This has the practical implication that when subsequently downloading the PDF from a Fotoware user interface, a zip file will be delivered with the PDF file and the sidecar included. However, when downloading PDFs using the API, for which there is no UI, only the PDF file will be delivered, and any added metadata will not be included in the downloaded file since it has not been embedded. 

To successfully embed metadata into the PDF so that it can be downloaded completely via the API, there are two options:

  • Apply the metadata to the PDF post-upload. This will ensure that any sidecar information is embedded in the actual PDF
  • Execute a metadata patch operation on any field in the PDF post-upload. This will trigger the re-indexing of the PDF and embed any sidecar information into the PDF file.

Metadata fields that are automatically set

When uploading assets, Fotoware sets certain fields automatically. This is described here.

Order in which metadata is applied

When an asset is uploaded, any metadata changes will be applied in the following order:

The revision's metadata will be set to the metadata of the uploaded file when uploading a new revision.

The metadata in the uploaded XMP sidecar file will overwrite the asset's metadata if hasXmp is true.

Otherwise, ALL XMP metadata embedded in the uploaded asset or an XMP sidecar file will be stored in the system, including unknown fields and fields that are not in any metadata views or in the metadata configuration (MDC).

Changing the file attributes during upload

You can change the file attributes of an asset during upload by adding a metadata parameter to the request body to apply attributes patch instructions to the asset:

1

2

3

4

5

6

7

8

9

{

...

"metadata": {

"attributes": [

{"key": "mt", "value": "2022-12-24T11:22:33Z"}

]

}

...

}

Parameter Description
key

Specifies which attribute to set.

  • "mt": File modification time
value

Specifies the value of the attribute.

Example: "mt": "2018-01-02T11:22:33Z"

The ISO 8601 format is accepted.

Note: Time zone information is not retained. The value MUST be in UTC with an explicit time zone designator (Z).

Example: Preserving the modification date/time of uploaded assets

When uploading assets via the API you might want to preserve the original modification time of the assets being uploaded. To do so, get the file modification date from the file to upload (e.g. using the file system API on your platform), then send it in the upload request using the "mt" attribute, as shown here:

01

02

03

04

05

06

07

08
09

10

11

12

13

{

"destination": "/fotoweb/archives/5000/",

"filename": "sunset.jpg"

"hasXmp": false,

"fileSize": 895841,

"checkoutId": null,

"metadata": {

"attributes": [

{"key": "mt", "value": "2022-02-10T14:22:33Z"}

]

} 

"comment": null

}

Full example of an initial upload request

The following example shows request parameters to initiate uploading a 5 GB video file to new subfolders within an archive with changes to the metadata and file attributes:

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

{

"destination": "/fotoweb/archives/5000/DocFolder/SubFolder/",

"folder": "NewFolder1/NewSubFolder2/"

"filename": "roadrunnervideo.mp4"

"hasXmp": false,

"fileSize": 5368709120,

"checkoutId": null,

"metadata": {

"fields": [

{"id": 5, "value": "Roadrunner"},

{"id": 80, "value": "Wyle E. Coyote", "action": "add"},

{"id": 25, "action": "erase"},

{"id": 25, "action": "add", "value": ["chicken", "food"]}

],

"attributes": [

{"key": "mt", "value": "2022-12-24T11:22:33Z"}

]

} 

"comment": null

}

 

Response: 200 OK

On success, the upload response is:

200 OK
Content-Type: application/json

with a response body:

1

2

3

4

5

6

{
"id": "<UPLOAD_ID>",

"chunkSize": 4194304,

"numChunks": 1280,

"hasXmp": false

}

Parameter Type Description
id String The <UPLOAD_ID> is a random 128-bit GUID encoded as BASE64URL.
chunkSize Integer The upload chunk size in bytes.
numChunks Integer Total number of chunks to upload.
hasXmp Boolean

This boolean value specifies whether an XMP sidecar file is to be uploaded.

true: An XMP sidecar file with metadata is uploaded along with the file chunks.

false: No XMP sidecar file is uploaded.

If set to true, the XMP sidecar file must be sent using the Send XMP sidecar file command before the upload can be finalized.

Response: 400 Bad Request

On a bad request, the response is:

400 Bad Request

with a response body:

1

2

3

4

5

6

{
"value": "<VALUE>",
"heading": "...",
"description": "...",

"technicalInfo": “...”

}

where <VALUE> is:

Bad Request <VALUE> Description
invalid_argument If one or more request parameters have invalid parameters (such as fileSizebeing negative), or the request body is in an invalid JSON format.
metadata_not_allowed Ifmetadata was not nullor hasXmpwas true.
destination_invalid_url If the value of destinationwas an invalid URL.
destination_not_found If the asset or collection given by destinationwas not found or the archive was disabled.
destination_invalid_asset If destinationrefers to an asset URL and the uploaded revision file type is unsuitable for existing asset (e.g. file extension of uploaded revision file is not compatible with file extension of existing asset).
destination_invalid_location
  • If destination refers to a folder, but the input location setting of the archive is NOT set to User Selection.
  • If destination refers to a folder, but the given folder does NOT allow upload (e.g., root of an index or union member in Index Manager, or a smart folder).
  • (Fotoware On-Premises only) If destination refers to the root of the archive, but the input location setting of the archive is set to User Selection AND the Show document Folders option is enabled for the archive.
  • If destinationrefers to the root of the archive, but the archive has no folders that allow upload (e.g. no document folders in Index Manager).
  • (Fotoware SaaS only) Ifdestination is nullit is an invalid location on a Fotoware Veloz tenant.
  • (Fotoware On-Premises only) If destination is null for uploading to the Upload Area but the Enable Upload Area option on the site is disabled or the Group permission Allow uploads to the upload area is disabled.
invalid_filename
  • If fileNameis not null, and fileNameis not a valid filename.
  • If fileNameis null, and destinationrefers to a folder.
invalid_folder

If folderis not null, and

  • the folder name is invalid (e.g. has invalid characters).
  • the input location setting of the archive is NOT set to User Selection.
  • destinationrefers to an asset URL.
  • (Fotoware On-Premises only)  destination is null for uploading to the user Upload Area, it is not possible to create folders.
invalid_checkout_id If checkoutIdwas given and was not valid.

The other Bad Request attributes (heading, description, technicalInfo) are the standard human-readable error information returned by all API endpoints.

Response: 403 Forbidden

On a forbidden request, the response is:

403 Forbidden

This error will occur if: 

  • the user does not have permission to upload in the destination archive
  • the user does not have the Allow upload to upload area group permission and destination is null
  • thecheckoutId exists but does not belong to the user.

Send file data

Using the information from the initial upload response begin uploading the file in "chunks".

Chunking

The chunk size is returned in the response to the initial upload request. The number of chunks of a file depends only on the file size:

numChunks = ceil(fileSize / chunkSize)

Chunk indexes are zero-based so the first chunk to upload will have <CHUNK_INDEX> = 0.

Chunks can be uploaded in any order, even in parallel. The client application will need to keep track of which chunks have been successfully received by the server or have failed and need to be retried. The server will return 204 No Content when a chunk has been successfully received. Truncated upload requests are rejected.

Clients may retry uploading the same chunk after a request timeout. If a chunk has already been received successfully, then a request to upload it again will fail with 409 Conflict with no other side effects. If any number of multiple upload requests of the same chunks are made simultaneously, then at most one of them may return 204 No Content (and its content will be used). All others should fail with 409Conflictif no other error occurs. In this case, it is unspecified which request will succeed. This means that it is safe to retry upload requests, even when it is unknown if the server has received a previous attempted request, as long as all requests to upload the same chunk have an identical payload.

Once all the chunks have been successfully received, the upload is finalized on the server by creating an upload background task to merge the chunks into a single file. Uploading chunks after an upload is finalized results in a 409 Conflict error but has no other side effects and the upload background task will continue.

If an upload is not finalized, and no more chunks have been received for a certain amount of time, then the upload has expired. All future attempts to upload with the same <UPLOAD_ID> will result in response 404 Not Found.

HTTP Multipart requests

Upload uses HTTP Multipart requests, as defined in RFC1341 (external link).

Note: You usually do not need to implement RFC1341 yourself. Most likely, the HTTP client library of your programming platform, which you use for sending HTTP requests, has built-in support for HTTP multipart requests. This is the standard format for uploading files, so check if your HTTP client library has functions for attaching files to requests.

All line breaks must be CR+LF. For more information, see RFC 7578 (external link).

Request syntax

POST /fotoweb/api/uploads/<UPLOAD_ID>/chunks/<CHUNK_INDEX>
Content-Type: multipart/form-data;boundary=<RANDOM_BOUNDARY>
--<RANDOM_BOUNDARY>
Content-Disposition: form-data;name="chunk";filename="chunk"
Content-Type: application/octet-stream
<BINARY_CHUNK_DATA>
--<RANDOM_BOUNDARY>--
Parameter Type Description
<UPLOAD_ID> String The Upload ID returned by the initial upload request.
<CHUNK_INDEX> Integer Chunk index is the unique zero-based number of the chunk which needs to be incremented by 1 for each chunk. The first chunk to upload will have <CHUNK_INDEX> = 0. The last chunk will have <CHUNK_INDEX> = numChunks-1.
<RANDOM_BOUNDARY> String A random string (at least 16 bytes) created by the client.
name String The example "chunk" value for name is ignored.
filename String The example "chunk" value for filename is ignored.
<BINARY_CHUNK_DATA> Binary data The content of the chunk that will contain chunkSizebytes of binary data.

Here is an example of a complete upload request for a file chunk:

POST /fotoweb/api/uploads/<UPLOAD_ID>/chunks/<CHUNK_INDEX>
Content-Type: multipart/form-data; boundary=WUG7zDvyA3hVq16Q
--WUG7zDvyA3hVq16Q
Content-Disposition: form-data;name="chunk";filename="chunk"
Content-Type: application/octet-stream
<BINARY_CHUNK_DATA>
--WUG7zDvyA3hVq16Q--

Response: 204 No Content

On success, the upload chunk response is:

204 No Content

Response: 404 Not Found

If there is no upload task with ID <UPLOAD_ID> that belongs to the requesting user, the upload chunk response is:

404 Not Found

Note: If an upload is not finalized, and no more chunks have been received for a certain amount of time, then the upload has expired. All future attempts to upload with the same <UPLOAD_ID> will result in 404 Not Found

Response: 415 Unsupported Media Type

If the request body is not multipart/form-data, the upload chunk response is:

415 Unsupported Media Type

Response: 400 Bad Request

On a bad request, the upload chunk response is:

400 Bad Request

with a response body:

1

2

3

4

5

6

{
"value": "<VALUE>",
"heading": "...",
"description": "...",
"technicalInfo": "..."
}

where <VALUE> is:

Bad Request <VALUE> Description
invalid_chunk_index If the chunk index is negative or greater than the number of chunks (numChunks) for the given upload task .
invalid_chunk_size If the chunk size is wrong and doesn't match the chunkSizereturned by the initial upload response.
invalid_number_of_files If no files or more than one file were attached to the request body.
any other value If the request is otherwise invalid.

The other Bad Request attributes (heading, description, technicalInfo) are the standard human-readable error information returned by all API endpoints.

Response: 409 Conflict

When a chunk with the same index has already been received successfully or the same chunk is already being uploaded by another process, the upload chunk response is:

409 Conflict

with a response body:

1

2

3

4

5

6

{
"value": "<VALUE>",
"heading": "...",
"description": "...",
"technicalInfo": “...”

C

where <VALUE> is:

Conflict <VALUE> Description
already_finalized If the upload task is not in awaitingData state.
already_uploaded If the chunk with the same index has already been uploaded.

The other Bad Request attributes (heading, description, technicalInfo) are the standard human-readable error information returned by all API endpoints.

Send XMP sidecar file (optional)

This step is only necessary if the original file has metadata stored in an XMP sidecar file. If the original file does not have an XMP sidecar file, this step can be skipped.

This is an optional request to upload an XMP sidecar file that contains the metadata of the asset file. If the asset has an XMP sidecar file, then the initial upload request must declare it usinghasXmpis true. The XMP sidecar file can then be uploaded in one go using the following request, and the upload will be finalized once the server has received all the chunks and the XMP sidecar file.

POST /fotoweb/api/uploads/<UPLOAD_ID>/xmp
Content-Type: multipart/form-data;boundary=<RANDOM_BOUNDARY>
--<RANDOM_BOUNDARY>
Content-Disposition: form-data;name="xmp";filename="xmp"
Content-Type: application/octet-stream
<XMP_DATA>
--<RANDOM_BOUNDARY>--

HTTP Multipart requests

Upload uses HTTP Multipart requests, as defined in RFC1341 (external link).

Note: You usually do not need to implement RFC1341 by yourself. Most likely, the HTTP client library of your programming platform which you use for sending HTTP requests has built-in support for HTTP multipart requests. This is the standard format for uploading files, so check if your HTTP client library has functions for attaching files to requests.

All line-breaks must be CR+LF. For more information, see RFC 7578 (external link).

Parameter Type Description
<UPLOAD_ID> String The Upload ID returned by the initial upload request.
<RANDOM_BOUNDARY> String A random string (at least 16 bytes) created by the client.
name String The example "xmp" value for name is ignored.
filename String The example "xmp" value for filename is ignored.
<XMP_DATA> Binary data The content of the XMP sidecar file.

Response: 204 No Content

On success, the XMP sidecar file upload response is:

204 No Content

Response: 404 Not Found

If there is no upload task with ID <UPLOAD_ID> that belongs to the requesting user, the XMP sidecar file upload response is:

404 Not Found

Response: 415 Unsupported Media Type

If the request body is not multipart/form-data, the XMP sidecar file upload response is:

415 Unsupported Media Type

Response: 400 Bad Request

On a bad request, the XMP sidecar file upload response is:

400 Bad Request

with a response body:

1

2

3

4

5

6

{

"value": "<VALUE>",
"heading": "...",
"description": "...",
"technicalInfo": "..."
}

where <VALUE> is:

Bad Request <VALUE> Description
invalid_metadata If the XMP data is malformed.
metadata_not_allowed If the initial upload task was created without hasXmp set to true.
invalid_number_of_files If no files or more than one file were attached to the request body.
any other value If the request is otherwise invalid.

The other Bad Request attributes (heading, description, technicalInfo) are the standard human-readable error information returned by all API endpoints.

Response: 409 Conflict

On a conflict, the XMP sidecar file upload response is:

409 Conflict

with a response body:

1

2

3

4

5

6

{
"value": "<VALUE>",
"heading": "...",
"description": "...",
"technicalInfo": "..."

}

where <VALUE> is:

Conflict <VALUE> Description
already_finalized If the upload task is not in awaitingData state.
already_uploaded If the XMP sidecar file has already been uploaded.

The other Bad Request attributes (heading, description, technicalInfo) are the standard human-readable error information returned by all API endpoints.

Poll status for completion

This request is made to poll the status of the upload.

GET /fotoweb/api/uploads/<UPLOAD_ID>/status
Accept: application/json

Response: 200 OK

On success, the status response is:

200 OK
Content-Type: application/json

with a response body:

01
02


03

04

05

 

06

07

08

09

10

11

{
"status": "awaitingData" | "pending" | "inProgress" | "done" | "failed",

"result": {

"assetUrl": "/fotoweb/archives/5000/DocFolder/SubFolder/file.jpeg" | null,

"assetDetails": {...} | null

} | null,

"error": {

"value": "...",

"message": "..."

} | null

}

Parameter Type Description
status Enum (string)

The status of the <UPLOAD_ID> upload task.

  • awaitingDataSome chunks or the XMP file have not been received yet.
  • pendingThe upload is finalized and has been queued for processing.
  • inProgressThe upload is finalized and is being processed.
  • doneThe upload has completed successfully and result contains more information.
  • failedThe upload has failed and error contains more information.

Theresult and error are both null unless specified otherwise above.

result Array of Objects The result of the upload task.
This is null unless status is done.
result.assetUrl URL (String) The assetUrl is the API URL of the uploaded asset.
If the input location of the archive is a custom file system folder, thenassetUrlisnull.
result.assetDetails Asset (Object) The assetDetails object is the asset representation of the asset.
If the input location of the archive is a custom file system folder, thenassetDetailsis null.
error Array of Objects The error reported by the upload task.
This is nullunless status is failed .
error.value Enum (String)

Symbolic name of the type of error that has occurred when uploading this asset.
Can be used programmatically to distinguish between errors.

  • uploadFailedThe upload has failed for unspecified reasons and can be retried.
  • destinationDoesNotExistThe destination folder or archive no longer existed at the time of finalizing the upload.
  • forbiddenThe user no longer has permission to perform the upload at the time of finalizing the upload.
  • corruptedXmpThe XMP sidecar file is corrupted.
  • rejectedThe upload has been rejected and should not be retried. This can be due to file filtering rules or other safeguards.
error.message String Human-readable description of error that has occurred that can be displayed to a user.
This attribute is null if the asset has been uploaded successfully and status is not failed.
This attribute is not present if status is done.

Response: 403 Forbidden

On a forbidden request, the status response is:

403 Forbidden

This error will occur if the <UPLOAD_ID> does not exist OR belongs to a different user.

Using the Upload API for Version Control

The Version Control system allows an existing asset to be replaced with a new revision by setting the destinationto the URL of the asset in the initial upload request. The uploaded asset will be added as the latest revision and replace all the metadata with the contents of the uploaded file.

transfer api submit api

Was this article helpful?

Yes
No
Give feedback about this article

Related Articles

  • Using database lookup to populate metadata fields with photographer information
  • Turning filenames into usable, searchable metadata
  • Transferring assets that have been used in production into a long-term archive
eco-lighthouse-miljøfyrtårn

Company

  • About us
  • Resellers
  • Careers
  • Contact us

Help & support

  • Support center
  • Consultancy
  • Tech partners
  • Fotostation
  • System status

Trust Center

  • Legal
  • Security
  • Sustainability & ESG

Locations

Fotoware AS (HQ)
Tollbugata 35
0157 OSLO
Norway
FotoWare Switzerland AG
Industriestrasse 25
5033 Buchs (AG)
Switzerland

Copyright 2025 Fotoware All rights reserved.

  • Terms of service
  • Privacy policy
  • Cookie policy

Knowledge Base Software powered by Helpjuice

Expand