Get started

Act

The workflow engine agents can prove.

QuoxFlow replaces fragile automation chains with a structured workflow engine. Governed work streaming through the AOCL pipeline, with an audit trail on every run.

$npm install @quoxai/quoxflow
node types33control layers7
The QuoxFlow workflow builder canvas with nodes wired into a governed pipeline

In plain words

What it is, where it lives, when to reach for it

What is it
A workflow engine inside QuoxCORE that runs multi step automations with human approval gates.
Where do I use it
In the dashboard's workflow builder, and through the quox workflow commands in your terminal.
When would I use it
When a job has more than one step and you want it to run the same way every time.
How do I use it
Open Workflows in the dashboard, build the steps on the canvas, then click Run.

QuoxCORE is the free, self-hosted platform underneath this. What is QuoxCORE

Build

Visual builder, version control.

Design flows, version them, and replay any execution. Workflows are JSON DAGs under the hood, so they diff, review and ship like code.

▸ live WireMap · replayable runs
Govern

Governed by default.

Every step passes through AOCL. Policy gates decide what runs immediately, and human approval stands in front of anything that matters.

▸ policy gates · human approval
Watch

Streamed, not batched.

Work moves through the pipeline live, and you can watch it: running executions, node-by-node progress, and evidence landing as it happens.

▸ live monitoring · evidence on landing

The problem

Most workflow tools treat "reboot production" the same as "send a Slack message".

A junior engineer triggers "reboot production VM" at 3am and it just runs. No approval gate stood in the way, no audit trail says who or why, and no evidence proves what happened. The tool is opaque middleware between you and your infrastructure: you see inputs and outputs, nothing in between.

no audit trailno governanceblack box

QuoxFlow is the opposite bet. Here is the engine: everything below is shipped and in the repo. No vapour, no roadmap dressed as product.

What it is

A workflow engine you can trust with production.

Workflows are JSON DAGs: nodes connected by edges, executed via CLI, REST API, cron schedules or event triggers. QuoxFlow calls your HTTP APIs and governed platform tools directly, no proxy layer in between.

What makes it different: every execution runs through seven control layers. Policy gates can block, or hold a step for human approval. Every result produces immutable evidence. You always know what ran, who authorised it, and what happened.

  • Visual workflow builder with live WireMap preview and AI-assisted creation
  • Real-time execution monitoring with a Running Now view and APM-style drilldowns
  • Policy management with inline testing, and approval workflows in the Inbox
  • 33 node types, from webhook triggers to agents, teams and browser automation
  • Subworkflow nesting to depth 5 with automatic depth guards
  • Built-in n8n workflow importer with automatic node mapping
QuoxFlow CLI
$ quoxflow run health-check.json \
    --data '{"host": "nw-web-01"}'

▸ Ingress    envelope created
▸ Identity   authenticated: admin
▸ Policy      allowed (read-only)
▸ Context    inputs resolved
▸ Execute    call → nw-web-01 status API
▸ Verify     3 containers healthy
▸ Assemble   evidence stored

✓ Completed in 1.2s
  Correlation: exec_01HQXM...

Live demonstration

Watch a governed run cross the gate.

The whole engine in one loop. A webhook fires, the workflow checks a Docker host, and a healthy result simply logs and seals evidence. When a container is unhealthy the fix is destructive, so policy holds the run at an approval gate. Approve or deny the restart yourself.

illustrative demo · sample data · timings compressed

workflow builder · health-check.jsonengine quoxflowtrigger webhookcompleted 0denied 0

approval required · restart api-worker on nw-web-01 is destructive · approvers admin / infrastructure · timeout 1h

Every line in that log is an AEE envelope with a globally unique ID, and the run above is the same canvas the real builder renders: a live WireMap preview of the graph as you build it, a palette of 33 node types to drag from, and an AI assistant that builds the workflow from plain English through a guided 7-phase flow, then deploys it in one click.

The real builder

Not a simulation. The actual canvas.

The run above is staged. This is the workflow builder itself: Weaver drafting the graph from plain English, the node inspector configuring a schedule trigger, and the toolbar that ships it.

