The provisioning API lets you create and configure localization engines and their components programmatically. Every resource you can set up in the dashboard is also available through these endpoints.
All endpoints on this page require the same X-API-Key authentication described on the How it works page.
Engines#
A localization engine is the core unit - it holds model configs, glossary items, brand voices, and instructions that together define how translations are produced.
Create an engine#
POST /engines| Parameter | Type | Description |
|---|---|---|
ownerOrganizationId | string | Organization ID (org_...) |
name | string | Engine display name |
description | string (optional) | Engine description |
sourceLocales | string[] (optional) | BCP-47 source locales (e.g., ["en"]) |
targetLocales | string[] (optional) | BCP-47 target locales (e.g., ["de", "fr", "ja"]) |
Default model configs
Every new engine is created with a default set of model configurations (primary + fallback) using wildcard locale pairs. You can customize these after creation via the model config endpoints.
const response = await fetch("https://api.lingo.dev/engines", {
method: "POST",
headers: {
"X-API-Key": "your_api_key",
"Content-Type": "application/json",
},
body: JSON.stringify({
ownerOrganizationId: "org_abc123",
name: "Production Engine",
description: "Main localization engine",
sourceLocales: ["en"],
targetLocales: ["de", "fr", "ja"],
}),
});
const engine = await response.json();
// { id: "eng_xyz789", name: "Production Engine", ... }Update an engine#
PUT /engines/:id| Parameter | Type | Description |
|---|---|---|
name | string (optional) | New engine name |
description | string (optional) | New description |
sourceLocales | string[] (optional) | New source locales |
targetLocales | string[] (optional) | New target locales |
Get an engine#
GET /engines/:idDelete an engine#
DELETE /engines/:idCascade deletion
Deleting an engine removes all its model configs, glossary items, brand voices, and instructions.
Model Configs#
Model configs map AI provider/model pairs to locale pairs on an engine. Each config has a rank - lower rank means higher priority. When the primary model fails, the engine falls through to the next ranked model.
Create a model config#
POST /model-configs| Parameter | Type | Description |
|---|---|---|
ownerEngineId | string | Engine ID (eng_...) |
provider | string | AI provider (e.g., anthropic, openai) |
model | string | Model name (e.g., claude-sonnet-4-6, gpt-4.1) |
sourceLocale | string | BCP-47 source locale, or * for all |
targetLocale | string | BCP-47 target locale, or * for all |
rank | number (optional) | Priority rank (0 = primary, default: 0) |
const response = await fetch("https://api.lingo.dev/model-configs", {
method: "POST",
headers: {
"X-API-Key": "your_api_key",
"Content-Type": "application/json",
},
body: JSON.stringify({
ownerEngineId: "eng_xyz789",
provider: "anthropic",
model: "claude-sonnet-4-6",
sourceLocale: "*",
targetLocale: "*",
rank: 0,
}),
});
const config = await response.json();Use * as the locale to create a wildcard config that applies to all locale pairs. Locale-specific configs take precedence over wildcard configs.
Update a model config#
PUT /model-configs/:id| Parameter | Type | Description |
|---|---|---|
provider | string (optional) | New provider |
model | string (optional) | New model |
sourceLocale | string (optional) | New source locale |
targetLocale | string (optional) | New target locale |
rank | number (optional) | New priority rank |
Reorder model configs#
POST /model-configs/reorder| Parameter | Type | Description |
|---|---|---|
ids | string[] | Ordered list of model config IDs (first = rank 0) |
Delete a model config#
DELETE /model-configs/:idGlossary Items#
Glossary items enforce exact translations or mark terms as non-translatable. During localization, the engine performs a vector similarity search against glossary items to find matching terms.
Create a glossary item#
POST /glossary-items| Parameter | Type | Description |
|---|---|---|
ownerEngineId | string | Engine ID (eng_...) |
sourceLocale | string | BCP-47 source locale |
targetLocale | string | BCP-47 target locale |
sourceText | string | Source term |
targetText | string | Target translation |
hint | string (optional) | Disambiguation hint for context |
type | string | custom_translation or non_translatable |
// Enforce a specific translation
await fetch("https://api.lingo.dev/glossary-items", {
method: "POST",
headers: {
"X-API-Key": "your_api_key",
"Content-Type": "application/json",
},
body: JSON.stringify({
ownerEngineId: "eng_xyz789",
sourceLocale: "en",
targetLocale: "de",
sourceText: "workspace",
targetText: "Arbeitsbereich",
hint: "UI term for a project container",
type: "custom_translation",
}),
});
// Mark a term as non-translatable
await fetch("https://api.lingo.dev/glossary-items", {
method: "POST",
headers: {
"X-API-Key": "your_api_key",
"Content-Type": "application/json",
},
body: JSON.stringify({
ownerEngineId: "eng_xyz789",
sourceLocale: "en",
targetLocale: "*",
sourceText: "Lingo.dev",
targetText: "Lingo.dev",
type: "non_translatable",
}),
});Update a glossary item#
PUT /glossary-items/:idAll fields are optional - only provide the fields you want to change.
Delete a glossary item#
DELETE /glossary-items/:idBrand Voices#
Brand voices define how translations should sound in a specific locale. Each brand voice is scoped to a target locale on an engine. Use * as the locale for a default brand voice that applies to all locales without a specific one.
Create a brand voice#
POST /brand-voices| Parameter | Type | Description |
|---|---|---|
ownerEngineId | string | Engine ID (eng_...) |
targetLocale | string | BCP-47 target locale, or * for all |
text | string | Brand voice description guiding tone and style |
await fetch("https://api.lingo.dev/brand-voices", {
method: "POST",
headers: {
"X-API-Key": "your_api_key",
"Content-Type": "application/json",
},
body: JSON.stringify({
ownerEngineId: "eng_xyz789",
targetLocale: "de",
text: "Use formal German (Sie-form). Keep sentences concise and direct. Prefer active voice. Use technical terminology consistently.",
}),
});Update a brand voice#
PUT /brand-voices/:id| Parameter | Type | Description |
|---|---|---|
targetLocale | string (optional) | New target locale |
text | string (optional) | New brand voice text |
Delete a brand voice#
DELETE /brand-voices/:idInstructions#
Instructions are custom prompts included in every localization request for a target locale. Unlike brand voices which guide tone, instructions provide specific rules - "always use Oxford comma", "abbreviate United States as US", etc.
Create an instruction#
POST /instructions| Parameter | Type | Description |
|---|---|---|
ownerEngineId | string | Engine ID (eng_...) |
name | string | Instruction name (for display) |
text | string | Instruction text included in the localization prompt |
targetLocale | string | BCP-47 target locale, or * for all |
await fetch("https://api.lingo.dev/instructions", {
method: "POST",
headers: {
"X-API-Key": "your_api_key",
"Content-Type": "application/json",
},
body: JSON.stringify({
ownerEngineId: "eng_xyz789",
name: "Date format",
text: "Always format dates as DD.MM.YYYY in German translations.",
targetLocale: "de",
}),
});Update an instruction#
PUT /instructions/:id| Parameter | Type | Description |
|---|---|---|
name | string (optional) | New instruction name |
text | string (optional) | New instruction text |
targetLocale | string (optional) | New target locale |
Delete an instruction#
DELETE /instructions/:idAPI Keys#
API keys authenticate requests to the localization API. Each key is scoped to an organization and has access to all engines within it.
Create an API key#
POST /api-keys| Parameter | Type | Description |
|---|---|---|
ownerOrganizationId | string | Organization ID (org_...) |
name | string | Key display name |
The response includes a key field with the full API key. This is the only time the key is returned - store it securely.
{
"id": "key_abc123",
"ownerOrganizationId": "org_abc123",
"name": "Production",
"key": "lingo_sk_..."
}Get an API key#
GET /api-keys/:idReturns metadata only (name, ID). The key value is never returned after creation.
Delete an API key#
DELETE /api-keys/:idFull Provisioning Example#
This example creates a complete engine configuration from scratch:
const API = "https://api.lingo.dev";
const headers = {
"X-API-Key": "your_api_key",
"Content-Type": "application/json",
};
// 1. Create an engine
const engine = await fetch(`${API}/engines`, {
method: "POST",
headers,
body: JSON.stringify({
ownerOrganizationId: "org_abc123",
name: "Web App Engine",
sourceLocales: ["en"],
targetLocales: ["de", "fr", "ja"],
}),
}).then((r) => r.json());
// 2. Add a locale-specific model for Japanese
// (the engine already has default wildcard models)
await fetch(`${API}/model-configs`, {
method: "POST",
headers,
body: JSON.stringify({
ownerEngineId: engine.id,
provider: "anthropic",
model: "claude-sonnet-4-6",
sourceLocale: "en",
targetLocale: "ja",
rank: 0,
}),
});
// 3. Set brand voice for German
await fetch(`${API}/brand-voices`, {
method: "POST",
headers,
body: JSON.stringify({
ownerEngineId: engine.id,
targetLocale: "de",
text: "Use formal German (Sie-form). Technical but approachable.",
}),
});
// 4. Add a glossary term
await fetch(`${API}/glossary-items`, {
method: "POST",
headers,
body: JSON.stringify({
ownerEngineId: engine.id,
sourceLocale: "en",
targetLocale: "de",
sourceText: "workspace",
targetText: "Arbeitsbereich",
type: "custom_translation",
}),
});
// 5. Add an instruction
await fetch(`${API}/instructions`, {
method: "POST",
headers,
body: JSON.stringify({
ownerEngineId: engine.id,
name: "Formality",
text: "Always use formal address in all translations.",
targetLocale: "*",
}),
});
// Engine is ready - use it with the localize endpoint
const translation = await fetch(`${API}/process/localize`, {
method: "POST",
headers,
body: JSON.stringify({
engineId: engine.id,
sourceLocale: "en",
targetLocale: "de",
data: { greeting: "Hello, world!" },
}),
}).then((r) => r.json());