Upload Asset
POST/api/v1/assets/new/content/original/upload
Use this API to upload one or more files and create assets within FileSpin. For uploads from websites, use the File Picker Web Widget.
This endpoint is served on https://upload.filespin.io — not the standard https://app.filespin.io host used by the rest of the API. Make sure your client targets the upload host for this request.
Note:
- To upload a single file, use
fileas multipart-form field name for file. - To upload multiple files in a single request, use
file1,file2,file3, etc. as multipart-form field names for files. - Each uploaded file will result in a new asset being created.
file,file1,file2,file3, etc. are conventional names for multipart-form field names. You can use any name for the field names.
Adding metadata to the asset
There are two ways to add custom metadata to the asset.
- Update the asset with custom metadata once the upload completes. See Update Data API to do this.
- Send custom metadata with the upload. To send custom asset metadata with the upload, include JSON metadata as string in
custom_metadataform-data field, like below. Custom metadata sent as below will be added to the asset.
curl --request POST \
--url https://upload.filespin.io/api/v1/assets/new/content/original/upload \
--header 'X-FileSpin-Api-Key: YOUR_API_KEY' \
--header 'content-type: multipart/form-data' \
--form file=@sample.jpg \
--form 'custom_metadata={"data":{"foo":"bar"}, "data_schema_id":1}'
The custom_metadata field JSON value follows the same format and rules as the Update Data API payload.
Note: Since data being sent as multipart/form-data, custom_metadata JSON should be sent as string as shown above.
Recording where the file came from
Add source to custom_metadata to record where the file came from, so users can find the asset by the folder names they know:
--form 'custom_metadata={"data":{"foo":"bar"}, "source":{"system":"my-uploader", "path":"~/Projects/Acme/Spring 2026/hero.jpg"}}'
| Key | Description |
|---|---|
source.system | Required in source. What uploaded the file: lowercase letters, digits and hyphens, up to 40 characters (e.g. my-uploader). |
source.path | Optional. The file's path where it came from, up to 1024 characters. A home directory (/Users/<name>/, /home/<name>/, C:\Users\<name>\) is stored as ~. |
They are stored on the asset as _filespin_source_system and _filespin_source_path. These fields are read-only: data can't set them, and the words of the path are keyword-searchable (searching spring finds a file under Acme_Spring/). A malformed source is rejected with HTTP 400. Replacements keep the asset's original source.
HTTP RESPONSE
Standard HTTP Status Code (200 or 202)
| Key | Value | Description |
|---|---|---|
files | JSON | List of files |
id | string | Asset ID, 32 character alphanumeric UUID |
name | string | File name |
size | integer | Size of file in bytes |
checksum | string | MD5 checksum |
content_type | string | MIME type |
provider | string | Always "local" to indicate local upload |
success | boolean | true if upload completed, false otherwise |
metadata | JSON | Only returned for custom plans. Applies to image uploads. Where available, Exiftool tag values for 'ColorMode', 'ColorSpace', 'Orientation', 'Make' and 'Model' are returned. 'Width' and 'Height' are always returned |
Response JSON
{
"files": [
{
"id": "99d819953914402babbdeb68337ea6a3",
"name": "sample.jpg",
"size": 8836363,
"checksum": "5f5f26bd7c0f62c6e02e44c73d09734e",
"content_type": "image/jpeg",
"metadata": {
"Make": "Apple",
"ColorSpace": "sRGB",
"Model": "iPhone 3G",
"Orientation": "Horizontal (normal)",
"width": 1200,
"height": 800
}
}
],
"success": true,
"provider": "local"
}
Request
Responses
- 200
- 400
- 401
- 500
Asset uploaded successfully
Invalid upload request
Unauthorized
Internal server error