Documentation menu

API reference

Workflows

A flow is a graph of nodes joined by edges — the same thing you build on the Simple Flow canvas. Read tokens can list flows and inspect graphs and run results; write tokens can create flows, edit nodes and edges, test a single node and run the flow. Your canvas live-syncs API edits within a few seconds.

GET/meWho am I
GET/node-typesNode catalog
GET/flowsList flows
POST/flowsCreate a flow
GET/flows/{flowId}Get a flow summary
PATCH/flows/{flowId}Rename or activate a flow
GET/flows/{flowId}/graphGet the full graph
PUT/flows/{flowId}/graphReplace the whole graph
GET/flows/{flowId}/nodesList / search nodes
GET/flows/{flowId}/nodes/{nodeId}Get a node
POST/flows/{flowId}/nodesAdd a node
PATCH/flows/{flowId}/nodes/{nodeId}Edit a node
DELETE/flows/{flowId}/nodes/{nodeId}Delete a node
POST/flows/{flowId}/nodes/{nodeId}/testTest one node
GET/flows/{flowId}/edgesList edges
POST/flows/{flowId}/edgesConnect two nodes
DELETE/flows/{flowId}/edges/{edgeId}Delete an edge
POST/flows/{flowId}/executeRun the flow
GET/flows/{flowId}/executionsRecent runs
GET/flows/{flowId}/executions/{executionId}Run status and log
GET/mescope · read

Who am I

Confirms the token works and what it may do on Workflows.

No parameters

Request
curl https://api.simplynice.ai/api/ai/simple-flow/me -H "Authorization: Bearer $DJC_TOKEN"
Response · 200
{ "userId": "Qrpc3k06…", "orgId": "d3fe674f-…", "tokenKind": "token", "access": "write", "scopes": ["workflows:write"], "flowId": null }

flowId is only set for legacy per-flow keys.

StatusWhen
401Missing, revoked or expired token.
403Token lacks workflows:read (INSUFFICIENT_SCOPE).
GET/node-typesscope · read

Node catalog

Every node type with its config schema, defaults and the merge-field syntax. **This is the source of truth** — never assume config shapes.

No parameters

Request
curl https://api.simplynice.ai/api/ai/simple-flow/node-types -H "Authorization: Bearer $DJC_TOKEN"
Response · 200
{
  "nodeTypes": [
    { "type": "trigger", "label": "Trigger", "category": "trigger", "pins": { "input": false, "output": true }, "configSchema": {  }, "defaultConfig": {  } },
    { "type": "whatsappTrigger", "label": "WhatsApp message",  },
    { "type": "llmChain", "label": "Basic LLM Chain",  },
    { "type": "httpRequest",  }, { "type": "condition", "label": "If", "outputs": [{ "id": "true" }, { "id": "false" }],  },
    { "type": "sendWhatsapp",  }, { "type": "action",  }, { "type": "output", "label": "Respond",  }
  ],
  "mergeFields": "…",
  "nodeIdConvention": "node1, node2, … (auto-assigned when omitted)"
}
GET/flowsscope · read

List flows

The flows you own in this workspace, as summaries.

No parameters

Request
curl https://api.simplynice.ai/api/ai/simple-flow/flows -H "Authorization: Bearer $DJC_TOKEN"
Response · 200
[ {
    "id": "8d6ffd0f-…", "name": "WhatsApp concierge", "active": true,
    "nodeCount": 5, "edgeCount": 4,
    "createdAt": "2026-08-22T02:52:18Z", "updatedAt": "2026-08-29T07:32:20Z"
  } ]
StatusWhen
403Token lacks workflows:read (INSUFFICIENT_SCOPE).
POST/flowsscope · read & write

Create a flow

Creates a flow, optionally with its whole graph in one call. Inactive by default.

