Playbooks & workflows~9 min read

How to build your first playbook

A single validated agent solves a lot of problems: extract this, classify that, answer with a schema-checked JSON. But real workflows are rarely one step. A support ticket needs to be classified, then routed, then answered, with a validated escalation path if anything looks wrong along the way. A KYC review needs to extract two documents, cross-check them, and hand off to a human on any mismatch. That's what a playbook is for: a multi-step, multi-agent workflow with routing logic and validation gates built in, callable through the exact same API endpoint you already use for single agents.

This tutorial is the fastest path from zero to a published, callable playbook: starting from a template, wiring up the steps, and calling it in production with a single header change. By the end, you'll know:

  • What a playbook actually is, and how it differs from calling several agents yourself from your own backend
  • How to provision your first playbook from a template in under 15 minutes
  • How steps, routes, and node types fit together in the underlying graph
  • How to publish a playbook and call it with X-VG-Flow
  • What to check before you trust a playbook with real traffic
UI note: In current UI you may see both labels: Playbooks and Orchestration (same section, depending on plan/version). Agent creation is in Dashboard -> Agents -> Create agent. If a guide mentions Validation logs, open Dashboard -> Logs and apply filters.
  1. 1How It Works

    A playbook is a directed graph stored in ValGuard: a set of steps (mostly agents, each with their own validators) connected by routes that decide what happens next based on what happened at the previous step. When your application calls /v1/chat/completions with an X-VG-Flow header instead of X-VG-Agent, the engine walks this graph on your behalf, calling each step's agent, running its validators, and following whichever route condition matches, until it reaches a terminal step.

    The most common node type is agent: a normal validated LLM call, exactly like a single-agent request, but as one node in a larger graph. Other node types exist for structural needs: terminal (end state), merge (join parallel branches), fan_out (start parallel branches), http and webhook (calls outside the LLM), and sub_flow (nest another playbook inside this one).

    Routes connect steps and carry a condition type that decides when they're taken: always (unconditional, for simple linear chains), on_validation_pass / on_validation_block / on_validation_warn (branch based on what the previous step's validators decided), json_field_equals / json_field_exists (branch based on the previous step's actual output content), output_contains / output_not_contains, and on_rule_failed / on_rule_passed (branch based on a specific named rule, not just the overall pass/fail). Each route has a priority, so when multiple routes could match, the graph walker picks the highest-priority one that does.

    This tutorial builds the simplest meaningful shape: a linear chain with one validation-based branch: extract structured data, then route to an approval step on success or a review-handoff step on failure. Once this is comfortable, the chain-agents and fallback-logic tutorials go deeper on multi-step chains and branch design.

  2. 2Prerequisites

    • A ValGuard account with orchestration enabled for your plan (most plans include multi-agent playbooks; check Pricing if Playbooks is hidden in the Build section of the sidebar; a platform admin needs to enable orchestration in Admin → System configuration on self-hosted setups)
    • An API key
    • 15-20 minutes and a concrete use case in mind. This tutorial uses invoice processing as the running example, but any two-or-three-step workflow with a validation gate works the same way
  3. 3Step-by-Step Setup

    Step 1: Open Playbooks in the dashboard

    Go to Dashboard → Playbooks (under Build in the sidebar).

    Dashboard sidebar with Playbooks under the Build section

    If this is your first playbook, you'll see an empty state with a template picker instead of a graph editor.

    Step 2: Pick a starter template

    Scroll to Start from a template. Use Search templates by name or use case and the All categories filter if the catalog is long. For this walkthrough, pick Invoice processing. ValGuard ships with dozens of playbook templates (KYC document review, ticket routing, support automation, refund handling, and many more); you can also browse the same catalog from Playbook templates in the sidebar.

    Start from a template on the Playbooks page, with search and category filters above the template tiles

    Step 3: Let the wizard create or map agents

    The template wizard needs an agent for each step. If you have no existing agents, it creates draft ones with sensible default validators for that role. If you already have an agent that fits a step (say, an existing invoice-extraction agent), use Map to existing instead of creating a duplicate. The wizard shows you a diff so you know exactly what changes.

    Template wizard agent mapping for the extract_invoice step

    Step 4: Review the generated graph

    Once the wizard finishes, you land in the playbook editor with a draft graph already built, typically in Storyboard view for a template this simple (a straight chain plus one branch).

    Storyboard view of extract, validate, and approve or review_handoff branches

    Storyboard view reads top-to-bottom like a flowchart description; Map view (a toggle at the top of the editor) shows the same graph as connected nodes, which becomes more useful once you add parallel branches or fan-out later.

    Step 5: Fix any unassigned steps

    Every step needs an assigned agent before you can publish. If the wizard skipped a step (for example, an optional fraud-check node you didn't map), assign an agent to it now or delete it from the graph if you don't need it for your first version. Unmapped steps show a red Assign agent badge in Storyboard view.

    Step 6: Check the route conditions

    Open the branch after your validation step and confirm the two routes make sense: one for on_validation_pass leading to approval, one for on_validation_block leading to review-handoff.

    Route editor with on_validation_pass and on_validation_block conditions

    Step 7: Test in Simulate before publishing

    Before going live, use the Try it → Simulate panel to preview the graph's routing. Simulate never calls a real agent or validator. It's a free, client-side walk of the graph, where you declare each agent step's outcome (Pass, Block, or Warn) via Advanced per-agent, and Simulate shows you which route that produces. It doesn't count against your monthly request quota, since nothing is actually executed.

    Try it Simulate tab with execution timeline

    Run at least one scenario where you declare the validation step as Pass and one where you declare it Block, and confirm the graph takes the branch you expect in both cases.

    Step 8: Publish with Go Live

    Once Simulate confirms the graph behaves correctly, open the publish panel and click Go Live.

    Publish panel with Go Live and setup checklist

    Step 9: Call it from your application with X-VG-Flow

    Production calls use the playbook's slug in the X-VG-Flow header. Never combine this with X-VG-Agent on the same request; they're mutually exclusive targets.

    curl -si "$VG_PROXY/v1/chat/completions" \
      -H "Authorization: Bearer $VG_API_KEY" \
      -H "X-VG-Flow: invoice-processing" \
      -H "Content-Type: application/json" \
      -d '{"model":"openai/gpt-4o-mini","messages":[{"role":"user","content":"Process this invoice: Invoice #4471, Acme Supplies, $1,240.00, due 2026-08-01"}]}'
    ```
    
    ### Step 10: Confirm the response shows the playbook path
    
    Successful responses include orchestration-specific headers showing which steps actually ran.
    
    ```
    X-VG-Orchestration-Path: extract_invoice > validate_totals > approve
    X-VG-Target-Type: playbook
  4. 4Diagram / Flow

  5. 5Configuration Examples

    Simplified orchestration template shape (what the wizard generates under the hood):

    id: invoice-processing
    display_name: Invoice Processing
    required_agents:
      - step_key: extract_invoice
        role_label: Extract invoice fields
        template_slug: invoice_extraction_agent
        suggested_agent_slug: invoice-extract
      - step_key: validate_totals
        role_label: Validate totals and required fields
        template_slug: numeric_consistency_agent
        suggested_agent_slug: invoice-validate
    graph:
      entry_step_key: extract_invoice
      steps:
        - step_key: extract_invoice
          node_type: agent
          agent_slug: "{{extract_invoice}}"
          input_mode: pass_through
        - step_key: validate_totals
          node_type: agent
          agent_slug: "{{validate_totals}}"
          input_mode: append_previous
        - step_key: approve
          node_type: terminal
        - step_key: review_handoff
          node_type: terminal
      routes:
        - from_step_key: validate_totals
          to_step_key: approve
          condition_type: on_validation_pass
          priority: 10
        - from_step_key: validate_totals
          to_step_key: review_handoff
          condition_type: on_validation_block
          priority: 20
    ```
    
    **curl call with a message designed to fail validation:**
    
    ```bash
    curl -si "$VG_PROXY/v1/chat/completions" \
      -H "Authorization: Bearer $VG_API_KEY" \
      -H "X-VG-Flow: invoice-processing" \
      -H "Content-Type: application/json" \
      -d '{"model":"openai/gpt-4o-mini","messages":[{"role":"user","content":"Process this invoice: totally illegible scan, no amounts visible"}]}'
    ```
    
    ```
    X-VG-Orchestration-Path: extract_invoice > validate_totals > review_handoff
  6. 6Testing and Verification

    1. Simulate happy path. Declare a Pass outcome on the validation step and confirm the timeline shows every step you expect, ending at your success terminal.
    2. Simulate failure path. Declare a Block outcome on the same step and confirm the graph takes the review_handoff branch, not the approval one.
    3. One real Live run before announcing it. Simulate never calls a real agent, validator, or upstream LLM. It only proves the graph's routing logic. Run one real Live execution with an actual malformed message to confirm your validators genuinely produce a block in that case, not just that the graph would route correctly if they did.
    Try it panel with Live tab for a real execution
  7. 7Troubleshooting

    "Go Live is disabled / greyed out." Every step needs an assigned agent, and the graph needs at least one path from the entry step to a terminal step. Check the Storyboard view for any red "Assign agent" badges first.

    "The playbook always takes the same branch regardless of input." Check route priority values. If two routes from the same step have condition types that could both technically apply, the lower-priority-number route (evaluated first) wins. Also confirm you're not accidentally using always on a route that should be conditional.

    "X-VG-Flow returns a 404 or 'target not found' error." Confirm the slug in the header exactly matches the playbook's slug (visible in the publish panel and the dashboard URL), and that the playbook is actually published (Go Live), not still a draft. Drafts are only reachable through Simulate, not real API calls.

    "I sent X-VG-Agent and X-VG-Flow together and got an error." These headers are mutually exclusive. Decide per request whether you're calling a single agent or a playbook, and send only the corresponding header.

    "A step's output doesn't seem to reach the next step correctly." Check that step's input_mode. pass_through sends the original playbook input, append_previous adds the prior step's output to the context, and replace_with_previous uses only the prior step's output. A common mistake is leaving a step on pass_through when it actually needs the previous step's extracted data via append_previous.

  8. 8Best Practices

    • Start from a template close to your use case, even if you'll customize heavily. The wizard's default validator packs per role are a faster starting point than building an agent from scratch.
    • Keep your first playbook simple. A linear chain with one validation branch is enough to learn the publish/call cycle; add fan-out, repair loops, and sub-flows once this pattern feels routine.
    • Always declare both a pass-case and a fail-case in Simulate before publishing, then confirm both with a real Live run. A graph whose routes have never been exercised, or whose validators have never actually been proven to fail on bad input, hasn't actually been tested.
    • Name step keys descriptively, not step1/step2. extract_invoice, validate_totals, review_handoff make the graph self-documenting for the next person (including future you) who opens it.
    • Map to existing agents when you have them, rather than letting the wizard create near-duplicates. Fewer agents to maintain, and validator changes apply everywhere that agent is used.
  9. 9Advanced Options

    Branching on extracted field values, not just validation pass/fail. Once the basic pattern is comfortable, json_field_equals and json_field_exists route conditions let you branch on the actual content of a step's output, for example, routing a support ticket to different downstream agents based on a classified category field, not just whether the classification step's validators passed.

    Nesting playbooks with sub_flow. If one part of your workflow is complex enough to deserve independent versioning and testing, a sub_flow node lets you call another playbook as a single step in this one, useful for a shared KYC sub-flow reused across several onboarding playbooks rather than duplicated in each.

    Community and marketplace templates. Beyond the built-in template catalog, the playbook marketplace includes community-published templates for more specific use cases. Worth browsing before building a workflow from scratch, since someone may have already solved a very similar problem.

  10. 10Summary and Next Steps

    Building your first playbook is mostly about the publish cycle, not the graph complexity: pick a template, let the wizard scaffold agents, fix any unassigned steps, verify both the pass and fail routes in Simulate (and confirm them with a real Live run), and publish with Go Live. Everything else (fan-out, repair loops, sub-flows) is the same underlying primitives (steps, routes, node types) applied to more ambitious shapes.

    From here, chaining agents goes deeper on multi-step input passing between steps, and testing branches in sandbox mode covers Simulate in more depth, including how to build a reusable library of test fixtures for a graph before every publish, not just the first one.

What's next?