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

# Workflows Overview

> Build automated workflows with a visual drag-and-drop editor. Chain API calls, add conditional logic, transform data, and handle errors.

# Workflows Overview

Workflows let you build automated processes that chain multiple API calls, add conditional logic, transform data, and handle errors - all through a visual drag-and-drop interface.

## What Are Workflows?

**Workflows** are automated sequences of actions that execute in response to triggers or manual invocation.

**Example workflow:**

```text theme={"dark"}
Trigger: Incoming webhook from Stripe
    ↓
HTTP Request: Validate payment with your backend
    ↓
Condition: Is payment successful?
    ↓ Yes                           ↓ No
Send confirmation email         Log error to Slack
    ↓                               ↓
Update CRM record               Create support ticket
```

## Key Concepts

### Nodes

Nodes are the building blocks of workflows. Each node performs a specific action:

| Node Type         | Purpose                                                         |
| ----------------- | --------------------------------------------------------------- |
| **Trigger**       | Starts the workflow (webhook, manual, schedule)                 |
| **HTTP Request**  | Make API calls to external services                             |
| **Email**         | Send notification emails                                        |
| **SMS**           | Send text messages                                              |
| **Code Block**    | Run custom JavaScript code *(coming soon — execution disabled)* |
| **Condition**     | Branch based on if/else logic                                   |
| **Loop**          | Iterate over arrays                                             |
| **Router**        | Route to different paths based on conditions                    |
| **Delay**         | Pause execution for a specified time                            |
| **Error Handler** | Catch and handle errors                                         |

### Edges

Edges connect nodes and define the flow of execution. Data passes from one node to the next through these connections.

### Variables

Workflows use a variable system to pass data between nodes:

```javascript theme={"dark"}
// Reference a previous node's output by its node id and output path:
// {{<nodeId>.<outputField>.<nested.path>}}

// Access the trigger node's output (the trigger node has id "trigger-node",
// also available via the "trigger" alias)
{{trigger.data.email}}

// Access an HTTP Request node's response (output fields are
// status, statusText, headers, body, url, method, success)
{{http_1.body.customer_id}}
{{http_1.status}}
```

<Note>
  Variables resolve against node outputs keyed by **node id**. There is no
  `nodes.`, `env.`, or `loop.` namespace, and HTTP responses expose their
  payload under `.body` (not `.response.data`).
</Note>

## Node Types

### Trigger Node

Every workflow starts with a trigger node that determines when the workflow runs:

**Trigger Types:**

* **Manual**: Run on-demand from the UI or API
* **Webhook**: Run when an HTTP request hits the workflow endpoint
* **Route Event**: Run when a KnoxCall route processes a request

**Webhook trigger example:**

```json theme={"dark"}
{
  "type": "trigger",
  "trigger_type": "webhook",
  "data": {
    "method": "POST",
    "path": "/payment-received"
  }
}
```

### HTTP Request Node

Make HTTP requests to external APIs:

**Configuration:** (node config is nested under `data.config`)

```json theme={"dark"}
{
  "type": "http_request",
  "data": {
    "type": "http_request",
    "config": {
      "method": "POST",
      "url": "https://api.example.com/users",
      "headers": {
        "Content-Type": "application/json"
      },
      "body": {
        "email": "{{trigger.data.email}}",
        "name": "{{trigger.data.name}}"
      }
    }
  }
}
```

**Output:** (the response payload is exposed under `body`)

```javascript theme={"dark"}
{
  status: 200,
  statusText: "OK",
  headers: { ... },
  body: { id: "user_123", ... },
  url: "https://api.example.com/users",
  method: "POST",
  success: true
}
```

### Code Block Node

<Note>
  **Coming soon:** Code Block execution is currently **disabled for security** and is planned for a future release — a Code Block does not run custom JavaScript yet (an empty Code Block passes its input through unchanged). The example below shows the intended behaviour.
</Note>

Run custom JavaScript for data transformation:

**Example:**

```javascript theme={"dark"}
// Input: trigger.body.items = [{ price: 10 }, { price: 20 }]

const total = input.trigger.body.items.reduce(
  (sum, item) => sum + item.price,
  0
);

return {
  total: total,
  itemCount: input.trigger.body.items.length,
  timestamp: new Date().toISOString()
};
```

**Use cases:**

* Data transformation
* Calculations
* Formatting responses
* Complex conditional logic

### Condition Node

Branch workflow execution based on conditions:

**Configuration:** (a structured list of conditions, not a JS expression)

```json theme={"dark"}
{
  "type": "condition",
  "data": {
    "type": "condition",
    "config": {
      "conditions": [
        { "type": "equals", "path": "$.status", "value": 200 }
      ],
      "logic": "AND"
    }
  }
}
```

Each condition has a `type`, a `path` (JSONPath into the input data), and a
`value` to compare against. Multiple conditions are combined with `logic`
(`AND` or `OR`).

