Skip to content

Taxonomy

The taxonomy is the channel's product format, registered in Mirakl Connect. It has two parts:

  • product types, which set the category a product belongs to and the attributes a product of that category must carry,
  • taxonomy rules, which redefine the requirement level of an attribute for a specific case.

This page covers the two calls that register the taxonomy, the structure each call expects, what the Catalog Transformer reads from it, and how to keep it in step with the channel.

Business context

Registering the taxonomy is a required step. Mirakl Connect uses the Catalog Transformer to turn a seller's products into channel products, and the Catalog Transformer transforms against the registered taxonomy. Until the taxonomy exists there is nothing to transform against, so no product reaches the channel.

Its completeness then sets the accuracy of the result. The Catalog Transformer infers each channel attribute from the seller's own data, and the taxonomy is everything it knows about the target.

Once the taxonomy and the catalog configuration are complete, the seller can synchronize products to the channel through the catalog flow.

Activation by Mirakl

Mirakl must activate the taxonomy in the Catalog Transformer, and train the model on it. That step is not self service, and only the Mirakl Partner team can do it.

Request the activation from your contact in the Mirakl Partner team, and give them the channel ID. Register the complete taxonomy before you ask, because the training reads the taxonomy that is registered at that moment.

Until the Mirakl Partner team completes the activation, the Catalog Transformer transforms no product for the channel. Your connector then receives no ProductUpsertEvent, whatever your taxonomy holds and whatever product status you report.

Once the initial activation is done, Mirakl Connect pushes the registered taxonomy to the Catalog Transformer on a recurring daily schedule, and not on each call.

How it works

Your connector reads the taxonomy from the channel, then registers it in Mirakl Connect with two calls.

ChannelMiddlewareMiraklChannelChannel ConnectorMirakl ConnectChannelChannel ConnectorMirakl ConnectThe registered taxonomy feeds the Catalog TransformerFetch the taxonomyCategories, attributes, and their constraintscreateTaxonomyRule (the rules the product type needs)202 Accepted, the rules are storedupsertProductType (references those rules)202 Accepted, the upsert is queuedRead the payload and store the product type
ChannelMiddlewareMiraklChannelChannel ConnectorMirakl ConnectChannelChannel ConnectorMirakl ConnectThe registered taxonomy feeds the Catalog TransformerFetch the taxonomyCategories, attributes, and their constraintscreateTaxonomyRule (the rules the product type needs)202 Accepted, the rules are storedupsertProductType (references those rules)202 Accepted, the upsert is queuedRead the payload and store the product type

Three properties of this flow shape everything below.

  • The rules come first. A product type references a rule by its id. Mirakl Connect drops a reference to a rule it does not hold yet, and it reports nothing back, so the rule never applies. Register the rules of a product type before you register the product type.
  • One call carries one product type, in full. upsertProductType replaces the product type, so a call that omits an attribute removes that attribute.
  • The two calls do not behave the same way. createTaxonomyRule validates its payload during the request, so a malformed rule fails the call with a 400. upsertProductType queues its payload, so a problem inside the content surfaces after the 202.

upsertProductType is asynchronous. A 202 Accepted response means that Mirakl Connect queued the request, not that it applied the product type. Refer to Calling the APIs.

Product types

A product type describes the format of a product: the category it belongs to, and the attributes a product of that category must provide.

Register one with the upsertProductType API. The identity is the product_type_id query parameter, which is the channel's own identifier for the product type. The body holds four nodes:

  • labels: the name of the product type, one entry per locale. At least one entry is required. This is what the seller reads when it picks a category.
  • context.labels: the position of the product type in the channel's own category tree, such as Electronics / Mobile Devices / Smartphones. It is optional, and the Catalog Transformer reads it.
  • embedded_attributes: the attributes of the product type. Read Attribute types below.
  • rules: the taxonomy rules that apply to the product type, each one referenced as { "ref": "<rule id>" }. Read Taxonomy rules below.

upsertProductType operates as a full replacement, with PUT. Always send the product type's complete definition, because Mirakl Connect removes anything that is absent from the request body. This covers the attributes, the entries of a value list, and the rule references alike.

