> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zavu.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Conversational Flows

> Build structured conversation paths for lead capture, booking, and multi-step processes

# Conversational Flows

Flows are deterministic conversation paths that guide users through structured interactions. While the AI agent handles free-form questions, flows ensure consistent data collection and multi-step processes.

## What are Flows?

A **Flow** is a series of steps that execute in sequence when triggered. Each step can:

* Send a message
* Collect and validate user input
* Branch based on conditions
* Call webhook tools
* Generate AI responses
* Transfer to a human agent

```
[Trigger] → [Welcome] → [Collect Name] → [Collect Email] → [Confirm] → [End]
```

## When to Use Flows

| Scenario                                      | Use Flow | Use Free-form LLM |
| --------------------------------------------- | -------- | ----------------- |
| Collecting required data (name, email, phone) | Yes      | No                |
| Compliance-required messaging                 | Yes      | No                |
| Appointment booking                           | Yes      | Maybe             |
| General Q\&A                                  | No       | Yes               |
| Product recommendations                       | No       | Yes               |
| Order status lookup                           | Maybe    | Yes               |

<Tip>
  Use flows when you need **guaranteed outcomes**. Use the LLM when you need **flexibility**.
</Tip>

## Flow Triggers

Flows can be triggered in several ways:

| Trigger Type | Description                             | Example                           |
| ------------ | --------------------------------------- | --------------------------------- |
| `keyword`    | Message contains specific words         | "book", "appointment", "schedule" |
| `intent`     | AI detects user intent                  | Booking intent, support intent    |
| `always`     | Every new conversation starts this flow | Welcome/onboarding flow           |
| `manual`     | Triggered by API call                   | After webhook event               |

## Step Types

### Message Step

Send a fixed message to the user.

```json theme={null}
{
  "type": "message",
  "content": "Welcome to Acme Corp! How can I help you today?",
  "channel": "whatsapp" // Optional: send via specific channel
}
```

### Collect Step

Collect and validate user input.

```json theme={null}
{
  "type": "collect",
  "variable": "customer_email",
  "prompt": "What's your email address?",
  "validation": {
    "type": "email",
    "errorMessage": "Please enter a valid email address."
  }
}
```

**Validation Types:**

* `email` - Valid email format
* `phone` - Valid phone number
* `number` - Numeric value
* `date` - Date format
* `regex` - Custom pattern
* `options` - One of provided choices

### Condition Step

Branch the flow based on conditions.

```json theme={null}
{
  "type": "condition",
  "conditions": [
    {
      "if": "{{budget}} > 10000",
      "goto": "premium_path"
    },
    {
      "if": "{{budget}} <= 10000",
      "goto": "standard_path"
    }
  ]
}
```

### Tool Step

Execute a webhook tool and use the result.

```json theme={null}
{
  "type": "tool",
  "toolName": "check_availability",
  "parameters": {
    "date": "{{preferred_date}}",
    "service": "{{service_type}}"
  },
  "resultVariable": "available_slots"
}
```

### LLM Step

Generate a response using the AI model.

```json theme={null}
{
  "type": "llm",
  "prompt": "Based on the customer's preferences ({{preferences}}), suggest 3 products.",
  "resultVariable": "recommendations"
}
```

### Transfer Step

End the flow and hand off to a human agent.

```json theme={null}
{
  "type": "transfer",
  "message": "I'm connecting you with a specialist. Please hold.",
  "department": "support"
}
```

## Via Dashboard

