Noma

Translations

Translations

Content entries can participate in a translation group so multiple locales stay linked. The API supports reading a linked translation and linking two existing entries in the same collection.

Read a linked translation (translation_locale)

On Get an Entry, pass translation_locale to fetch the entry that shares the same translation group in another locale.

  • The path uuid still identifies the entry you start from.
  • The response is the other locale’s entry when a link exists.
  • The entry at uuid is loaded without a state filter when translation_locale is present; the linked entry is then filtered by state (same state query value you send).

Errors (404)

MessageMeaning
Translation not found for locale '{locale}'.No linked entry in that locale.
This entry has no translations linked.The entry has no translation_group_id.

Links two existing entries in the same collection that have different locales.

Request

POST /api/{collection}/{uuid}/link-translation HTTP/1.1
Host: app.nomacms.com
Content-Type: application/json
project-id: <project-uuid>
Authorization: Bearer <api-token>
Accept: application/json

Requires the update ability on the token.

Path parameters

ParamDescription
collectionCollection slug
uuidUUID of one of the entries to link (the “source” row)

JSON body

FieldTypeDescription
translation_entry_uuidstring (UUID)The other entry’s UUID (must exist in the same collection and project)

Response (200)

{
  "message": "Translation linked successfully.",
  "translation_group_id": 123
}

Errors

StatusWhen
400Missing project-id or project cannot be resolved
401Missing or invalid bearer token
403Token does not have update (or *)
404Collection or source entry not found
422Translation UUID missing, entry not in collection, same entry, or same locale as the source
429Rate limited

The server uses the translation service to assign a shared translation group for both entries.

Singleton collections

When you create an entry in a singleton collection, the API may auto-link it with singleton entries in other locales for the same project (implementation in ContentEntryTranslationService). Treat that as a convenience for multilingual singletons; exact behavior follows your project’s locale setup.

Example

GET examples resolve the linked row via translation_locale (see Get an Entry). POST calls link-translation to connect two existing entries (EN_UUID / OTHER_UUID must differ in locale). Use one flow or the other as needed.

import { createClient } from "@nomacms/js-sdk"
 
const client = createClient({
  projectId: process.env.NOMA_PROJECT_ID!,
  apiKey: process.env.NOMA_API_KEY!,
})
 
const en = await client.content.get("blog-posts", enUuid, { state: "published" })
 
const tr = await client.content.get("blog-posts", enUuid, {
  state: "published",
  translation_locale: "tr",
})
 
await client.content.linkTranslation("blog-posts", enUuid, {
  translation_entry_uuid: otherUuid,
})
import axios from "axios"
 
const headers = {
  "project-id": process.env.NOMA_PROJECT_ID!,
  Authorization: `Bearer ${process.env.NOMA_API_KEY}`,
  Accept: "application/json",
}
 
async function main() {
  const base = `https://app.nomacms.com/api/blog-posts/${encodeURIComponent(enUuid)}`
 
  const english = await axios.get(base, {
    params: { state: "published" },
    headers,
  })
  console.log(english.data)
 
  const turkish = await axios.get(base, {
    params: { state: "published", translation_locale: "tr" },
    headers,
  })
  console.log(turkish.data)
 
  const linked = await axios.post(
    `${base}/link-translation`,
    { translation_entry_uuid: otherUuid },
    { headers: { ...headers, "Content-Type": "application/json" } },
  )
  console.log(linked.data)
}
 
void main()
<?php
 
$slug = 'blog-posts';
$enUuid = getenv('EN_UUID');
$basePath = '/api/' . rawurlencode($slug) . '/' . rawurlencode($enUuid);
$hdr = [
    'project-id: ' . getenv('NOMA_PROJECT_ID'),
    'Authorization: Bearer ' . getenv('NOMA_API_KEY'),
    'Accept: application/json',
];
 
// GET — linked translation (Turkish)
$query = http_build_query([
    'state' => 'published',
    'translation_locale' => 'tr',
]);
$ch = curl_init('https://app.nomacms.com' . $basePath . '?' . $query);
curl_setopt_array($ch, [
    CURLOPT_HTTPHEADER => $hdr,
    CURLOPT_RETURNTRANSFER => true,
]);
echo curl_exec($ch) . "\n";
 
// POST — link translation
$body = json_encode(['translation_entry_uuid' => getenv('OTHER_UUID')]);
$ch = curl_init('https://app.nomacms.com' . $basePath . '/link-translation');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => $body,
    CURLOPT_HTTPHEADER => array_merge([
        'Content-Type: application/json',
        'Content-Length: ' . strlen($body),
    ], $hdr),
    CURLOPT_RETURNTRANSFER => true,
]);
echo curl_exec($ch);
# GET — fetch linked entry in another locale (path uuid = source entry)
curl -sS -G "https://app.nomacms.com/api/blog-posts/${EN_UUID}" \
  --data-urlencode "state=published" \
  --data-urlencode "translation_locale=tr" \
  -H "project-id: $NOMA_PROJECT_ID" \
  -H "Authorization: Bearer $NOMA_API_KEY" \
  -H "Accept: application/json"
 
