Search Documentation

Search for a documentation page...

Localization

Serve translated catalog content and per-currency prices through the API.

A YNS store can sell in more than one language and price in more than one currency. Both are driven by the Localization module, and both surface through the API as request parameters rather than separate endpoints — the same product, asked for differently.

Discover what's enabled

Start with GET /api/v1/me. Its settings block tells you what the merchant has switched on:

{
"store": {
"currency": "usd",
"locale": "en-US",
"settings": {
"defaultLanguage": "en-US",
"enabledLanguages": { "pl-PL": true, "de-DE": true },
"enabledCurrencies": ["usd", "eur"]
}
}
}
FieldWhat it drives
store.currencyThe base currency — always available
store.localeThe store's own locale
settings.defaultLanguageThe language content falls back to
settings.enabledLanguagesWhich extra languages to offer in a switcher
settings.enabledCurrenciesWhich currencies have prices set

Build your language and currency switchers from these two lists rather than hard-coding them, and the storefront follows whatever the merchant enables later.

Translated content

Pass lang with a locale code to overlay translated fields onto the response.

GET /api/v1/products?lang=pl-PL

Supported on:

EndpointTranslated fields
Productsname, slug, summary, content, seo.title, seo.description
CollectionsName, slug, description, SEO fields
CategoriesName, slug, description, SEO fields
BrandsName, slug, description, SEO fields
Poststitle, slug, content, seo.title, seo.description

Fields with no translation keep their default-language value, so a partially translated catalog never returns blanks. Locale codes are the full form — en-US, pl-PL, es-ES, de-DE.

curl \
-H "Authorization: Bearer your_api_key" \
"https://your-store.yns.store/api/v1/products?lang=pl-PL&limit=20"

Translated slugs are returned too. If you route by slug, resolve the incoming slug in the same language you rendered the links in.

Per-currency prices

Pass currency with a three-letter code to price a response in one of the store's enabled currencies.

GET /api/v1/products?currency=EUR

Supported on Products, Variants, Carts, Events, Coupons, Promotions, Shipping, Orders, and Analytics.

Prices are set per currency by the merchant rather than converted at request time, so the number you get back is the exact price they chose for that market. Product responses only include prices for currencies the store has enabled.

When writing products you can supply the extra prices directly:

{
"name": "Ceramic Mug",
"price": 24.99,
"prices": { "EUR": 22.50 }
}

Writing translations

Use the translation PUT endpoints to create, update, or delete translated content for products, collections, and categories. Each call targets one entity and one locale. Requires the catalog:write scope.

PUT /api/v1/products/:idOrSlug/translations/:locale
PUT /api/v1/collections/:idOrSlug/translations/:locale
PUT /api/v1/categories/:idOrSlug/translations/:locale
PUT /api/v1/posts/:idOrSlug/translations/:locale

The entity can be identified by UUID or slug. The locale must be a supported locale code (e.g. pl-PL, de-DE) and cannot be the store's base locale — base content is edited via the entity's own PATCH endpoint.

Behaviour

  • Upsert: if a translation row exists for this entity + locale, it is updated. Otherwise a new row is created.
  • Delete: sending an empty body (all fields omitted or blank) deletes the translation row entirely, so the entity falls back to its base-language content.
  • The locale does not have to be enabled in settings.enabledLanguages — you can stage translations before flipping the language on.

Product translation fields

FieldTypeDescription
namestringTranslated product name
slugstringTranslated URL slug
summarystringTranslated short summary
contentobjectTranslated description (TipTap JSONContent)
badgeContentstringTranslated badge text
seoTitlestringTranslated SEO title
seoDescriptionstringTranslated SEO description

All fields are optional. The schema is strict — unknown fields are rejected.

curl -X PUT \
-H "Authorization: Bearer your_api_key" \
-H "Content-Type: application/json" \
-d '{
"name": "Klasyczna koszulka",
"slug": "klasyczna-koszulka",
"summary": "Wygodna koszulka na co dzień",
"seoTitle": "Klasyczna koszulka — Twój sklep"
}' \
https://your-store.yns.store/api/v1/products/classic-tee/translations/pl-PL

Post translation fields

FieldTypeDescription
titlestringTranslated post title
slugstringTranslated URL slug
contentobjectTranslated body (TipTap JSONContent)
seoTitlestringTranslated SEO title
seoDescriptionstringTranslated SEO description
curl -X PUT \
-H "Authorization: Bearer your_api_key" \
-H "Content-Type: application/json" \
-d '{
"title": "Witamy w naszym sklepie",
"slug": "witamy-w-naszym-sklepie",
"seoTitle": "Witamy | Nasz sklep"
}' \
https://your-store.yns.store/api/v1/posts/welcome-to-our-store/translations/pl-PL

Collection and category translation fields

Collections and categories share the same field set:

FieldTypeDescription
namestringTranslated name
slugstringTranslated URL slug
descriptionobjectTranslated description (TipTap JSONContent)
longDescriptionobjectTranslated long description (TipTap JSONContent)
seoTitlestringTranslated SEO title
seoDescriptionstringTranslated SEO description
# Collection translation
curl -X PUT \
-H "Authorization: Bearer your_api_key" \
-H "Content-Type: application/json" \
-d '{"name": "Polecane produkty", "slug": "polecane-produkty"}' \
https://your-store.yns.store/api/v1/collections/featured-products/translations/pl-PL

# Category translation
curl -X PUT \
-H "Authorization: Bearer your_api_key" \
-H "Content-Type: application/json" \
-d '{"name": "Koszulki", "slug": "koszulki"}' \
https://your-store.yns.store/api/v1/categories/shirts/translations/pl-PL

Response

{
"ok": true,
"productId": "0191abc0-1234-7def-8000-000000000001",
"locale": "pl-PL",
"deleted": false
}

The response includes productId, collectionId, categoryId, or postId depending on the entity type, plus the locale and a deleted flag indicating whether the translation was removed (all fields were empty).

Errors

StatusMeaning
400Unsupported locale, or the locale is the store's base locale
404No entity matches the identifier
409A translation with this slug already exists for the same locale

Putting it together

  1. Call GET /api/v1/me once and cache it.
  2. Render switchers from enabledLanguages and enabledCurrencies.
  3. Thread the visitor's choice through every catalog call as lang and currency.
  4. Fall back to defaultLanguage and store.currency when the visitor hasn't chosen.