<Steps>
  <Step title="Navigate to Flows">
    Go to **Senders** > select your sender > **Agent** tab > **Flows** section.
  </Step>

  <Step title="Create New Flow">
    Click **Create Flow** and enter:

    * **Name**: A descriptive name (e.g., "Lead Capture Flow")
    * **Description**: What this flow does
    * **Trigger**: How the flow is activated
  </Step>

  <Step title="Add Steps">
    Use the visual flow builder to add steps:

    1. Click **Add Step**
    2. Select the step type
    3. Configure the step parameters
    4. Connect steps by dragging between nodes
  </Step>

  <Step title="Configure Triggers">
    Set up how the flow is triggered:

    * For **keyword** triggers, enter the words that activate the flow
    * For **intent** triggers, describe the intent in natural language
    * For **always**, the flow runs on every new conversation
  </Step>

  <Step title="Test the Flow">
    Use the **Test** button to simulate a conversation and verify each step works correctly.
  </Step>

  <Step title="Activate Flow">
    Toggle the flow to **Active** to enable it for incoming messages.
  </Step>
</Steps>

## Via API

### Create Flow

<CodeGroup>
  ```typescript TypeScript theme={null}
  import Zavudev from "@zavudev/sdk";

  const zavu = new Zavudev({
    apiKey: process.env["ZAVUDEV_API_KEY"],
  });

  const flow = await zavu.senders.agent.flows.create("sender_abc123", {
    name: "Lead Capture",
    description: "Collect lead information from new contacts",
    trigger: {
      type: "keyword",
      keywords: ["interested", "info", "learn more"],
    },
    steps: [
      {
        id: "welcome",
        type: "message",
        content: "Great! I'd love to help. Let me collect some information.",
      },
      {
        id: "get_name",
        type: "collect",
        variable: "customer_name",
        prompt: "What's your name?",
      },
      {
        id: "get_email",
        type: "collect",
        variable: "customer_email",
        prompt: "What's your email address?",
        validation: { type: "email" },
      },
      {
        id: "get_company",
        type: "collect",
        variable: "company_name",
        prompt: "What company are you with?",
      },
      {
        id: "confirm",
        type: "message",
        content: "Thanks {{customer_name}}! Our team will contact you at {{customer_email}} within 24 hours.",
      },
    ],
  });

  console.log("Flow created:", flow.id);
  ```

  ```python Python theme={null}
  import os
  from zavudev import Zavudev

  zavu = Zavudev(
      api_key=os.environ.get("ZAVUDEV_API_KEY"),
  )

  flow = zavu.senders.agent.flows.create(
      "sender_abc123",
      name="Lead Capture",
      description="Collect lead information from new contacts",
      trigger={
          "type": "keyword",
          "keywords": ["interested", "info", "learn more"],
      },
      steps=[
          {
              "id": "welcome",
              "type": "message",
              "content": "Great! I'd love to help. Let me collect some information.",
          },
          {
              "id": "get_name",
              "type": "collect",
              "variable": "customer_name",
              "prompt": "What's your name?",
          },
          {
              "id": "get_email",
              "type": "collect",
              "variable": "customer_email",
              "prompt": "What's your email address?",
              "validation": {"type": "email"},
          },
          {
              "id": "get_company",
              "type": "collect",
              "variable": "company_name",
              "prompt": "What company are you with?",
          },
          {
              "id": "confirm",
              "type": "message",
              "content": "Thanks {{customer_name}}! Our team will contact you at {{customer_email}} within 24 hours.",
          },
      ],
  )

  print(f"Flow created: {flow.id}")
  ```

  ```ruby Ruby theme={null}
  require "zavudev"

  client = Zavudev::Client.new(api_key: ENV["ZAVUDEV_API_KEY"])

  flow = client.senders.agent.flows.create("sender_abc123",
    name: "Lead Capture",
    description: "Collect lead information from new contacts",
    trigger: {
      type: "keyword",
      keywords: ["interested", "info", "learn more"]
    },
    steps: [
      {
        id: "welcome",
        type: "message",
        content: "Great! I'd love to help. Let me collect some information."
      },
      {
        id: "get_name",
        type: "collect",
        variable: "customer_name",
        prompt: "What's your name?"
      },
      {
        id: "get_email",
        type: "collect",
        variable: "customer_email",
        prompt: "What's your email address?",
        validation: { type: "email" }
      },
      {
        id: "get_company",
        type: "collect",
        variable: "company_name",
        prompt: "What company are you with?"
      },
      {
        id: "confirm",
        type: "message",
        content: "Thanks {{customer_name}}! Our team will contact you at {{customer_email}} within 24 hours."
      }
    ]
  )

  puts "Flow created: #{flow.id}"
  ```

  ```go Go theme={null}
  flow, _ := client.Senders.Agent.Flows.Create(context.TODO(), "sender_abc123", zavudev.FlowCreateParams{
  	Name:        zavudev.String("Lead Capture"),
  	Description: zavudev.String("Collect lead information from new contacts"),
  	Trigger: &zavudev.FlowTrigger{
  		Type:     zavudev.String("keyword"),
  		Keywords: []string{"interested", "info", "learn more"},
  	},
  	Steps: []zavudev.FlowStep{
  		{
  			ID:      zavudev.String("welcome"),
  			Type:    zavudev.String("message"),
  			Config:  map[string]interface{}{"content": "Great! I'd love to help. Let me collect some information."},
  		},
  		{
  			ID:      zavudev.String("get_name"),
  			Type:    zavudev.String("collect"),
  			Config:  map[string]interface{}{"variable": "customer_name", "prompt": "What's your name?"},
  		},
  		{
  			ID:      zavudev.String("get_email"),
  			Type:    zavudev.String("collect"),
  			Config:  map[string]interface{}{"variable": "customer_email", "prompt": "What's your email address?", "validation": map[string]interface{}{"type": "email"}},
  		},
  		{
  			ID:      zavudev.String("get_company"),
  			Type:    zavudev.String("collect"),
  			Config:  map[string]interface{}{"variable": "company_name", "prompt": "What company are you with?"},
  		},
  		{
  			ID:      zavudev.String("confirm"),
  			Type:    zavudev.String("message"),
  			Config:  map[string]interface{}{"content": "Thanks {{customer_name}}! Our team will contact you at {{customer_email}} within 24 hours."},
  		},
  	},
  })

  fmt.Printf("Flow created: %s\n", flow.ID)
  ```

  ```php PHP theme={null}
  $flow = $client->senders->agent->flows->create('sender_abc123', [
      'name' => 'Lead Capture',
      'description' => 'Collect lead information from new contacts',
      'trigger' => [
          'type' => 'keyword',
          'keywords' => ['interested', 'info', 'learn more'],
      ],
      'steps' => [
          [
              'id' => 'welcome',
              'type' => 'message',
              'content' => "Great! I'd love to help. Let me collect some information.",
          ],
          [
              'id' => 'get_name',
              'type' => 'collect',
              'variable' => 'customer_name',
              'prompt' => "What's your name?",
          ],
          [
              'id' => 'get_email',
              'type' => 'collect',
              'variable' => 'customer_email',
              'prompt' => "What's your email address?",
              'validation' => ['type' => 'email'],
          ],
          [
              'id' => 'get_company',
              'type' => 'collect',
              'variable' => 'company_name',
              'prompt' => 'What company are you with?',
          ],
          [
              'id' => 'confirm',
              'type' => 'message',
              'content' => 'Thanks {{customer_name}}! Our team will contact you at {{customer_email}} within 24 hours.',
          ],
      ],
  ]);

  echo "Flow created: {$flow->id}\n";
  ```

  ```bash cURL theme={null}
  curl -X POST https://api.zavu.dev/v1/senders/sender_abc123/agent/flows \
    -H "Authorization: Bearer $ZAVU_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "Lead Capture",
      "description": "Collect lead information from new contacts",
      "trigger": {
        "type": "keyword",
        "keywords": ["interested", "info", "learn more"]
      },
      "steps": [
        {
          "id": "welcome",
          "type": "message",
          "content": "Great! I'\''d love to help. Let me collect some information."
        },
        {
          "id": "get_name",
          "type": "collect",
          "variable": "customer_name",
          "prompt": "What'\''s your name?"
        },
        {
          "id": "get_email",
          "type": "collect",
          "variable": "customer_email",
          "prompt": "What'\''s your email address?",
          "validation": {"type": "email"}
        },
        {
          "id": "confirm",
          "type": "message",
          "content": "Thanks {{customer_name}}! Our team will contact you at {{customer_email}} within 24 hours."
        }
      ]
    }'
  ```
