Neuroship Cloud Documentation
Neuroship is a workflow orchestration platform for building multi-step AI agent pipelines. You define workflows in YAML, and the platform handles parallel execution, human-in-the-loop approvals, and real-time streaming — all through a visual interface.
Core Concepts
Workflows
A workflow is a YAML file that describes a pipeline of steps (nodes) connected in a directed acyclic graph (DAG). Each workflow has exactly one input node that collects user data, and one or more processing nodes that do work — calling LLMs, running functions, or making HTTP requests.
Nodes
Nodes are the building blocks of a workflow. Each node has a type that determines what it does:
- Input — collects user data through form fields
- Agent — calls a language model (GPT-4o, Claude, Gemini, etc.)
- Function — runs a registered Python handler
- Webhook — makes an HTTP request to an external service
- Ref — runs another workflow as a sub-workflow
Dependencies & Parallel Execution
The deps section in your YAML defines which nodes depend on which. When multiple nodes have their dependencies satisfied at the same time, they run in parallel automatically. No extra configuration needed.
Runners
Runners are the execution engines. They are separate services (available as Docker images) that pull jobs and execute your workflows. The platform never runs workflows itself — it delegates to runners. You can run multiple runners for load distribution.
Providers
Providers are LLM API configurations (API keys, base URLs) stored on runners. When a workflow calls an LLM, the runner resolves the API key from: inline YAML → runner provider config → environment variables.
How It Works
- Create a workflow — write YAML in the editor or use the AI Planner to generate one
- Run it — fill in the input form and click Run. The platform sends the job to an available runner.
- Watch it execute — nodes light up in real-time on the DAG view as they run. You see logs, outputs, and cost telemetry live.
- Approve when needed — if a node has an approval gate, execution pauses and you review the inputs or outputs before continuing.
- Get results — when all nodes complete, the workflow outputs are available for review. The full execution history is saved.
Workflow Structure
Every workflow is a YAML file with these top-level keys:
version: 1 # Spec version (default: 1) name: My Workflow # Workflow name (required) description: string # Optional description models: # LLM configurations (required for agent nodes) default: provider: openai model: gpt-4o deps: # Dependency graph — who waits for whom analysis: [start] report: [analysis] nodes: # Node definitions start: type: input ... analysis: type: agent ... outputs: # Optional: workflow-level output contract result: report.final_report
Node Types
Input Node
The entry point of every workflow. Defines the form fields shown to the user when they run it. Exactly one input node is required.
start: type: input description: Collect project details fields: project_description: type: textarea label: Project Description required: true placeholder: Describe the project... priority: type: dropdown label: Priority options: [low, medium, high] default: medium output: user_input # Downstream nodes reference as start.user_input
Agent Node
Calls a language model. You provide a system prompt (instruction), map inputs from upstream nodes, and capture the response.
analysis: type: agent model: default # References the models section description: Analyze the proposal instruction: | Analyze the feasibility of the proposed project. Consider technical complexity and timeline. input: proposal: start.user_input # Map upstream outputs to local names output: analysis_result # Single output (full response)
For structured responses, use multi-output with JSONPath extraction:
output: summary: "$.summary" # Extract from JSON response score: "$.score" # The LLM is automatically instructed to return JSON # Referenced as: analysis.summary, analysis.score
Function Node
Runs a registered Python handler. Useful for data transformation, report compilation, or any custom logic.
report: type: function handler: compile_report # Built-in handler description: Generate final report input: research: research.findings analysis: analysis.result output: final_report template: | # Optional markdown template # Report ## Research {{research}} ## Analysis {{analysis}}
Built-in handlers:
| Handler | Description |
|---|---|
save_input | Returns the user's input as-is |
compile_report | Merges all inputs into a markdown report. Supports template with {{key}} placeholders. |
Webhook Node
Makes an HTTP request to an external service. Use {{key}} placeholders in the payload and headers.
notify: type: webhook url: https://api.example.com/notify method: POST headers: Content-Type: application/json Authorization: Bearer {{token}} payload: '{"message": "{{summary}}"}' input: summary: analysis.result token: start.api_key output: response
Ref Node (Sub-workflow)
Runs another workflow as a sub-workflow. The referenced workflow must define explicit outputs. Inner events are namespaced and streamed in the parent execution.
sub_analysis: type: ref config_id: my-analysis-workflow # Slug or ID of another workflow description: Run the analysis sub-workflow input: prompt: start.user_input output: result
Input Field Types
Fields on the input node determine the form shown to users when running a workflow.
| Type | Widget | Notes |
|---|---|---|
text | Text input | Single-line text |
textarea | Textarea | Multi-line text |
number | Number input | Numeric value |
boolean | Checkbox | True/false toggle |
date | Date picker | YYYY-MM-DD |
time | Time picker | HH:MM |
datetime | Datetime picker | Date + time |
file | File upload | File content as text |
dropdown | Dropdown select | Requires options list |
radio | Radio buttons | Requires options list |
Each field supports: label, required, placeholder, default, and options (for dropdown/radio).
Data Flow & References
Nodes pass data to each other using the node_name.key reference format.
How It Works
- Each node produces outputs defined by its
outputfield - Downstream nodes reference those outputs as
node_name.output_key - The
inputmap on each node assigns local names to upstream references
start: type: input output: user_input # Produces: start.user_input analysis: type: agent input: context: start.user_input # Reads from start node output: result # Produces: analysis.result review: type: agent input: analysis: analysis.result # Reads from analysis node original: start.user_input # Can reference any upstream node output: review_result
Inherited Input
By default, all non-input nodes automatically receive the start node's output as user_input. Set inherit_input: false on a node to disable this.
Parallel Execution
The deps section declares which nodes must finish before others can start. Nodes whose dependencies are all satisfied run simultaneously.
deps: research: [start] analysis: [start] # research + analysis run in parallel review: [research, analysis] # review waits for both report: [review]
Rules
B: [A]means B waits for A to complete- The start node is always the root — don't list it in deps
- Nodes not in deps depend on the start node implicitly
- Cycles are not allowed (validated automatically)
Approval Gates
Add human review to any node. Execution pauses until the approver decides to continue or reject.
| When | What Happens |
|---|---|
before | Pauses before the node runs. Approver reviews the inputs. |
after | Pauses after the node runs. Approver reviews the output. |
analysis: type: agent instruction: Analyze the project proposal output: result approval: when: after message: "Review the analysis before it goes to the report"
- Approve — workflow continues to downstream nodes
- Reject — node marked as rejected, all downstream nodes are skipped. An optional rejection reason can be provided.
Model Configuration
The models section defines which LLMs your agent nodes can use. All calls are routed through an OpenAI-compatible client, so any provider with a compatible API works.
models: default: provider: openai model: gpt-4o claude: provider: anthropic model: claude-sonnet-4-0 local: provider: openai # Use OpenAI-compatible API model: llama3 base_url: http://localhost:11434/v1
| Field | Required | Description |
|---|---|---|
provider | Yes | openai, anthropic, google, groq, together, etc. |
model | Yes | Model name: gpt-4o, claude-sonnet-4-0, gemini-2.0-flash |
api_key | No | Inline API key (overrides provider config and env vars) |
base_url | No | Custom endpoint for self-hosted or compatible providers |
Agent nodes reference models by name: model: default. If omitted, the model named default is used.
Template Syntax
Use {{key}} placeholders in function templates and webhook payloads/headers. Each placeholder is replaced with the matching value from the node's input map.
report: type: function handler: compile_report input: research: research.findings analysis: analysis.result template: | # Final Report ## Research {{research}} <-- replaced with research.findings value ## Analysis {{analysis}} <-- replaced with analysis.result value
Unmatched placeholders are left as-is in the output.
Multi-Output (JSONPath)
When you need structured output from an agent, use a dict-style output with JSONPath expressions. The LLM is automatically instructed to respond in JSON.
| Expression | Extracts | Example |
|---|---|---|
$.key | Top-level property | $.summary |
$.key.subkey | Nested property | $.data.result |
$.array.N | Array element (zero-based) | $.items.0 |
$.array.N.key | Property of array element | $.results.0.name |
scoring: type: agent instruction: Rate the proposal on technical and business feasibility output: summary: "$.summary" tech_score: "$.scores.technical" biz_score: "$.scores.business" # Referenced as: scoring.summary, scoring.tech_score, scoring.biz_score
Workflow Outputs
The optional outputs section defines what the workflow produces as its final result. This is especially important for workflows used as sub-workflows via ref nodes.
outputs: report: report_node.final_report score: scoring.score
- Resolved after all nodes complete successfully
- Defines a stable interface for sub-workflow composition
- Referenced workflows must have outputs defined to be used as ref nodes
Runners
Runners are the execution engines that actually run your workflows. They are separate services that connect to the platform via NATS messaging. The platform itself never executes workflows — it always delegates to a runner.
neuroship/runner. Pull it and configure with environment variables to get started.
Setting Up a Runner
- Register — In the UI, go to the Runners panel and click "Register Runner". This generates a unique runner ID.
- Configure — Set the runner ID and connection details as environment variables:
docker run -d \ -e RUNNER_ID=your-runner-id \ -e RUNNER_NAME="My Runner" \ -e NATS_URL=nats://your-nats-server:4222 \ -e NATS_TOKEN=your-token \ -e DATABASE_URL=postgresql+asyncpg://user:pass@db:5432/runner \ neuroship/runner
- Connect — The runner connects to NATS, starts sending heartbeats, and begins pulling jobs. It will appear as "online" in the UI within seconds.
How Runners Work
- Runners send a heartbeat every 10 seconds so the platform knows they're alive (60s TTL)
- Jobs are distributed via a work queue — if you run multiple runners, they share the load automatically
- Each runner reports its spec version — jobs with a newer spec version than the runner supports are rejected
- Runners store job history and provider configs in their own database
Scaling
Run multiple runners to handle more concurrent workflows. Each runner pulls jobs independently from the same work queue, so load balancing is automatic. You can also run specialized runners with different provider configurations (e.g., one with OpenAI keys, another with Anthropic).
Providers
Providers are LLM API configurations stored on runners. They tell the runner how to connect to OpenAI, Anthropic, Google, and other LLM services.
Managing Providers
In the UI, select a runner and open the Providers panel. You can add, edit, and delete provider configurations. Templates for common providers (OpenAI, Anthropic, Azure OpenAI, Google) pre-populate the expected fields.
API Key Resolution
When an agent node needs an API key, the system checks in this order:
- Inline YAML —
api_keyin themodelssection (highest priority) - Runner provider config — matched by provider type
- Environment variables —
OPENAI_API_KEY,ANTHROPIC_API_KEY, etc.
Security
- Secrets are stored only in the runner's own database — they never leave the runner
- The platform API only sees masked values (
••••••) - Secret keys are auto-detected from patterns like
api_key,secret,token,password
Registries
Registries store pre-built agent definitions that you can reuse across workflows. Instead of writing the same agent configuration repeatedly, reference it from a registry.
Using Registry Agents
- Register a registry URL in the platform (Registries panel in the UI)
- In your workflow YAML, reference a pre-built agent with the
reffield on an agent node:
analysis: type: agent ref: registry/project-analyzer # Pull pre-built agent config input: data: start.user_input output: result
The registry provides the agent's model, instruction, and other settings. You only need to wire up inputs and outputs.
Roles & Permissions
The platform has three roles with increasing permissions:
| Role | Workflows | Runners | Providers | Users |
|---|---|---|---|---|
| User | Create, edit, run | Register, view | View (masked) | Own profile |
| Operator | Create, edit, run | Register, view | Full CRUD | Own profile |
| Admin | Create, edit, run | Register, view | Full CRUD | Manage all users |
- Provider secrets are never visible to any role — only masked values are shown
- Only operators and admins can configure providers on runners
- The platform supports OIDC authentication (Keycloak) for enterprise deployments
AI Planner
The AI Planner is a built-in assistant that helps you design workflows. Describe what you want in natural language, and it generates the YAML for you.
How to Use
- Open a workflow config and click the Planner panel
- Describe your workflow: "Create a workflow that takes a research topic, does web research and competitive analysis in parallel, then compiles a report"
- The planner generates YAML and explains its choices
- Click Apply to update your workflow. A snapshot is saved automatically so you can revert if needed.
Complete Example
A full workflow that analyzes project proposals with parallel research & analysis, human review, and a compiled report.
name: Project Analysis Workflow description: Analyzes project proposals and generates a report models: default: provider: openai model: gpt-4o deps: research: [start] analysis: [start] # research + analysis run in parallel review: [research, analysis] report: [review] outputs: result: report.final_report nodes: start: type: input description: Project proposal entry fields: project_description: type: textarea label: Project Description required: true placeholder: Describe the project... priority: type: dropdown label: Priority options: [low, medium, high] default: medium deadline: type: date label: Target Deadline output: user_input research: type: agent model: default description: Research the project domain instruction: | Research the domain described in the project proposal. Identify key challenges, competitors, and opportunities. input: proposal: start.user_input output: research_findings analysis: type: agent model: default description: Analyze feasibility instruction: | Analyze the feasibility of the proposed project. Consider technical complexity, resource requirements, and timeline. input: proposal: start.user_input output: feasibility_analysis review: type: agent model: default description: Review and synthesize findings instruction: | Review the research findings and feasibility analysis. Provide a balanced assessment with recommendations. input: research: research.research_findings analysis: analysis.feasibility_analysis output: review_summary approval: when: after message: "Review the synthesis before generating the final report" report: type: function handler: compile_report description: Generate final report input: research: research.research_findings analysis: analysis.feasibility_analysis review: review.review_summary output: final_report template: | # Project Analysis Report ## Research Findings {{research}} ## Feasibility Analysis {{analysis}} ## Review & Recommendations {{review}}
Status Reference
Node Statuses
| Status | Meaning |
|---|---|
| pending | Waiting for dependencies to complete |
| running | Currently executing |
| awaiting_approval | Paused for human approval |
| completed | Finished successfully |
| failed | An error occurred during execution |
| rejected | Approval was denied by the reviewer |
| skipped | Skipped because an upstream node failed or was rejected |
| stopped | User manually stopped the execution |
Workflow Statuses
| Status | Condition |
|---|---|
| running | At least one node is executing or pending |
| awaiting_approval | Paused waiting for human approval |
| completed | All nodes completed successfully |
| failed | One or more nodes failed or were rejected |
| stopped | User manually stopped the workflow |
Validation Rules
Workflows are validated when you save or run them. These rules help catch errors before execution.
Required
- Exactly one node with
type: input - The input node must be a root (no dependencies on it)
- The graph must be acyclic — no circular dependencies
- Every node must define an
output - Output names must be unique across all nodes
- All
node_name.keyreferences must point to existing nodes and outputs - Agent nodes must reference a model from the
modelssection - Agent nodes must have an
instruction - Function nodes must have a
handler - Webhook nodes must have a
url
Warnings
These don't block execution but indicate potential issues:
- Unknown input field type
- Dropdown/radio fields missing
options - Deps referencing a node that doesn't exist