ParameterTypeDescription
namerequiredstring1–200 characters.
activebooleanWhether event triggers (WhatsApp) fire. Default false.
nodesNodeInput[]{ id?, type, label?, description?, config?, position? } — omitted fields use the type's defaults; a partial config is merged over defaultConfig.
edgesEdgeInput[]{ source, target, sourceHandle? }sourceHandle is "true" / "false" when leaving an If node.
Request
curl -X POST https://api.simplynice.ai/api/ai/simple-flow/flows -H "Authorization: Bearer $DJC_TOKEN" -H "Content-Type: application/json" \
  -d '{
    "name": "Translate to Chinese",
    "nodes": [
      { "id": "node1", "type": "trigger", "config": { "sampleData": { "text": "Good morning" } } },
      { "id": "node2", "type": "llmChain", "label": "Translate", "config": { "prompt": "Translate to Chinese: {{text}}" } },
      { "id": "node3", "type": "output" }
    ],
    "edges": [ { "source": "node1", "target": "node2" }, { "source": "node2", "target": "node3" } ]
  }'
Response · 201
{ …summary, "nodes": [ {
      "id": "node2", "type": "llmChain", "nodeType": "llmChain",
      "label": "Translate → Chinese", "description": "Translate the incoming sentence",
      "config": { "model": "qwen3.7-flash", "prompt": "Translate to Chinese: {{text}}", "outputType": "text", "temperature": 0 },
      "position": { "x": 440, "y": 200 }
    } ,  ], "edges": [ { "id": "e-node1-node2", "source": "node1", "target": "node2" },  ] }
StatusWhen
400Unknown node type, duplicate id, invalid edge (self-loop, missing pin, duplicate).
403Token lacks workflows:write (INSUFFICIENT_SCOPE).
  • There is no delete through the API — remove a flow from the app.
GET/flows/{flowId}scope · read

Get a flow summary

Name, active state and counts.

Request
curl https://api.simplynice.ai/api/ai/simple-flow/flows/$FLOW_ID -H "Authorization: Bearer $DJC_TOKEN"
Response · 200
{
  "id": "8d6ffd0f-…", "name": "WhatsApp concierge", "active": true,
  "nodeCount": 5, "edgeCount": 4,
  "createdAt": "2026-08-22T02:52:18Z", "updatedAt": "2026-08-29T07:32:20Z"
}
StatusWhen
404Flow not found (it must belong to you in this workspace).
PATCH/flows/{flowId}scope · read & write

Rename or activate a flow

active gates event triggers: a whatsappTrigger only fires while the flow is active.

ParameterTypeDescription
namestring1–200 characters.
activeboolean
Request
curl -X PATCH https://api.simplynice.ai/api/ai/simple-flow/flows/$FLOW_ID -H "Authorization: Bearer $DJC_TOKEN" -H "Content-Type: application/json" -d '{ "active": true }'
Response · 200
{
  "id": "8d6ffd0f-…", "name": "WhatsApp concierge", "active": true,
  "nodeCount": 5, "edgeCount": 4,
  "createdAt": "2026-08-22T02:52:18Z", "updatedAt": "2026-08-29T07:32:20Z"
}
StatusWhen
404Flow not found (it must belong to you in this workspace).
403Token lacks workflows:write (INSUFFICIENT_SCOPE).
GET/flows/{flowId}/graphscope · read

Get the full graph

Summary plus every node and edge. Add ?includeOutput=1 for each node's last run (lastRun: { status, output, error }).

ParameterTypeDescription
includeOutput1Include last-run output per node.
Request
curl "https://api.simplynice.ai/api/ai/simple-flow/flows/$FLOW_ID/graph?includeOutput=1" -H "Authorization: Bearer $DJC_TOKEN"
Response · 200
{ …summary,
  "nodes": [ {
      "id": "node2", "type": "llmChain", "nodeType": "llmChain",
      "label": "Translate → Chinese", "description": "Translate the incoming sentence",
      "config": { "model": "qwen3.7-flash", "prompt": "Translate to Chinese: {{text}}", "outputType": "text", "temperature": 0 },
      "position": { "x": 440, "y": 200 }
    } ,  ],
  "edges": [ { "id": "e-node1-node2", "source": "node1", "target": "node2" }, { "id": "e-node4-true-node5", "source": "node4", "target": "node5", "sourceHandle": "true" } ]
}
StatusWhen
404Flow not found (it must belong to you in this workspace).
PUT/flows/{flowId}/graphscope · read & write

