Files
The Files API stores binary assets behind stable file_... IDs so the rest of Commerce can reference them safely. Use it for product images, product videos, digital downloads, and support documents when you want durable asset IDs instead of ad hoc remote URLs.
The file object
A file is the stable record for uploaded bytes. Other Commerce resources should store the file ID, not the original upload URL or local filename.
Properties
- Name
purpose- Type
- string
- Description
Purpose policy used to validate and store the file:
product_downloadfor downloadable product files and merchant-managed attachments. Accepts.pdf,.zip,.txt, and.csvfiles up to 100 MiB. Not linkable through file links.product_imagefor product images. Accepts JPEG, PNG, and GIF up to 10 MiB. Linkable through file links.product_videofor product videos. Accepts MP4, WebM, and QuickTime up to 250 MiB. Linkable through file links.products_importfor product-catalog imports. Accepts CSV files up to 32 MiB that follow the required import schema and contain no more than 10,000 data rows. Not linkable through file links.support_documentfor support evidence and attachments. Accepts PDF, JPEG, PNG, and plain text up to 25 MiB. Not linkable through file links.
For products_import, every nonblank data row must contain at least these columns in order: name, type, price_currency, price_value, reference, description, about, category, tax_code, unit_dimension, price_label, publish, and attributes. An optional first header row may use those names in the same order. The file must contain between 1 and 10,000 data rows.
Upload a file
Upload one file with multipart/form-data. Use this endpoint when your backend already has the bytes; use Create an upload request when someone outside your backend should upload directly.
Send retry keys with the Idempotency-Key header. The API rejects idempotency_key form fields so the key cannot be confused with file custom data.
Request body
Response
The response returns a top-level file object. Store file.id on the Commerce resource that will reference the asset.
Request
curl https://api.zebo.dev/files/create \
-H "Authorization: Bearer $COMMERCE_API_KEY" \
-H "Idempotency-Key: upload-hero-image-001" \
-F "purpose=product_image" \
-F "title=Hero image" \
-F 'custom_data={"product_ref":"SKU-12345"}' \
-F "file=@./hero.png;type=image/png"
{
"file": {
"id": "file_4q6YcQk1RzPv2mDa8nFw0sHu",
"purpose": "product_image",
"status": "available",
"scan_status": "skipped",
"name": "Hero image",
"filename": "hero.png",
"content_type": "image/png",
"size": 248391,
"checksum_sha256": "db6f2f1d7b4b4d9d9c30a3ddcc7f9d506e8c9d67c4a61e5b9fd2dd9b0f5d0000",
"created_by": { "type": "api_key" },
"source": { "type": "direct" },
"storage": { "encoding": "br", "stored_size": 211042 },
"delivery": {
"public_url": "<PUBLIC_FILE_URL>",
"cache_control": "public, max-age=31536000, immutable",
"content_type": "image/png"
},
"custom_data": { "product_ref": "SKU-12345" },
"metadata": { "source_type": "direct" },
"created_at": "2026-06-05T12:30:00Z",
"updated_at": "2026-06-05T12:30:00Z",
"available_at": "2026-06-05T12:30:00Z"
}
}
Lookup a file
Retrieve details for one file. Lookup does not return file bytes; use Download file contents for the original object stream.
Request body
Response
The response returns a top-level file object.
Request
curl https://api.zebo.dev/files/lookup \
-H "Authorization: Bearer $COMMERCE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"file_id":"file_4q6YcQk1RzPv2mDa8nFw0sHu"}'
Page files
List files for the authorized application. Filters are optional and can be combined to find files by lifecycle state, purpose, or creation window.
Request body
Response
Files are returned newest first. The response returns a top-level page object with files, number, and size; size is the number of files returned, not the requested limit. An exhausted page returns files: [] and size: 0. Page numbers and sizes below 1 are normalized to their defaults.
Request
curl https://api.zebo.dev/files/page \
-H "Authorization: Bearer $COMMERCE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"purpose":"product_image","status":"available","page_number":1,"page_size":25}'
{
"page": {
"number": 1,
"size": 1,
"files": [
{
"id": "file_4q6YcQk1RzPv2mDa8nFw0sHu",
"purpose": "product_image",
"status": "available",
"content_type": "image/png",
"size": 248391
}
]
}
}
Download file contents
Deliver the original file through an authenticated backend request. Use this for private downloads and for file purposes that cannot be exposed through file links.
Request body
Response
With delivery: stream, the API returns 200 OK with the file bytes, its content type, Content-Disposition, and Cache-Control: private, max-age=60. Content-Length is present when the original byte length can be reported directly.
With delivery: redirect, the API returns 303 See Other with a short-lived download URL in Location and no file body. The current SDK download helpers use stream delivery; send the JSON request with your HTTP client when you need redirect delivery.
A missing file returns 404. Unreadable contents return 424, an unsupported stored representation returns 422, and a temporarily unavailable operation returns 503.
Stream request
curl https://api.zebo.dev/files/contents \
-H "Authorization: Bearer $COMMERCE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"file_id":"file_4q6YcQk1RzPv2mDa8nFw0sHu","disposition":"attachment"}' \
--output hero.png
Delete a file
Tombstone a file when you no longer need it. Deletion returns 409 while live Commerce resources still reference the file. After deletion succeeds, links to the file can no longer serve its contents.
This endpoint supports Idempotency-Key. Reuse the same key and request when retrying an uncertain deletion result.
Request body
Response
The response returns the deleted file object with status set to deleted.
Request
curl https://api.zebo.dev/files/delete \
-H "Authorization: Bearer $COMMERCE_API_KEY" \
-H "Idempotency-Key: delete-file-001" \
-H "Content-Type: application/json" \
-d '{"file_id":"file_4q6YcQk1RzPv2mDa8nFw0sHu"}'
{
"file": {
"id": "file_4q6YcQk1RzPv2mDa8nFw0sHu",
"purpose": "product_image",
"status": "deleted"
}
}