Skip to main content

What This Example Shows

  • Both edge syntaxes the Graph Workflow endpoint actually accepts — and the list/tuple forms it rejects
  • Side-by-side examples where each format produces the same three-agent DAG
  • How to express multi-target (fan-out) edges and conditional gating
  • A summary table for picking the right format for the job
  • One end-to-end runnable workflow that mixes formats in a single edges array
The Graph Workflow endpoint (POST /v1/graph-workflow/completions) is a premium-only feature available on Pro, Ultra, and Premium plans. Free-tier keys receive a 403. Upgrade your account to run production DAGs.

Why This Matters

Most teams adopt Graph Workflow with one edge format in mind — usually the dict form {"source": "A", "target": "B"} — then run into friction when their DAG grows or when ops needs to tag specific edges. The API accepts two interchangeable formats: the plain dict form and the dict form with a metadata block. List and tuple shorthands like ["A", "B"] are rejected by request validation before the workflow runs. This reference walks each accepted format end to end against the same target DAG so you can see the trade-offs in one place, and shows how to compose multi-target fan-outs and prompt-level conditional gating without inventing a syntax the API doesn’t actually support.

Step 1: Setup

Install dependencies and load your API key.

Step 2: Define the Shared Agent Pool

Every example below reuses the same three-agent pool so only the edges change between formats.
The baseline target DAG for both formats is the same linear pipeline:

Step 3: Format 1 — Dict Form

The canonical and most common format. Each edge is a dictionary with explicit source and target keys. Verbose but extremely readable in code reviews — most production codebases standardize on this.

Step 4: Format 2 — Dict with Metadata

The dict form plus an optional metadata field — a free-form dictionary you can attach to any edge for routing hints, priority labels, telemetry tags, retry policies, or downstream business rules. The metadata travels with the edge through the compiler.
Metadata keys are unconstrained — use whatever your ops or audit tooling expects. Common patterns: priority, retry_on_failure, audit_tag, data_type, timeout, cost_center. See Tagging Graph Workflow Edges with Metadata for the full production playbook.

Step 5: List and Tuple Edges Are Rejected

Each edge in the request schema must be an object (an EdgeSpec or a dictionary with source and target keys). Terse list shorthands — [source, target] or [source, target, metadata], and their Python tuple equivalents — fail request validation with a 422 Unprocessable Entity before the workflow ever runs.
If you prefer writing arrow-like pairs in your own code, keep them as local shorthand and convert before submission:

Step 6: Multi-Target (Fan-Out) Edges

There is no dedicated multi-target syntax in the API — you express a fan-out by writing one edge per downstream target, all sharing the same source. The compiler builds the parallel branches and runs them concurrently. This is the same expressive power as a hypothetical "A -> [B, C]" shorthand, just stated explicitly.
The same trick scales — N edges with the same source produce an N-way fan-out, and N edges with the same target produce an N-way fan-in. The full DAG is just a list of pairwise edges; structure emerges from the edge set.

Step 7: Conditional Edges via Prompt-Level Gating

The Graph Workflow endpoint does not expose a schema-level condition field on edges — every declared edge fires when its upstream node completes. To implement a conditional path, encode the gate in the downstream node’s prompt:
The HumanEscalation node runs every time, but produces a SKIPPED no-op when the upstream emits PASS. Downstream consumers (or a final synthesis node) check for SKIPPED and ignore the branch. See Graph Workflows for Production Pipelines for the full SKIP-gating pattern in a real DAG.

Step 8: Mix Formats in One Workflow

The API accepts heterogeneous edges in the same edges array. Sketch the trunk of the graph with plain dict edges and add a metadata block only on the edges ops actually cares about.

Step 9: Read the Per-Node Output

Regardless of which edge format you submit, the response shape is identical. Outputs are keyed by agent_name.

Choosing the Right Format

A common production convention: use the plain dict form everywhere, and add a metadata block only on edges that participate in audit, retry, or routing logic.

Common Pitfalls

The API expects each edge to be an object — an EdgeSpec or a dict with source and target keys. List/tuple shorthands like ["Agent1", "Agent2"] and strings like "Agent1 -> Agent2" are rejected with a 422 before the workflow runs. Convert them to the dict form.
Every edge’s source and target must match an agent_name in the agents array exactly. Watch for whitespace, casing, and trailing punctuation — the comparison is exact.
Check that the downstream node appears as the target of at least one edge whose source actually executes. A node with no incoming edge and no entry in entry_points will never fire.

Next Steps