Store-level product types

A product type is registered for the whole channel by default. The optional store_id query parameter registers it for one store instead, which suits a channel that gives each seller its own category set.

Two conditions apply. The store must already exist in Mirakl Connect, and the call returns a 404 when it does not. Mirakl enables this granularity for each channel, so ask your contact in the Mirakl Partner team before you use it.

Attribute types

Every attribute of embedded_attributes carries the same five required fields.

  • id: the channel's own identifier for the attribute, unique inside the product type. It is the identifier you receive back on the events, so keep it stable.
  • type: one of Text, Integer, Decimal, List, and Media.
  • requirement_level: REQUIRED, RECOMMENDED, or OPTIONAL.
  • labels: the name of the attribute, one entry per locale, with at least one entry.
  • descriptions: the help text of the attribute, one entry per locale. The field is required, and an empty array is valid.

Two optional nodes complete an attribute, and both reach the Catalog Transformer.

  • connect_standard_attributes: the standard attributes the attribute corresponds to. Only a few attributes of a product type have one. Read Standard attributes below.
  • context, with labels and path. Catalog Transformer below says what to put in them.

Each type then adds its own fields.

  • Text accepts min_length and max_length.
  • Integer accepts minimum and maximum.
  • Decimal requires scale, the number of decimal places, and accepts minimum and maximum.
  • List requires available_values, from 1 to 1000 entries. Each entry carries an id and its labels.
  • Media accepts media_type, either IMAGE or OTHER.

A locale is an ISO-639 language, alone or with an ISO-3166 country, such as en or en_US.

There is no boolean type. Register a boolean as a List of two values, and give each value a label the seller and the Catalog Transformer can read.

Mirakl Connect reads the attributes after it answers the 202, and it skips an attribute it cannot read instead of failing the call. An attribute disappears when it misses id or requirement_level, when a List carries no available_values, or when a Decimal carries no scale. Two attributes that share one id also lose one of the two. In each case the product type is registered without that attribute, and the response already said 202.

Example

The product type below carries a title, a colour taken from a closed list, and a main image.

{
  "labels": [
    { "locale": "en_US", "value": "Smartphones" }
  ],
  "context": {
    "labels": [
      { "locale": "en_US", "value": "Electronics / Mobile Devices / Smartphones" }
    ]
  },
  "embedded_attributes": [
    {
      "id": "item_name",
      "type": "Text",
      "requirement_level": "REQUIRED",
      "labels": [{ "locale": "en_US", "value": "Product name" }],
      "descriptions": [{ "locale": "en_US", "value": "The name shown on the product page, without the brand." }],
      "context": {
        "labels": [{ "locale": "en_US", "value": "Basic information / Product name" }],
        "path": "$.item_name[0].value"
      },
      "connect_standard_attributes": ["TITLE"],
      "max_length": 200
    },
    {
      "id": "color",
      "type": "List",
      "requirement_level": "RECOMMENDED",
      "labels": [{ "locale": "en_US", "value": "Colour" }],
      "descriptions": [{ "locale": "en_US", "value": "The dominant colour of the item as the buyer sees it." }],
      "context": {
        "labels": [{ "locale": "en_US", "value": "Appearance / Colour" }],
        "path": "$.color[0].value"
      },
      "available_values": [
        { "id": "NB01", "labels": [{ "locale": "en_US", "value": "Navy blue" }] },
        { "id": "BK01", "labels": [{ "locale": "en_US", "value": "Black" }] }
      ]
    },
    {
      "id": "main_image",
      "type": "Media",
      "requirement_level": "REQUIRED",
      "labels": [{ "locale": "en_US", "value": "Main image" }],
      "descriptions": [{ "locale": "en_US", "value": "The first image of the product page, on a white background." }],
      "context": {
        "labels": [{ "locale": "en_US", "value": "Images / Main image" }],
        "path": "$.main_product_image_locator[0].media_location"
      },
      "connect_standard_attributes": ["IMAGE"],
      "media_type": "IMAGE"
    }
  ]
}

