Fetch translations
Pull finished translations into your application via the Public API — endpoints, response shapes, and integration patterns.
Once a namespace has translated terms and you have an API key, your application can fetch translations at build time or at runtime. The two read endpoints below are the whole runtime surface — see Public API for the reference view of the same thing.
Authentication
Every request carries the API key in the Authorization header:
Authorization: Apikey <your-api-key>(Bearer <your-api-key> is also accepted for clients that hard-code
the scheme.) Keys are organization-scoped — one key can read every
namespace in the org.
1. Discover language IDs
Translations are fetched per language, by numeric ID. Get the IDs once and cache them — they never change:
curl -H "Authorization: Apikey $LANGSYNC_API_KEY" \
"https://langsync.api.norcube.com/api/v1/namespaces/web-app/languages"[
{
"id": 68,
"code": "en",
"name": "English",
"isDefault": true,
"isFallback": false,
"isCustom": false
},
{
"id": 31,
"code": "de",
"name": "German",
"isDefault": false,
"isFallback": false,
"isCustom": false
}
]2. Fetch translations for one language
curl -H "Authorization: Apikey $LANGSYNC_API_KEY" \
"https://langsync.api.norcube.com/api/v1/namespaces/web-app/terms/translations?langId=31"{
"meta": { "timestamp": "2026-07-10T12:00:00Z" },
"cursors": {},
"list": [
{ "mark": "welcome.title", "value": "Willkommen" },
{ "mark": "welcome.subtitle", "value": "Schön, dass Sie hier sind" },
{ "mark": "button.submit", "value": "Absenden" }
]
}Everything you need is in list: one { mark, value } pair per term.
Reduce it to whatever your i18n library expects, e.g. a flat map:
const res = await fetch(
`https://langsync.api.norcube.com/api/v1/namespaces/${ns}/terms/translations?langId=${langId}`,
{ headers: { Authorization: `Apikey ${process.env.LANGSYNC_API_KEY}` } }
).then((r) => r.json());
const messages = Object.fromEntries(res.list.map((t) => [t.mark, t.value]));Two behaviours to design around:
- Only translated terms are returned. A term with no stored
translation in the requested language is absent from
list— not present with an empty value. Configure your i18n library to fall back to your default language for missing keys. - Always pass
langIdexplicitly. If you omit it, the endpoint falls back to LangSync's built-in English language — almost never what you want.
Integration patterns
Fetch at build time
For static sites and SPAs, fetch during the build and ship the JSON with your bundle. No runtime dependency on LangSync, CDN-cacheable, and a broken network at 3 a.m. can't take your copy down:
# build script
for pair in "en:68" "de:31" "fr:45"; do
lang="${pair%%:*}"; id="${pair##*:}"
curl -sf -H "Authorization: Apikey $LANGSYNC_API_KEY" \
"https://langsync.api.norcube.com/api/v1/namespaces/web-app/terms/translations?langId=$id" \
| jq '[.list[] | {(.mark): .value}] | add' > "src/locales/$lang.json"
doneFetch at runtime with caching
For server-rendered apps, fetch on startup, cache in memory, and refresh on a TTL you're comfortable with. Translations change on human timescales — minutes of staleness is almost always fine, so cache aggressively rather than fetching per request.
Keep files in the repo instead
If you'd rather review translation changes in pull requests, flip the
model: keep <lang>.json files in the repo and run
nrc langsync pull (or sync) to
refresh them. Your app then reads local files and never talks to the
API at runtime.
Errors
| Status | When |
|---|---|
401 UNAUTHORIZED | Missing/invalid/revoked API key, or the namespace name doesn't exist in the key's organization. |
500 INTERNAL_ERROR | Transient server problem — retry with backoff. |
Error bodies follow the platform shape { "type": "...", "msg": "..." }
— see Limits and errors.
Related
- Public API — the reference for these endpoints.
- API keys — creating and rotating credentials.