FlowDSL Specification
The formal definition of the FlowDSL JSON Schema — nodes, edges, delivery policies, and the event system.
JSON Schema
https://flowdsl.com/schemas/v1/flowdsl.schema.json
Overview
A FlowDSL document describes a directed acyclic graph (DAG) of processing nodes connected by edges with explicit delivery semantics. It is always the authoritative source of truth — not the visual canvas.
FlowDSL occupies a distinct layer: OpenAPI describes HTTP interfaces, AsyncAPI describes event contracts, and FlowDSL describes how those events flow through executable processing graphs. FlowDSL is fully self-contained — external schema imports are optional.
Nodes
Nodes represent units of business logic. They are transport-agnostic — they never own delivery semantics. Node names use PascalCase. operationId values use snake_case.
nodes:
RuleFilterNode:
operationId: run_domain_rule_filter
kind: router
inputs:
- name: IncomingDomain
message:
$ref: "#/components/events/DomainReceived"
outputs:
- name: RulePassed
message:
$ref: "#/components/events/DomainRulePassed"
- name: RuleRejected
message:
$ref: "#/components/events/DomainRuleRejected"Edges
Edges carry the delivery policy for messages moving between two nodes. The policy lives on the edge, not the node — keeping nodes reusable across flows with different durability requirements.
edges:
- from: RuleFilterNode
to: DomainEnricherNode
when: "output.name == 'RulePassed'"
delivery:
mode: durable
store: mongoDelivery Policies
Five built-in delivery modes cover the full durability spectrum.
Communication Protocols
Nodes declare which protocols they support via runtime.supports. The specific protocol for a connection is selected on the edge via the protocol field. FlowDSL supports 9 protocols — from in-process function calls to durable message queues.
components:
nodes:
EventRouterNode:
operationId: route_events
kind: router
runtime:
supports:
- nats
- grpc
nats:
url: "nats://localhost:4222"
subject: "flowdsl.events.route"
queueGroup: "routers"Events & Packets
FlowDSL has a first-class schema system. No external specification required.
components.events— primary message contracts
Named, versioned event definitions. The preferred way to define typed messages flowing through the system.
components:
events:
DomainReceived:
summary: Fired when a new domain enters the processing pipeline
version: "1.0.0"
tags: [domain, ingestion]
payload:
schema:
type: object
properties:
domain: { type: string }
source: { type: string }
receivedAt: { type: string, format: date-time }components.packets— raw reusable schema shapes
Low-level JSON Schema types shared across multiple events. Referenced directly when no event metadata is needed.
components:
packets:
EnrichedDomainPacket:
type: object
properties:
domain: { type: string }
dnsValid: { type: boolean }
whoisAge: { type: integer }
seoScore: { type: number }Resolution order on a node port: #/components/events/…→#/components/packets/…→ inline schema
Node Contracts
Every node in a FlowDSL document is a bilateral contract — typed inputs on one side, typed outputs on the other. Click any port to inspect its payload schema.
External Schema Integration
FlowDSL works standalone. If you have an existing OpenAPI or AsyncAPI specification, you can optionally import schemas from it by declaring externalDocs in your document.
externalDocs:
openapi: "https://api.example.com/api/v1/openapi.json"
asyncapi: "https://api.example.com/asyncapi.json"
# Then reference imported schemas on any node port:
inputs:
- name: IncomingOrder
message:
$ref: "openapi#/components/schemas/Order"
outputs:
- name: OrderPlaced
message:
$ref: "asyncapi#/components/messages/OrderPlaced"x-ui Extensions
Canvas layout hints are stored in x-ui extensions on nodes and edges. They are optional and ignored by the runtime.
nodes:
ChargePayment:
operationId: charge_payment
x-ui:
position: { x: 300, y: 200 }
color: "#f59e0b"
icon: "credit-card"Version History
| Version | Date | Status | Notes |
|---|---|---|---|
| 1.0.0 | 2025-01-01 | stable | Initial release |