Standard attributes

A standard attribute is a product field that Mirakl Connect holds for every channel. Associate each one with the channel attribute that corresponds to it, in connect_standard_attributes.

There are eight.

  • PRODUCT_ID: the SKU, the seller's own product reference.
  • CATEGORY: the product type.
  • BRAND: the brand.
  • TITLE: the title.
  • DESCRIPTION: the description.
  • IMAGE: the main image.
  • GTIN: the product identifier.
  • VARIANT_GROUP_CODE: the code that groups the variants of one product.

Taxonomy rules

A taxonomy rule redefines the requirement level of an attribute when a condition holds.

Register rules with the createTaxonomyRule API. Rules belong to the channel, not to a product type, and one call sends a batch of them in the rules array. A product type then references the ones it needs, by their id.

Each rule holds three fields.

  • id: your own identifier, and the value a product type references.
  • when: the condition.
  • then: the actions to apply when the condition holds.

A condition is one of six forms, and the three that combine can nest to any depth:

  • all: every nested condition holds.
  • any: at least one nested condition holds.
  • not: the nested condition does not hold.
  • isSet: the named attribute carries a value.
  • equals: the named attribute equals a string, a number, or a boolean.
  • in: the value of the named attribute is one of a list.

then.all holds the actions, and there is one action. redefine names an attribute and the requirementLevel to give it.

{
  "rules": [
    {
      "id": "size-required-for-clothing",
      "when": {
        "all": [
          { "in": { "attribute": "item_type", "values": ["shirt", "trousers"] } },
          { "not": { "isSet": { "attribute": "size" } } }
        ]
      },
      "then": {
        "all": [
          { "redefine": { "attribute": "size", "requirementLevel": "REQUIRED" } }
        ]
      }
    }
  ]
}

Two patterns worth copying

Derive the rules from the channel's own conditional schema. A channel that publishes a JSON schema for each product type usually expresses its conditional requirements there. Translate each of those conditions into a when, and each conditional requirement into a redefine. The rules then stay correct without a human maintaining them.

Keep a group of attributes consistent. When the channel groups attributes that only make sense together, emit one rule whose when is an any of isSet over every member, and whose then makes every member REQUIRED. A seller who fills one member is then asked for the rest, instead of sending the channel a half-filled group.

Use a content hash as the rule id

Compute the id of a rule from a hash of its content. This gives you two properties. Sending the same rule again changes nothing, and two product types that need the same rule reference one rule instead of two.

Catalog Transformer

The Catalog Transformer is the Mirakl capability that transforms a seller's products into channel products, with the channel's registered taxonomy. That taxonomy is the only thing that describes the channel to it. Everything below reaches the model, and anything you leave out does not.

  • labels: the name of the attribute or of the product type. Write the name the channel itself uses. When the attribute sits inside a nested structure, put the whole path in the label, such as Certificate - Issuing body, because a label that reads Name on its own is ambiguous.
  • descriptions: the help text. Copy the channel's own wording, without shortening it. This is the richest signal the model gets, because it states what the channel expects rather than what the field is called.
  • context.labels: where the attribute or the product type sits in the channel's own structure, such as Appearance / Colour. It separates two attributes that share a label under different parents.
  • context.path: where the value sits in the channel's payload, as a JSON path such as $.color[0].value.
  • requirement_level: what the model must produce, and what it may leave empty.
  • available_values: the closed set the model must choose from. Give every entry a label, in every locale the sellers write in. The model matches the seller's wording against the labels, so an entry with only an id can be reached only by an exact match on that id.
  • The bounds: min_length and max_length, minimum and maximum, and scale. They tell the model the shape of an acceptable value.
  • media_type: whether the attribute expects an image or another kind of file.
  • The standard attributes: which of Mirakl Connect's own fields feed the attribute.
  • The rules, with the attributes their conditions and their actions name.

The bounds guide the model, and Mirakl Connect does not enforce them. A value that exceeds max_length is not rejected before it reaches the channel, so the channel is what refuses the product. Your connector reports that outcome through the feedback. The same holds for a required attribute that stays empty.