</CodeGroup>

### List Flows

<CodeGroup>
  ```typescript TypeScript theme={null}
  const flows = await zavu.senders.agent.flows.list("sender_abc123");

  for (const flow of flows.items) {
    console.log(`${flow.name} (${flow.id}) - ${flow.enabled ? "Active" : "Inactive"}`);
  }
  ```

  ```python Python theme={null}
  flows = zavu.senders.agent.flows.list("sender_abc123")

  for flow in flows.items:
      status = "Active" if flow.enabled else "Inactive"
      print(f"{flow.name} ({flow.id}) - {status}")
  ```

  ```ruby Ruby theme={null}
  flows = client.senders.agent.flows.list("sender_abc123")

  flows.items.each do |flow|
    status = flow.enabled ? "Active" : "Inactive"
    puts "#{flow.name} (#{flow.id}) - #{status}"
  end
  ```

  ```go Go theme={null}
  flows, _ := client.Senders.Agent.Flows.List(context.TODO(), "sender_abc123", zavudev.FlowListParams{})

  for _, flow := range flows.Items {
  	status := "Inactive"
  	if flow.Enabled {
  		status = "Active"
  	}
  	fmt.Printf("%s (%s) - %s\n", flow.Name, flow.ID, status)
  }
  ```

  ```php PHP theme={null}
  $flows = $client->senders->agent->flows->list('sender_abc123');

  foreach ($flows->items as $flow) {
      $status = $flow->enabled ? 'Active' : 'Inactive';
      echo "{$flow->name} ({$flow->id}) - {$status}\n";
  }
  ```

  ```bash cURL theme={null}
  curl https://api.zavu.dev/v1/senders/sender_abc123/agent/flows \
    -H "Authorization: Bearer $ZAVU_API_KEY"
  ```
