Você criou um job de provisionamento e recebeu de volta um ID de job pjb_ e um ID de engine eng_ em milissegundos. O engine já está pronto para uso, mas ainda está sendo preenchido: um agente de IA está rastreando suas fontes e gravando voz da marca, itens de glossário e instruções nele. Enquanto isso acontece, faz sentido mostrar esse andamento — uma linha como "Rastreando seu guia de estilo... configurando o engine... concluído", como em um assistente de instalação, em vez de um spinner que não diz nada.
O WebSocket entrega exatamente esse fluxo. Conecte-se ao job e o servidor envia um snapshot do estado atual e, depois, um evento provisioning.progress toda vez que o workflow avança para uma nova etapa. E, como o servidor envia o estado atual no momento da conexão e fecha um job concluído logo em seguida, você pode se conectar a qualquer momento, até mesmo depois que ele terminar — não existe uma janela específica que você precise acertar.
GET /jobs/provisioning/:jobId/wsO jobId é o valor pjb_ da chamada de criação. Está começando agora com provisionamento assíncrono? Comece pela Visão geral para entender o modelo mental.
Nesta página
- Tipos de mensagem
- Snapshot ao conectar
- Eventos de progresso
- Conectando depois que o job termina
- Integrando isso à sua UI
- Mantenha sua chave de API no servidor
Tipos de mensagem#
Dois tipos de mensagem passam pelo socket. O primeiro chega uma vez, ao conectar; o segundo chega repetidamente, à medida que o job avança.
| Tipo | Quando | Campos principais |
|---|---|---|
provisioning.snapshot | Na conexão inicial | jobId, status, errorMessage |
provisioning.progress | Quando cada etapa do workflow começa ou termina | jobId, step, detail |
Este é um feed de atividade, não um feed de resultados: ele mostra em que ponto o job está e se houve falha, não quais registros a IA criou. O resumo de tudo o que foi provisionado — os IDs de voz da marca, glossário e instrução — chega separadamente, no webhook de conclusão ou ao consultar o job quando ele terminar. Use o socket para a barra de progresso; use o webhook para o payload.
Snapshot ao conectar#
No instante em que você se conecta, o servidor lê o estado atual do job no banco de dados e o envia. Não é preciso esperar por um evento de progresso antes — o snapshot se sustenta sozinho.
{
"type": "provisioning.snapshot",
"jobId": "pjb_A1b2C3d4E5f6G7h8",
"status": "in_progress",
"errorMessage": null
}| Campo | Descrição |
|---|---|
status | in_progress, completed ou failed. |
errorMessage | A descrição da falha quando status é failed; caso contrário, null. |
O snapshot é a única mensagem que você tem garantia de receber. Se o job ainda estiver em execução, você receberá eventos de progresso depois dele; se o job já tiver terminado, receberá o snapshot e nada mais (veja abaixo).
Eventos de progresso#
À medida que o workflow roda, o servidor transmite um evento provisioning.progress sempre que entra em uma nova etapa. Cada evento informa o step e traz uma detail legível por humanos.
{
"type": "provisioning.progress",
"jobId": "pjb_A1b2C3d4E5f6G7h8",
"step": "crawling",
"detail": "Crawling source URLs..."
}step | Quando | Exemplo de detail |
|---|---|---|
crawling | As URLs de origem estão sendo buscadas | "Crawling source URLs..." ou "Retrying crawl (attempt 2)..." |
configuring | O agente de IA está analisando o conteúdo e escrevendo a configuração do engine | "AI agent analyzing content and configuring engine..." ou "Retrying configuration (attempt 2)..." |
completed | O job foi concluído com sucesso | "Provisioning complete" |
failed | O job falhou | Uma mensagem de erro descrevendo a falha |
Nova tentativa não é falha
As etapas crawling e configuring podem acontecer mais de uma vez — um erro transitório de busca ou análise pode gerar uma nova tentativa, e essa nova tentativa aparece como um evento de progresso com uma detail como "Retrying crawl (attempt 2)...". Isso significa que o job está se recuperando, não que falhou. Trate apenas a etapa failed como terminal; a detail dela traz o motivo real.
Saiba lidar com etapas desconhecidas
Novos valores de step podem ser adicionados com o tempo. Faça switch nas etapas que você conhece, trate completed e failed como as duas que encerram o socket e ignore qualquer outra como informativa — um cliente compatível com versões futuras continua funcionando sem precisar de atualização.
Conectando depois que o job termina#
A grande dúvida em qualquer socket de progresso é o que acontece se você se conectar tarde — depois que o crawling terminar, depois que um deploy reconectar a aba, depois que o job já tiver falhado. Aqui, a resposta está embutida na forma como o snapshot funciona.
Se o job já tiver chegado a completed ou failed, o servidor enviará o snapshot com esse status final (e errorMessage, se tiver falhado) e fechará a conexão imediatamente. Não há eventos de progresso para reproduzir, porque o estado final já está no snapshot. Um job ainda em andamento mantém a conexão aberta e transmite o progresso; um job concluído entrega o resultado e encerra a conexão.
De qualquer forma, a primeira mensagem já mostra a situação atual. Conecte-se a qualquer momento, até mesmo depois que terminar — você não pode se conectar cedo demais nem tarde demais.
Integrando isso à sua UI#
Abra o socket usando o ID do job pjb_, leia o snapshot para definir o estado inicial e depois atualize a cada evento de progresso, fechando quando o job chegar a completed ou failed:
import WebSocket from "ws";
const jobId = "pjb_A1b2C3d4E5f6G7h8";
const ws = new WebSocket(
`wss://api.lingo.dev/jobs/provisioning/${jobId}/ws`,
{ headers: { "X-API-Key": process.env.LINGO_API_KEY } }
);
ws.on("message", (raw) => {
const event = JSON.parse(raw);
switch (event.type) {
case "provisioning.snapshot":
console.log(`status: ${event.status}`);
break;
case "provisioning.progress":
console.log(`${event.step}: ${event.detail}`);
if (event.step === "completed" || event.step === "failed") {
ws.close();
}
break;
}
});Teste com um job que conclua o crawling sem problemas e mostre a configuração acontecendo, etapa por etapa:
status: in_progress
crawling: Crawling source URLs...
configuring: AI agent analyzing content and configuring engine...
completed: Provisioning completeEsse é o fluxo completo na tela: o job começa em in_progress, você acompanha o crawling e depois a configuração, e completed informa que o engine foi totalmente provisionado. O mesmo loop também funciona em uma conexão tardia — um job concluído envia um único snapshot com seu status final e o socket fecha, então o código que trata a execução ao vivo também lida com esse replay sem precisar de um caso especial.
Mantenha sua chave de API no servidor#
O socket se autentica com sua chave de API — a mesma chave com escopo de organização usada pelos endpoints REST. Essa chave dá acesso a todos os engines da sua organização, então o navegador é o lugar errado para abrir a conexão: qualquer pessoa que visualizar o código-fonte conseguiria vê-la.
Conecte pelo backend, não pelo navegador
Abra o WebSocket a partir do seu servidor, onde a chave já está, e depois encaminhe o progresso para o navegador pelo seu próprio canal — um WebSocket ou stream de server-sent events que você controla. Seu frontend mostra o engine sendo configurado; sua chave nunca sai da sua infraestrutura.
Isso segue o mesmo modelo do webhook: a conexão que toca o Lingo.dev roda no servidor, e o que chega ao usuário é apenas o que o seu app decidir encaminhar.
Onde isso se encaixa#
O WebSocket é a visão ao vivo — ele fica vinculado a um job e fecha quando esse job termina. Para ter um registro durável, de servidor para servidor, do resultado que sobreviva ao fechamento de uma aba ou a um deploy, combine-o com o webhook de conclusão: o socket alimenta a barra de progresso enquanto o job está na tela, e o webhook entrega o resumo de tudo o que a IA criou no momento em que estiver pronto. Conecte os dois a partir da mesma chamada de criação.
