Skip to content

Node Types ​

AwaitStep ships 12 built-in nodes. Every node is automatically wrapped in step.do() by the compile pipeline, giving it durable execution, automatic retries, and persistent output storage.

step ​

Run arbitrary TypeScript inside a durable step. The platform retries automatically on throw.

FieldTypeRequiredDefaultDescription
codecodeyes—TypeScript to execute. ctx.attempt holds the current retry count (1-indexed). Return value must be JSON-serializable.
retryLimitnumberno5Max retry attempts.
retryDelaystringno10 secondsDelay between retries.
backoffselectnoexponentialBackoff strategy: exponential, linear, or constant.
timeoutstringno—Per-attempt timeout (e.g. 10 minutes).
typescript
// Generated code
const my_step_result = await step.do('my_step', { retries: { limit: 5 } }, async () => {
  const data = await fetch('https://api.example.com/data').then((r) => r.json())
  return { value: data.value }
})

branch ​

Route execution to one of several paths based on conditions. Each outgoing edge carries a condition expression that is evaluated at runtime. The first truthy condition wins.

FieldTypeRequiredDescription
(none)——Conditions are set on the outgoing edges in the canvas.
typescript
// Generated code
if (charge_result.success) {
  // "success" branch ...
} else {
  // "failure" branch ...
}

parallel ​

Execute multiple branches concurrently. Execution resumes after the last branch completes.

FieldTypeRequiredDescription
(none)——Branches are the outgoing edges from this node.
typescript
// Generated code
await Promise.all([
  step.do('notify_slack', async () => {
    /* ... */
  }),
  step.do('send_email', async () => {
    /* ... */
  }),
])

loop ​

Repeat a set of steps using forEach, while, or a fixed count.

FieldTypeRequiredDefaultDescription
loopTypeselectyesforEachforEach, while, or times.
collectionexpressionno—Array to iterate over (forEach only).
itemVarstringnoitemVariable name for the current item (forEach only).
indexVarstringnoiVariable name for the current index (forEach only).
conditionexpressionno—Continue condition (while only).
countnumberno5Number of iterations (times only).

Output: results — array of results collected from each iteration.

typescript
// Generated code (forEach)
const loop_results = []
for (const [i, item] of get_orders_result.orders.entries()) {
  const iter_result = await step.do(`loop_iter_${i}`, async () => {
    return processOrder(item)
  })
  loop_results.push(iter_result)
}

break ​

Exit a loop early or stop workflow execution entirely, optionally based on a condition.

FieldTypeRequiredDescription
conditionexpressionnoJS expression — breaks only when truthy. Leave empty for unconditional break.
typescript
// Generated code (inside a loop)
if (poll_result.status === 'complete') {
  break
}

race ​

Run multiple branches concurrently. The first branch to complete wins; all others are cancelled.

FieldTypeRequiredDescription
(none)——Branches are the outgoing edges from this node.
typescript
// Generated code
const race_result = await Promise.race([
  step.do('path_a', async () => {
    /* ... */
  }),
  step.do('path_b', async () => {
    /* ... */
  }),
])

try_catch ​

Wrap a group of steps in try/catch/finally error handling. Connect nodes to the try, catch, and finally edges.

FieldTypeRequiredDescription
(none)——Error handling paths are the outgoing edges from this node.
typescript
// Generated code
try {
  await step.do('risky_operation', async () => {
    /* ... */
  })
} catch (err) {
  await step.do('handle_error', async () => {
    /* ... */
  })
} finally {
  await step.do('cleanup', async () => {
    /* ... */
  })
}

sleep ​

Pause workflow execution for a duration. Does not count against the step limit.

FieldTypeRequiredDescription
durationstringyesDuration string (e.g. 10 seconds, 5 minutes, 2 hours). Max 365 days.
typescript
// Generated code
await step.sleep('wait', '5 minutes')

sleep_until ​

Pause workflow execution until a specific ISO 8601 timestamp.

FieldTypeRequiredDescription
timestampstringyesISO 8601 datetime (e.g. 2025-12-31T09:00:00Z). Must be at least 1 hour from now.
typescript
// Generated code
await step.sleepUntil('wait_until', '2025-12-31T09:00:00Z')

wait_for_event ​

Pause execution until an external event is sent to this workflow instance via the sendEvent API.

FieldTypeRequiredDescription
eventTypestringyesEvent type identifier. a-z 0-9 - _ only, max 100 chars.
timeoutstringnoMax wait time (e.g. 24 hours). Workflow throws if timeout expires. Max 365 days.

Output: payload — the event payload object sent via sendEvent().

typescript
// Generated code
const approval_result = await step.waitForEvent('wait_for_approval', {
  type: 'user-approval',
  timeout: '24 hours',
})

http_request ​

Make an HTTP API call. Supports all common HTTP methods, custom headers, and request bodies.

FieldTypeRequiredDefaultDescription
methodselectyesGETHTTP method.
urlstringyes—Request URL. Must be a valid URL.
headersjsonno—JSON object of request headers.
bodycodeno—Request body. Used for POST, PUT, PATCH.
retryLimitnumberno5Max retry attempts.
timeoutstringno—Request timeout.

Output:

FieldTypeDescription
statusnumberHTTP status code
bodystringResponse body as text
headersobjectResponse headers
typescript
// Generated code
const fetch_user_result = await step.do('fetch_user', { retries: { limit: 5 } }, async () => {
  const response = await fetch('https://api.example.com/user', {
    method: 'GET',
    headers: { Authorization: 'Bearer token' },
  })
  return {
    status: response.status,
    body: await response.text(),
    headers: Object.fromEntries(response.headers.entries()),
  }
})

sub_workflow ​

Trigger another AwaitStep workflow, optionally waiting for it to complete before continuing.

FieldTypeRequiredDefaultDescription
workflowIdstringyes—The ID of the child workflow.
workflowNamestringyes—Human-readable name used for the CF binding.
inputexpressionno—Expression for params passed to the child workflow.
waitForCompletionbooleannotrueBlock until the child workflow finishes.
timeoutstringno5 minutesMax time to wait for child completion.

Output:

FieldTypeDescription
instanceIdstringThe child workflow instance ID
typescript
// Generated code
const child_result = await step.do('trigger_fulfillment', async () => {
  const instance = await env.ORDER_FULFILLMENT.create({ params: charge_result })
  return { instanceId: instance.id }
})