Version: 1.0Updated on: October 5th, 2026
This manual is for brand partners publishing the multimedia of their own products — videos, 360 spins, manuals, leaflets, energy labels, safety sheets, and other documents that travel with a product. It describes what a brand account can do and the limits that apply.
Read Manual for Brand Partners: Icecat Push-API (API-IN) first. This page continues it, and assumes you have it behind you: what a product is, how international and local content differ, how you authenticate, how you find locale ids, and what a brand account may see. None of that is repeated here.
Product pictures are not multimedia. They live in their own API, described in Manual for Brand Partners: Icecat Gallery API.
The same header as everywhere else in the Brand API, on every request:
Api-Token: your_api_token
{productId}
{languageId}
0
{uuid}
Uuid
{apiAsyncRequestId}
ApiAsyncRequestId
The product has to be yours. Every call below works on products of the brands your account is assigned to. Another brand’s product answers 403.
403
POST https://bo.icecat.biz/restful/v3/multimedia/{productId}
GET https://bo.icecat.biz/restful/v3/multimedia/{productId}
GET https://bo.icecat.biz/restful/v3/multimedia/{productId}?Uuid={uuid}
PATCH https://bo.icecat.biz/restful/v3/multimedia/{productId}
PUT https://bo.icecat.biz/restful/v3/multimedia/{productId}
GET https://bo.icecat.biz/restful/v3/ApiAsyncRequests/{apiAsyncRequestId}
PUT https://bo.icecat.biz/restful/v3/multimedia/{productId}/Batch
The page is ordered the way an integration is usually built: one object first, then a batch. Every field of these is in the Icecat Brand API swagger. Every limit is collected in section 15, and the messages you are most likely to meet are in section 16.
A brand account does not delete multimedia. The DELETE operation exists in the spec and is refused for brand accounts — You can not delete mmo object!. What a brand account does instead is deactivate: section 11.
DELETE
PUT is queued; everything else is immediate. POST, PATCH and the reads do the work while you wait and answer with the result. PUT — one object or a whole batch — accepts the work and answers before it is done, so the answer is not the outcome. That is why this page starts with POST: section 8 explains the queue, and it is worth reading before you build anything on PUT.
PUT
POST
PATCH
A multimedia object is one file — or one link — attached to one product, in one locale, under one type. The type says what the file is for: a manual, a leaflet, a video, an energy label.
Each object has a Uuid given by Icecat when the object is created. That is how you address a single object afterwards.
Most multimedia is local. An object carries a LangId, and a partner in that market receives the objects of that market. A few types carry no market at all and are stored as international (LangId: 0) — section 3 says which, and the choice is not yours to make freely: a type that is not on that list is refused at LangId: 0.
LangId
LangId: 0
A product carries many objects at once: several manuals in several languages, a video, a spin, a safety sheet. What a product may not carry is the same file twice in the same locale — section 4.
Type is a fixed string and has to match exactly, spaces and capitals included. These are the eleven types a brand account can push:
Type
manual pdf
leaflet
EU Product Fiche
EU Energy Label
UK Energy Label
Safety Data Sheet
Repairability index overview
Size Chart
video/mp4
360
other digital assets
Images are JPG or PNG. A file whose content does not match its type is refused with Content type ‘…’ is not allowed for type ….
One document on the list is not yours to push: a Generated PDF is a leaflet Icecat builds from what it knows about an Open Icecat product that has no brand leaflet of its own. It is assembled at export time and is not stored on the product, so it never appears in a read and nothing you send replaces it. Send a real leaflet and it is the one that is distributed.
Several documents brands are obliged to supply have no type of their own. They are pushed as other digital assets, and what distinguishes them is ShortDescr: Icecat recognises ten captions and treats a document carrying one of them as that kind of document everywhere else. The caption travels unchanged into every export format, so it is what a channel partner reads to know which document this is.
ShortDescr
Quick Start Guide
Carbon Footprint
Durability Index
CE Marking
EU Declaration of Conformity
UK Declaration of Conformity
Safety Information
EU GARAN Label
EU GARAN Label (nested)
EU Data Act
All ten are issued per market as well as internationally, so any of them can be sent in any locale your account is assigned, or at LangId: 0.
Spell the caption exactly as the table has it, give or take capitals — the match ignores case and nothing else. A Quick Start Guide sent as “Quickstart guide” is stored and distributed, but as an unnamed other digital asset: no export format will identify it as a quick start guide.
Anything that fits none of the ten is still welcome as other digital assets with a caption of your own; it is simply distributed as a document without a kind.
International is allowed only where the table says so. manual pdf, Size Chart, video/mp4, 360, other digital assets and EU Energy Label may be stored at LangId: 0; everything else answers Language should not be international for type ….
Two types in the spec are not open to brand accounts. The swagger also lists ProductStory and ProductStory2.0. A brand account that pushes one gets 403 Access denied.
ProductStory
ProductStory2.0
403 Access denied
ShortDescr is a short caption, up to 255 characters, and it is kept only on four types: other digital assets, video/mp4, 360 and Repairability index overview. For every other type Icecat overwrites it with the name of the type, so a caption you send on a leaflet will come back as leaflet. Tags are stripped and unprintable characters are refused.
On other digital assets the caption is not decoration — it is what says which document this is. On the other three it is a free caption, and a video is the one place where it is worth writing something a shopper would read.
For what each of these assets looks like on a real product, and what a channel partner does with it, see Multimedia Assets and Documents Overview. This page covers what a brand account can push; that one covers the whole catalogue of assets, including the ones Icecat produces itself.
Start here. POST adds one object and answers with the result, so you find out immediately whether Icecat accepted the file.
Request line
Headers
Api-Token: your_api_token Content-Type: application/json
Body
{“LangId”: {languageId},“Type”: “manual pdf”,“Link”: “https://example.com/manuals/x1-carbon-gen12-en.pdf“}
LangId and Type are required. Link is where Icecat fetches the file from — section 14 says what happens to it afterwards.
Link
The answer gives you the new object’s id:
{ "Code": 201, "Message": "Created", "Uuid": "{uuid}" }
Keep that Uuid. It is how you address this object in every later call.
If the product already carries that file in that locale, nothing is added and the call answers This MMO object already present: uuid: …. Two files count as the same when they come from the same link, or when their contents are identical — Icecat compares the file, not only the address.
That strictness is useful while you are finding your feet, and wrong for a feed that re-sends the same catalogue every night. For that, PUT creates or replaces instead: section 7.
An object has exactly one source. Send Link for an ordinary file and ImagesBatch for a 360 — never both, or the call answers Link, file or batch can’t be passed simultaneously.
ImagesBatch
header:
Add ?Uuid={uuid} to read one object instead of all of them. A product with nothing to show answers 204.
?Uuid={uuid}
204
The answer is filtered to the locales your account may write — an object in a locale you are not assigned is not in the list. Each entry carries, among other fields:
LinkOrigin
Visible
ExpiryDate
Expired
IsPrivate
Size
ContentType
Md5Origin
ConversionStatus
Read before you push. The read tells you which types and locales the product already carries, and once you move to batches (section 9) that is exactly what decides what your push will switch off.
{ "Uuid": "{uuid}", "ShortDescr": "Unboxing and first setup", "Visible": false }
Uuid is required and identifies the object; everything else you send is changed and everything you leave out is left alone. This is the call for switching an object off, moving its expiry date, or fixing a caption, and it answers 304 when the object is already exactly like that.
304
Like POST, it is immediate: the answer is the outcome.
Once a feed is running you stop caring whether an object is already there. PUT creates it if it is not and replaces it if it is — the same call either way.
PUT https://bo.icecat.biz/restful/v3/multimedia/{productId}?Allow202=1
{ "LangId": {languageId}, "Type": "manual pdf", "Link": "https://example.com/manuals/x1-carbon-gen12-en.pdf" }
The body is the one you already know from section 4. What is different is the answer:
{ "ApiAsyncRequestId": "{apiAsyncRequestId}" }
with status 202. This is not the result of the work — it is a receipt. The work is queued, and that id is how you collect the outcome. Section 8.
202
Allow202=1 is worth sending on every PUT. Without it the call answers 200 with Query was queued and it will be processed later and no id, and the outcome of that write is not retrievable afterwards.
Allow202=1
200
A PUT — one object or a whole batch — is put on a queue and carried out behind the call. What came back at the moment of the push says only that the work was accepted. Validation that needs the file itself, the effect on the objects already there, and every per-object verdict happen later.
With Allow202=1 the push answers 202 and an ApiAsyncRequestId. Read it back whenever you like:
While the work is still queued, the answer describes the request you sent and carries no Response:
Response
{ "Data": { "ApiAsyncRequestId": "{apiAsyncRequestId}", "Request": { "Method": "PUT", "Path": "/restful/v3/multimedia/{productId}", "Body": "…" }, "CreatedAt": "2026-10-03 09:14:21", "UpdatedAt": "2026-10-03 09:14:21" } }
The absence of Response is the signal that it has not run yet. Once it has, Response appears:
{ "Data": { "ApiAsyncRequestId": "{apiAsyncRequestId}", "Request": { "Method": "PUT", "Path": "/restful/v3/multimedia/{productId}", "Body": "…" }, "Response": { "Code": 200, "Body": "[{\"LangId\":1,\"Type\":\"manual pdf\",\"Code\":200,\"Message\":\"Replaced\",\"Uuid\":\"{uuid}\"}]" }, "CreatedAt": "2026-10-03 09:14:21", "UpdatedAt": "2026-10-03 09:14:48" } }
Response.Body is a JSON string. Parse it, and you have exactly what a synchronous call would have returned: for a single push a Code and a Message, for a batch one entry per item.
Response.Body
Code
Message
Response.Code is the verdict on the submission as a whole:
Response.Code
400
409
The immediate answer is still worth checking, because two refusals happen before the queue:
Code: 403
Message: Access denied
Code: 400
Everything else comes back as Code: 200, Message: Queued. — which means accepted, not applied.
Code: 200
Message: Queued.
A queued request that has not run yet can be withdrawn:
DELETE https://bo.icecat.biz/restful/v3/ApiAsyncRequests/{apiAsyncRequestId}
Once it has run, that call answers 409 — Cannot delete processed async request.
Everything so far moved one object at a time. A batch moves up to 2000 of them, and adds something a single push cannot do: it decides what happens to the objects your submission does not mention.
PUT https://bo.icecat.biz/restful/v3/multimedia/{productId}/Batch?Allow202=1
{ "PolicyName": "replaceAllByType", "Batch": [ { "LangId": 1, "Type": "manual pdf", "Link": "https://example.com/manuals/en.pdf" }, { "LangId": 4, "Type": "manual pdf", "Link": "https://example.com/manuals/de.pdf" }, { "LangId": 1, "Type": "video/mp4", "Link": "https://example.com/video/overview.mp4" } ] }
PolicyName and Batch are both required. Each item takes the same fields as the single push in section 4, and LangId and Type are required in each.
PolicyName
Batch
Nothing is deleted by any of them — what they do is deactivate, and a deactivated object can be switched back on.
createOrSkip
replaceAllByType
replaceOwn
replaceAll
Three limits apply to all four:
replaceAllByType is the one to reach for when your system owns some types and not others.
A batch is queued like any other PUT, so the real answer arrives through ApiAsyncRequestId (section 8). Inside Response.Body each item of your batch comes back with a verdict of its own:
Replaced
Not modified
Access denied
500
Each item also carries OriginalItemNumber, the item’s position in the batch you sent, so you can match a verdict to what you submitted even though the order of the list changes.
OriginalItemNumber
Every item in a batch is stored as visible. Visible: false on a batch item does not survive — pushing an object again switches it back on. To switch one off, use PATCH (section 6) or RemoveLanguageIds (section 10).
Visible: false
RemoveLanguageIds
RemoveLanguageIds deactivates whole locales of a given type as part of the same submission. It works only with replaceAllByType; the other three policies answer Remove language ids is not supported for this policy.
{ "PolicyName": "replaceAllByType", "Batch": [ { "LangId": 1, "Type": "manual pdf", "Link": "https://example.com/manuals/en.pdf" } ], "RemoveLanguageIds": { "manual pdf": [ 4, 3 ], "leaflet": [ 1 ] } }
The English manual is pushed; the German and French manuals are switched off, and so is the English leaflet. The key is the type, exactly as section 3 spells it, and the value is the list of locales to clear for that type — up to 100 per type, each named once.
A locale that appears both in Batch and in RemoveLanguageIds for the same type is pushed, not removed: what you sent wins.
A brand account does not delete multimedia. Three fields decide instead whether an object is distributed.
true
false
yyyy-MM-dd
An object switched off either way is still yours to read: a brand account sees it in a GET, with Expired: true when its date has passed. Channel partners do not receive it.
GET
Expired: true
To switch one off, PATCH it with Visible: false. To switch it back on, PATCH it with Visible: true — or push it again, which has the same effect (section 9).
Visible: true
The two label types have rules of their own, and they are the ones most likely to surprise a feed that treats all types alike.
Two fields belong to these types alone, and sending either on any other type answers EnergyLabellingLink and IsNewEnergyLabelling are allowed for ‘EU Energy Label’ OR ‘UK Energy Label’ types only.:
EnergyLabellingLink
""
IsNewEnergyLabelling
A label is converted after it is stored, so its ConvertedLink and ConvertedMimeType are empty for a while. Section 14.
ConvertedLink
ConvertedMimeType
A 360 is not a file but a series of still images that Icecat assembles into a spin. Instead of Link, the object carries ImagesBatch:
{ "LangId": 0, "Type": "360", "ImagesBatch": [ { "Link": "https://example.com/spin/frame-01.jpg", "Order": 1 }, { "Link": "https://example.com/spin/frame-02.jpg", "Order": 2 } ] }
Order
Icecat fetches every frame. If frames fail, the spin is still built from the rest — but if fewer than ten survive, the whole object is refused, and the message names the frames that failed. Downloading also stops early when four frames in a row fail, and the message says so.
For most types, Icecat downloads your file and serves its own copy. The Link you get back is an Icecat link; the address you sent is kept as LinkOrigin. Your server is read once, at push time, so a file you later change at the same address is not picked up — push it again.
Four types may stay at your address instead. Send KeepAsUrl: true with video/mp4, Size Chart, Safety Data Sheet or Repairability index overview and Icecat stores the link rather than the file. Any other type answers Keep as url is not allowed for type …. A video kept as a URL keeps working only as long as your address does.
KeepAsUrl: true
Some types are converted after they are stored, and the conversion is not instant. video/mp4, EU Energy Label and UK Energy Label come back with a ConversionStatus:
Processing
Converted
Failed
For every other type the field is an empty string, which is not a problem — it means there is nothing to convert.
The Brand API’s error shape applies here — Code, Error, Message, DetailedCode — as described in Manual for Brand Partners: Icecat Push-API (API-IN).
Error
DetailedCode
You can not delete mmo object!
This MMO object already present: uuid: …
This object has duplicate among uploaded objects. Duplicate is :…
Skipped by policy rules.
Language should not be international for type …
`EU Energy Label` available for INT language only
`UK Energy Label` available for EN language only
'EU Energy Label' already exists in the product. It's not allowed to have one more
EnergyLabellingLink and IsNewEnergyLabelling are allowed for 'EU Energy Label' OR 'UK Energy Label' types only.
EnergyLabellingLink is not valid url
Keep as url is not allowed for type …
Content type '…' is not allowed for type …
Link, file or batch can't be passed simultaneously
Type "360" should have array of images . minimum 10 items
Batch has less than 10 images after download. failed images numbers: …
ExpiryDate should be more than present date
Remove language ids is not supported for this policy.
Languages … of product … are locked by another user
Cannot delete processed async request.
Read further: Icecat, e-commerce, ecommerce, Icecat, manuals