Upload files
POST /bucket/upload
Up to 20 files in one request.
Headers
zetta-api-key— your app’s API key.zetta-app-name— your app’s name, e.g.my-shop. Case and spaces around it do not matter.
Request
- Body:
multipart/form-data. - Field
files— one part per file. The field isfiles;fileis refused. Each part needs its real content type, notapplication/octet-stream. - Field
subFolder— optional. Groups files underuploads/<app>/<subFolder>; slashes are allowed,..is not.
Success response
201,success: true, and one entry per stored file indata.files:id,url,storedName,originalName,size.sizeis what was stored, after photos are converted to WebP.skippedFileslists any file that was refused, with a reason.
{
"success": true,
"message": "✅ 1 images uploaded. ",
"data": {
"files": [
{
"id": "0b7c3f9e-5a3e-4d57-9a53-3a1f2c9d8e11",
"url": "https://cloud.zettabyteincorp.com/uploads/my-shop/avatars/photo-1759570000000.webp",
"storedName": "photo-1759570000000.webp",
"originalName": "photo.jpg",
"size": 48213
}
]
},
"skippedFiles": []
}Errors
- 401
MISSING_API_KEYThezetta-api-keyheader is missing. - 401
MISSING_APP_NAMEThezetta-app-nameheader is missing. - 403
INVALID_APP_CREDENTIALSNo app has this name with this key. - 403
STORAGE_LIMIT_EXCEEDEDThe app has used all its storage. Upgrade the plan or delete files. - 403
SUBSCRIPTION_SUSPENDEDThe paid period ended more than 7 days ago and was not renewed. Pay the renewal invoice to restore uploads. - 403
SERVER_STORAGE_FULLThe service’s disk is full. Not your fault; try again later. - 201
success: falseNo file in the request, every file refused (wrong type), or an invalidsubFolder. Readmessage;skippedFilessays which file and why. - 413—A file is larger than 50 MB.
Examples
URL=https://cloud.zettabyteincorp.com/backend/api
curl -s -X POST "$URL/bucket/upload" \
-H "zetta-api-key: $ZETTA_API_KEY" \
-H "zetta-app-name: my-shop" \
-F "files=@photo.jpg" \
-F "subFolder=avatars" \
| grep -o '"url":"[^"]*' | cut -d'"' -f4