StepflowStepflow

Workflow Context

The main interface for interacting with Stepflow workflows

Workflow Context

The WorkflowContext is the primary interface provided to your workflow handler. it provides methods for executing steps, sleeping, waiting for events, and logging.

const myWorkflow = createWorkflow({ id: "my-workflow" }, async (ctx) => {
  // ctx is the WorkflowContext
});

Properties

event

The event that triggered the workflow execution.

  • ctx.event.id: Unique event ID
  • ctx.event.name: Name of the event (usually the workflow ID)
  • ctx.event.data: The payload passed to the trigger
  • ctx.event.timestamp: When the event was created

execution

Metadata about the current execution.

  • ctx.execution.id: Unique execution ID
  • ctx.execution.runId: The ID of the workflow run (persists across retries)
  • ctx.execution.attempt: Current retry attempt (starts at 1)
  • ctx.execution.startedAt: When the execution first started

Step Methods

step.run()

Executes a function as a checkpointed step. If the workflow retries, completed steps are skipped and their cached results are returned.

const result = await ctx.step.run(
  "my-step",
  async () => {
    return await fetchData();
  },
  {
    timeout: "30s",
    idempotencyKey: "custom-key",
  },
);

step.parallel()

Executes multiple functions in parallel. Like step.run(), the entire group is checkpointed.

const [res1, res2] = await ctx.step.parallel("parallel-fetch", [
  () => fetchOne(),
  () => fetchTwo(),
]);

step.invoke()

Invokes another workflow as a child. The parent workflow will wait for the child to complete.

const result = await ctx.step.invoke("child-workflow", {
  some: "data",
});

step.sendEvent()

Sends an event to the event bus. This is useful for triggering other workflows or notifying workflows waiting via waitForEvent.

await ctx.step.sendEvent("external-event-id", { status: "ok" });

Durable Delays

sleep()

Pauses the workflow for a specific duration. The delay is durable and survives worker restarts.

await ctx.sleep("wait-a-while", "1h");

sleepUntil()

Pauses the workflow until a specific date and time.

await ctx.sleepUntil("wait-for-deadline", new Date("2026-01-01"));

External Events

waitForEvent()

Pauses the workflow until an external event is received or a timeout occurs.

const { eventData, timeout } = await ctx.waitForEvent(
  "wait-for-approval",
  "approval-id",
  {
    timeout: "24h",
  },
);

if (timeout) {
  // Handle timeout
}

Logging

Stepflow provides structured logging that is captured in the workflow's timeline and visible in the dashboard.

ctx.log.info("Processing order", { orderId: "123" });
ctx.log.warn("Retryable error occurred");
ctx.log.error("Fatal error", { details: "..." });
ctx.log.debug("Internal state", { state: "..." });

Metadata

Metadata allows you to store arbitrary state that is visible to real-time subscribers (like the React SDK) and the dashboard.

await ctx.setMetadata("progress", 50);
const progress = ctx.getMetadata<number>("progress");

On this page