Call a Workflow

Use a synchronous call when the parent needs the child's final JSON result.

JavaScript
const risk = await services.workflows.call("calculate-risk", {
  customerId: context.payload.customerId
}, { name: "calculate-customer-risk" });

return { score: risk.score };

The caller waits durably. Failure, cancellation, or an invalid/missing child result fails the call. A child whose successful main route returns no JSON value cannot satisfy a synchronous call. Calls that create a lineage cycle are rejected, and v1 does not wait synchronously through child human approvals.

Build the child

Create a call-only workflow with no <triggers>:

WOML
<workflow id="calculate-risk" name="Calculate risk" version="1.0.0">
  <steps>
    <step id="score">
      <script>
        return {
          customerId: context.payload.customerId,
          score: context.payload.orderTotal > 500 ? 80 : 20
        };
      </script>
    </step>
  </steps>
</workflow>

Its final value-producing step becomes the child result.

Call it from the parent

JavaScript
const risk = await services.workflows.call(
  "calculate-risk",
  {
    customerId: context.payload.customerId,
    orderTotal: context.steps.total.amount
  },
  { name: "calculate-customer-risk", timeout: "30s" }
);

return { riskScore: risk.score };

The parent script waits, but the runtime releases the parent's workflow concurrency slot while the child is durably pending. The child applies its own runtime policy.

Result and failure rules

The child must end successfully with JSON, including explicit null when that is the intended answer. Missing or undefined output cannot satisfy a synchronous call.

Child failure, cancellation, timeout, or invalid result fails the managed call. Cycles such as A calling B while B calls A are rejected. Cancelling a waiting parent does not silently cancel the independent child run.

Use a stable operation name so a retried parent step reattaches to the same durable call instead of starting accidental duplicate children.