quoxflow · workflow builder
The QuoxFlow workflow builder: a Schedule node inspector open on the left with cron cells and a timezone field, a six-node webhook-to-Telegram incident graph in the centre, and the Weaver assistant panel with its action chips on the right.
  1. 1Set the schedule inlineCron cells, a timezone and an enabled toggle sit right in the node inspector.
  2. 2Ask Weaver to build itThe assistant panel drafts and edits the workflow from plain English, next to the canvas it is changing.
  3. 3Act on Weaver's suggestionsConnect an orphan node, add error handling or validate the graph, each one a single chip.
  4. 4Trace the incident pathA production-down webhook wires straight through to a Telegram on-call alert, drawn as a live node graph.
  5. 5Read the canvas at a glanceThe status bar counts nodes, connections and separate flows, so a tangled graph never hides.
  6. 6Export or deploy in one clickUndo, redo, export and deploy live in the same toolbar as the running node count.

Captured from the real QuoxFlow workflow builder, not a mockup.

Build

Workflows are JSON DAGs.

This is the definition behind the canvas above. Nodes connected by edges, with optional variables: each node has a type, config and position, and edges can carry conditional expressions. Because the definition is a file, it versions, diffs and reviews like the rest of your code, and any execution can be replayed against it.

  • Execute via CLI, REST API, cron schedule or event trigger
  • Validate definitions before running with quoxflow validate
  • Query past runs by correlation ID with quoxflow query
  • REST API for workflows, executions, policies, approvals and evidence
health-check.json
{
  "id": "health-check",
  "name": "Docker health check",
  "nodes": [
    { "id": "trigger", "type": "trigger:webhook",
      "config": { "path": "/health-check", "method": "POST" } },
    { "id": "check", "type": "call",
      "config": { "url": "https://nw-web-01/api/containers" } },
    { "id": "branch", "type": "flow:condition",
      "config": { "expression": "${input.unhealthy > 0}" } }
  ],
  "edges": [
    { "source": "trigger", "target": "check" },
    { "source": "check", "target": "branch" }
  ]
}

Node types

33 node types, webhooks to agents.

Every type below is defined in the engine today. Agents, teams and browser automation are first-class workflow steps, not bolt-ons.

Triggers 3 types

trigger:webhook · HTTP endpointstrigger:schedule · crontrigger:event · event bus

Control flow 5 types

flow:conditionflow:switchflow:loopflow:parallel · all/race/anyflow:merge

Actions 2 types

call · HTTP with retry + timeoutaction:tool · governed platform tools

Data 3 types

data:transform · sandboxed JSdata:setdata:aggregate

Error handling 3 types

error:tryerror:catcherror:throw

Utilities 3 types

util:waitutil:logutil:subworkflow · depth 5

Human-in-the-loop 2 types

approval:gate · Inbox approvalhuman:task

Agents & teams 5 types

agent:invokeagent:agenticteam:invoketeam:memberassistant:invoke

Browser automation 5 types

browser:navigatebrowser:screenshotbrowser:extractbrowser:fill_formbrowser:objective

Integration 2 types

notification:deliverrespondToWebhook

Counted from the engine's type definitions in the quoxflow repository.

Expression engine

Sandboxed JavaScript expressions.

Expressions use ${...} syntax and run in isolated V8 sandboxes via isolated-vm, not eval. Each expression gets an 8 MB memory limit and a 1-second timeout, with no access to process.env or Node.js APIs.

  • Access input, nodes, vars and workflow context
  • Built-in helpers: $.now(), $.uuid(), $.jsonPath(), $.base64Encode()
  • Use in any config field: conditions, HTTP bodies, transform logic
  • Validated at definition time via quoxflow validate
expressions · isolated-vm
// Condition node
"${input.amount > 10000}"

// Transform node
"${input.items.filter(i => i.status === 'active')}"

// HTTP body template
{
  "alert": "${input.host} is unhealthy",
  "count": "${input.unhealthy}",
  "time":  "${$.now()}"
}

// Access previous node outputs
"${nodes.check.status === 200}"

// Built-in helpers
"${$.jsonPath(input, 'data.results[0].value')}"
"${$.base64Encode(JSON.stringify(input))}"

Govern

Governed by default.

Every execution passes through seven control layers, and each layer emits observable, queryable AEE envelopes. Not a log line: a causal chain with globally unique IDs, linked via reply_to references.

L0Ingressnormalise input
L1Identityauthenticate
L2Policyallow · deny · hold
L3Contextresolve inputs
L4Executerun the graph
L5Verifycheck the result
L6Assembleseal the evidence
▸ AEE envelopes · routed▸ AOCL layers · enforced▸ evidence · immutable

