Version: 1.0
Updated 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 | Placeholder | What it is | Where you get it |
|---|---|---|
{productId} | your product in Icecat | the answer you got when you created the product |
{languageId} | the locale you are writing — one of those your account is assigned, or 0 for international | Get your locales, in Manual for Brand Partners: Icecat Push-API (API-IN) |
{uuid} | one multimedia object of one product | Uuid in the answer to a read, or in the answer to the call that created it |
{apiAsyncRequestId} | one queued write | ApiAsyncRequestId in the answer to a push. Section 8 |
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.
| What you want to do | Call | Explained in |
|---|---|---|
| add one object | POST https://bo.icecat.biz/restful/v3/multimedia/{productId} | §4 |
| see everything a product carries | GET https://bo.icecat.biz/restful/v3/multimedia/{productId} | §5 |
| see one object | GET https://bo.icecat.biz/restful/v3/multimedia/{productId}?Uuid={uuid} | §5 |
| change one object | PATCH https://bo.icecat.biz/restful/v3/multimedia/{productId} | §6 |
| push one object, creating or replacing | PUT https://bo.icecat.biz/restful/v3/multimedia/{productId} | §7 |
| read the outcome of a queued push | GET https://bo.icecat.biz/restful/v3/ApiAsyncRequests/{apiAsyncRequestId} | §8 |
| push a whole set under a policy | PUT https://bo.icecat.biz/restful/v3/multimedia/{productId}/Batch | §9 |
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.
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.
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.
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 | What it is | Accepted file | Locale |
|---|---|---|---|
manual pdf | the full product manual — installation, use, maintenance, safety, troubleshooting. Most manuals are multilingual, so this one is often international | any assigned locale, or international | |
leaflet | the product brochure: a visually designed document that sells the product’s value rather than instructing | any assigned locale | |
EU Product Fiche | the EU product information sheet that accompanies the energy label, with the energy-consumption and efficiency figures | PDF or image | any assigned locale |
EU Energy Label | the EU energy label, A–G or A+++–D. Rules of its own — section 12 | PDF or image | international only, one per product |
UK Energy Label | the UK energy label, the post-Brexit equivalent of the EU one. Rules of its own — section 12 | PDF or image | English only, one per product |
Safety Data Sheet | the short safety brochure: hazards, first aid, protective equipment, disposal | any assigned locale | |
Repairability index overview | the indice de réparabilité — a score from 1 to 10, mandatory in France and used in the DACH region and elsewhere in the EU | PDF or image | any assigned locale |
Size Chart | the product’s dimensions or sizing table | PDF or image | any assigned locale, or international |
video/mp4 | official video: a trailer, a guide, an overview, anything | any common video format | any assigned locale, or international |
360 | a 360° spin, built from a series of images the shopper can rotate. Some Icecat APIs and export formats call it a 3D tour. Pushed differently — section 13 | a list of images, not a single file | any assigned locale, or international |
other digital assets | every other document. The caption decides which one — see below | PDF or image | any assigned locale, or international |
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.
other digital assetsSeveral 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 | What the document is |
|---|---|
Quick Start Guide | the short set-up guide: the critical steps only, not the full manual |
Carbon Footprint | the product’s greenhouse-gas emissions over its lifecycle, in kg CO₂e |
Durability Index | the French indice de durabilité — how long the product is expected to last, which goes further than the repairability score |
CE Marking | the CE certification document. Unlike the declaration of conformity, this one is issued by an independent authority |
EU Declaration of Conformity | your own formal declaration that the product meets the applicable EU requirements |
UK Declaration of Conformity | the same, under UK law |
Safety Information | the long-form safety manual, as against the shorter Safety Data Sheet, which has a type of its own |
EU GARAN Label | the EU guarantee label |
EU GARAN Label (nested) | the nested form of the guarantee label. A different document from the one above, not a variant of it — a partner tells the two apart by the caption alone, so put each under its own |
EU Data Act | the product’s EU Data Act document |
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.
ShortDescr — where your own caption survivesShortDescr 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
POST https://bo.icecat.biz/restful/v3/multimedia/{productId} 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.
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.
POST refuses a duplicate rather than replacing itIf 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.
GET https://bo.icecat.biz/restful/v3/multimedia/{productId} header:
Api-Token: your_api_token Add ?Uuid={uuid} to read one object instead of all of them. A product with nothing to show answers 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:
Uuid — the id of this object, which the change calls take;LangId, Type, ShortDescr — what you set;Link — where the file is served from now. For most types this is an Icecat link, not yours;LinkOrigin — the link you originally sent, kept for reference;Visible, ExpiryDate, Expired, IsPrivate — section 11;Size, ContentType, Md5Origin — what Icecat found in the file;ConversionStatus — section 14;ImagesBatch — the frames, for a 360.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.
PATCH https://bo.icecat.biz/restful/v3/multimedia/{productId} {
"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.
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.
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.
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:
GET https://bo.icecat.biz/restful/v3/ApiAsyncRequests/{apiAsyncRequestId} While the work is still queued, the answer describes the request you sent and carries no 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.Code is the verdict on the submission as a whole:
Response.Code | What it means |
|---|---|
200 | the work ran. The per-item verdicts are in Response.Body |
400 | the whole submission was refused before anything was written — Response.Body says why |
409 | the product’s locales were locked by another write at that moment. Nothing was applied; send it again |
The immediate answer is still worth checking, because two refusals happen before the queue:
Code: 403 and Message: Access denied and never reaches the queue;Code: 400.Everything else comes back as Code: 200, Message: Queued. — which means accepted, not applied.
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.
Nothing is deleted by any of them — what they do is deactivate, and a deactivated object can be switched back on.
PolicyName | What happens to objects already on the product |
|---|---|
createOrSkip | nothing is deactivated, and nothing existing is updated either. An item that matches something already there is skipped with Skipped by policy rules. Use it to add without touching anything |
replaceAllByType | only the objects whose type and locale your batch also carries are deactivated. The product’s other types are left alone |
replaceOwn | every object in the locales your batch touches that came from your own account is deactivated, unless your batch carries it. Objects from other sources are left alone |
replaceAll | every object in the locales your batch touches is deactivated, unless your batch carries it, whoever put it there |
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:
Code | Message | What happened |
|---|---|---|
200 | Replaced | the object was created or updated |
304 | Not modified | it was already exactly like this; nothing was written |
400 | the reason | this item was refused — the rest of the batch still applied |
403 | Access denied | that locale or type is not one your account may write |
500 | the reason | our side failed on this item |
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.
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).
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.
| Field | What it does |
|---|---|
Visible | true by default. false keeps the object on the product and stops distributing it. This is the brand account’s equivalent of deleting, and it is reversible |
ExpiryDate | yyyy-MM-dd. From that date the object stops being distributed. It has to be a real date in the future, or the call answers ExpiryDate should be more than present date |
IsPrivate | false by default. true means the object is given only to channel partners authorised on your brand in the Icecat system. Everyone else receives the product without it |
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.
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).
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.
EU Energy Label is international. It has to be sent with LangId: 0; any other locale answers EU Energy Label available for INT language only.UK Energy Label is English. Any other locale answers UK Energy Label available for EN language only.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.:
| Field | What it is |
|---|---|
EnergyLabellingLink | the product’s entry in EPREL, the European Product Registry for Energy Labelling. Send "" to clear it |
IsNewEnergyLabelling | true for a rescaled label, which is the current form. false marks a non-rescaled one — the deprecated format, still found on older products |
A label is converted after it is stored, so its ConvertedLink and ConvertedMimeType are empty for a while. Section 14.
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 }
]
} Link and Order are required on every frame;Order runs from 0 to 360 and sets the sequence the frames are played in;360 cannot be kept as a URL, and it cannot carry a Link of its own.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.
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:
ConversionStatus | What it means |
|---|---|
Processing | accepted, not converted yet. ConvertedLink is empty for now |
Converted | done. ConvertedLink and ConvertedMimeType are filled in |
Failed | conversion was attempted five times and did not succeed. Check the source file and push it again |
"" | this type is not converted at all |
For every other type the field is an empty string, which is not a problem — it means there is nothing to convert.
Type | one of the eleven in section 3, spelled exactly |
LangId | a locale your account is assigned, or 0 where section 3 allows it |
ShortDescr | up to 255 characters, and stored only for four types (section 3) |
ShortDescr on other digital assets | one of the ten captions in section 3, if the document is to be recognised as that kind |
Link | up to 1000 characters |
ExpiryDate | yyyy-MM-dd, in the future |
| Energy label file size | up to 10 MB |
ImagesBatch | 10 to 360 frames, Order from 0 to 360 |
Batch items in one call | up to 2000 |
RemoveLanguageIds | up to 100 locales per type, each named once |
PolicyName | createOrSkip, replaceAllByType, replaceOwn, replaceAll |
EU Energy Label / UK Energy Label | one of each per product |
| The same file twice in one locale | not allowed |
| Deleting | not available to a brand account — deactivate instead (section 11) |
| Products | those of the brands assigned to your account |
The Brand API’s error shape applies here — Code, Error, Message, DetailedCode — as described in Manual for Brand Partners: Icecat Push-API (API-IN).
| Status | What it means |
|---|---|
200 | accepted. For a PUT, that means queued — the outcome is in section 8 |
202 | queued, and an ApiAsyncRequestId came with it |
204 | the product has no multimedia you may see |
304 | it was already exactly like this. Nothing was written, and nothing is wrong |
400 | the request, or one item in it, is wrong |
403 | the product, the locale or the type is not one your account may write |
409 | the product was locked by another write, or a queued request has already run |
500 | our side failed — retry with a backoff |
| Message | What happened | What to do |
|---|---|---|
You can not delete mmo object! | a brand account called DELETE | deactivate instead — section 11 |
Access denied | the locale or the type is outside what your account may write | check the locale against Get your locales, and the type against section 3 |
This MMO object already present: uuid: … | POST with a file the product already carries in that locale | use PUT if you meant to replace it — section 7 |
This object has duplicate among uploaded objects. Duplicate is :… | one batch carries the same file twice | de-duplicate the batch |
Skipped by policy rules. | under createOrSkip, that object is already there | use another policy if you meant to replace it |
Language should not be international for type … | LangId: 0 on a type that may not be international | section 3 |
`EU Energy Label` available for INT language only | an EU energy label in a market locale | send it with LangId: 0 |
`UK Energy Label` available for EN language only | a UK energy label in another locale | send it in English |
'EU Energy Label' already exists in the product. It's not allowed to have one more | a second label | replace the one that is there |
EnergyLabellingLink and IsNewEnergyLabelling are allowed for 'EU Energy Label' OR 'UK Energy Label' types only. | one of those fields on another type | drop the field |
EnergyLabellingLink is not valid url | the EPREL link is malformed | check the address |
Keep as url is not allowed for type … | KeepAsUrl: true on a type that must be hosted by Icecat | section 14 |
Content type '…' is not allowed for type … | the file is not what the type accepts | check the file against section 3 |
Link, file or batch can't be passed simultaneously | more than one source in one object | one object, one source |
Type "360" should have array of images . minimum 10 items | a spin with fewer than ten frames | section 13 |
Batch has less than 10 images after download. failed images numbers: … | too many frames could not be fetched | check the frames the message names |
ExpiryDate should be more than present date | an expiry date in the past | to switch an object off now, send Visible: false |
Remove language ids is not supported for this policy. | RemoveLanguageIds with a policy other than replaceAllByType | section 10 |
Languages … of product … are locked by another user | two writes hit the same product’s locales at once | send it again |
Cannot delete processed async request. | the queued request had already run | nothing to withdraw |
The U.S. Federal Trade Commission has opened an investigation into OpenAI and Anthropic as regulators…
Sprint 105 shipped one of our anticipated milestones yet: the Studio MCP server went live…
Icecat continued to expand its platform activity during the first nine months of 2026, with…
Version: 1.0Updated on: October 5th, 2026 This manual is for brand partners publishing the GTINs of…
Version: 1.0Updated on: October 5th, 2026 This manual is for brand partners setting the model name…
Hasbro has expanded its collaboration with Icecat by extending the regional availability of its above-the-fold…