Replace the whole graph

Atomic rebuild: validates everything, saves nothing on error, resets run state. Use it to build from scratch or when a rebuild was asked for — it **replaces every node**, including ones made on the canvas.

ParameterTypeDescription
nodesrequiredNodeInput[]
edgesrequiredEdgeInput[]
Request
curl -X PUT https://api.simplynice.ai/api/ai/simple-flow/flows/$FLOW_ID/graph -H "Authorization: Bearer $DJC_TOKEN" -H "Content-Type: application/json" \
  -d '{ "nodes": [ { "id": "node1", "type": "trigger" }, { "id": "node2", "type": "output" } ],
        "edges": [ { "source": "node1", "target": "node2" } ] }'
Response · 200
{ …summary, "nodes": [  ], "edges": [  ] }
StatusWhen
400Any node or edge is invalid — nothing is saved.
404Flow not found (it must belong to you in this workspace).
403Token lacks workflows:write (INSUFFICIENT_SCOPE).
GET/flows/{flowId}/nodesscope · read

List / search nodes

q matches id, label, description, type and config text (case-insensitive).

ParameterTypeDescription
qstring
typestringNode type filter.
includeOutput1
Request
curl "https://api.simplynice.ai/api/ai/simple-flow/flows/$FLOW_ID/nodes?type=llmChain" -H "Authorization: Bearer $DJC_TOKEN"
Response · 200
{ "count": 1, "nodes": [ {
      "id": "node2", "type": "llmChain", "nodeType": "llmChain",
      "label": "Translate → Chinese", "description": "Translate the incoming sentence",
      "config": { "model": "qwen3.7-flash", "prompt": "Translate to Chinese: {{text}}", "outputType": "text", "temperature": 0 },
      "position": { "x": 440, "y": 200 }
    } ] }
StatusWhen
404Flow not found (it must belong to you in this workspace).
GET/flows/{flowId}/nodes/{nodeId}scope · read

Get a node

The node plus its incoming[] and outgoing[] edges.

Request
curl https://api.simplynice.ai/api/ai/simple-flow/flows/$FLOW_ID/nodes/node2 -H "Authorization: Bearer $DJC_TOKEN"
Response · 200
{ "id": "node2", "type": "llmChain", "nodeType": "llmChain",
  "label": "Translate → Chinese", "description": "Translate the incoming sentence",
  "config": { "model": "qwen3.7-flash", "prompt": "Translate to Chinese: {{text}}", "outputType": "text", "temperature": 0 },
  "position": { "x": 440, "y": 200 },
  "incoming": [ { "id": "e-node1-node2", "source": "node1", "target": "node2" } ],
  "outgoing": [ { "id": "e-node2-node3", "source": "node2", "target": "node3" } ]
}
StatusWhen
404Flow or node not found.
POST/flows/{flowId}/nodesscope · read & write

Add a node

A NodeInput, optionally wired in the same call.

ParameterTypeDescription
typerequiredstringFrom GET /node-types.
idstringnode7-style; auto-assigned when omitted.
label / description / config / positionSee NodeInput.
connectFromstringAdd an edge from this node id.
connectFromHandlestringtrue / false when connecting from an If node.
connectTostringAdd an edge to this node id.
Request
curl -X POST https://api.simplynice.ai/api/ai/simple-flow/flows/$FLOW_ID/nodes -H "Authorization: Bearer $DJC_TOKEN" -H "Content-Type: application/json" \
  -d '{ "type": "llmChain", "label": "Summarise", "config": { "prompt": "Summarise in one line: {{text}}" },
        "connectFrom": "node1", "connectTo": "node3" }'