What this means in practice.

When someone triggers "stop production VM", you get a complete record: who requested it, whether policy allowed it, whether a human approved it, whether it succeeded, and immutable evidence of the result. Queryable via CLI or API.

  • Policy management · full CRUD with inline testing: create, edit and validate rules in the dashboard, and test them against sample operations before deploying
  • Approval workflows · destructive operations pause and wait for a human in the Inbox, with configurable timeout and escalation, approve or reject with comments
  • Evidence browser · every execution produces an immutable record, browsable with correlation search, detail panels and full causality chain views

See a complete walkthrough → The full HITL story →

policy.json · proxmox-destructive
{
  "name": "proxmox-destructive",
  "rules": [{
    "conditions": {
      "tool": "proxmox_vm_action",
      "params": { "action": ["stop", "reboot", "shutdown"] }
    },
    "effect": "require_approval",
    "approvers": ["admin", "group:infrastructure"],
    "timeout": "1h"
  }]
}

This policy watches for Proxmox VM actions. If the action is stop, reboot or shutdown, it pauses execution and creates an approval request: an admin or infrastructure team member has one hour to approve or deny.

Safe operations run immediately. Destructive operations pause for a human, and the approval itself becomes part of the evidence.

The gate is not a speed bump, it is a witness. Who approved, when, and with what context is sealed into the same immutable record as the execution it authorised.

Watch

See everything. Miss nothing.

Work moves through the pipeline live. Watch running executions, drill into any node, and trace the causality chain after the fact.

01Running now

A live view of every executing workflow with animated progress. 5-second polling shows the active node, elapsed time and status at a glance.▸ live · 5s polling

02APM-style drilldown

Click any execution for a node-by-node timeline with waterfall visualisation and collapsible payload data. See where time went and what data flowed.▸ waterfall · payload inspector

03Schedule visibility

All scheduled and cron workflows in one view: next run times, countdown timers, execution history and status filters.▸ countdowns · track record

04Audit trail search

Search audit records by correlation ID or intent. Filter by type and trace causality chains across workflows and agent hand-offs.▸ correlation · causality chains

05Run and re-run

Run any workflow from its card and get instant feedback with the execution ID. From the detail page, run it again in one click.▸ instant feedback · run again

06Inline history

Expand any workflow card for its last 10 runs: status, timestamp and duration, with one click through to the full waterfall.▸ per workflow · click to drill

07Import from n8n

Paste or upload an n8n workflow JSON export and QuoxFlow converts it with automatic node mapping and warnings for unmapped features.▸ JSON import · no n8n instance required

08Approval to execution

Approval requests in the Inbox link straight to their execution detail. One click from approve to the full timeline, no hunting for correlation IDs.▸ linked · traceable

n8n import

Build native. Or bring your n8n workflows.

QuoxFlow executes directly against your own APIs and hosts. If you already have workflows built in n8n, the built-in importer converts them once, offline, into native QuoxFlow workflows.

path one · nativecall · HTTP with retry, timeout, SSRF protection action:tool · governed platform tools

Native execution against your own APIs and hosts. No middleware in the way, and policy gates can hold anything destructive for a human.

path two · imported from n8nn8n workflow JSON automatic node mapping native QuoxFlow workflow

Paste or upload an n8n workflow export and the importer converts it, node by node, into a QuoxFlow workflow. No running n8n instance required: the JSON is converted once, then the workflow runs natively from that point on.

both paths convergeAEE envelopes · policy gates · immutable evidence

Whether it was built natively or imported from n8n, every QuoxFlow workflow produces the same record: who triggered it, what policy said, and what happened.

Already on n8n? Import it.

The built-in importer converts n8n workflow JSON to QuoxFlow format. 50+ n8n node types are automatically mapped, expressions are converted from {{ }} to ${ } syntax, and connections and canvas positions are preserved.

  • 50+ n8n node types auto-mapped
  • Expression syntax automatically converted
  • No running n8n instance required: it converts JSON only
  • Warnings for unmapped credentials and unsupported features
Import
$ quoxflow import docker-status.json \
    --output converted.json --pretty

Converting n8n workflow...
  Webhook          → trigger:webhook
  Code             → data:transform
  IF               → flow:condition
  HTTP Request     → call
  Set              → data:set

