ローカライゼーションジョブグループを作成します。1回のリクエストで、指定したすべての対象ロケールにコンテンツを展開できます。
文字列のペイロードとロケールの一覧があり、それらをまとめて翻訳したい。でも、ロケールごとに振り分ける処理は自前で実装したくない。そんなときは POST /jobs/localization です。ペイロード全体と最大100件の対象ロケールを1回のリクエストで受け取り、202 Accepted を即座に返します。返ってくるのはグループIDと、ロケールごとに1件のジョブ。1回のリクエストで、すべてのロケールへ。ジョブの作成はプラットフォームが行い、それぞれを独立して処理します。
POST /jobs/localizationこのページでは、作成エンドポイントの呼び出し方法を説明します。パラメータ、リクエストの形式、202 レスポンス、そして安全に再試行できるようにする方法までをカバーします。非同期ローカライゼーションが初めてなら、まずは Async Localization API overview で全体像をつかんでください。グループ作成後に各ロケールのステータスの意味を確認したい場合は、ジョブグループの追跡 を参照してください。
認証
APIキーは X-API-Key ヘッダーで渡します。キーは組織単位でスコープされ、組織内のすべてのエンジンにアクセスできます。詳しくは Authentication を参照してください。
パラメータ#
sourceLocale、targetLocales、data は必須です。それ以外の項目は、動作を調整したり、同じ呼び出しを安全に繰り返せるようにしたりするためのものです。
| パラメータ | 型 | 説明 |
|---|---|---|
sourceLocale | string | BCP-47 のソースロケール(例: en)。 |
targetLocales | string[] | BCP-47 の対象ロケール(例: ["de", "fr", "ja"])。1リクエストあたり1〜100件。ロケールごとに1件のジョブが作成されます。 |
data | object | 翻訳対象のキーと値からなるコンテンツ。ネストしたオブジェクトや配列も、任意の深さで指定できます。 |
context | string (optional) | この翻訳ペイロードに対する大まかなコンテキスト。たとえば、製品上の表示箇所、対象読者、用途などです。このリクエストで作成されるすべてのジョブに適用されます。 |
hints | object (optional) | 短い文字列や使い回される文字列の意味を明確にするための、キーごとのコンテキスト。breadcrumb 文字列の配列として指定します。 |
callbackUrl | string (optional) | このグループ用の HTTPS webhook URL。組織のデフォルト設定を上書きします。HTTP は受け付けられません。 |
idempotencyKey | string (optional) | クライアント側で生成するキーです。同じキーで同じリクエストを2回送ると、新しいグループではなく既存のグループが返されます。スコープはエンジン単位です。 |
engineId | string (optional) | ジョブの実行に使うローカライゼーションエンジン。省略した場合は、組織のデフォルトエンジンが使われます。 |
pipelineConfig | object (optional) | リクエスト単位の pipeline 上書き設定。省略したステージはエンジン設定を継承します。 |
lockedKeys | string[] (optional) | 値を翻訳対象から除外し、outputData にそのままマージし直すキーまたは glob パターン。最大100件まで指定できます。詳しくは 翻訳不要キーをロックする を参照してください。 |
リクエスト#
data フィールドには、フラットなキー・バリュー形式でも、オブジェクトや配列を任意の深さで含むネスト構造でも指定できます。エンジンはすべての文字列値を翻訳し、文字列以外の値(数値、真偽値、null)はそのまま保持したうえで、送信したものとまったく同じ形で返します。つまり、アプリがすでに保持しているオブジェクトをそのまま渡せます。フラット化も、構造の組み替えも不要です。
{
"sourceLocale": "en",
"targetLocales": ["de", "fr", "ja"],
"data": {
"lesson_title": "Introduction to Machine Learning",
"lesson_summary": "This lesson covers the fundamentals of ML, including supervised and unsupervised learning."
},
"callbackUrl": "https://your-app.com/webhooks/translations",
"idempotencyKey": "course_101-v3"
}HTTPS 必須
callbackUrl には HTTPS を使用する必要があります。HTTP URL は 400 エラーで拒否されます。
このネストされたペイロードには、翻訳すべきテキストと、変更せずそのまま残す必要がある値が混在しています。たとえば id、course_101、difficulty です。文字列は翻訳され、それ以外は型を保ったまま維持されます。文字列であっても翻訳対象から外したい場合(slug、アセット URL、enum コードなど)は、lockedKeys に指定してください。各ロケールの出力に、そのままマージし直されます。
レスポンス(202 Accepted)#
この呼び出しはすぐに返ります。翻訳完了は待ちません。まずグループIDとロケールごとのジョブIDが返され、その後はプラットフォームがバックグラウンドで各ジョブを独立して処理します。
{
"groupId": "ljg_A1b2C3d4E5f6G7h8",
"status": "pending",
"jobs": [
{ "id": "ljb_A1b2C3d4E5f6G7h8", "targetLocale": "de", "status": "queued" },
{ "id": "ljb_B2c3D4e5F6g7H8i9", "targetLocale": "fr", "status": "queued" },
{ "id": "ljb_C3d4E5f6G7h8I9j0", "targetLocale": "ja", "status": "queued" }
],
"createdAt": "2026-03-16T10:30:00.000Z"
}| フィールド | 説明 |
|---|---|
groupId | グループ全体を表す ljg_ 接頭辞付きの識別子です。必ず保存してください。追跡 やライブ進捗確認に使うハンドルになります。 |
status | 作成時点でのグループステータス。通常は pending です。 |
jobs | 対象ロケールごとに1エントリ。id(ljb_ 接頭辞付き)、targetLocale、およびジョブの status が含まれます。 |
createdAt | ISO 8601 形式のタイムスタンプ。 |
3つのロケールを指定すれば、3件のジョブが返り、どれも queued の状態で実行待ちになります。ジョブの進行に応じて各ステータスが何を意味するのか、また1つのロケールだけ失敗して他がそのまま進む場合にどうなるのかは、Track a job group を参照してください。
例#
同じリクエストを Node と Python で示します。どちらも1回の POST を送るだけで、202 からグループIDとジョブ数をそのまま取得できます。
const response = await fetch("https://api.lingo.dev/jobs/localization", {
method: "POST",
headers: {
"X-API-Key": process.env.LINGO_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
sourceLocale: "en",
targetLocales: ["de", "fr", "ja"],
data: {
title: "Introduction to Machine Learning",
steps: [
{ heading: "What is ML?", body: "Machine learning is a subset of AI." },
{ heading: "Supervised Learning", body: "Training with labeled data." },
],
},
callbackUrl: "https://your-app.com/webhooks/translations",
}),
});
const { groupId, jobs } = await response.json();
// 202 Accepted – the call returns without waiting for translation.
console.log(groupId); // "ljg_A1b2C3d4E5f6G7h8"
console.log(jobs.length); // 3 – one queued job per target locale呼び出しを安全に再試行する#
このリクエストを送る場所として自然なのは、save hook や event handler のような箇所です。つまり、再試行が走ったり重複イベントが届いたりしたときに、同じコードが2回実行されがちな場所です。対策なしでは、2回の呼び出しで2つのジョブグループが作成され、同じコンテンツが2回翻訳キューに入ってしまいます。
idempotencyKey を渡せば、そのリスクはなくなります。同じキーで同じリクエストを2回送ると、プラットフォームは新しいグループを作らず、既存のグループを返します。つまり、2セット目のジョブは作成されません。キーはエンジン単位でスコープされるため、別のエンジンに対して同じキーを使うと別グループになります。
意味のあるキーを選ぶ
良いキーは、コンテンツの識別子とバージョンを組み合わせたものです: {contentId}-v{contentVersion}。同じコンテンツの同じバージョンなら、常に同じグループに解決されるため、再試行は自動的に no-op になります。コンテンツが変わったらバージョンを更新すれば、新しいグループが作成されます。
const key = `${content.id}-v${content.version}`;
async function submit() {
const response = await fetch("https://api.lingo.dev/jobs/localization", {
method: "POST",
headers: {
"X-API-Key": process.env.LINGO_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
sourceLocale: "en",
targetLocales: ["de", "fr", "ja", "ko", "pt-BR"],
data: { title: content.title, steps: content.steps },
callbackUrl: "https://your-app.com/webhooks/translations",
idempotencyKey: key,
}),
});
return (await response.json()).groupId;
}
const first = await submit();
const again = await submit(); // same key – duplicate submission
console.log(first === again); // true – same group returned, no second set of jobs1つのペイロードをすべてのロケールへ展開できる POST はこれだけです。しかも、再試行が起こりうる同じコードパスから安全に呼び出せます。groupId は必ず保存してください。追跡やライブ進捗確認で使うのはこの値です。
