Runs
Start, observe, list, cancel, and inspect queued ActionFlow runs with the TypeScript SDK, including the current option and queue limitations.
Runs
The TypeScript SDK wraps the REST run endpoints. runActionFlow is asynchronous: it returns either an immediately dispatched run or a queued run while the graph continues in the background.
import { ActionFlows } from "actionflows";
const client = new ActionFlows({
apiKey: process.env.ACTIONFLOWS_API_KEY!,
});The SDK uses server-side API-key authentication for external integrations; it does not use an application session cookie. See Installation for setup and authentication, and ActionFlows for flow discovery.
Start a run
import type { RunActionFlowOptions } from "actionflows";
const options: RunActionFlowOptions = {
idempotencyKey: `order-created-${orderId}`,
tags: ["production", "api"],
maxAttempts: 3,
maxDuration: 3600,
inputs: {
"node_start_prompt": "Hello",
},
trigger: {
body: { event: "order.created" },
method: "POST",
},
};
const run = await client.runActionFlow("org_123", "flow_456", options);
if (run.status === "waiting") {
console.log("Queued:", run.queueId, "position:", run.position);
} else {
console.log("Dispatched:", run.id);
}The SDK returns the REST data object, not the outer { success, data } envelope. A queued result has status: "waiting", a queueId, and usually no runtime id yet. A dispatched result has status: "dispatched", id, runHistoryId, and triggerRunId. The local admission record is scoped by organization and ActionFlow; request payloads are not compared. Reusing a key for a different payload in the same organization and ActionFlow refers to the existing admission. For direct admission, success requires the execution response to contain a runtime id; an otherwise successful response without that id is an admission failure and may leave a history row in executing. A direct duplicate whose existing admission is executing/not dispatched and lacks triggerRunId also fails. A dispatched direct duplicate with a triggerRunId is successful and returns the direct response shape. REST returns a generic 500 for these direct-admission failures, and the SDK throws ActionFlowsError with statusCode === 500. In queue mode, a waiting duplicate can be republished, a dispatched duplicate with a triggerRunId is successful, and a dispatched duplicate without a triggerRunId or a failed/cancelled terminal duplicate is unavailable and also returns REST 500; the SDK throws ActionFlowsError with statusCode === 500. These failures are not admitted as new runs. The current QueuedRunResponse TypeScript union only permits status: "queued" | "waiting", so a successful dispatched duplicate can still arrive at runtime with status: "dispatched"; handle that value defensively. The SDK type is not changed by this documentation task.
Run options
| Option | Type | Meaning |
|---|---|---|
idempotencyKey | string | Stable key used by local queue/direct admission, scoped by organization and ActionFlow; request payloads are not compared |
delay | string | Delay passed to the execution service; the schema documents ISO 8601 such as PT5M |
tags | string[] | Caller tags; the platform protects and adds its organization tag |
maxAttempts | number | Positive retry-budget override passed to the execution service |
maxDuration | number | Positive maximum run duration in seconds |
inputs | Record<string, unknown> | Per-run overrides keyed as {nodeId}_{inputName} |
trigger | object | Optional envelope with body, headers, query, and method |
The current Flow task definition defaults to one attempt because retries can repeat non-idempotent side effects. A supplied retry value is forwarded as an execution-service override; it does not guarantee checkpoint-safe replay.
Do not use a userId option to change run attribution. The current gateway takes the acting user from the authenticated API-key context; a client-supplied userId is not the public attribution control. The SDK does not expose a supported way to impersonate or reassign that user.
Get and list runs
const result = await client.getRun("run_123");
const flowRuns = await client.getActionFlowRunHistory("flow_456", {
status: ["COMPLETED"],
pageSize: 20,
});
const allRuns = await client.listRuns({
organizationId: "org_123",
pageSize: 50,
});getActionFlowRunHistory and listRuns are the SDK wrappers for the run-history list endpoints. Their current list options are:
| Option | Type | Meaning |
|---|---|---|
pageSize | number | Page size for the run list |
pageAfter / pageBefore | string | Run-list cursors |
status | string[] | Run status filter |
tag | string[] | Caller tag filter |
organizationId | string | Organization filter for listRuns |
isTest | boolean | Test-run filter |
createdAtFrom / createdAtTo / createdAtPeriod | string | Created-time filters |
REST: Get Run, List Runs, and List Flow Runs.
Cancel or stream
await client.cancelRun("run_123");
const response = await client.streamRun("run_123");
const reader = response.body?.getReader();cancelRun targets a runtime run. A waiting queue item should be cancelled with the queue operation instead. streamRun returns the raw Response for the SSE endpoint GET /api/runs/{runId}/stream; the SDK does not turn the stream into a higher-level event iterator.
Run queue
When the organization queue is enabled, use the queue methods with the organization ID:
import type { PublicQueuedRun } from "actionflows";
const queued = (await client.listQueuedRuns("org_123")) as {
items: PublicQueuedRun[];
total: number;
};
console.log(queued.items.length, queued.total);
await client.cancelQueuedRun("queue_item_id", "org_123");
const item = await client.getQueuedRun("queue_item_id", "org_123");The REST list response is data: { items, total }; the SDK HTTP client unwraps data, so the method receives that object. The list is an active-queue view containing only waiting and dispatching items. Use getQueuedRun with the queueId to observe dispatched, failed, or cancelled and retrieve triggerRunId when present; an item that leaves the active list is not missing from the detail endpoint. The current SDK method signature exposes only the organization argument. It does not expose the REST queue filters filter[actionFlowId], page[number], or page[size]; use GET /api/runs/queue directly when you need those options. The queue page-size maximum is 100 at the REST endpoint.
getQueuedRun returns the queue item after unwrapping the response. cancelQueuedRun targets a waiting item and releases its held credits according to the queue endpoint. A queue response is admission state; follow a dispatched item's triggerRunId through Get Run for execution status.
Validation and uploads
The SDK calls the same pre-enqueue validateFlow path as REST. A 400 from the API becomes an ActionFlowsError; inspect its response for validationErrors and validationWarnings. Run inputs are merged into the execution copy after saved-graph validation, so they do not bypass a missing required saved value.
There is no SDK upload method. Put files in the app through ActionFlow artifacts, or pass values that the graph already expects in inputs.