Assets and media

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

MethodPathWhat it does
POST/v1/sellers/{sellerId}/assets/uploadsCreate upload
POST/v1/assets/uploads/{uploadId}/completeComplete upload
POST/v1/assets/ingestionsImport from a URL (coming soon)
POST/v1/sellers/{sellerId}/media-copiesCopy media
GET/v1/assets/{assetId}Get asset
DELETE/v1/assets/{assetId}Delete asset
GET/v1/assets/{assetId}/contentRead content

Two classes

classExamplesAccess
product_medialisting picture and videoGET /v1/assets/{assetId} returns a signed url valid for 15 min
confidentialinvoice XML, label, attachmentnever 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

  1. Create the upload with the class, the type, and the exact size of the file. The response has url and headers.
  2. Send the file with PUT to that url, repeating the headers unchanged. They are signed: another size or type gets 403 from the storage.
  3. Complete the upload. The API checks size and type against the content and returns the asset ready or failed, with its failureReason.
# 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.