</CodeGroup>

### Update Flow

<CodeGroup>
  ```typescript TypeScript theme={null}
  const flow = await zavu.senders.agent.flows.update(
    "sender_abc123",
    "flow_xyz789",
    {
      name: "Updated Lead Capture",
      enabled: true,
    }
  );
  ```

  ```python Python theme={null}
  flow = zavu.senders.agent.flows.update(
      "sender_abc123",
      "flow_xyz789",
      name="Updated Lead Capture",
      enabled=True,
  )
  ```

  ```ruby Ruby theme={null}
  flow = client.senders.agent.flows.update("sender_abc123", "flow_xyz789",
    name: "Updated Lead Capture",
    enabled: true
  )
  ```

  ```go Go theme={null}
  flow, _ := client.Senders.Agent.Flows.Update(context.TODO(), "sender_abc123", "flow_xyz789", zavudev.FlowUpdateParams{
  	Name:    zavudev.String("Updated Lead Capture"),
  	Enabled: zavudev.Bool(true),
  })
  ```

  ```php PHP theme={null}
  $flow = $client->senders->agent->flows->update('sender_abc123', 'flow_xyz789', [
      'name' => 'Updated Lead Capture',
      'enabled' => true,
  ]);
  ```

  ```bash cURL theme={null}
  curl -X PATCH https://api.zavu.dev/v1/senders/sender_abc123/agent/flows/flow_xyz789 \
    -H "Authorization: Bearer $ZAVU_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"name": "Updated Lead Capture", "enabled": true}'
  ```
</CodeGroup>

## Example Flows

### Lead Capture Flow

