Overview
How the API stores pictures, videos and documents.
An Asset is a file stored by the API: product picture and video, invoice, label, attachment. Each Asset belongs to one seller. You send the file straight to storage through a signed URL, without the content going through the API.
Where it fits in the journey: Catalog and stock.
Endpoints
| Method | Path | What it does |
|---|---|---|
POST | /v1/sellers/{sellerId}/assets/uploads | Create upload |
POST | /v1/assets/uploads/{uploadId}/complete | Complete upload |
POST | /v1/assets/ingestions | Import from a URL (coming soon) |
POST | /v1/sellers/{sellerId}/media-copies | Copy media |
GET | /v1/assets/{assetId} | Get asset |
DELETE | /v1/assets/{assetId} | Delete asset |
GET | /v1/assets/{assetId}/content | Read content |
Two classes
class | Examples | Access |
|---|---|---|
product_media | listing picture and video | GET /v1/assets/{assetId} returns a signed url valid for 15 min |
confidential | invoice XML, label, attachment | never has a url; only through content, which logs the access |
Accepted types: image/jpeg, image/png, image/webp, video/mp4, application/pdf, and application/xml, checked against the content, not the name. The limit is 10 MiB for images, 100 MiB for MP4, 20 MiB for PDF, and 5 MiB for XML. SVG and HTML are always refused. application/xml is only accepted for confidential. A product_media PDF has a url, and it downloads the file as an attachment instead of opening it in the browser.
How to send
- Create the upload with the class, the type, and the exact size of the file. The response has
urlandheaders. - Send the file with
PUTto thaturl, repeating theheadersunchanged. They are signed: another size or type gets403from the storage. - Complete the upload. The API checks size and type against the content and returns the asset
readyorfailed, with itsfailureReason.
# 1. create the upload
curl -X POST "$API/v1/sellers/$SELLER_ID/assets/uploads" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{ "class": "product_media", "contentType": "image/jpeg", "sizeBytes": 482113, "filename": "front.jpg" }'
# 2. PUT with the url and headers from the response
curl -X PUT "$UPLOAD_URL" \
-H "Content-Type: image/jpeg" \
-H "Content-Length: 482113" \
--data-binary @front.jpg
# 3. complete
curl -X POST "$API/v1/assets/uploads/$UPLOAD_ID/complete" \
-H "Authorization: Bearer $API_KEY"The PUT URL is valid for 15 minutes. After that, complete answers 409 upload_expired. If you call complete before the file arrives, you get 409 upload_not_received and can try again. A second complete answers 409 upload_already_completed.
When the asset is ready (or fails), the API sends the asset.ready or asset.failed webhook. The event carries only the id, class, status, and reason, never the URL.
Bringing a file from a URL (import from a URL) is not in the API yet.
Rules
- A seller's listing only accepts that seller's media. To use the same picture in another seller, copy the asset: the copy is made inside the storage, becomes a new asset (
source: copy), and the original stays as it is. - Delete removes the asset and its file. If any product, variant, or listing still points at it, the answer is
409 asset_in_use: remove the reference first. Deleting the seller deletes its files. - Products and variants keep media by
assetId: see Products.
Every asset route answers 503 STORAGE_UNAVAILABLE when file storage is not
configured in the environment.