Orchestrate a Workflow
Build a runnable, typed flow from the start node to the output node
The workflow editor uses a React Flow canvas. The node panel on the left adds nodes, the central canvas connects the flow, and the drawer on the right configures the selected node. Workflows support manual triggers, webhook triggers, and cron scheduling (requires additional deployment of a scheduler task).
Workflow Builder Interface
Layout
The workflow editor consists of the following parts:
- Nodes Panel (Left): Available node types, organized by category
- Model: LLM, Media Generation
- Logic: Condition, Question Classifier, Decision, Iteration, Loop, Pause
- Transform: Code, Template, File to URL, Variable Aggregator, Variable Assignment, Parameter Extractor
- Extension: Sub-workflow, Agent, Tool, Knowledge Retrieval, Answer
- Canvas (Center): Workflow design area; add, connect, and arrange nodes
- Properties Panel (Right): Node configuration, settings, and variables
- Toolbar (Top): Save workflow, test (debug) workflow, zoom controls
Building a Workflow — Step by Step
- Add a Start Node: Every workflow begins with a start node (user input or trigger), which defines the input parameters
- Add Processing Nodes: Add nodes to process data; see Node Types below
- Connect Nodes: Click the output port of the source node, drag to the input port of the target node
- Configure Nodes: Configure each node's settings in the properties panel
- Add an Answer Node: Use the Answer node to define the final output returned by the workflow; it is the builder's output node, not a separate runtime terminal named
end - Test the Workflow: Click the Test (debug) button, enter test inputs, run, and review results
- Save and Publish: Click Save to store as a draft; click Publish to activate the workflow
Variables and Data Flow
Variable Scope:
- Input Variables: Defined at the start node, collected from the user or trigger
- Node Variables: Outputs from nodes, referenced in subsequent nodes
- System Variables:
{{workflow.id}}— Workflow ID{{workflow.name}}— Workflow name{{run.id}}— Current run ID
Variable Usage:
- In prompts:
Analyze this inquiry from {{customer_email}}: {{inquiry_text}} - In conditions:
{{analysis.urgency}} == "high"
Error Handling
There is no try-catch / retry UI in the builder. What happens after a node failure depends on the executor and workflow structure; the error is recorded on the run/node execution for inspection. The HTTP request executor retries up to 3 times by default, but the builder has no separate retry setting.
Workflow Templates
Built-in workflow templates:
- Simple Q&A Bot: A basic question-answering bot using an LLM
- RAG Knowledge Bot: Knowledge-base-powered Q&A with retrieval augmentation
- Intent Router: Route conversations based on detected intent
- Code Review Assistant: Automated code review with multiple perspectives
Templates are instantiated into new workflows. After instantiation, review and configure model, knowledge-base, and other node references in the editor; do not assume that template variable names are fixed API field names.
Keyboard Shortcuts
Space + Drag: Pan canvasCtrl/Cmd + Scroll: ZoomCtrl/Cmd + 0: Reset zoom
Creating and Saving Drafts
- Navigate to Apps > Create App > Workflow.
- In Workflow Settings, fill in the name, description, visibility, and owning team.
- Choose a start node: User Input suits interactive forms; Trigger suits API or Webhook calls.
- Drag nodes from the node panel onto the canvas, or click Add Node.
- Drag from a source handle to a target handle to create a connection. The start node cannot be deleted.
- Select Save. The editor records the last saved time and unsaved state.
Defining Variables
Start nodes use workflow-level variables. Variable types include text, paragraph, dropdown options, number, boolean, array, object, file, image, multi-file, and multi-image. Each variable can set required, default value, label, and description.
Use the editor selector when referencing variables; do not hand-write names that do not exist. The current definition format schema_version: 2 supports native object and array passing.
Node Types
The editor provides the following node types, organized by category:
The palette organizes nodes into four categories; the tables below use the same grouping. Type identifiers are what you write in API definitions, so use the exact values from the tables.
Model Nodes
| Node | Type Identifier | Purpose |
|---|---|---|
| LLM | llm | Call a language model for text generation and analysis |
| Media Generation | media_generation | Generate media with a compatible model |
Logic Nodes
| Node | Type Identifier | Purpose |
|---|---|---|
| User Input | user_input | Entry point for manually executed workflows (chosen when creating the workflow, not from the add-node menu) |
| Trigger | trigger | Entry point for triggered workflows (same) |
| Condition | condition | Branch based on expression result |
| Question Classifier | question_classifier | Classify input text with a chat model |
| Decision | decision | Ask a decision model one typed question (choice/score/noul) about a state and take the branch it returns |
| Iteration | iteration | Iterate a list, running the container's child nodes once per item |
| Loop | loop | Repeat a branch until a condition is met |
| Pause | pause | Wait for approval or variable input |
Transform Nodes
| Node | Type Identifier | Purpose |
|---|---|---|
| Code | code | Execute Python or JavaScript custom code |
| Template | template | Render a template string |
| File to URL | file_to_url | Convert a file asset to an accessible URL |
| Variable Aggregator | variable_aggregator | Combine multiple variable values |
| Variable Assignment | variable_assignment | Assign a value to a variable |
| Parameter Extractor | parameter_extractor | Extract structured parameters from text |
Extension Nodes
| Node | Type Identifier | Purpose |
|---|---|---|
| Sub-workflow | sub_workflow | Invoke another published workflow |
| Agent | agent | Invoke a published Agent |
| Tool | tool | Execute a configured tool |
| Knowledge Retrieval | knowledge_retrieval | Retrieve content from a knowledge base |
| Answer | answer | Define the workflow's final output |
Iteration, Loop, and Pause cannot be nested inside another container: opening the add-node menu inside an Iteration or Loop leaves only Condition, Question Classifier, and Decision in the Logic category, plus iteration_exit / loop_exit as the container's own end marker. Those two markers have no standalone executor — they only delimit the container, so do not connect them as independent nodes.
http_request and document_extractor have registered executors in the engine but no node component in the builder — they can only appear in definitions submitted through the API.
Not implemented: Transform, Parallel, Wait, Switch, Database, Email, Webhook (as a node), Log, Delay, Merge, Input, and Output node types. Variable handling is done via variable_assignment and variable_aggregator.
Configuring Nodes
Configure node parameters by task:
LLM Node
- Model: Select a configured model (e.g., GPT-4 Turbo, Claude, etc.)
- Prompt: Use
{{variable}}syntax to reference upstream variables - Temperature: Commonly configured as
0-2; the available range depends on the selected model. Controls output randomness - Max Tokens: Limit the length of model output
- Top P: Commonly configured as
0-1; the available range depends on the selected model. Nucleus sampling parameter - Output Variable: Define the variable name to store model output
Output variables: response, reasoning, usage (plus the configured output variable).
Media Generation Node
- Provider: image | video
- Prompt:
{{prompt}} - Width/Height: (image)
- Duration/Aspect Ratio: (video)
Condition Node
- Condition Expression: Use Jinja2 syntax, e.g.,
{{analysis_result.urgency}} == "high" - True Branch: Downstream node connected when condition is true
- False Branch: Downstream node connected when condition is false
Question Classifier Node
Classify the user's input into one of several intents/categories and route accordingly. It puts the categories in a prompt for a chat model to answer as JSON, then parses category out of the text; use the Decision node below when you need probabilities, confidence, or a guarantee that the answer will not come back in the wrong shape.
Decision Node
A Decision node asks a decision model (non-generative) one typed question about a state and takes the branch that matches the answer. The model produces no prose — it returns a probability distribution plus a confidence, so the route never depends on parsing generated text and cannot drift because the model added an extra sentence.
Connect a decision model first: an administrator adds TypeSafe AI under Integrations > Model Providers (provider is fixed to typesafe, default endpoint https://api.typesafe.ai/v1) and authorizes that model for the team with type Decision. The Decision Model dropdown lists only the current team's enabled models of type decision; with none available it shows "No available models".
| Setting | UI Label | Type | Default | Notes |
|---|---|---|---|---|
modelId | Decision model | string | none (required) | An enabled decision model for the team; the checklist reports "Model not selected" when empty |
stateTemplate | State | template string | none (required) | What the model evaluates; supports {{variables}}. It is rendered to a string, so assemble objects or arrays into text with a Template or Variable Assignment node first |
questionType | Question type | choice | score | noul | choice | Determines branch handles and outputs, see below |
instructions | Instructions | string | none (required) | One sentence saying what to decide, e.g. "Decide whether this refund request should be approved automatically" |
options | Choice options / Ordered score levels | string array | ["yes", "no"] | choice needs 1–255 unique options; score needs 2–10 ordered levels; empty or duplicate entries are rejected by the checklist |
defaultHandle | Fallback branch | string | default | Taken when confidence is below the threshold, or when no branch handle resolved |
confidenceThreshold | Confidence threshold | number 0–1 | unset (disabled) | Shown for choice/score only; a returned confidence strictly below it routes to the fallback branch |
The question type determines branch handles and outputs:
| Question type | UI Label | Branch handles | Confidence | Use when |
|---|---|---|---|---|
choice | Choose an option | one handle per option, plus the fallback branch | yes | Picking one of several mutually exclusive dispositions (refund / technical / billing / other) |
score | Score against ordered levels | one handle per level, plus the fallback branch | yes | The levels are inherently ordered (low / medium / high, P0–P3) and you also want a numeric score |
noul | Yes / No probability | fixed yes and no, plus the fallback branch | no | A single binary call: probability ≥ 0.5 routes yes, otherwise no; no confidence is returned, so the threshold does not apply |
Branch handles and renaming
- Each option (choice) or level (score) is an output handle on the canvas, named after that option or level; the fallback handle is named by
defaultHandle(defaultby default). - Editing option text remaps existing connections by position as long as the number of options is unchanged. If the count changed, the leftover connections point at an outdated output handle and the checklist reports
decisionBranchHandleInvalid— reconnect them to a current handle. - You do not have to connect every branch, but any branch you do connect needs downstream nodes. A low-confidence answer is rerouted to the fallback branch, so if the fallback has no downstream nodes the flow ends at this node.
Fallback branch and confidence threshold
- The threshold only fires when confidence is strictly below it; a confidence exactly equal to the threshold still takes the model's branch.
- The threshold affects routing only, not outputs:
answeris always the option/level the model picked, whileselected_handleis the branch actually taken. - Without a threshold, only "no branch handle resolved" uses the fallback.
noulnever uses the fallback because it always answers yes or no. - A decision node is retried up to 2 times by default (1 second initial delay, exponential backoff with jitter). Retries are independent of the threshold, which exists for answers that came back uncertain.
Output variables
| Output | Type | Meaning |
|---|---|---|
answer | string | The selected option/level, or yes/no |
selected_handle | string | The branch handle actually taken (the fallback handle when the threshold rerouted it) |
usage | object | Token usage for this decision call |
choice / score / noul | type-specific | choice adds choice, confidence, probabilities; score adds score, confidence, probabilities; noul adds noul (the probability of yes) |
Downstream nodes can record the verdict with {{decisionNodeId.answer}}, or branch again on {{decisionNodeId.confidence}} / {{decisionNodeId.probabilities}} to add a human review layer.
Failure paths
| Error | Trigger |
|---|---|
validation_error | No model, no state, or no instructions; question type is not choice/score/noul; option count out of range, empty, or duplicated |
decision_result_missing | The model's answer type, option set, or probability set does not match the node configuration (for example it returned an option you did not configure) |
| Provider/model errors | The decision model is not authorized for the team, the model or authorization is disabled, the endpoint is blocked by the model-endpoint allowlist, the request times out (default 60 seconds), or auth/quota errors |
Worked example: ticket triage
ticket_text (paragraph) and customer_tier (dropdown: free/pro/enterprise) to the start node.
{{start.ticket_text}}; set Question type to Choose an option; write "Decide which queue this ticket belongs to" as Instructions; set Choice options to refund, technical, billing, other.
manual_review and Confidence threshold to 0.6 — tickets the model is less than 0.6 sure about stop being auto-routed and go to a person.
refund to a refund-approval sub-workflow, technical to a technical-support LLM node, billing to a billing template node, and manual_review to a Pause node (approval mode) for human handling. Leaving other unconnected ends the flow there.
manual_review; inspect the node's answer, confidence, and probabilities in the run trace to decide whether 0.6 should move up or down.
Debugging a decision branch
- The checklist reports each problem separately: model not selected, state empty, instructions empty, too few or too many options/levels, empty or duplicate options, and connections using an outdated handle.
- In the run trace, read
selected_handle(which branch ran) andconfidence(whether the threshold rerouted it). If it always falls to the fallback, checkprobabilities: two near-equal options mean adjusting the threshold, while a flat distribution means the instructions or state need rewriting. - A decision node is one call with one result and no intermediate steps: you can only debug it by running the whole workflow — there are no breakpoints or single-step execution.
Iteration / Loop Node
- Collection:
{{items}} - Item Variable: item
- Output Variable: results
Pause Node
Pause execution until a team member supplies requested variables or submits an approval decision. A pause can be configured in Variables mode or Approval mode; a waiting run resumes after the request is handled.
- Mode: variables | approval
- Title: Review request
- Input Variables: List of variables to collect or approve
Code Node
- Language: Python or JavaScript
- Code: Custom execution logic
- Timeout: The code executor currently fixes this at
30seconds; it is not a freely configurable1-300second range in the builder - Input Variables: Variables passed to the code
- Output Variables: Variables returned by the code execution
Template Node
Render a template string with variables (e.g., Jinja-like {{variable}} substitution).
File to URL Node
Convert a file (e.g., a sandbox artifact) into a downloadable URL.
Variable Assignment Node
Assign a value to a variable.
Variable Aggregator Node
Aggregate values (e.g., collect loop iteration results into an array).
Parameter Extractor Node
Extract structured parameters from text using LLM, regex, or JSON path.
- Extraction Method: llm | regex | json_path
- Source Variable:
{{source}} - Parameters: [...]
HTTP Request Node
- Method: GET / POST / PUT / PATCH / DELETE
- URL: Target endpoint address
- Headers: Custom HTTP headers
- Body: JSON-formatted request payload
- Timeout: Default
30seconds; no verified1-300second code-execution timeout range is exposed - Output Variable: Store the response data
The HTTP request executor retries up to 3 times by default; the builder has no separate retry setting.
Tool Node
- Tool: Select a configured tool
- Parameter Mapping: Map upstream variables to tool parameters
- Output Variable: Store the tool execution result
Built-in tools available: web_search, fetch_webpage, calculate, unit_convert, get_weather, get_current_time, format_datetime, markitdown, plus sandbox tools (bash, read, edit, write, artifact).
Knowledge Retrieval Node
- Knowledge Base: Select the target knowledge base
- Query Template: Use
{{variable}}to reference query content - Top K: Default
5; the exact upper bound depends on the endpoint and configuration, so this guide does not present a fixed1-100range - Score Threshold: Default
0.0. Minimum similarity score - Search Mode: hybrid
Sub-workflow Node
Run another workflow as a sub-step and capture its output.
Agent Node
Invoke an AI agent with a message and optional context.
Answer Node
Return a final answer/output from the workflow.
When configuring nodes, ensure all input variables have a clear source (upstream node output or start node variable). The pre-publish checklist reports unconnected inputs as issues; resolve them before debugging and publishing.
Trigger Configuration
Workflows support three trigger types:
Manual Trigger
No additional configuration required. Once published, users with permissions can trigger the workflow via the UI or API.
Webhook Trigger
After setting the trigger type to Webhook, the system automatically generates a webhook token. The trigger endpoint is:
POST /api/v1/workflows/webhook/{webhook_token}Request requirements:
- Authentication: Provide a valid
clou_API key in theAuthorizationheader - Body: Workflow input variables (raw JSON or
{"inputs": {...}}format) - Webhook token: Matched using constant-time comparison to prevent timing attacks
Not implemented / Roadmap: wh_.../whsec_... credential pairs, IP allowlists, per-webhook rate limits, retry policies, and webhook request logs are currently unavailable.
Cron Trigger
After setting the trigger type to Cron, the schedule expression is stored in trigger_config (e.g., 0 9 * * 1-5 for weekdays at 9 AM). The UI's frequency presets are converted into the same expression; custom mode takes minute hour day month weekday directly.
Saving a Cron trigger does not make a workflow run on its own: the workflow.check_scheduled task implements the cron evaluation logic, but it is neither in the shipped Celery Beat schedule (backend/app/core/celery.py) nor in the Celery app's include module list, so no supplied deployment ever schedules it. To enable scheduled triggers, an operator must do all three of these in a custom deployment:
- Register the task — add
app.services.workflow.tasksto thecelery_appincludelist, or import the module when the worker starts. - Add it to the Beat schedule, once a minute is the intended cadence, e.g.
{"workflow-check-scheduled": {"task": "workflow.check_scheduled", "schedule": crontab(minute="*")}}. - Align the key name: the scheduling task reads
trigger_config["cron"], while the Workflow Settings schedule form writestrigger_config["cron_expression"]. An expression saved through the UI has to be renamed tocronto match, or write the expression under thecronkey through the API directly.
The task only selects published workflows with trigger_type=cron, uses croniter to test whether the current minute matches the expression, and fires a run with empty inputs {} attributed to the workflow creator. No route pattern matches it, so it lands on the default queue unless you set options.queue on the Beat entry.
Draft and Publication
Workflows have three statuses:
Draft
- Workflow is being edited
- Cannot be triggered
- Visible only to editors
- Can be saved at any time
Published
- Workflow is operational
- Can be triggered via UI, API, or webhook
- Visible to all users with permissions
- Must be unpublished before modification
Archived
- Workflow is retired
- Not visible in normal lists
- Configuration preserved
There is no active/inactive status. Archiving is a model-level status (archived) applied via updates; publish/unpublish are the admin lifecycle actions.
Pre-publish Checks
Select Checklist and resolve the following issues before debugging and publishing:
| Check Item | Description |
|---|---|
| Unselected Model | LLM node has no model configured |
| Input Variable Without Source | Node input is not connected to an upstream variable |
| Node Without Input | Required node lacks input connection |
| Output Undefined | Answer node has no output variable configured |
| Incomplete Condition Branch | Condition node missing True or False branch |
| Incomplete Decision Configuration | Decision node has no model, an empty state or instructions, or an invalid number/uniqueness of options or levels |
| Outdated Decision Branch Handle | A Decision node connection points at an option/level handle that no longer exists and must be reconnected |
| Missing Required Tool Parameter | Tool node lacks required parameter mapping |
| Incomplete Loop Container | Loop node not properly configured |
After validation passes, use Debug Run to test the workflow, confirm the output matches expectations, then publish.
Running a Workflow
Accessing Workflows
- Navigate to Apps (
/app/apps). - Open the Workflow tab.
- Select a workflow card to open
/app/apps/workflow/{id}. - Choose Run to start a manual execution.
Workflow List
The list shows:
| Column | Description |
|---|---|
| Name | Workflow name |
| Team | Team that owns the workflow |
| Status | Draft or Published |
| Last Run | Last execution time; a run may be waiting at a pause node |
| Actions | Run, View, Edit |
Manual Execution
Steps:
- Open the workflow
- Click the Run button
- If the workflow has input variables:
- Fill in required inputs
- Review optional inputs
- Click Start
- Watch the execution in real-time
- View the results when complete
Input Variables
Workflows may require inputs:
- Text: Free-form text input
- Number: Numeric values
- Select: Dropdown options
- Boolean: Yes/No checkbox
Watching Execution
Real-time progress:
- ⏸️ Pending: Not started yet
- ⏳ Running: Currently executing
- ⏳ Waiting: Paused for an external input or approval
- ✅ Success: Completed successfully
- ❌ Failed: Execution failed
- ⏭️ Skipped: Skipped (conditional)
Execution Details: Click on a node to see details including status, duration, input, and output.
Streaming Output: LLM nodes stream their output in real-time; the execution view shows partial content while running.
Execution Results
Success: Shows execution duration, nodes executed, and status.
Failed: Shows the failed node and error message.
Common Errors:
- Invalid input format
- API call failed
- Timeout exceeded
- Resource not found
- Permission denied
Stopping Execution
During execution:
- Click the Stop Execution button
- Confirm the stop action
- The workflow stops at the current node
Workflow Variables
Input Variables: Provided when starting the workflow.
Output Variables: Generated during execution by the Answer node and other node outputs.
Viewing Execution History
Execution History
- Select a workflow
- Click the Execution History tab
- View the run list:
- Run ID
- Status (
running,success,failed, etc.) - Start time
- Duration
- Trigger source
- Input/Output
Related API endpoints:
GET /api/v1/workflows/runs- Get all run recordsGET /api/v1/workflows/{workflow_id}/runs- Get runs for a specific workflowGET /api/v1/workflows/{workflow_id}/runs/mine- Get current user's runs
Execution Details
Click an individual run to view detailed information:
- Run Information: Run ID, workflow name, status, start time, completion time, duration, trigger method
- Node Execution Timeline: Start time, completion time, and duration for each node
- Node-level Details:
GET /runs/{run_id}/nodesfor per-node execution details - Streamed Events:
GET /runs/{run_id}/streamfor real-time node execution events
Workflow Logs
Workflow execution history is available from the workflow's Logs view at /app/apps/workflow/{id}/logs. Open Apps → Workflow, select the workflow, then choose Logs from its workflow menu.
Run Details Fields:
| Field | Description |
|---|---|
| Status | The Logs UI displays Completed (API success), Failed, Running, Pending, Cancelled, or Timeout. Raw API waiting runs currently fall back to the Pending badge in both the list and run-detail drawer; Cancelled and Timeout have dedicated badges but no filter controls. |
| Started | Execution start time |
| Duration | Total execution time |
| Triggered By | User or Webhook |
| Input | Input variables provided |
| Output | Execution results |
| Nodes Executed | Number of nodes run |
| Error | Error message (if failed) |
Status Icons:
| Badge | Logs Label | API Status | Description |
|---|---|---|---|
| ✅ | Completed | success | Successfully finished |
| ❌ | Failed | failed | Execution failed |
| ⏳ | Running | running | Currently executing |
| ⏳ | Pending | pending | Queued before execution |
| ⏳ | Pending | waiting | This raw status currently has no dedicated Logs badge or filter and falls back to Pending. |
| ⏹️ | Cancelled | cancelled | Stopped or cancelled; no dedicated filter control is currently available. |
| ⏱️ | Timeout | timeout | Exceeded the execution timeout; no dedicated filter control is currently available. |
Viewing Node Execution Details
View the node-by-node execution:
- Open the run's node executions
- Each node shows its status, duration, input, output, and error (if any)
Streaming
Runs stream events in real-time (GET /api/v1/workflows/runs/{run_id}/stream), including node status updates and LLM token output.
Filtering History
| Filter | Options |
|---|---|
| Status | All Status, Completed, Failed, Running, Pending |
| Date Range | All Time, Last 7 Days, Last 30 Days, Last 90 Days |
| Run ID | Exact run UUID |
Execution Statistics
Summary metrics (per workflow or system-wide):
- Total Runs
- Success Rate
- Failed Runs
- Avg Duration
Deleting History
Delete Single Execution:
- Find the execution in the history
- Click the "..." menu
- Select "Delete"
- Confirm deletion
- The execution is removed
Deleted executions cannot be recovered. Bulk deletion is not implemented, and there is no automatic retention/cleanup policy setting.
Not implemented / Roadmap: Real-time execution dashboard (running/queued executions, success rate, average execution time, cost) is currently unavailable. Run statistics are available via GET /api/v1/workflows/runs/stats (team-filterable) and GET /api/v1/workflows/{workflow_id}/stats (+ /stats/trends).
Webhook Management
Creating or Regenerating a Webhook Token
- Edit the workflow
- Set trigger type to Webhook
- Save — a
webhook_tokenis generated automatically - Regenerate anytime via
POST /api/v1/workflows/{workflow_id}/regenerate-webhook-token
Testing a Webhook
Use curl to test the webhook:
curl -X POST "https://your-domain.com/api/v1/workflows/webhook/TOKEN" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"customer_email": "test@example.com",
"inquiry_text": "Test inquiry",
"priority": "low"
}'Webhook Logs
Not implemented / Roadmap: There is no separate webhook request log view. Triggered runs appear in the workflow run history (GET /api/v1/workflows/runs).
API Endpoints
The Workflow API supports programmatic management of the workflow lifecycle:
| Operation | Endpoint | Description |
|---|---|---|
| List Workflows | GET /api/v1/workflows | Get workflow list |
| Create Workflow | POST /api/v1/workflows | Create a new workflow |
| Get Workflow | GET /api/v1/workflows/{id} | Get workflow details |
| Update Workflow | PUT /api/v1/workflows/{id} | Update workflow configuration |
| Delete Workflow | DELETE /api/v1/workflows/{id} | Delete a workflow |
| Publish Workflow | POST /api/v1/workflows/{id}/publish | Publish a workflow |
| Unpublish | POST /api/v1/workflows/{id}/unpublish | Unpublish a workflow |
| Run Workflow | POST /api/v1/workflows/{id}/run | Trigger workflow execution |
| List Runs | GET /api/v1/workflows/runs | Get run history |
| Get Run Details | GET /api/v1/workflows/runs/{run_id} | Get single run details |
| Node Execution Details | GET /api/v1/workflows/runs/{run_id}/nodes | Get per-node execution info |
| Streamed Events | GET /api/v1/workflows/runs/{run_id}/stream | Real-time node event stream |
| Run Statistics | GET /api/v1/workflows/runs/stats | Team-level run statistics |
| Workflow Statistics | GET /api/v1/workflows/{id}/stats | Single workflow statistics |
| Trend Statistics | GET /api/v1/workflows/{id}/stats/trends | Execution trend data |
| Regenerate Token | POST /api/v1/workflows/{id}/regenerate-webhook-token | Regenerate webhook token |
Admin endpoints are under /api/v1/admin/workflows and require admin:app:* permissions. Administrators can manage all workflows across teams.
Troubleshooting
Workflow Execution Failed
- Open the failed run in Execution History
- Check node execution details and error messages
- Common errors:
- Node Timeout: Increase timeout or optimize the node
- Invalid Input: Validate input variable format
- API Error: Check API credentials and connectivity
- LLM Error: Verify model availability and API key
- Tool Error: Check tool configuration
- Re-trigger using
POST /api/v1/workflows/{workflow_id}/run
Webhook Not Triggering
- Confirm the workflow trigger type is
webhook - Confirm POST to the correct
/api/v1/workflows/webhook/{webhook_token}endpoint - Confirm the
Authorizationheader contains a validclou_API key - Confirm the workflow is published (unpublished workflows reject webhook triggers)
Schedule Not Running
- Confirm the workflow is
publishedandtrigger_typeiscron - Confirm
trigger_configholds a valid cron expression (the scheduling task reads thecronkey) - Confirm the custom deployment added
app.services.workflow.tasksto the Celeryincludelist and dispatchesworkflow.check_scheduledfrom Beat (once a minute, for example) - Confirm the worker running that task consumes the queue it actually lands on (
default)
High Execution Time
- Optimize nodes: Reduce LLM
max_tokens, use faster models, optimize tool calls - Shorten the serial chain: the plan is layered by topology, but nodes inside a layer still run one after another and the canvas has no parallel node; fold repeated work into an Iteration node and shrink its input instead
- Add timeouts: Set reasonable node timeouts and handle gracefully
- Monitor performance: Review run duration statistics in run history
Workflow Won't Start
- Check if the workflow is published
- Verify you have permission to run
- Ensure all required inputs are provided
- Refresh the page and try again
Execution Stuck
- Check if a node is waiting for an external response
- Verify API endpoints are accessible
- Stop and restart the execution
- Contact the administrator
Cannot View History
- Refresh the page
- Check if you have permission
- Verify the workflow has been executed
- Check the date-range filter
- Contact the administrator
Missing Executions
- Check filters (may be hiding results)
- Verify the date range
- Check if executions were deleted
Cannot Start a New Run
- Check that you have permission to run the workflow
- Verify the workflow is published
- Start a new execution from the workflow page
Best Practices
Workflow Design
- Keep workflows simple and focused; avoid excessive complexity
- Use descriptive node names, include an action verb, be specific
- Add error handling logic
- Test thoroughly before activation
- Document workflow purpose
- Use variables for reusability; avoid hardcoding values
- Add logging for debugging
- Set appropriate timeouts
Performance Optimization
- Reduce serial steps: there is no parallel node, and independent nodes in the same layer still run one after another; merging nodes beats splitting them and hoping they overlap
- Keep iteration size down: an Iteration node that exceeds its cap truncates its input, so filter out items you do not need first
- Cache repeated operations
- Optimize LLM prompts
- Use appropriate models for the task
- Set reasonable timeouts
- Monitor execution times
- Optimize tool calls
Inputs and Monitoring
Inputs:
- Provide all required inputs
- Use correct data types
- Test with sample data first
Monitoring:
- Watch the execution progress
- Check node outputs
- Stop if behavior is unexpected
Error Handling:
- Read error messages carefully
- Check input values
- Review node configuration
- Try again with corrected inputs
Security
- Use webhook authentication (API key in Authorization header)
- Regenerate webhook tokens when compromised
- Enable audit logging
- Monitor for suspicious activity
Not implemented / Roadmap: Webhook IP allowlists and rate limits are currently unavailable.
Exiting and Lost Changes
Before returning to the app list or closing the page, the editor shows a confirmation dialog when there are unsaved changes. Select Leave Without Saving to discard the current draft changes.
How is this guide?