Du hast einen Bereitstellungsjob erstellt und in Millisekunden eine pjb_-Job-ID und eine eng_-Engine-ID zurückbekommen. Die Engine ist schon einsatzbereit, wird aber noch vervollständigt: Ein KI-Agent crawlt deine Quellen und schreibt Markenstimmen, Glossareinträge und Anweisungen hinein. Während das läuft, willst du diesen Fortschritt sichtbar machen – mit einer Zeile wie „Styleguide wird gecrawlt … Engine wird konfiguriert … fertig“, wie bei einem Installationsassistenten, statt mit einem Spinner, der nichts verrät.
Der WebSocket liefert dir genau diesen Feed. Verbinde dich mit dem Job, und der Server sendet einen Snapshot des aktuellen Status und danach bei jedem Wechsel in den nächsten Schritt ein provisioning.progress-Ereignis. Und weil der Server beim Verbinden immer den aktuellen Status sendet und einen abgeschlossenen Job direkt danach schließt, kannst du dich jederzeit verbinden, selbst nachdem er beendet ist – es gibt kein Zeitfenster, das du treffen musst.
GET /jobs/provisioning/:jobId/wsDie jobId ist der Wert pjb_ aus dem Create-Aufruf. Neu bei asynchroner Bereitstellung? Starte mit dem Überblick, um das Grundprinzip zu verstehen.
Auf dieser Seite
- Nachrichtentypen
- Snapshot beim Verbinden
- Fortschrittsereignisse
- Verbinden nach Abschluss des Jobs
- Einbindung in deine UI
- API-Schlüssel serverseitig halten
Nachrichtentypen#
Über den Socket laufen zwei Nachrichtentypen. Der erste kommt einmal beim Verbinden an, der zweite wiederholt sich, während der Job voranschreitet.
| Typ | Wann | Wichtige Felder |
|---|---|---|
provisioning.snapshot | Bei der ersten Verbindung | jobId, status, errorMessage |
provisioning.progress | Wenn jeder Workflow-Schritt beginnt oder abgeschlossen wird | jobId, step, detail |
Das ist ein Live-Status-Feed, kein Ergebnis-Feed: Er zeigt dir, wo der Job gerade steht und ob er fehlgeschlagen ist, aber nicht, welche Datensätze die KI erstellt hat. Die Zusammenfassung von allem, was bereitgestellt wurde – die IDs für Markenstimme, Glossar und Anweisungen – kommt separat, entweder im Completion-Webhook oder indem du den Job ausliest, sobald er abgeschlossen ist. Nutze den Socket für den Fortschrittsbalken; für die Payload nimm den Webhook.
Snapshot beim Verbinden#
Sobald du dich verbindest, liest der Server den aktuellen Status des Jobs aus der Datenbank und sendet ihn. Dafür muss nicht erst ein Fortschrittsereignis eintreffen – der Snapshot steht für sich allein.
{
"type": "provisioning.snapshot",
"jobId": "pjb_A1b2C3d4E5f6G7h8",
"status": "in_progress",
"errorMessage": null
}| Feld | Beschreibung |
|---|---|
status | in_progress, completed oder failed. |
errorMessage | Die Fehlerbeschreibung, wenn status den Wert failed hat, andernfalls null. |
Der Snapshot ist die eine Nachricht, die du garantiert bekommst. Wenn der Job noch läuft, erhältst du danach Fortschrittsereignisse; wenn der Job schon beendet ist, bekommst du den Snapshot und sonst nichts mehr (siehe unten).
Fortschrittsereignisse#
Während der Workflow läuft, sendet der Server jedes Mal ein provisioning.progress-Ereignis, wenn er in einen neuen Schritt wechselt. Jedes Ereignis nennt den step und enthält ein menschenlesbares detail.
{
"type": "provisioning.progress",
"jobId": "pjb_A1b2C3d4E5f6G7h8",
"step": "crawling",
"detail": "Crawling source URLs..."
}step | Wann | Beispiel für detail |
|---|---|---|
crawling | Quell-URLs werden abgerufen | "Crawling source URLs..." oder "Retrying crawl (attempt 2)..." |
configuring | Der KI-Agent analysiert Inhalte und schreibt die Engine-Konfiguration | "AI agent analyzing content and configuring engine..." oder "Retrying configuration (attempt 2)..." |
completed | Der Job wurde erfolgreich abgeschlossen | "Provisioning complete" |
failed | Der Job ist fehlgeschlagen | Eine Fehlermeldung, die den Fehler beschreibt |
Ein Retry ist kein Fehler
Die Schritte crawling und configuring können mehr als einmal ausgelöst werden – bei einem vorübergehenden Abruf- oder Analysefehler wird ein Retry gestartet, und dieser Retry erscheint als Fortschrittsereignis mit einem detail wie "Retrying crawl (attempt 2)...". Das heißt: Der Job fängt sich wieder, er schlägt nicht fehl. Behandle nur den Schritt failed als final; sein detail enthält den tatsächlichen Grund.
Auch unbekannte Schritte abfangen
Mit der Zeit können neue Werte für step dazukommen. Reagiere auf die Schritte, die du kennst, behandle completed und failed als die beiden Fälle, die den Socket schließen, und ignoriere alles andere als rein informativ – so funktioniert ein vorwärtskompatibler Client auch ohne Update weiter.
Verbinden nach Abschluss des Jobs#
Die knifflige Frage bei jedem Fortschritts-Socket ist, was passiert, wenn du dich spät verbindest – nachdem das Crawling durch ist, nachdem ein Deploy den Tab neu verbunden hat oder nachdem der Job bereits fehlgeschlagen ist. Hier steckt die Antwort schon in der Funktionsweise des Snapshots.
Wenn der Job bereits completed oder failed erreicht hat, sendet der Server den Snapshot mit diesem finalen status (und errorMessage, falls er fehlgeschlagen ist) und schließt die Verbindung sofort. Es gibt keine Fortschrittsereignisse zum Nachholen, denn der Endzustand steckt bereits im Snapshot. Ein Job, der noch läuft, hält die Verbindung offen und streamt Fortschritt; ein abgeschlossener Job liefert dir das Ergebnis und legt auf.
So oder so sagt dir die erste Nachricht, wie der Stand ist. Verbinde dich jederzeit, selbst nachdem er beendet ist – du kannst weder zu früh noch zu spät dran sein.
Einbindung in deine UI#
Öffne den Socket mit der pjb_-Job-ID, lies den Snapshot, um deinen Anfangszustand zu setzen, aktualisiere dann bei jedem Fortschrittsereignis und schließe, wenn der Job completed oder failed erreicht:
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 das Ganze mit einem Job, der sauber crawlt und die laufende Konfiguration Schritt für Schritt ausgibt:
status: in_progress
crawling: Crawling source URLs...
configuring: AI agent analyzing content and configuring engine...
completed: Provisioning completeDas ist der komplette Ablauf auf dem Bildschirm: Der Job startet bei in_progress, du beobachtest erst das Crawling und dann die Konfiguration, und completed zeigt dir, dass die Engine vollständig bereitgestellt ist. Dieselbe Schleife funktioniert auch bei einer späten Verbindung – ein abgeschlossener Job sendet genau einen Snapshot mit seinem finalen status, und der Socket schließt sich, sodass derselbe Code für den Live-Lauf auch das Replay ohne Sonderfall abdeckt.
API-Schlüssel serverseitig halten#
Der Socket authentifiziert sich mit deinem API-Schlüssel – demselben organisationsbezogenen Schlüssel, den auch die REST-Endpunkte verwenden. Dieser Schlüssel gibt Zugriff auf jede Engine in deiner Organisation, deshalb ist der Browser der falsche Ort, um die Verbindung zu öffnen: Jeder, der sich den Quellcode ansieht, könnte ihn sehen.
Vom Backend verbinden, nicht im Browser
Öffne den WebSocket von deinem Server aus, wo der Schlüssel ohnehin schon liegt, und leite den Fortschritt dann über deinen eigenen Kanal an den Browser weiter – per WebSocket oder über einen von dir kontrollierten Server-Sent-Events-Stream. Dein Frontend zeigt, wie die Engine konfiguriert wird; dein Schlüssel verlässt nie deine Infrastruktur.
Das entspricht dem Webhook-Modell: Die Verbindung zu Lingo.dev läuft serverseitig, und beim Nutzer kommt nur das an, was deine App selbst weiterleitet.
Wo das hineinpasst#
Der WebSocket ist die Live-Ansicht – er ist an genau einen Job gebunden und schließt sich, sobald dieser Job abgeschlossen ist. Für einen belastbaren Server-zu-Server-Nachweis des Ergebnisses, der einen geschlossenen Tab oder ein Deploy überdauert, kombiniere ihn mit dem Completion-Webhook: Der Socket steuert den Fortschrittsbalken, solange der Job auf dem Bildschirm ist, und der Webhook liefert die Zusammenfassung von allem, was die KI erstellt hat, genau in dem Moment, in dem sie vorliegt. Verbinde beides über denselben Create-Aufruf.