Build the taxonomy for the model, not only for the contract

The contract accepts a product type whose attributes carry an id, a bare label, and no description. The Catalog Transformer then infers from the id and the type alone, and the accuracy drops for every seller on the channel.

Three rules give most of the accuracy.

  • Send the channel's own wording. The channel's attribute names and help texts already describe the target. A wording you write yourself describes your connector instead.
  • Make each label readable on its own. The model reads a label without its neighbours, so Length needs its parent and its unit, as in Package dimensions - Length (cm).
  • Never send a value list without labels. A code the channel invented carries no meaning for a model that reads a seller's catalog.

Keep the taxonomy in step

A channel's taxonomy changes on its own schedule, and the API has no delete. Run this loop.

  1. Fetch the channel's taxonomy on a schedule. No channel notifies a taxonomy change, so a periodic full read is the only reliable source.
  2. Persist what you fetched, and hash each product type. Compute the hash over the product type and everything it references, which is its attributes, their value lists, and its rules. The push then reads your own database, and a channel outage cannot block it.
  3. Push only what changed. Compare the current hash to the hash you last pushed, and skip the product types that match. A taxonomy of thousands of product types changes a few at a time, so most runs then send no call at all.
  4. Send the rules of a product type before the product type. Mirakl Connect drops a reference to a rule it does not hold.
  5. Contain a failure to one product type. Log it, leave its pushed hash untouched, and carry on with the rest. The next run retries it.

Four constraints apply to the calls themselves.

  • Do not send two upserts of the same product type at the same time. Mirakl Connect compares the timestamp of an upsert to the last one it stored, and it drops the older one. Two concurrent upserts of one product type can therefore lose the later content.
  • Honour the published cadence. Both operations recommend 5 calls per second and allow 10. Refer to Call frequency.
  • A product type you stop sending stays registered. There is no delete operation, so plan for the sellers who still see a category the channel retired.
  • Both operations are idempotent. Sending the same content again is safe, which is what makes a retry safe. Refer to Idempotency.

Common mistakes

The product type references a rule that does not exist yet

What it looks like: one run sends upsertProductType with rules, and sends createTaxonomyRule after it, or in a separate job.

The failure: Mirakl Connect keeps only the references it can resolve, and it reports nothing. The product type is registered, the rules are registered, and no rule applies to the product type. Nothing in the response or in the feedback says so.

The fix: call createTaxonomyRule first, then upsertProductType in the same run. Take the rule ids from the rules you just sent, and reference those.

The upsert carries only what changed

What it looks like: an attribute changed its requirement level, so the call sends that one attribute.

The failure: upsertProductType replaces the product type, so every other attribute, value list entry, and rule reference is removed. The seller loses the fields, and the Catalog Transformer loses the target.

The fix: rebuild the complete definition on every call. The change detection decides if you call. It never decides what the body holds.

A type-specific required field is missing

What it looks like: a List attribute is sent with an empty available_values, or a Decimal is sent without scale.

The failure: the call returns 202, and Mirakl Connect then skips that attribute. The product type is registered without it, so the seller is never asked for the value and the channel rejects the product.

The fix: validate each attribute against its type before you send it. Give a List at least one value, and a Decimal a scale. An attribute whose values you cannot fetch from the channel is better left out of the payload than sent empty.

The labels and descriptions are empty or generic

What it looks like: labels repeats the id, descriptions is [], and the value lists carry ids only.

The failure: the Catalog Transformer has the identifier and the type, and infers from those. The accuracy drops for every seller on the channel, and it drops silently, because a wrong inference still produces a product.

The fix: carry the channel's own attribute name, help text, and value labels through your connector, and register them. Read Build the taxonomy for the model, not only for the contract.

Two attributes share one id

What it looks like: the channel's taxonomy exposes the same attribute under two parents, and the mapping flattens both to the same id.

The failure: Mirakl Connect keeps one and ignores the other. You do not control which one it keeps.

The fix: make the id unique inside the product type, by keeping the parent in it. Then use context.labels and context.path to say where each one belongs.