Crea un grupo de trabajos de localización: una sola solicitud que distribuye tu contenido a cada idioma de destino que indiques.
Tienes una carga útil de cadenas y una lista de idiomas, y quieres traducirlo todo sin tener que encargarte tú mismo de la distribución. POST /jobs/localization recibe la carga útil completa y hasta 100 idiomas de destino en una sola solicitud, y devuelve 202 Accepted de inmediato con un ID de grupo y un trabajo por idioma. Una solicitud, todos los idiomas: la plataforma crea los trabajos y procesa cada uno de forma independiente.
POST /jobs/localizationEsta página cubre la llamada de creación: sus parámetros, la estructura de la solicitud, la respuesta 202 y cómo hacer que la llamada sea segura de reintentar. ¿Eres nuevo en la localización asíncrona? Empieza con la Descripción general de la API de localización asíncrona para entender el modelo. Una vez que existe un grupo, hacer seguimiento de un grupo de trabajos te muestra qué significa el estado de cada idioma.
Autenticación
Pasa tu clave de API en el encabezado X-API-Key. Las claves tienen alcance a nivel de organización y dan acceso a cada motor de la organización. Consulta Autenticación para más detalles.
Parámetros#
sourceLocale, targetLocales y data son obligatorios. Todo lo demás ajusta el comportamiento o hace que la llamada sea más segura de repetir.
| Parámetro | Tipo | Descripción |
|---|---|---|
sourceLocale | string | Idioma de origen BCP-47 (por ejemplo, en). |
targetLocales | string[] | Idiomas de destino BCP-47 (por ejemplo, ["de", "fr", "ja"]). De 1 a 100 por solicitud. Se crea un trabajo por idioma. |
data | object | Contenido en formato clave-valor para traducir. Se permiten objetos anidados y arreglos a cualquier profundidad. |
context | string (opcional) | Contexto general para esta carga útil de traducción, como la superficie del producto, la audiencia o el propósito. Se aplica a cada trabajo creado para la solicitud. |
hints | object (opcional) | Contexto por clave como arreglos de cadenas tipo breadcrumb, para desambiguar cadenas cortas o reutilizadas. |
callbackUrl | string (opcional) | URL de webhook HTTPS para este grupo. Anula el valor predeterminado de la organización. HTTP se rechaza. |
idempotencyKey | string (opcional) | Clave generada por el cliente. Si envías la misma solicitud dos veces con la misma clave, se devuelve el grupo existente en lugar de crear uno nuevo. Su alcance es por motor. |
engineId | string (opcional) | Motor de localización por el que se ejecutarán los trabajos. Si se omite, se usa el motor predeterminado de la organización. |
pipelineConfig | object (opcional) | Anulaciones de pipeline por solicitud. Las etapas que omitas heredarán la configuración del motor. |
lockedKeys | string[] (opcional) | Claves o patrones glob cuyos valores se excluyen de la traducción y se reintegran literalmente en outputData. Hasta 100 patrones. Consulta Bloquear claves no traducibles. |
Solicitud#
El campo data acepta pares clave-valor planos o estructuras anidadas con objetos y arreglos a cualquier profundidad. El motor traduce cada valor de tipo cadena, deja intactos los valores que no son cadenas (números, booleanos, null) y devuelve exactamente la misma estructura que enviaste. Así que puedes pasarle el mismo objeto que tu app ya almacena, sin aplanarlo ni reformarlo.
{
"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 obligatorio
El callbackUrl debe usar HTTPS. Las URL con HTTP se rechazan con un error 400.
Esa carga útil anidada combina texto traducible con valores que deben conservarse intactos: id, course_101, difficulty. Las cadenas se traducen; el resto se preserva por tipo. Si también necesitas excluir una cadena de la traducción (un slug, una URL de recurso o un código de enum), indícala en lockedKeys y se reintegrará literalmente en la salida de cada idioma.
Respuesta (202 Accepted)#
La llamada devuelve el resultado de inmediato. No espera a que termine la traducción: te entrega el ID del grupo y los ID de trabajo por idioma, y luego la plataforma procesa cada trabajo de forma independiente en segundo plano.
{
"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"
}| Campo | Descripción |
|---|---|
groupId | Identificador con prefijo ljg_ para todo el grupo. Guárdalo: es la referencia para el seguimiento y el progreso en vivo. |
status | Estado del grupo al momento de su creación, normalmente pending. |
jobs | Una entrada por idioma de destino: id (con prefijo ljb_), targetLocale y el status del trabajo. |
createdAt | Marca de tiempo en formato ISO 8601. |
Si entran tres idiomas, vuelven tres trabajos, cada uno en queued y listo para ejecutarse. El significado de cada estado a medida que avanzan los trabajos, y qué pasa cuando un idioma falla mientras los demás sí se entregan, se explica en Track a job group.
Ejemplos#
La misma solicitud desde Node y Python. En ambos casos, se envía un solo POST y se leen el ID del grupo y la cantidad de trabajos directamente de 202.
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 localeHaz que la llamada sea segura de reintentar#
El lugar natural para lanzar esta solicitud es un hook de guardado o un controlador de eventos: justo el tipo de código que puede ejecutarse dos veces cuando hay un reintento o llega un evento duplicado. Sin protección, dos llamadas significan dos grupos de trabajos y el mismo contenido se pone en cola para traducirse dos veces.
Pasa un idempotencyKey y ese riesgo desaparece. Si envías la misma solicitud dos veces con la misma clave, la plataforma devuelve el grupo existente en lugar de crear uno nuevo, sin generar un segundo conjunto de trabajos. Las claves tienen alcance por motor, así que la misma clave contra un motor distinto corresponde a un grupo diferente.
Elige una clave que diga algo
Una buena clave combina la identidad del contenido con su versión: {contentId}-v{contentVersion}. El mismo contenido en la misma versión siempre se resuelve al mismo grupo, así que un reintento se convierte automáticamente en un no-op. Si cambias la versión cuando cambia el contenido, obtendrás un grupo nuevo.
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 jobsEste es el POST que distribuye una carga útil a todos los idiomas, y es seguro lanzarlo desde la misma ruta de código que hace reintentos. Guarda el groupId; eso es lo que usarás para el seguimiento y el progreso en vivo.