**Branches:**

* **True path**: Executes when the conditions evaluate to true
* **False path**: Executes when the conditions evaluate to false

**Supported condition types:**

* `equals`, `not_equals`
* `greater_than`, `less_than`, `greater_or_equal`, `less_or_equal`
* `contains`, `starts_with`, `ends_with`
* `exists`, `is_empty`
* `regex` (matches against the `regex` field)

### Loop Node

Iterate over arrays:

**Configuration:**

```json theme={"dark"}
{
  "type": "loop",
  "data": {
    "type": "loop",
    "config": {
      "loopType": "array",
      "maxIterations": 100,
      "arrayConfig": {
        "arrayPath": "$.users",
        "itemVariable": "user",
        "batchSize": 1
      }
    }
  }
}
```

`loopType` is `array` (iterate a JSONPath array via `arrayConfig`) or `while`
(repeat while conditions hold via `whileConfig`). For array loops, `arrayPath`
points at the array and `itemVariable` names the per-item variable, which is
stored in the execution context's variables for nodes inside the loop body.
`maxIterations` is a required safety limit.

### Router Node

Route to different paths based on multiple conditions:

**Configuration:** (each route needs an `id` and `name`; `condition` is the same
structured condition array used by the Condition node)

```json theme={"dark"}
{
  "type": "router",
  "data": {
    "type": "router",
    "config": {
      "executionMode": "sequential",
      "routes": [
        {
          "id": "route_high",
          "name": "high_priority",
          "condition": [
            { "type": "equals", "path": "$.priority", "value": "high" }
          ]
        },
        {
          "id": "route_medium",
          "name": "medium_priority",
          "condition": [
            { "type": "equals", "path": "$.priority", "value": "medium" }
          ]
        },
        {
          "id": "route_default",
          "name": "default",
          "isFallback": true
        }
      ]
    }
  }
}
```

`executionMode` is `sequential` or `parallel`. A route with `isFallback: true`
handles data that matches no other route.

### Delay Node

Pause execution for a specified duration:

**Configuration:**

```json theme={"dark"}
{
  "type": "delay",
  "data": {
    "type": "delay",
    "config": {
      "delayType": "duration",
      "duration": 5,
      "unit": "seconds"
    }
  }
}
```

`delayType` is required. Use `duration` mode with `duration` + `unit`, or
`until` mode with an ISO timestamp (`"until": "2026-01-15T10:30:00Z"`).

**Units:** seconds, minutes, hours

### Error Handler Node

Catch and handle errors from previous nodes:

An Error Handler reacts to an error present on its input (it sits downstream of
the node whose errors it should handle) and applies an `onError` strategy.

**Configuration:**

```json theme={"dark"}
{
  "type": "error_handler",
  "data": {
    "type": "error_handler",
    "config": {
      "onError": "fallback",
      "fallbackValue": { "status": "degraded" },
      "retryConfig": {
        "maxAttempts": 3,
        "backoff": "exponential",
        "initialDelay": 1000
      }
    }
  }
}
```

`onError` is `continue`, `retry`, or `fallback` (the `custom` strategy is
disabled). `retryConfig` applies to the `retry` strategy and `fallbackValue` to
the `fallback` strategy.

**Output:**

```javascript theme={"dark"}
{
  handled: true,
  action: "fallback",
  originalError: "Connection refused",
  fallback: true,
  value: { status: "degraded" }
}
```

## Creating a Workflow

### 1. Navigate to Workflows

1. Click **Workflows** in the sidebar
2. Click **+ Create Workflow**

### 2. Add a Trigger

Every workflow needs a trigger node:

1. The trigger node is added automatically
2. Configure the trigger type (manual, webhook, etc.)
3. Set any trigger-specific options

### 3. Add Nodes

1. Click the **+** button on a node's output
2. Select the node type from the menu
3. Configure the node settings

### 4. Connect Nodes

1. Drag from one node's output to another's input
2. Edges show the flow direction
3. Some nodes (Condition, Router) have multiple outputs

### 5. Configure Variables

Use the variable picker to reference:

* Trigger data
* Previous node outputs
* Environment variables

### 6. Save and Enable

1. Click **Save**
2. Toggle **Enabled** to ON
3. Your workflow is now active

## Executing Workflows

### Manual Execution

1. Open the workflow
2. Click **Run**
3. Optionally provide input data
4. View execution progress in real-time

### Webhook Execution

1. Configure a webhook trigger
2. Get the workflow URL
3. Send HTTP requests to trigger the workflow

**Workflow URL format:** (POST)

```text theme={"dark"}
https://api.knoxcall.com/admin/webhooks/workflows/{workflow_id}/trigger
```

### Via API

This is an admin-console endpoint, so authorize with your admin access token (and
`X-Tenant-ID` header), not a tenant data-plane API key:

