Querying Child Workflows

When a workflow uses forEach nodes, each iteration spawns a child workflow. The children API lets you discover, drill into, and retrieve the full execution tree β€” all without knowing Temporal internals.

Overview

When you call GET /workflows/{id}, the response now includes a children array: a lightweight manifest listing every direct child workflow with its status, iteration data, and an href link for drill-down.

For deeper nesting (a forEach inside a forEach), each child's response includes its own children manifest β€” same shape, all the way down.

Three endpoints cover every use case:

Use caseEndpoint
"What happened? What children exist?"GET /workflows/{id}
"Drill into Spanish (index 0)"GET /workflows/{id}/forEach/{nodeId}/{index}
"Give me everything in one call"GET /workflows/{id}/tree

API endpoints

All endpoints are relative to https://api.graphcompose.io/api/v1.

EndpointMethodDescription
/workflows/{id}GETParent state + children[] manifest
/workflows/{id}/forEach/{nodeId}/{index}GETSpecific child by forEach node ID and index
/workflows/{id}/treeGETFull recursive execution tree

Children manifest

The children array on the parent response is a manifest β€” lightweight metadata with links. It never includes child state inline.

curl https://api.graphcompose.io/api/v1/workflows/abc123 \
  -H "Authorization: Bearer $GRAPH_COMPOSE_TOKEN"

Each manifest entry includes:

FieldDescription
forEachNodeIdThe forEach node that spawned this child
indexIteration index (0-based)
statusCurrent status (RUNNING, COMPLETED, FAILED, etc.)
dataThe forEach item data for this iteration
hrefAPI link to fetch the child's full state
childCountNumber of grandchildren (0 = leaf, no deeper nesting)

View full ChildManifestEntry schema in API Reference β†’

Get a forEach child by index

Use the href from the manifest, or construct the path yourself using the forEach node ID and iteration index:

curl https://api.graphcompose.io/api/v1/workflows/abc123/forEach/dub_langs/0 \
  -H "Authorization: Bearer $GRAPH_COMPOSE_TOKEN"

The response has the same shape as the parent endpoint β€” executionState, status, and children[].

View full response schema in API Reference β†’

Deep nesting

For nested forEach loops (forEach inside forEach), chain the path segments:

curl https://api.graphcompose.io/api/v1/workflows/abc123/forEach/dub_langs/0/forEach/dub_chunks/1 \
  -H "Authorization: Bearer $GRAPH_COMPOSE_TOKEN"

The path pattern is /forEach/{nodeId}/{index} repeated for each level of nesting. The API constructs the internal Temporal workflow ID from the path β€” you never need to know compound IDs.

Full execution tree

For workflows with many children, use the tree endpoint to fetch everything in a single call:

curl https://api.graphcompose.io/api/v1/workflows/abc123/tree \
  -H "Authorization: Bearer $GRAPH_COMPOSE_TOKEN"

The tree is keyed by forEach node ID at each level. Use ?maxDepth=N to limit recursion depth for large workflows.

View full WorkflowTree response schema in API Reference β†’

Programmatic traversal

Use the href links in the children manifest to crawl the tree programmatically:

const parent = await fetch(`/api/v1/workflows/${id}`, {
  headers: { Authorization: `Bearer ${token}` }
}).then(r => r.json())

const failedChild = parent.data.children.find(
  (c: any) => c.status === 'FAILED'
)

if (failedChild) {
  const child = await fetch(failedChild.href, {
    headers: { Authorization: `Bearer ${token}` }
  }).then(r => r.json())

  console.log('Failed child state:', child.data.executionState)

  // Check grandchildren too β€” same shape
  const failedGrandchild = child.data.children.find(
    (c: any) => c.status === 'FAILED'
  )
}

Response shape consistency

A key design principle: the parent endpoint and the forEach child endpoint return the exact same response type. This means:

  • The same TypeScript interface works for both
  • Recursive traversal code doesn't need special cases per depth level
  • The children field is always present (empty array [] for leaf nodes)

The tree endpoint (/tree) uses a different recursive shape since it includes all states inline, but it's a dedicated endpoint β€” no shape-shifting within a single URL.