Backend API
Content localization is supported by providing alternative values for each configured locale. Any string or array of strings can be set in multiple locales with the $locale parameter when creating or updating objects.
Locales can be specified with or without a country code (e.g., en and en-US).
Use the format $locale: { <code>: { <field>: value } } with any PUT or POST request. For nested values, the $locale parameter must be defined on the nearest parent object.
All locale content is optional using this API, even if the setting Require content for this locale is enabled in the Swell dashboard.
const { swell } = require('swell-node');
swell.init('store-id', 'secret-key');
await swell.put('/products/5cad15bc9b14d1990724663a', {
name: 'Test product',
tags: ['tag1', 'tag2'],
$locale: {
fr: {
name: 'Test produit',
tags: ['étiqueter1', 'étiqueter2']
},
es: {
name: 'Producto de prueba',
tags: ['etiqueta1', 'etiqueta2']
},
},
});
Response
{
"id": "5cad15bc9b14d1990724663a",
"name": "Test product",
"tags": ["tag1", "tag2"],
"$locale": {
"en": {
"name": "Test product",
"tags": ["tag1", "tag2"]
},
"fr": {
"name": "Test produit",
"tags": ["étiqueter1", "étiqueter2"]
},
"es": {
"name": "Producto de prueba",
"tags": ["etiqueta1", "etiqueta2"]
}
}
...
}Use the query parameter $locale: <code>, or alternatively an HTTP header X-Locale: <code> with any GET request. All fields with localized values will be returned according to the locale code and fallback settings.
const { swell } = require('swell-node');
swell.init('store-id', 'secret-key');
await swell.get('/products', {
$locale: 'fr'
});
Response
{
"count": 36,
"results": [
{
"id": "5cad15bc9b14d1990724663a",
"name": "Test produit",
"tags": ["étiqueter1", "étiqueter2"],
...
}
],
"page": 1,
...
}To retrieve records with $locale values in order to review localized content or build custom localization interfaces, pass an array of locale codes using the parameter $locale: [<code>, ...] with any GET request. All objects with $locale values will be returned matching the specific locale codes requested.
const { swell } = require('swell-node');
swell.init('store-id', 'secret-key');
await swell.get('/products', {
$locale: ['en', 'fr', 'es']
});
Response
{
"count": 36,
"results": [
{
"id": "5cad15bc9b14d1990724663a",
"name": "Test product",
"$locale": {
"en": {
"name": "Test product",
"tags": ["tag1", "tag2"]
},
"fr": {
"name": "Test produit",
"tags": ["étiqueter1", "étiqueter2"]
},
"es": {
"name": "Producto de prueba",
"tags": ["etiqueta1", "etiqueta2"]
},
}
...
}
],
"page": 1,
...
}Every store has a base currency, and can enable additional currencies in settings. Each additional currency works in one of two modes: priced—you set explicit prices in that currency—or display, where prices are converted automatically from the base currency at the current exchange rate. Exchange rates come from a platform-level table that refreshes hourly.
Retrieve the store's currency configuration and current rates from /:currencies. Each entry's type is base, priced, or display:
await swell.get('/:currencies');{
"base": "USD",
"rates": {
"USD": 1,
"EUR": 0.92,
"AUD": 1.53
},
"config": [
{
"code": "USD",
"rate": 1,
"name": "US Dollar",
"symbol": "$",
"decimals": 2,
"priced": true,
"type": "base"
},
{
"code": "EUR",
"rate": 0.92,
"name": "Euro",
"symbol": "€",
"decimals": 2,
"priced": true,
"type": "priced"
},
{
"code": "AUD",
"rate": 1.53,
"name": "Australian Dollar",
"symbol": "A$",
"decimals": 2,
"priced": false,
"type": "display"
}
]
}For priced currencies, set explicit values by including a $currency object beside the regular fields, keyed by currency code (codes are uppercased automatically):
await swell.put('/products/{id}', {
id: '5ca24abb9c077817e5fe2b36',
price: 15,
$currency: {
EUR: { price: 14 },
GBP: { price: 12.5 }
}
});This works at any level where price fields live—the product root, purchase_options and their subscription plans, prices entries, options, and variants. Fields that support per-currency values are the currency-typed fields on each object, such as price and sale_price. Write responses always include the full $currency map, so you can confirm what is stored.
Pass $currency on a GET request to have price fields returned in that currency:
// Prices flattened to EUR
await swell.get('/products/{id}', {
id: '5ca24abb9c077817e5fe2b36',
$currency: 'EUR'
});
// Keep the per-currency map for several currencies
await swell.get('/products/{id}', {
id: '5ca24abb9c077817e5fe2b36',
$currency: ['USD', 'EUR']
});The value returned for each price field depends on the currency's configuration:
- Priced currency with an explicit stored value: the stored value is returned.
- Priced currency with no stored value: converted from the base price at the current rate when the currency has fallback conversion enabled; otherwise null.
- Display currency: always converted from the base price at the current rate, even if a stored value exists.
- Unconfigured currency code: no error is returned, and prices are left unchanged (or use stored values if any exist for that code).
Converted values are rounded using the currency's settings—decimals, and optional rounding to whole units or fraction endings (for example, prices ending in .95). With a single code, the response's currency field is set to the requested code and the $currency map is omitted; with an array of codes, the map is kept and filtered to the requested codes. $currency also applies to records brought in with expand and include.
To transact in another currency, set the currency field on the cart or order—not the $currency parameter, which only affects how records are read:
await swell.put('/carts/{id}', {
id: '5cad15bc9b14d1990724663a',
currency: 'EUR'
});- A priced currency re-prices the cart in that currency—items need a price in it, either stored on the product or passed explicitly on the item.
- A display currency is recorded as display_currency while the transaction currency and totals are unchanged—the base currency for a new cart, or whatever currency the cart already transacts in.
- An inactive currency is rejected with an error, and the currency can't be changed after a payment has been made.
When a record's currency differs from the base currency, currency_rate is snapshotted at write time and not refreshed by later writes—pass currency_rate: null to recompute it at the current rate, or supply your own value.