```bash theme={"dark"}
curl -X POST https://api.knoxcall.com/admin/workflows/{workflow_id}/execute \
  -H "Authorization: Bearer YOUR_ADMIN_ACCESS_TOKEN" \
  -H "X-Tenant-ID: YOUR_TENANT_ID" \
  -H "Content-Type: application/json" \
  -d '{"input": {"key": "value"}}'
```

The workflow runs in the background; the call returns `201` immediately:

```json theme={"dark"}
{
  "id": "execution-uuid",
  "workflow_id": "{workflow_id}",
  "status": "running",
  "started_at": "2026-01-15T10:30:45.000Z"
}
```

## Execution Monitoring

### Real-time Progress

When a workflow runs, you can watch execution in real-time:

* Each node highlights when it starts
* Success/failure status shown per node
* Execution time displayed
* Output data visible

### Execution History

View past executions:

1. Open the workflow
2. Click the **Executions** tab
3. See list of all executions with:
   * Status (running, completed, failed, cancelled)
   * Start time
   * Duration
   * Trigger type

### Execution Details

Click on an execution to see:

* Full execution timeline
* Each node's input and output
* Error messages (if any)
* Duration per node

## Error Handling

### Automatic Retries

HTTP Request nodes can be configured to retry on failure. The retry settings
live under the node's `config`:

```json theme={"dark"}
{
  "config": {
    "retry": {
      "enabled": true,
      "maxAttempts": 3,
      "backoff": "exponential",
      "initialDelay": 1000
    }
  }
}
```

`backoff` is `linear` or `exponential`, and `initialDelay` (default `1000`ms)
sets the wait before the first retry.

### Error Handler Nodes

Catch errors and execute recovery logic:

```text theme={"dark"}
HTTP Request → Error Handler → Slack Notification
                    ↓
              Log to Database
```

### Workflow-level Error Handling

If no error handler catches an error:

* Workflow status set to "failed"
* Error message logged
* Execution stops at the failing node

## Common Use Cases

### 1. Payment Processing Pipeline

```text theme={"dark"}
Stripe Webhook
    ↓
Validate Payment
    ↓
Condition: Successful?
    ↓ Yes           ↓ No
Update Order    Notify Support
    ↓
Send Receipt
    ↓
Update Analytics
```

### 2. User Onboarding

```text theme={"dark"}
New User Trigger
    ↓
Create CRM Record
    ↓
Send Welcome Email
    ↓
Delay: 1 day
    ↓
Send Getting Started Guide
```

### 3. Data Synchronization

```text theme={"dark"}
Schedule: Every hour
    ↓
Fetch from API A
    ↓
Loop: For each record
    ↓
Transform Data
    ↓
Push to API B
```

### 4. Error Alerting

```text theme={"dark"}
Route Error Event
    ↓
Code Block: Format Message
    ↓
Router: By Severity
    ↓ Critical              ↓ Warning
PagerDuty Alert         Slack Message
```

## Workflow Versioning

Workflows automatically version when you save changes:

* Each save creates a new version
* View version history

**View versions:**

1. Open workflow
2. Click **Versions** tab
3. See all saved versions with timestamps

<Note>
  **One-click rollback is coming soon.** Today you can view the full version
  history (`GET /admin/workflows/:id/versions`), but restoring a previous
  version from the UI/API is not yet available. To revert, re-save the workflow
  with the desired definition.
</Note>

## Best Practices

### 1. Start Simple

Begin with basic workflows and add complexity gradually:

* Start with Trigger → HTTP Request
* Add Condition nodes as needed
* Use Error Handlers for critical paths

### 2. Use Descriptive Names

Name nodes clearly:

* "Fetch Customer Data" not "HTTP Request 1"
* "Is Payment Valid?" not "Condition 1"

### 3. Handle Errors

Always add error handling for:

* External API calls
* Critical business logic
* Data transformations

### 4. Test Thoroughly

Before enabling:

* Run manually with test data
* Verify each node's output
* Test error scenarios

### 5. Monitor Executions

Regularly check:

* Execution history for failures
* Execution times for performance
* Error patterns

## Next Steps

<CardGroup cols={2}>
  <Card title="Creating Workflows" icon="plus" href="/workflows/creating-workflows">
    Step-by-step workflow creation guide
  </Card>

  <Card title="Webhooks" icon="webhook" href="/webhooks/webhooks-overview">
    Get notified when workflows complete
  </Card>

  <Card title="Routes" icon="route" href="/essentials/routes/what-are-routes">
    Understand API routing basics
  </Card>

  <Card title="Monitoring" icon="chart-line" href="/monitoring/analytics">
    Track workflow performance
  </Card>
</CardGroup>

***

<CardGroup cols={2}>
  <Card title="Statistics" icon="chart-line">
    * **Level**: intermediate
    * **Time**: 10 minutes
  </Card>

  <Card title="Tags" icon="tags">
    `workflows`, `automation`, `orchestration`, `visual-builder`, `no-code`
  </Card>
</CardGroup>
