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`](/docs/api-reference/store). Its `settings` block tells you what the merchant has switched on:

```json
{
  "store": {
    "currency": "usd",
    "locale": "en-US",
    "settings": {
      "defaultLanguage": "en-US",
      "enabledLanguages": { "pl-PL": true, "de-DE": true },
      "enabledCurrencies": ["usd", "eur"]
    }
  }
}
```

| Field | What it drives |
|-------|----------------|
| `store.currency` | The base currency – always available |
| `store.locale` | The store's own locale |
| `settings.defaultLanguage` | The language content falls back to |
| `settings.enabledLanguages` | Which extra languages to offer in a switcher |
| `settings.enabledCurrencies` | Which 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:

| Endpoint | Translated fields |
|----------|-------------------|
| [Products](/docs/api-reference/products) | `name`, `slug`, `summary`, `content`, `seo.title`, `seo.description` |
| [Collections](/docs/api-reference/collections) | Name, slug, description, SEO fields |
| [Categories](/docs/api-reference/categories) | Name, slug, description, SEO fields |
| [Brands](/docs/api-reference/brands) | Name, slug, description, SEO fields |
| [Posts](/docs/api-reference/posts) | `title`, `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`.

```bash
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](/docs/api-reference/products), [Variants](/docs/api-reference/variants), [Carts](/docs/api-reference/carts), [Events](/docs/api-reference/events), [Coupons](/docs/api-reference/coupons), [Promotions](/docs/api-reference/promotions), [Shipping](/docs/api-reference/shipping), [Orders](/docs/api-reference/orders), and [Analytics](/docs/api-reference/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:

```json
{
  "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

| Field | Type | Description |
|-------|------|-------------|
| `name` | `string` | Translated product name |
| `slug` | `string` | Translated URL slug |
| `summary` | `string` | Translated short summary |
| `content` | `object` | Translated description (TipTap JSONContent) |
| `badgeContent` | `string` | Translated badge text |
| `seoTitle` | `string` | Translated SEO title |
| `seoDescription` | `string` | Translated SEO description |

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

```bash
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

| Field | Type | Description |
|-------|------|-------------|
| `title` | `string` | Translated post title |
| `slug` | `string` | Translated URL slug |
| `content` | `object` | Translated body (TipTap JSONContent) |
| `seoTitle` | `string` | Translated SEO title |
| `seoDescription` | `string` | Translated SEO description |

```bash
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:

| Field | Type | Description |
|-------|------|-------------|
| `name` | `string` | Translated name |
| `slug` | `string` | Translated URL slug |
| `description` | `object` | Translated description (TipTap JSONContent) |
| `longDescription` | `object` | Translated long description (TipTap JSONContent) |
| `seoTitle` | `string` | Translated SEO title |
| `seoDescription` | `string` | Translated SEO description |

```bash
# 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

```json
{
  "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

| Status | Meaning |
|--------|---------|
| `400` | Unsupported locale, or the locale is the store's base locale |
| `404` | No entity matches the identifier |
| `409` | A 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.

## Related

- [Store API](/docs/api-reference/store) – what's enabled for this store
- [Products API](/docs/api-reference/products) – the main consumer of both parameters
- Merchant-facing setup: [Sell in multiple languages](/help/localization/multi-language)