# POST — link two entries as translations
curl -sS -X POST "https://app.nomacms.com/api/blog-posts/${EN_UUID}/link-translation" \
  -H "Content-Type: application/json" \
  -H "project-id: $NOMA_PROJECT_ID" \
  -H "Authorization: Bearer $NOMA_API_KEY" \
  -H "Accept: application/json" \
  -d "{\"translation_entry_uuid\":\"${OTHER_UUID}\"}"
package main
 
import (
	"bytes"
	"encoding/json"
	"io"
	"net/http"
	"net/url"
	"os"
)
 
func main() {
	host := "https://app.nomacms.com/api/blog-posts/" + url.PathEscape(os.Getenv("EN_UUID"))
	hdr := func(req *http.Request) {
		req.Header.Set("project-id", os.Getenv("NOMA_PROJECT_ID"))
		req.Header.Set("Authorization", "Bearer "+os.Getenv("NOMA_API_KEY"))
		req.Header.Set("Accept", "application/json")
	}
 
	// GET — linked translation
	u, _ := url.Parse(host)
	q := u.Query()
	q.Set("state", "published")
	q.Set("translation_locale", "tr")
	u.RawQuery = q.Encode()
	req, _ := http.NewRequest("GET", u.String(), nil)
	hdr(req)
	do(req)
 
	// POST — link translation
	payload, _ := json.Marshal(map[string]string{
		"translation_entry_uuid": os.Getenv("OTHER_UUID"),
	})
	req, _ = http.NewRequest("POST", host+"/link-translation", bytes.NewReader(payload))
	hdr(req)
	req.Header.Set("Content-Type", "application/json")
	do(req)
}
 
func do(req *http.Request) {
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	_, _ = io.Copy(os.Stdout, res.Body)
}
require "net/http"
require "json"
require "uri"
 
slug = "blog-posts"
en_uuid = ENV.fetch("EN_UUID")
base = URI("https://app.nomacms.com/api/#{slug}/#{en_uuid}")
 
headers = {
  "project-id" => ENV.fetch("NOMA_PROJECT_ID"),
  "Authorization" => "Bearer #{ENV.fetch('NOMA_API_KEY')}",
  "Accept" => "application/json"
}
 
# GET — linked translation
get_uri = base.dup
get_uri.query = URI.encode_www_form("state" => "published", "translation_locale" => "tr")
req = Net::HTTP::Get.new(get_uri)
headers.each { |k, v| req[k] = v }
Net::HTTP.start(get_uri.hostname, get_uri.port, use_ssl: get_uri.scheme == "https") do |http|
  puts http.request(req).body
end
 
# POST — link translation
post_uri = URI("https://app.nomacms.com/api/#{slug}/#{en_uuid}/link-translation")
req = Net::HTTP::Post.new(post_uri)
req["Content-Type"] = "application/json"
headers.each { |k, v| req[k] = v }
req.body = JSON.generate("translation_entry_uuid" => ENV.fetch("OTHER_UUID"))
Net::HTTP.start(post_uri.hostname, post_uri.port, use_ssl: post_uri.scheme == "https") do |http|
  puts http.request(req).body
end
import json
import os
import urllib.parse
import urllib.request
 
slug = "blog-posts"
en_uuid = os.environ["EN_UUID"]
path = f"/api/{urllib.parse.quote(slug, safe='')}/{urllib.parse.quote(en_uuid, safe='')}"
base = f"https://app.nomacms.com{path}"
hdr = {
    "project-id": os.environ["NOMA_PROJECT_ID"],
    "Authorization": f"Bearer {os.environ['NOMA_API_KEY']}",
    "Accept": "application/json",
}
 
# GET — linked translation
q = urllib.parse.urlencode({"state": "published", "translation_locale": "tr"})
req = urllib.request.Request(
    f"{base}?{q}",
    headers=hdr,
    method="GET",
)
with urllib.request.urlopen(req) as res:
    print(res.read().decode())
 
# POST — link translation
body = {"translation_entry_uuid": os.environ["OTHER_UUID"]}
req = urllib.request.Request(
    f"{base}/link-translation",
    data=json.dumps(body).encode(),
    headers={**hdr, "Content-Type": "application/json"},
    method="POST",
)
with urllib.request.urlopen(req) as res:
    print(res.read().decode())
  • Get an Entry - translation_locale
  • JavaScript SDK - content.get, content.linkTranslation

Search documentation

Find guides and reference pages