✓ Converted 5 nodes, 4 edges
⚠ 1 warning: credential 'docker_ssh'
  requires manual setup

Saved to converted.json

# or over the REST API:
POST /api/workflows/import-n8n
{ "workflow": <n8n JSON>, "options": { "includePositions": true } }

Connector library

Real vendor calls, not placeholders.

The n8n importer resolves nine of the vendor node types it sees most often to a genuine API request (real endpoint, real method, a body reshaped into that vendor's own request format) instead of the generic HTTP placeholder.

Each connector covers that vendor's dominant real-world operation(s), sampled from a library of real n8n workflows, not its entire API surface, so a less common operation on the same node type can still fall back to the placeholder.

Vendors covered 9 connectors

Slack · chat.postMessageTelegram · sendMessageGmail · messages.sendGoogle Sheets · append · readGoogle Drive · files.get (download)Airtable · create · searchNotion · page create · updateEmail send · mail send (n8n's SMTP-generic node)OpenAI · chat · image-analyze

Agent & Chain composition

n8n's Agent and Chain nodes compose onto QuoxFlow's own agents.

n8n's LangChain Agent node maps onto QuoxFlow's agent:invoke; its Basic LLM Chain node maps onto assistant:invoke.

What doesn't come along automatically: n8n's attached Chat Model and Memory nodes are informational only (the QuoxFlow agent you assign brings its own model), attached Tool nodes are named in a warning rather than auto-wired, and conversation memory across separate runs isn't preserved.

Most agent-shaped n8n workflows use more than just the agent node, so composing that one piece rarely makes the whole workflow run end to end by itself.

  • 308 sampled workflows contain an Agent or Chain node
  • 22 of those are fully clean or minor-polish after this pass
  • The remaining 286 are still blocked by a different, unmapped node type, not by the agent piece itself

The honest numbers

What the sample library looks like today.

Re-run against the same 1,340-workflow sample used to scope this work: 63 convert cleanly with no edits, 91 more need only minor polish (typically filling in a credential variable), and the remaining majority still contain other node types this pass didn't reach (structural nodes like Merge and Split In Batches, or vendors like HubSpot and Redis).

Every connector authenticates via a workflow variable you set yourself (for example ${vars.CREDENTIAL_SLACK_API}). QuoxFlow does not yet pull these from an encrypted vault automatically: that wiring is a tracked next step, not shipped.

Read the full engineering writeup →

Battle tested

Tested like production software.

Every executor, every policy gate, every approval flow and the whole n8n importer is covered by the engine's test suite. The figures below are counted directly from the quoxflow repository.

2,500+test cases
196test files
0skipped
  • Control pipelinelayer ordering, conditional edges, parallel branches, error propagation
  • Executorsevery node type, including loop iteration, subworkflow nesting and agent invocation
  • Approval gatestimeout, escalation, multi-approver, deny with reason
  • n8n importnode type mappings, expression conversion, position preservation
  • Policy enginepattern matching, RBAC, effect evaluation, inline testing
  • Expression enginesandbox isolation, helper functions, timeout behaviour

Install

Docker Compose. One command.

QuoxFlow runs as a container alongside QuoxCORE, with PostgreSQL included in the compose file and JWT auth handled by the QuoxCORE auth service. Around 512 MB of RAM.

$npm install @quoxai/quoxflow
github.com/quoxai/quoxflow · PostgreSQL included

The npm package ships a full CLI: run workflows, import n8n exports, validate definitions and query audit trails from the terminal. Or use the REST API, 30+ endpoints for workflows, executions, policies, approvals, evidence and template deployment. The QuoxCORE dashboard adds the visual builder, the Running Now monitor and the execution drilldowns on top.

Terminal
$ quoxflow run workflow.json --data '{"host":"nw-web-01"}'
# Execute a workflow with input data

$ quoxflow import n8n-export.json --output converted.json
# Convert an n8n workflow to QuoxFlow format

$ quoxflow validate workflow.json
# Validate a workflow definition

$ quoxflow query --corr exec_01ABC --db postgres://...
# Query audit envelopes by correlation ID

End of the pipeline

Put your pipeline on the record.

Stop running blind. Governed workflows with executors, gates and receipts included, and evidence you can hand to an auditor.

audit trail on every executionruns replayablegoverned through AOCL
scroll to fly ↓