Skip to content

AI jobs and progress

Start a job and follow its progress. Generation, review, document import and diagrams share an asynchronous job system.

POST/ai/start

Start a job and return its identifier.

Parameters

NameTypeRequiredDescription
typestringrequiredgenerateSop | generateChart | reviewSop | applySuggestions | importDocument | generateFlow
paramsobjectrequiredJob-specific fields; see the table below.

Example response

Json
{ "jobId": "JOB_UUID" }

Types and parameters

Parameters

NameTypeRequiredDescription
generateSop{ orgNodeId, prompt }optionalCreate a draft SOP owned by the selected organization node.
generateChart{ prompt }optionalGenerate organization-chart structure.
reviewSop{ sopId }optionalReview an accessible version and return its source version and content identity.
applySuggestions{ sopId, review }optionalSend the returned review object, including sourceVersionId and sourceContentHash. A stale review cannot authorize edits.
importDocument{ orgNodeId, documentBase64, mimeType }optionalapplication/pdf | text/plain | text/markdown; base64 ≤ 50 MB.
generateFlow{ flowId, prompt }optionalAppend generated diagram content to an editable draft flow.

Identifiers are UUIDs. Prompts accept 5–5,000 characters. The review object includes summary, improvements and optionally missingSteps, together with the reviewed content identity.

GET/ai/progress/:jobId

SSE progress for a job owned by your session. Messages contain a status field, not job.done event names.

Parameters

NameTypeRequiredDescription
statusrunning | done | erroroptionalClose the stream on completion or failure.
resultobjectoptionalJob-specific completion result.
errorstringoptionalFailure message when the job fails.

Example response

Json
data: {"status":"running","stage":"generating","message":"Writing steps…","progress":40}

data: {"status":"done","stage":"done","message":"Done","progress":100,"result":{}}
GET/ai/status/:jobId

Check status with the same session after a stream interruption. An expired job result may no longer be available.

Example response

Json
{ "id":"JOB_UUID", "status":"running", "stage":"generating", "message":"Writing steps…", "progress":40 }

Review example

// Run on the SOPFlow application origin with a signed-in session.
const response = await fetch("/ai/start", {
  method: "POST", credentials: "include",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ type: "reviewSop", params: { sopId: "SOP_UUID" } }),
});
if (!response.ok) throw new Error(await response.text());
const { jobId } = await response.json();
const stream = new EventSource("/ai/progress/" + jobId, { withCredentials: true });
stream.onmessage = event => {
  const job = JSON.parse(event.data);
  console.log(job.stage, job.message, job.progress);
  if (job.status === "done") { console.log(job.result); stream.close(); }
  if (job.status === "error") { console.error(job.error); stream.close(); }
};
stream.onerror = () => {
  stream.close();
  // Check /ai/status/:jobId with the same session before offering a retry.
};

Handle interrupted job progress

Start one job and retain its returned jobId. Process the status field from the progress stream; close the stream when the job finishes or fails. If it disconnects, check status with the same authorized session.

Do not start a second generation just because a progress connection failed. First determine whether the original job completed. Review the result, quota and destination before applying generated content.