Multilingual ecommerce setup

D365 Commerce Headless Language Support

January 26, 20263 min read

Language trick in headless commerce!

If you follow my quarterly unofficial release notes for D365 Commerce CSU (example link), you've probably found a link to my website which hosts the latest openapi documentation for the ~700 Commerce CSU APIs:

Swagger

In a truly headless environment, you'd want some of these APIs to adapt content based on user language. For example, when a customer user clicks a language flag in a portal to change from English to German, you'd want the content to return Product names or Mode of Delivery in German, right?

If you look into the API request definitions, you'll find language related properties in some of the APIs. But what the Microsoft documentation doesn't tell you is that passing a Accept-Language header actually steers the response content - Thats our hidden gem for today..


What CSU does with Accept-Language

When you add the header, CSU will return certain translated values in that language (when translations exist and are synchronized to the channel DB).

Example request with Accept-Langage header:

Header - language translated in CSU

This header sets RequestContext.Language:

  • It reads the Accept-Language header

  • Takes the first language entry

  • If the header is missing or null, Commerce CSU sets RequestContext.Language as per the channel's (online store's) default language


Example 1: Country/region names translated in shipping APIs

If you maintain country/region translations in D365 (Address setup > Country/region > Translations), CSU can return the translated short/long names when you pass Accept-Language.

API example

  • GET /Commerce/GetCountryRegionsForShipping

Behavior

  • With Accept-Language: the response returns country/region ShortName and LongName in German (if translations exist).

This is a super clean way to avoid translation work in your frontend.


Example 2: Mode of delivery descriptions translated (with a gotcha)

Modes of delivery: you can’t translate the code, but you can translate the description. CSU applies those translations when Accept-Language is set. Background info

Works for:

  • GET /Commerce/GetDeliveryOptions

  • GET /Commerce/Carts('{Retail_CartId}')/GetDeliveryOptions

Does NOT work for

  • GET /Commerce/OrgUnits/GetChannelDeliveryOptions

Gotcha (important):If you configure Mode of delivery translations in D365, define translations forall languages, including the default online store language. Otherwise, when the Accept-Language header is missing and CSU will fall back to the default language (which is missing a translation), CSU will pick the “first available translation record” in an unexpected language.


Example 3: Product search and Accept-Language (subtle but useful)

This is where things get interesting. CSU product search isn’t “one engine”. Different endpoints behave differently with language:

  • Products/Search and SearchByText donotsupport searching in another language than the channel default.

  • SearchByCriteria can search in a non-default channel language if set in the request body. Note: this language needs to be listed under languages on the online store setup in D365 ERP to make this work.

  • With Accept-Language on SearchByCriteria, attribute/search condition evaluation runs against the online store's default languageandthe Accept-Language language (if different), whileProduct Name/Description are returned in theAccept-Language language.

Concrete exampleFor a channel with default language en-us, using:

  • POST /Commerce/Products/SearchByCriteria

  • Accept-Language: de

  • Search condition: “Brush” (default language) or "Bürste" (Accept-Language) -> Both work

Result: product info comes back in de as “Bürste/Brüste" (so as per Accept-Language). Attribute values will also be translated into the Accept-Language (de) if translations exist.

Article content

Why I’m sharing this

Because this is the kind of thing that:

  • improves customer experience immediately,

  • reduces frontend translation complexity,

  • and is easy to miss if you only test with default channel language.

If you’re building headless Commerce on CSU, add Accept-Language to your test scripts and see where it changes your responses.


We're experts designing and implementing B2C and B2B headless Commerce in Retail, Wholesale, Manufacturing, or Professional Services - Connect with us at 365Connect.

Back to Blog
Blog Image

Designing Headless Commerce Starts with Data — Not Apps

Patrick Mouwen Published on: 07/02/2026

Broken APIs = Broken Customer Experience. Stop building from scratch. Our latest article outlines how to deploy a quick-start Data Quality framework that identifies errors in Dynamics 365 before they reach your customers. #AzureDataFactory #PowerBI

Headless Commerce ArchitectureD365 ERP APIsAzure Data Factory Data QualityComposite APIs