Complete upload
Checks the uploaded file and makes the asset ready.
Call it after the PUT. The API checks the size and the type from the content (SVG and HTML are refused) and answers the asset as ready, or failed with a failureReason. A failed asset does not recover: create another upload.
It works once per upload:
409 upload_not_received: the file has not reached the storage yet. Upload it and call again.409 upload_already_completed: this upload was already completed.409 upload_expired: the 15 minutes passed. Create another upload.
The result is also sent in the asset.ready and asset.failed webhooks.
api_keyAuthorizationBearer <token>API key (mk_...)
uploadId*stringIdentifier of the upload, from POST …/assets/uploads.
^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$uuidIdempotency-Key?stringOptional. A unique value (for example a UUID), 1 to 255 characters, that makes the request safe to retry: repeating it with the same body within 24h returns the original response with Idempotency-Replayed: true instead of running the operation again. Scoped to your account. Reusing it with a different body returns 409.
1 <= length <= 255The checked asset: ready, or failed with failureReason when the size or the content did not match what was declared (the file was discarded).
application/json- response
A file stored by marketapi: listing media or a confidential document.
id*stringIdentifier of the asset.
^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$uuidsellerId*stringSeller that owns the asset.
^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$uuidclass*stringAccess class. confidential never has a url: read it through GET /v1/assets/{assetId}/content. product_media has a signed url while ready.
"confidential""product_media"status*stringpending_upload until the upload is completed, processing while it is checked, then ready or failed. New values may be added: do not treat this list as closed.
"pending_upload""processing""ready""failed"contentType*stringMedia type. Declared at the upload and confirmed against the content before ready.
"image/jpeg""image/png""image/webp""video/mp4""application/pdf""application/xml"sizeBytes*integerSize of the file, in bytes.
1 <= value <= 9007199254740991sha256*|SHA-256 of the content, in hex. null until the asset is ready.
^[0-9a-f]{64}$filename*|File name given at the upload, used in the download. null when none was given.
source*stringHow the asset was created: upload by the client, copy of another asset, or brought in by the API (ingestion, marketplace).
"upload""ingestion""copy""marketplace"failureReason*|Why the asset is failed: the size or the content did not match what was declared (size_mismatch, content_type_mismatch), the content is not an accepted type (unsupported_content, which includes SVG and HTML), the file is too large (size_exceeded), the upload was never completed (upload_expired) or its check was interrupted (processing_interrupted). null otherwise.
"size_mismatch""size_exceeded""content_type_mismatch""unsupported_content""upload_expired""processing_interrupted"nullurl*|Signed download URL, valid until urlExpiresAt (15 minutes). Only for a ready product_media asset; always null for confidential. Read the asset again for a fresh one.
uriurlExpiresAt*|When url stops working. null when there is no url.
^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z))$date-timecreatedAt*stringWhen the asset was created.
^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z))$date-timeupdatedAt*stringWhen the asset last changed.
^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z))$date-timecurl -X POST "https://example.com/v1/assets/uploads/9e2b5f14-6c3d-4e8a-b1f7-0d4c2a6e8b31/complete"{ "id": "4a7f2701-c5f7-477f-9658-5ce6be74ef80", "sellerId": "b6a1c0de-3f0c-4f53-9c6e-2a1d7d3b9e10", "class": "product_media", "status": "ready", "contentType": "image/jpeg", "sizeBytes": 482113, "sha256": "3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b", "filename": "front.jpg", "source": "upload", "failureReason": null, "url": "https://storage.example.com/marketapi-assets/assets/4a7f2701-c5f7-477f-9658-5ce6be74ef80?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=900&X-Amz-Signature=5d1b9c", "urlExpiresAt": "2026-10-16T12:15:00.000Z", "createdAt": "2026-10-16T12:00:00.000Z", "updatedAt": "2026-10-16T12:00:05.000Z"}