Skip to main content
Skip to main content

Multi-Language Support

How to handle multiple languages in Axiom.

Overview

Use language_code to declare which language the data in your request is written in. It labels the content you are sending — it is not a request to have that content translated into something else.

A product is one record with an English base and any number of translations attached to it, not one record per language. Sending the same product_identifier again with a different language_code adds a translation to the existing product.

When to use

Optional for each product and variant. Omitting language_code is the same as sending en.

Format

Follow these formatting guidelines to make sure that Axiom understands the data that you're submitting.

TypeISO 639-1 language code, optionally with an ISO 3166-1 region suffix — for example de, fr, de-CH, pt-BR
LimitsUp to 5 characters, and must be a language code Axiom supports
Case sensitiveNo. DE and de are the same code
Repeated fieldNo. One language per product or variant payload
Variant inheritsYes. A variant takes the product's language_code when the product declares one

Fetch the supported codes from GET /api/common/language-codes, which returns each code with its name and requires the language-code-list permission. An unrecognised code fails validation.

English is always the base record

Whatever language you submit, the product's own fields end up in English. When you create a product with a non-English language_code, Axiom stores your copy as a translation for that language and machine-translates it into English for the product record itself.

This means a German-only catalogue is searchable and orderable in English as soon as it lands, while German buyers are still served your own wording.

Three details are worth knowing:

  • Translation is asynchronous. The product is created immediately; the English name and description appear shortly afterwards.
  • Only name and description are machine-translated. product_page_url is kept verbatim on the translation and cleared from the English record, so a product submitted only in German has no English product_page_url until you send one.
  • A machine-translated name is truncated to 188 characters.

Note

Machine translation only ever fills the English base record. If you have already supplied a translation for the language you're submitting, Axiom will not overwrite it with a machine translation.

Adding a translation

To add a language to an existing product, send it again with the same product_identifier — and the same variant_identifier for variants — and the new language_code. Matching identifiers are what tie the languages together, so they must be identical across every language of the same product.

What is stored per language

Only language-specific fields are held per language. Everything else is shared by every language of the product, which means the last payload to touch a shared field wins, whichever language it declared.

FieldScope
namePer language
descriptionPer language
product_page_urlPer language
propertiesPer language
categoriesPer language
document_urlsPer language
Variant options (name and value)Per language
codesShared
image_urlsShared
pricesShared
stocksShared
sku, brand, manufacturer, unit_size, unit_labelShared

Updating a single language

On an update, the language_code decides where the language-specific fields land:

  • en or omitted — the product record itself is updated.
  • Any other codename, description and product_page_url are written to that language's translation, and the rest of the payload updates the shared fields on the product.

So an update sent as de never changes the English wording, but it will change the shared sku, prices or codes if you include them.

Reading data back

Pass languageCode to the product detail endpoints to get a product back in a given language. Language-scoped fields resolve to that language, and shared fields are returned as-is.

The product list endpoint takes languageCode too, and applies the translation to the fields that have one:

GET/api/suppliers/products?languageCode=de
curl --location --request GET 'https://api.axiomdata.io/api/suppliers/products?languageCode=de'

Where a product has no translation for the code you ask for, that product's fields fall back to the English base record, so a mixed-language catalogue comes back with the translations it has rather than failing.

GET /api/suppliers/products/languages returns the codes a product already exists in. It takes product_type (product or variant) and product_identifier, and requires the supplier-product-languages permission.

Regional dialects and fallback

Language codes may carry a region suffix, such as de-CH (German, Switzerland) or pt-BR (Portuguese, Brazil). Use them when your wording genuinely differs by market; use the plain code when it doesn't.

When a buyer's language is resolved against a country, Axiom promotes the request to the matching dialect if that dialect exists, then falls back down the chain.

You do not need to supply every dialect. A single de translation serves Germany, Austria and Switzerland unless you add de-AT or de-CH to override it.

Duplicate identifiers are merged

If the same product_identifier ends up on more than one product record — for example an older catalogue loaded before translations were in use — Axiom merges them into one product automatically:

  • The oldest record is kept, along with its uuid.
  • English content from the most recently updated English record becomes the base.
  • Other languages are folded in as translations of that record.
  • For codes and properties the most recent value per type or name wins, and for stock the most recent entry per country wins.
  • The redundant records are deleted.

You do not need to do anything to trigger this, but it is a reason to keep identifiers stable rather than minting a new one per language.

Examples

Create a product in German

POST/api/suppliers/products
curl --location --request POST 'https://api.axiomdata.io/api/suppliers/products' \
--header 'Content-Type: application/json' \
--data-raw '{
"language_code": "de",
"product_identifier": "testproduct",
"type": "simple",
"name": "Automatischer Immunoblot-Prozessor",
"description": "Automatisiert das Protokoll für die meisten streifenbasierten Assays.",
"sku": "1234",
"brand": "BeeBlot",
"manufacturer": "Gold Standard Diagnostics",
"unit_label": "EA",
"unit_size": "1 x each"
}'

The product is created with the German copy stored as its German translation, and its English name and description follow once translation completes.

Add a French translation

Reuse the identifier and change the language:

PUT/api/suppliers/products/update
curl --location --request PUT 'https://api.axiomdata.io/api/suppliers/products/update' \
--header 'Content-Type: application/json' \
--data-raw '{
"language_code": "fr",
"product_identifier": "testproduct",
"name": "Processeur automatisé pour immunoblot",
"description": "Automatise le protocole de la plupart des tests sur bandelettes."
}'

Read a product back in German

GET/api/suppliers/products/testproduct?languageCode=de
curl --location --request GET 'https://api.axiomdata.io/api/suppliers/products/testproduct?languageCode=de'

Check which languages a product has

GET/api/suppliers/products/languages?product_type=product&product_identifier=testproduct
curl --location --request GET 'https://api.axiomdata.io/api/suppliers/products/languages?product_type=product&product_identifier=testproduct'

Importing translations from a CSV

The products CSV has a Language Code column, and the importer expects it to be mapped. Add one row per product per language, keeping product_identifier the same across those rows.

A file cannot contain two rows with the same product identifier and language code — the importer reports There is more than one entry for the same product identifier and language code combination. Only the first entry will be processed. and skips the later rows.

Guidelines

Minimum requirements

These are the requirements that you'll need to meet to show your product. If you don't follow these requirements, we could reject your product.

  • Declare the language you are actually sending. Submitting German copy without language_code labels it as English, which leaves untranslated German on the English record and offers nothing to German buyers.
  • Use the same identifiers in every language. Different identifiers create different products rather than translations. See identifiers for the full rules.
  • Use a supported code. Anything not in the language list is rejected.

Best practices

These best practices can help you go beyond the basic requirements to optimise your product data for performance.

  • Supply your own translations for copy that matters. Machine translation is a safety net that keeps products sellable in English, not a substitute for reviewed marketing or regulatory wording.
  • Keep shared fields consistent. Because sku, prices, codes and stock are shared, sending different values on different language payloads will overwrite each other rather than coexist.
  • Only add a dialect when the wording differs. de covers every German-speaking market; reach for de-CH when Switzerland genuinely needs different copy.