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.

DAG Workflows
Define multi-step AI pipelines in YAML. Nodes run in parallel when their dependencies allow it.
Remote Runners
Execute workflows on distributed runners. Scale independently with runner pools.
Approval Gates
Pause execution for human review before or after any node. Approve, reject, or provide feedback.
Real-time Streaming
Watch workflows execute live. Track node status, logs, and cost telemetry as they happen.
Secure by Default
API keys never leave the runner. Secrets are masked, roles enforce access, OIDC supported.
Multi-Provider LLMs
OpenAI, Anthropic, Google, Groq, Together, or any OpenAI-compatible endpoint.

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

  1. Create a workflow — write YAML in the editor or use the AI Planner to generate one
  2. Run it — fill in the input form and click Run. The platform sends the job to an available runner.
  3. Watch it execute — nodes light up in real-time on the DAG view as they run. You see logs, outputs, and cost telemetry live.
  4. Approve when needed — if a node has an approval gate, execution pauses and you review the inputs or outputs before continuing.
  5. Get results — when all nodes complete, the workflow outputs are available for review. The full execution history is saved.
Visual Editor
You don't have to write YAML from scratch. The UI provides a visual node editor for adding and configuring nodes, and an AI Planner that can generate entire workflows from a natural language description.

Workflow Structure

Every workflow is a YAML file with these top-level keys:

yaml
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.

yaml
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.

yaml
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:

yaml
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.

yaml
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:

HandlerDescription
save_inputReturns the user's input as-is
compile_reportMerges 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.

yaml
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.

yaml
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.

TypeWidgetNotes
textText inputSingle-line text
textareaTextareaMulti-line text
numberNumber inputNumeric value
booleanCheckboxTrue/false toggle
dateDate pickerYYYY-MM-DD
timeTime pickerHH:MM
datetimeDatetime pickerDate + time
fileFile uploadFile content as text
dropdownDropdown selectRequires options list
radioRadio buttonsRequires 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

  1. Each node produces outputs defined by its output field
  2. Downstream nodes reference those outputs as node_name.output_key
  3. The input map on each node assigns local names to upstream references
yaml
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.

yaml
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.

WhenWhat Happens
beforePauses before the node runs. Approver reviews the inputs.
afterPauses after the node runs. Approver reviews the output.
yaml
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.

yaml
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
FieldRequiredDescription
providerYesopenai, anthropic, google, groq, together, etc.
modelYesModel name: gpt-4o, claude-sonnet-4-0, gemini-2.0-flash
api_keyNoInline API key (overrides provider config and env vars)
base_urlNoCustom 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.

yaml
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.

ExpressionExtractsExample
$.keyTop-level property$.summary
$.key.subkeyNested property$.data.result
$.array.NArray element (zero-based)$.items.0
$.array.N.keyProperty of array element$.results.0.name
yaml
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.

yaml
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.

Docker Image
The runner is available as a Docker image on Docker Hub: neuroship/runner. Pull it and configure with environment variables to get started.

Setting Up a Runner

  1. Register — In the UI, go to the Runners panel and click "Register Runner". This generates a unique runner ID.
  2. Configure — Set the runner ID and connection details as environment variables:
docker
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
  1. 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:

  1. Inline YAMLapi_key in the models section (highest priority)
  2. Runner provider config — matched by provider type
  3. Environment variablesOPENAI_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

  1. Register a registry URL in the platform (Registries panel in the UI)
  2. In your workflow YAML, reference a pre-built agent with the ref field on an agent node:
yaml
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:

RoleWorkflowsRunnersProvidersUsers
UserCreate, edit, runRegister, viewView (masked)Own profile
OperatorCreate, edit, runRegister, viewFull CRUDOwn profile
AdminCreate, edit, runRegister, viewFull CRUDManage 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

  1. Open a workflow config and click the Planner panel
  2. Describe your workflow: "Create a workflow that takes a research topic, does web research and competitive analysis in parallel, then compiles a report"
  3. The planner generates YAML and explains its choices
  4. Click Apply to update your workflow. A snapshot is saved automatically so you can revert if needed.
Iterative Design
You can have a conversation with the planner. Ask it to modify specific nodes, add approval gates, change models, or restructure the DAG. Each apply creates a new snapshot.

Complete Example

A full workflow that analyzes project proposals with parallel research & analysis, human review, and a compiled report.

yaml
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

StatusMeaning
pendingWaiting for dependencies to complete
runningCurrently executing
awaiting_approvalPaused for human approval
completedFinished successfully
failedAn error occurred during execution
rejectedApproval was denied by the reviewer
skippedSkipped because an upstream node failed or was rejected
stoppedUser manually stopped the execution

Workflow Statuses

StatusCondition
runningAt least one node is executing or pending
awaiting_approvalPaused waiting for human approval
completedAll nodes completed successfully
failedOne or more nodes failed or were rejected
stoppedUser 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.key references must point to existing nodes and outputs
  • Agent nodes must reference a model from the models section
  • 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