FlowDrop Workflow Specification 1.0-draft

Every surface that returns a workflow returns one object

List, create, read and update all publish the same workflow object. A client learns one shape, not four.

The rule

Normative: this is the rule
  1. Every surface that returns a workflow publishes the same keys in the same order: id, name, description, nodes, edges, metadata, created, changed, uid.
  2. nodes is enriched with each node's node-type metadata, and metadata is the value as published on read.
  3. The spelling is uniformly lower-case, created, changed and uid included.
  4. A tenth key, interface, is appended immediately after metadata when the workflow declares at least one input or output port, and is omitted entirely (never emitted as an empty object or an empty list) when it declares none.
  5. One derivation serves every surface, including any surface that embeds a workflow outside the API.

What it means

A client that has decoded a workflow from one surface can decode it from any other without a special case: same nine keys, same order, same casing. That includes the list surface, where each row is a full workflow object rather than a thinner projection — a caller does not have to fetch a workflow a second time to learn a field the list already carried.

interface, the tenth key, is conditional on the workflow itself, not on which surface answered. A workflow with no declared input or output is one object short everywhere, not just on the surfaces that happen to check; a workflow with at least one declared port carries interface everywhere, never as an empty placeholder. Absent and empty mean different things elsewhere in this specification, and this is the case where the difference is load-bearing: an author who removes every declared port should see the key disappear, not turn into {}.

Example

Unfiltered, interface does not appear at all.

A workflow with no declared ports200 — read
GET /api/flowdrop/workflows/{workflow}

{"id": "wf_no_ports", "name": "No ports", "description": "", "nodes": [  ], "edges": [  ], "metadata": {  }, "created": , "changed": , "uid":  }

Declare one input, and the same nine keys gain a tenth, in the same position, on create as much as on read.

Creating a workflow that declares one input201 — stored
POST /api/flowdrop/workflows

{"id": "wf_shape_iface", "name": "Shape with interface", "nodes": [  ], "interface": {"inputs": [{"id": "numbers", "bindings": [{"nodeId": "calc1", "portId": "values"}]}]}}
The same workflow, read back200 — read
GET /api/flowdrop/workflows/{workflow}

{"id": "wf_shape_iface", "name": "Shape with interface", "description": "", "nodes": [  ], "edges": [  ], "metadata": {  }, "created": , "changed": , "uid": , "interface": {"inputs": [  ]}}

The list surface answers the same shape, row by row: a caller scanning GET /api/flowdrop/workflows sees interface on exactly the rows that declare a port, never on the rows that do not.

Rule identifiers are permanent and are never renumbered. Each implementation publishes its own standing against these rules; this specification does not.spec 1.0-draft · STORE-14 · changed in spec 1.0