```json theme={null}
{
  "name": "Lead Capture",
  "trigger": {
    "type": "keyword",
    "keywords": ["pricing", "demo", "interested"]
  },
  "steps": [
    {
      "id": "welcome",
      "type": "message",
      "content": "Thanks for your interest! Let me get some details."
    },
    {
      "id": "name",
      "type": "collect",
      "variable": "name",
      "prompt": "What's your name?"
    },
    {
      "id": "email",
      "type": "collect",
      "variable": "email",
      "prompt": "What's your email?",
      "validation": { "type": "email" }
    },
    {
      "id": "company_size",
      "type": "collect",
      "variable": "size",
      "prompt": "How many employees at your company?",
      "validation": {
        "type": "options",
        "options": ["1-10", "11-50", "51-200", "200+"]
      }
    },
    {
      "id": "save_lead",
      "type": "tool",
      "toolName": "create_lead",
      "parameters": {
        "name": "{{name}}",
        "email": "{{email}}",
        "companySize": "{{size}}"
      }
    },
    {
      "id": "confirm",
      "type": "message",
      "content": "Thanks {{name}}! A team member will reach out within 24 hours."
    }
  ]
}
```

### Appointment Booking Flow

```json theme={null}
{
  "name": "Book Appointment",
  "trigger": {
    "type": "keyword",
    "keywords": ["book", "appointment", "schedule", "meeting"]
  },
  "steps": [
    {
      "id": "welcome",
      "type": "message",
      "content": "I'd be happy to help you book an appointment!"
    },
    {
      "id": "service",
      "type": "collect",
      "variable": "service_type",
      "prompt": "What type of appointment?",
      "validation": {
        "type": "options",
        "options": ["Consultation", "Follow-up", "New Patient"]
      }
    },
    {
      "id": "date",
      "type": "collect",
      "variable": "preferred_date",
      "prompt": "What date works best? (e.g., Monday, Dec 20)",
      "validation": { "type": "date" }
    },
    {
      "id": "check_slots",
      "type": "tool",
      "toolName": "get_available_slots",
      "parameters": {
        "date": "{{preferred_date}}",
        "service": "{{service_type}}"
      },
      "resultVariable": "slots"
    },
    {
      "id": "show_slots",
      "type": "message",
      "content": "Available times on {{preferred_date}}: {{slots}}"
    },
    {
      "id": "time",
      "type": "collect",
      "variable": "selected_time",
      "prompt": "Which time works for you?"
    },
    {
      "id": "book",
      "type": "tool",
      "toolName": "create_appointment",
      "parameters": {
        "date": "{{preferred_date}}",
        "time": "{{selected_time}}",
        "service": "{{service_type}}"
      }
    },
    {
      "id": "confirm",
      "type": "message",
      "content": "Your {{service_type}} appointment is booked for {{preferred_date}} at {{selected_time}}. See you then!"
    }
  ]
}
```

## Flow Sessions

When a user enters a flow, a **session** is created to track their progress. Sessions store:

* Current step
* Collected variables
* Timestamps
* Channel information

Sessions expire after 24 hours of inactivity. If a user returns after expiration, they start from the beginning.

<Info>
  You can query active sessions via the API to see where users are in their flows.
</Info>

## Best Practices

<CardGroup cols={2}>
  <Card title="Keep Flows Short" icon="compress">
    Aim for 5-7 steps maximum. Long flows have higher abandonment rates.
  </Card>

  <Card title="Validate Early" icon="check">
    Validate critical inputs (email, phone) immediately after collection.
  </Card>

  <Card title="Provide Exit Points" icon="door-open">
    Let users say "stop" or "cancel" to exit the flow at any time.
  </Card>

  <Card title="Use Variables" icon="brackets-curly">
    Reference collected data in messages to personalize the experience.
  </Card>
</CardGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="Add Tools" icon="wrench" href="/guides/ai-agents/tools">
    Enable your flows to execute actions via webhooks
  </Card>

  <Card title="Knowledge Base" icon="book" href="/guides/ai-agents/knowledge-base">
    Let your agent answer questions from documents
  </Card>
</CardGroup>
