Os webhooks e o WebSocket em tempo real dizem-lhe quando uma tarefa é concluída, no exato momento em que isso acontece. Mas nenhum deles ajuda na manhã seguinte, depois de um deploy, ou quando quer ver todos os idiomas que falharam na última hora. O momento já passou; o evento já desapareceu. As tarefas, não — cada uma continua a ser um registo persistente na plataforma, muito depois de o processo que a submeteu seguir em frente.
GET /jobs/localization é a forma de recuperar esses registos. Devolve as suas tarefas das mais recentes para as mais antigas, em páginas percorridas com um cursor, filtradas pelo motor em que correram ou pelo estado com que terminaram. Este é o canal de recuperação: o registo persistente que consulta quando não estava a acompanhar em tempo real.
GET /jobs/localizationEstá a começar na localização assíncrona? Comece pela Visão geral. Esta página parte do princípio de que já tem tarefas para consultar. Como qualquer endpoint, autentica-se com a sua X-API-Key.
Filtros e paginação#
GET /jobs/localization?engineId=eng_abc123&status=completed&limit=20&cursor=...| Parâmetro | Tipo | Descrição |
|---|---|---|
engineId | string (opcional) | Devolve apenas tarefas executadas neste motor de localização (eng_...). |
status | string (opcional) | Devolve apenas tarefas neste estado: queued, processing, completed, completed_with_warnings ou failed. |
limit | number (opcional) | Tamanho da página. Por predefinição, 20; no máximo, 100. |
cursor | string (opcional) | Cursor opaco vindo do nextCursor da resposta anterior. Omita-o na primeira página. |
Ambos os filtros são opcionais e podem ser combinados: engineId=eng_abc123&status=failed devolve as tarefas com falha de um motor específico, e nada mais. Esta combinação responde a uma pergunta que vai mesmo fazer durante um incidente — mostre-me tudo o que falhou neste motor — sem ter de ir buscar todas as tarefas da organização para filtrar do lado do cliente.
O cursor é uma posição no fluxo de resultados, não um número de página. Não o calcula; recebe-o. Cada resposta devolve um nextCursor, e depois volta a enviar esse valor para obter a página seguinte.
Resposta#
Cada página é um array items mais um nextCursor. nextCursor é null na última página — essa é a condição de saída do seu ciclo, não um erro.
{
"items": [
{
"id": "ljb_C3d4E5f6G7h8I9j0",
"groupId": "ljg_A1b2C3d4E5f6G7h8",
"targetLocale": "ja",
"status": "completed",
"warnings": [],
"createdAt": "2026-03-16T10:30:00.000Z",
"completedAt": "2026-03-16T10:30:06.000Z"
}
],
"nextCursor": "eyJ0IjoiMjAyNi0wMy0xNlQxMDozMDowMC4wMDBaIiwiaSI6ImxqYl9CMmMzRDRlNUY2ZzdIOGk5In0"
}Cada item é um resumo — suficiente para localizar uma tarefa e perceber o respetivo resultado: que idioma, que grupo, que estado, quando foi criada e quando terminou. Deliberadamente, não inclui o conteúdo traduzido. Para obter o outputData completo e os steps por etapa de uma dessas tarefas, pegue no respetivo id e chame Obter uma única tarefa. Liste para encontrar; obtenha para ler.
Trate valores de estado desconhecidos com robustez
Faça correspondência com os valores de estado que conhece e deixe os restantes cair num ramo predefinido, em vez de fazer falhar o consumidor perante um valor que ainda não viu. Tolerar um valor não reconhecido é a opção defensiva por defeito para qualquer enumeração em string que não controla — mantém o seu leitor a funcionar, em vez de lançar um erro com dados que não consegue classificar.
Percorrer todos os resultados#
A condição de saída é o ponto central: continue a pedir até que nextCursor volte como null. Passe o nextCursor de uma resposta como cursor na seguinte, e o ciclo termina por si só.
async function listFailedJobs(engineId) {
const failed = [];
let cursor = undefined; // first page: no cursor
do {
const url = new URL("https://api.lingo.dev/jobs/localization");
url.searchParams.set("engineId", engineId);
url.searchParams.set("status", "failed");
url.searchParams.set("limit", "100"); // fewer round-trips
if (cursor) url.searchParams.set("cursor", cursor);
const response = await fetch(url, {
headers: { "X-API-Key": process.env.LINGO_API_KEY },
});
const { items, nextCursor } = await response.json();
failed.push(...items);
cursor = nextCursor; // null on the last page -> loop ends
} while (cursor);
return failed; // every failed job for this engine
}Aumentar limit para 100 reduz o número de idas e voltas num backlog grande; não altera o resultado, apenas o número de páginas que precisa de percorrer para o ler. Não há offset que se desalinhe, nem contagem de páginas para manter sincronizada — o cursor guarda a sua posição, e null diz-lhe quando já leu tudo.
Próximos passos#
Já tem o id de uma tarefa. O canal de recuperação trouxe-o até aqui; a partir daqui, pode ler o resultado ou ligar os canais em tempo real para que, da próxima vez, saiba o que aconteceu no momento em que acontece.
