Home/Docs/Visual Workflows

Visual Workflows

Visual workflows let you build multi-step automations using a drag-and-drop builder in the dashboard. Unlike markdown-based workflows (defined as JSON or YAML files in ~/.zubo/workspace/workflows/), visual workflows are created entirely in the browser with an interactive canvas, step palette, and real-time execution preview.

Copy-Paste Task Cards

Secure API Access

Enable API auth and create a key before exposing ports beyond localhost.

zubo config set auth.enabled true
zubo auth create-key my-app

Set Local Model Fallback

Keep responses available during provider outages or API quota issues.

zubo config set failover '["openai","ollama"]'
zubo config set providers.ollama.model llama3.3

Common Errors

401 Unauthorized / Missing Bearer token

If auth.enabled is true, all /api/* calls require Authorization: Bearer <key>. Create a new key if needed.

curl -H "Authorization: Bearer YOUR_KEY" http://localhost:3000/api/dashboard/status
Provider Timeout / Upstream unavailable

Use failover and switch temporarily to a responsive provider or smaller model. Check logs for repeated timeout patterns.

zubo model openai/gpt-4o-mini
zubo logs --follow
Missing local model (Ollama/LM Studio)

If local providers fail, ensure the runtime is running and a model is installed.

ollama serve
ollama pull llama3.3

Visual Workflows vs. Markdown Workflows

Zubo supports two workflow formats. Choose the one that fits your use case:

FeatureVisual WorkflowsMarkdown Workflows
CreationDashboard drag-and-drop builderJSON/YAML files in ~/.zubo/workspace/workflows/
Step typesTool, Agent, Condition, Message, DelayAgent steps with dependency resolution
TriggersManual, Cron, WebhookManual, Cron
Variables{{trigger.payload}}, {{steps.stepId.result}}{{prev.result}}, named variables
EditingVisual canvas in browserText editor
Best forInteractive building, non-technical users, webhook-driven automationVersion control, CI/CD, complex pipelines

Both formats are stored in the database and can be triggered via the API. Visual workflows are additionally accessible through the dashboard builder. Markdown workflows are documented in Agents & Workflows.

Step Types

Visual workflows are composed of steps. Each step has a type, a unique ID, optional configuration, and connections to other steps.

Tool Step

Execute a built-in tool or MCP tool. Configure the tool name and input parameters. The step result contains the tool's output.

{
  "id": "search-web",
  "type": "tool",
  "tool": "web_search",
  "input": {
    "query": "{{trigger.payload.topic}} latest news"
  }
}

Agent Step

Send a prompt to the agent (or a specific sub-agent) and capture the response. The agent has full access to tools and memory within the step.

{
  "id": "summarize",
  "type": "agent",
  "agent": "default",
  "prompt": "Summarize these search results: {{steps.search-web.result}}"
}

Condition Step

Branch the workflow based on a condition. Evaluates a JavaScript expression and routes to different steps based on the result.

{
  "id": "check-sentiment",
  "type": "condition",
  "expression": "{{steps.analyze.result.sentiment}} === 'negative'",
  "ifTrue": "escalate",
  "ifFalse": "log-result"
}

Message Step

Send a message to a specific channel. Useful for notifications and alerts at any point in the workflow.

{
  "id": "notify",
  "type": "message",
  "channel": "telegram",
  "content": "Workflow complete. Result: {{steps.summarize.result}}"
}

Delay Step

Pause the workflow for a specified duration. Useful for rate limiting, waiting for external processes, or scheduling follow-ups.

{
  "id": "wait",
  "type": "delay",
  "duration": "5m"
}

Duration supports shorthand notation: 30s (seconds), 5m (minutes), 2h (hours), 1d (days).

Trigger Types

Every workflow has a trigger that defines when it runs.

Manual Trigger

Run the workflow on demand via the dashboard or API. You can pass an optional payload that is available as {{trigger.payload}} in all steps.

{
  "trigger": {
    "type": "manual"
  }
}

Cron Trigger

Run the workflow on a schedule using a cron expression. The trigger payload contains the scheduled time.

{
  "trigger": {
    "type": "cron",
    "schedule": "0 9 * * 1-5"
  }
}

Webhook Trigger

Run the workflow when a specific webhook receives an event. The full webhook payload is available as {{trigger.payload}}.

{
  "trigger": {
    "type": "webhook",
    "webhookId": "wh_a1b2c3"
  }
}

Template Variables

Template variables use double-brace syntax and are resolved at execution time. They allow data to flow between steps and from the trigger into the workflow.

VariableDescription
{{trigger.payload}}The full payload from the trigger (webhook body, manual input, or cron metadata).
{{trigger.payload.field}}Access a specific field within the trigger payload using dot notation.
{{steps.stepId.result}}The output of a previously completed step, referenced by its step ID.
{{steps.stepId.status}}The status of a step: "completed", "failed", or "skipped".
{{workflow.name}}The name of the currently running workflow.
{{workflow.runId}}The unique ID of the current workflow execution.
{{env.VARIABLE}}Access an environment variable.

Variable Resolution Example

# Step 1: Fetch data
{
  "id": "fetch",
  "type": "tool",
  "tool": "http_request",
  "input": { "url": "https://api.example.com/data/{{trigger.payload.id}}" }
}

# Step 2: Process with agent (references step 1 result)
{
  "id": "process",
  "type": "agent",
  "prompt": "Analyze this data: {{steps.fetch.result}}"
}

# Step 3: Notify (references step 2 result)
{
  "id": "notify",
  "type": "message",
  "channel": "telegram",
  "content": "Analysis complete: {{steps.process.result}}"
}

Dashboard Builder

The visual workflow builder is accessible from the Workflows panel in the dashboard. It provides an interactive canvas for creating and editing workflows without writing JSON.

API Endpoints

All visual workflow endpoints are under /api/workflows/visual and require authentication when auth.enabled is true.

List Visual Workflows

GET /api/workflows/visual

Returns all visual workflows with their metadata, step count, and trigger type.

Response:

{
  "workflows": [
    {
      "id": "vw_abc123",
      "name": "Daily Report",
      "trigger": { "type": "cron", "schedule": "0 9 * * 1-5" },
      "stepCount": 4,
      "enabled": true,
      "lastRunAt": "2026-02-15T09:00:00Z",
      "lastRunStatus": "completed",
      "createdAt": "2026-02-10T12:00:00Z"
    }
  ]
}

Get Visual Workflow

GET /api/workflows/visual/:id

Returns the full workflow definition, including all steps, connections, and trigger configuration.

Create Visual Workflow

POST /api/workflows/visual
Content-Type: application/json

{
  "name": "Daily Report",
  "trigger": { "type": "cron", "schedule": "0 9 * * 1-5" },
  "steps": [
    {
      "id": "fetch-news",
      "type": "tool",
      "tool": "web_search",
      "input": { "query": "tech news today" }
    },
    {
      "id": "summarize",
      "type": "agent",
      "prompt": "Summarize: {{steps.fetch-news.result}}"
    },
    {
      "id": "send",
      "type": "message",
      "channel": "telegram",
      "content": "{{steps.summarize.result}}"
    }
  ],
  "connections": [
    { "from": "fetch-news", "to": "summarize" },
    { "from": "summarize", "to": "send" }
  ]
}

Create a new visual workflow. Returns the created workflow with its generated id.

Update Visual Workflow

PUT /api/workflows/visual/:id
Content-Type: application/json

{
  "name": "Updated Report",
  "steps": [...],
  "connections": [...]
}

Update a workflow's name, trigger, steps, or connections. All fields are optional — only included fields are updated.

Delete Visual Workflow

DELETE /api/workflows/visual/:id

Delete a workflow and all its execution history. Returns 204 No Content on success.

Run Visual Workflow

POST /api/workflows/visual/:id/run
Content-Type: application/json

{
  "payload": { "topic": "AI research" }
}

Execute a workflow immediately with an optional payload. The payload is available as {{trigger.payload}} in all steps. Returns the run ID for tracking execution.

Response:

{
  "runId": "run_xyz789",
  "status": "started",
  "workflowId": "vw_abc123"
}

Get Workflow Runs

GET /api/workflows/visual/:id/runs?limit=20

Returns the execution history for a workflow.

Response:

{
  "runs": [
    {
      "runId": "run_xyz789",
      "status": "completed",
      "trigger": "manual",
      "startedAt": "2026-02-15T14:00:00Z",
      "completedAt": "2026-02-15T14:00:12Z",
      "durationMs": 12340,
      "steps": [
        { "id": "fetch-news", "status": "completed", "durationMs": 3200 },
        { "id": "summarize", "status": "completed", "durationMs": 8100 },
        { "id": "send", "status": "completed", "durationMs": 420 }
      ]
    }
  ]
}

Toggle Visual Workflow

PUT /api/workflows/visual/:id/toggle
Content-Type: application/json

{
  "enabled": false
}

Enable or disable a workflow. Disabled workflows do not execute on their cron or webhook triggers but can still be run manually via the API.