Response · 201
{
  "id": "node2", "type": "llmChain", "nodeType": "llmChain",
  "label": "Translate → Chinese", "description": "Translate the incoming sentence",
  "config": { "model": "qwen3.7-flash", "prompt": "Translate to Chinese: {{text}}", "outputType": "text", "temperature": 0 },
  "position": { "x": 440, "y": 200 }
}
StatusWhen
400Unknown type, id taken, or the connection is invalid.
404Flow not found (it must belong to you in this workspace).
403Token lacks workflows:write (INSUFFICIENT_SCOPE).
PATCH/flows/{flowId}/nodes/{nodeId}scope · read & write

Edit a node

config **replaces** the whole config; configPatch **shallow-merges** into it — prefer configPatch so unrelated settings survive.

ParameterTypeDescription
labelstring
descriptionstring
configobjectReplace.
configPatchobjectMerge.
position{ x, y }Cosmetic; the canvas lays out left → right in steps of ~320.
Request
curl -X PATCH https://api.simplynice.ai/api/ai/simple-flow/flows/$FLOW_ID/nodes/node2 -H "Authorization: Bearer $DJC_TOKEN" -H "Content-Type: application/json" \
  -d '{ "configPatch": { "temperature": 0, "maxOutputTokens": 200 } }'
Response · 200
{
  "id": "node2", "type": "llmChain", "nodeType": "llmChain",
  "label": "Translate → Chinese", "description": "Translate the incoming sentence",
  "config": { "model": "qwen3.7-flash", "prompt": "Translate to Chinese: {{text}}", "outputType": "text", "temperature": 0 },
  "position": { "x": 440, "y": 200 }
}
StatusWhen
404Flow or node not found.
403Token lacks workflows:write (INSUFFICIENT_SCOPE).
DELETE/flows/{flowId}/nodes/{nodeId}scope · read & write

Delete a node

Removes the node and every edge touching it.

Request
curl -X DELETE https://api.simplynice.ai/api/ai/simple-flow/flows/$FLOW_ID/nodes/node2 -H "Authorization: Bearer $DJC_TOKEN"
Response · 200
{ "deleted": "node2", "removedEdges": ["e-node1-node2", "e-node2-node3"] }
StatusWhen
404Flow or node not found.
403Token lacks workflows:write (INSUFFICIENT_SCOPE).
POST/flows/{flowId}/nodes/{nodeId}/testscope · read & write

Test one node

Runs a single node with the items you supply — the cheap way to check a prompt or condition before a full run. No execution record is written; LLM nodes still use credits.

ParameterTypeDescription
inputItemsItem[][{ "json": { … } }] — what the node receives.
nodeOutputsobject{ [nodeId]: Item[] } — outputs of other nodes, for {{[nodeN].field}} references.
Request
curl -X POST https://api.simplynice.ai/api/ai/simple-flow/flows/$FLOW_ID/nodes/node2/test -H "Authorization: Bearer $DJC_TOKEN" -H "Content-Type: application/json" \
  -d '{ "inputItems": [ { "json": { "text": "Good morning" } } ] }'
Response · 200
{ "status": "success", "startedAt": "…", "finishedAt": "…",
  "output": [ { "json": { "text": "早上好", "_llm": { "model": "qwen3.7-flash", "inputTokens": 18, "outputTokens": 4, "credits": 0.0002 } } } ] }

An If node returns outputs: [trueItems, falseItems] as well. Errors come back as { "status": "error", "error": "…" } with HTTP 200.

StatusWhen
404Flow or node not found.
402Your credit balance in this workspace is 0 (INSUFFICIENT_CREDITS, balance in details.balance).
403Token lacks workflows:write (INSUFFICIENT_SCOPE).
GET/flows/{flowId}/edgesscope · read

List edges

No parameters

Request
curl https://api.simplynice.ai/api/ai/simple-flow/flows/$FLOW_ID/edges -H "Authorization: Bearer $DJC_TOKEN"
Response · 200
{ "count": 2, "edges": [ { "id": "e-node1-node2", "source": "node1", "target": "node2" }, { "id": "e-node2-node3", "source": "node2", "target": "node3" } ] }
StatusWhen
404Flow not found (it must belong to you in this workspace).
POST/flows/{flowId}/edgesscope · read & write

Connect two nodes

