Runs

Execute a Workflow app: send its input variables, get the outputs back — as one blocking response or as a stream of progress events.

POST/v1/runs

Workflow apps only

Only Workflow apps start a run directly. Agent Flow apps also execute flows internally, but they are driven through POST /chat/completions.

Request body

PropertyTypeRequiredDefaultDescription
variablesobjectYesThe workflow's input variables, keyed by variable name.
userstringYesStable end-user identifier the run is attributed to.
streambooleanNofalseStream progress events instead of waiting for the finished run.
attachmentsarrayNoOptional file attachments, same shape as in /chat/completions: { type, url } or { type, file_id }.

Blocking run

bash
curl https://cloud.xpectrum.dev/v1/runs \
  -H "Authorization: Bearer xpectrum_XXXXXXXXXXXXXXXX" \
  -H "Content-Type: application/json" \
  -d '{
    "variables": { "topic": "quarterly report" },
    "user": "user-123"
  }'

The response is a run object:

json
{
  "id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "object": "run",
  "status": "succeeded",
  "variables": { "topic": "quarterly report" },
  "outputs": { "summary": "..." },
  "error": null,
  "steps": 4,
  "tokens": 1832,
  "elapsed_seconds": 6.42,
  "created_at": 1754900000,
  "finished_at": 1754900006
}

Streaming run

With "stream": true the response is a server-sent event stream of progress events, terminated by data: [DONE]:

EventMeaning
run.startedThe run began; carries the run id.
step.startedA workflow step (node) began: title, type, index.
step.completedThe step finished: status, outputs, error, elapsed_seconds.
run.completedThe finished run object (same shape as the blocking response).
text
data: {"id":"7c9e...","object":"run.started","created_at":1754900000}

data: {"id":"3b1f...","object":"step.started","title":"Retrieve","type":"knowledge-retrieval","index":1,"created_at":1754900000}

data: {"id":"3b1f...","object":"step.completed","title":"Retrieve","type":"knowledge-retrieval","index":1,"status":"succeeded","outputs":{...},"error":null,"elapsed_seconds":0.8,"created_at":1754900000}

data: {"id":"7c9e...","object":"run.completed","status":"succeeded","outputs":{"summary":"..."},"steps":4,"tokens":1832,"elapsed_seconds":6.42,...}

data: [DONE]

Keep-alive pings arrive as SSE comments (: ping). To stop a run in progress, call POST /runs/{run_id}/cancel with the run id.

With the Xpectrum SDK

typescript
import { XpectrumWorkflow } from "xpectrum";

const wf = new XpectrumWorkflow({
  baseUrl: "https://cloud.xpectrum.dev/v1",
  apiKey: "xpectrum_XXXXXXXXXXXXXXXX", // a Workflow app key
  user: "user-123",
});

// Wait for the result
const run = await wf.run({ variables: { topic: "quarterly report" } });
console.log(run.status, run.outputs);

// Or follow progress step by step
await wf.stream({
  variables: { topic: "quarterly report" },
  onStart: (r) => console.log("run", r.id),
  onStepStart: (s) => console.log("→", s.title),
  onStepComplete: (s) => console.log("✓", s.title, s.status),
  onDone: (run) => console.log(run.outputs),
});

await wf.cancel(run.id); // stop a run in progress