One edge carries both execution order and data: the source's output items flow into the target.

ParameterTypeDescription
sourcerequiredstring
targetrequiredstring
sourceHandlestringtrue / false when the source is an If node (defaults to true).
Request
curl -X POST https://api.simplynice.ai/api/ai/simple-flow/flows/$FLOW_ID/edges -H "Authorization: Bearer $DJC_TOKEN" -H "Content-Type: application/json" \
  -d '{ "source": "node4", "target": "node6", "sourceHandle": "false" }'
Response · 201
{ "id": "e-node4-false-node6", "source": "node4", "target": "node6", "sourceHandle": "false" }
StatusWhen
400Self-loop, duplicate edge, a node without the needed pin, or a bad sourceHandle.
404Flow not found (it must belong to you in this workspace).
403Token lacks workflows:write (INSUFFICIENT_SCOPE).
DELETE/flows/{flowId}/edges/{edgeId}scope · read & write

Delete an edge

By id — or use DELETE /flows/{flowId}/edges?source=&target=&sourceHandle= to delete by endpoints.

Request
curl -X DELETE https://api.simplynice.ai/api/ai/simple-flow/flows/$FLOW_ID/edges/e-node1-node2 -H "Authorization: Bearer $DJC_TOKEN"
Response · 200
{ "deleted": "e-node1-node2" }
StatusWhen
404Flow or edge not found.
403Token lacks workflows:write (INSUFFICIENT_SCOPE).
POST/flows/{flowId}/executescope · read & write

Run the flow

Starts a run in the background and returns immediately. Every start node is seeded (a manual trigger emits its sampleData; a whatsappTrigger emits its sample message). Poll the execution until it finishes.

No parameters

Request
curl -X POST https://api.simplynice.ai/api/ai/simple-flow/flows/$FLOW_ID/execute -H "Authorization: Bearer $DJC_TOKEN"
Response · 202
{ "executionId": "3f9c…", "poll": "/api/ai/simple-flow/flows/8d6ffd0f-…/executions/3f9c…" }
StatusWhen
404Flow not found (it must belong to you in this workspace).
402Your credit balance in this workspace is 0 (INSUFFICIENT_CREDITS, balance in details.balance).
403Token lacks workflows:write (INSUFFICIENT_SCOPE).
GET/flows/{flowId}/executionsscope · read

Recent runs

The last 20 runs, newest first.

No parameters

Request
curl https://api.simplynice.ai/api/ai/simple-flow/flows/$FLOW_ID/executions -H "Authorization: Bearer $DJC_TOKEN"
Response · 200
[ { "id": "3f9c…", "workflowId": "8d6ffd0f-…", "status": "success", "startedAt": "…", "finishedAt": "…", "log": [  ] } ]
StatusWhen
404Flow not found (it must belong to you in this workspace).
GET/flows/{flowId}/executions/{executionId}scope · read

Run status and log

Poll every 1–3 s until status is success or error. log[] has one entry per node that ran, with its output items (or outputs[] per branch for an If node) and any error.

Request
curl https://api.simplynice.ai/api/ai/simple-flow/flows/$FLOW_ID/executions/$EXECUTION_ID -H "Authorization: Bearer $DJC_TOKEN"
Response · 200
{
  "id": "3f9c…", "workflowId": "8d6ffd0f-…", "status": "success",
  "startedAt": "2026-08-29T08:33:15Z", "finishedAt": "2026-08-29T08:33:19Z",
  "log": [
    { "nodeId": "node1", "status": "success", "startedAt": "…", "finishedAt": "…", "output": [ { "json": { "text": "Good morning" } } ] },
    { "nodeId": "node2", "status": "success", "startedAt": "…", "finishedAt": "…", "output": [ { "json": { "text": "早上好", "_llm": {  } } } ] },
    { "nodeId": "node3", "status": "success", "startedAt": "…", "finishedAt": "…", "output": [ { "json": { "text": "早上好" } } ] }
  ]
}

A node error stops the run: status: "error" with the failing node's error in its log entry.

StatusWhen
404Flow or execution not found.