| GET | /me | Who am I |
| GET | /node-types | Node catalog |
| GET | /flows | List flows |
| POST | /flows | Create a flow |
| GET | /flows/{flowId} | Get a flow summary |
| PATCH | /flows/{flowId} | Rename or activate a flow |
| GET | /flows/{flowId}/graph | Get the full graph |
| PUT | /flows/{flowId}/graph | Replace the whole graph |
| GET | /flows/{flowId}/nodes | List / search nodes |
| GET | /flows/{flowId}/nodes/{nodeId} | Get a node |
| POST | /flows/{flowId}/nodes | Add a node |
| PATCH | /flows/{flowId}/nodes/{nodeId} | Edit a node |
| DELETE | /flows/{flowId}/nodes/{nodeId} | Delete a node |
| POST | /flows/{flowId}/nodes/{nodeId}/test | Test one node |
| GET | /flows/{flowId}/edges | List edges |
| POST | /flows/{flowId}/edges | Connect two nodes |
| DELETE | /flows/{flowId}/edges/{edgeId} | Delete an edge |
| POST | /flows/{flowId}/execute | Run the flow |
| GET | /flows/{flowId}/executions | Recent runs |
| GET | /flows/{flowId}/executions/{executionId} | Run status and log |
/mescope · readWho am I
Confirms the token works and what it may do on Workflows.
No parameters
curl https://api.simplynice.ai/api/ai/simple-flow/me -H "Authorization: Bearer $DJC_TOKEN"{ "userId": "Qrpc3k06…", "orgId": "d3fe674f-…", "tokenKind": "token", "access": "write", "scopes": ["workflows:write"], "flowId": null }flowId is only set for legacy per-flow keys.
| Status | When |
|---|---|
401 | Missing, revoked or expired token. |
403 | Token lacks workflows:read (INSUFFICIENT_SCOPE). |
/node-typesscope · readNode 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
curl https://api.simplynice.ai/api/ai/simple-flow/node-types -H "Authorization: Bearer $DJC_TOKEN"{
"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)"
}/flowsscope · readList flows
The flows you own in this workspace, as summaries.
No parameters
curl https://api.simplynice.ai/api/ai/simple-flow/flows -H "Authorization: Bearer $DJC_TOKEN"[ {
"id": "8d6ffd0f-…", "name": "WhatsApp concierge", "active": true,
"nodeCount": 5, "edgeCount": 4,
"createdAt": "2026-08-22T02:52:18Z", "updatedAt": "2026-08-29T07:32:20Z"
} ]| Status | When |
|---|---|
403 | Token lacks workflows:read (INSUFFICIENT_SCOPE). |
/flowsscope · read & writeCreate a flow
Creates a flow, optionally with its whole graph in one call. Inactive by default.
| Parameter | Type | Description |
|---|---|---|
namerequired | string | 1–200 characters. |
active | boolean | Whether event triggers (WhatsApp) fire. Default false. |
nodes | NodeInput[] | { id?, type, label?, description?, config?, position? } — omitted fields use the type's defaults; a partial config is merged over defaultConfig. |
edges | EdgeInput[] | { source, target, sourceHandle? } — sourceHandle is "true" / "false" when leaving an If node. |
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" } ]
}'{ …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" }, … ] }| Status | When |
|---|---|
400 | Unknown node type, duplicate id, invalid edge (self-loop, missing pin, duplicate). |
403 | Token lacks workflows:write (INSUFFICIENT_SCOPE). |
- There is no delete through the API — remove a flow from the app.
/flows/{flowId}scope · readGet a flow summary
Name, active state and counts.
curl https://api.simplynice.ai/api/ai/simple-flow/flows/$FLOW_ID -H "Authorization: Bearer $DJC_TOKEN"{
"id": "8d6ffd0f-…", "name": "WhatsApp concierge", "active": true,
"nodeCount": 5, "edgeCount": 4,
"createdAt": "2026-08-22T02:52:18Z", "updatedAt": "2026-08-29T07:32:20Z"
}| Status | When |
|---|---|
404 | Flow not found (it must belong to you in this workspace). |
/flows/{flowId}scope · read & writeRename or activate a flow
active gates event triggers: a whatsappTrigger only fires while the flow is active.
| Parameter | Type | Description |
|---|---|---|
name | string | 1–200 characters. |
active | boolean |
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 }'{
"id": "8d6ffd0f-…", "name": "WhatsApp concierge", "active": true,
"nodeCount": 5, "edgeCount": 4,
"createdAt": "2026-08-22T02:52:18Z", "updatedAt": "2026-08-29T07:32:20Z"
}| Status | When |
|---|---|
404 | Flow not found (it must belong to you in this workspace). |
403 | Token lacks workflows:write (INSUFFICIENT_SCOPE). |
/flows/{flowId}/graphscope · readGet the full graph
Summary plus every node and edge. Add ?includeOutput=1 for each node's last run (lastRun: { status, output, error }).
| Parameter | Type | Description |
|---|---|---|
includeOutput | 1 | Include last-run output per node. |
curl "https://api.simplynice.ai/api/ai/simple-flow/flows/$FLOW_ID/graph?includeOutput=1" -H "Authorization: Bearer $DJC_TOKEN"{ …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" } ]
}| Status | When |
|---|---|
404 | Flow not found (it must belong to you in this workspace). |
/flows/{flowId}/graphscope · read & writeReplace 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.
| Parameter | Type | Description |
|---|---|---|
nodesrequired | NodeInput[] | |
edgesrequired | EdgeInput[] |
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" } ] }'{ …summary, "nodes": [ … ], "edges": [ … ] }| Status | When |
|---|---|
400 | Any node or edge is invalid — nothing is saved. |
404 | Flow not found (it must belong to you in this workspace). |
403 | Token lacks workflows:write (INSUFFICIENT_SCOPE). |
/flows/{flowId}/nodesscope · readList / search nodes
q matches id, label, description, type and config text (case-insensitive).
| Parameter | Type | Description |
|---|---|---|
q | string | |
type | string | Node type filter. |
includeOutput | 1 |
curl "https://api.simplynice.ai/api/ai/simple-flow/flows/$FLOW_ID/nodes?type=llmChain" -H "Authorization: Bearer $DJC_TOKEN"{ "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 }
} ] }| Status | When |
|---|---|
404 | Flow not found (it must belong to you in this workspace). |
/flows/{flowId}/nodes/{nodeId}scope · readGet a node
The node plus its incoming[] and outgoing[] edges.
curl https://api.simplynice.ai/api/ai/simple-flow/flows/$FLOW_ID/nodes/node2 -H "Authorization: Bearer $DJC_TOKEN"{ "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" } ]
}| Status | When |
|---|---|
404 | Flow or node not found. |
/flows/{flowId}/nodesscope · read & writeAdd a node
A NodeInput, optionally wired in the same call.
| Parameter | Type | Description |
|---|---|---|
typerequired | string | From GET /node-types. |
id | string | node7-style; auto-assigned when omitted. |
label / description / config / position | … | See NodeInput. |
connectFrom | string | Add an edge from this node id. |
connectFromHandle | string | true / false when connecting from an If node. |
connectTo | string | Add an edge to this node id. |
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" }'{
"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 }
}| Status | When |
|---|---|
400 | Unknown type, id taken, or the connection is invalid. |
404 | Flow not found (it must belong to you in this workspace). |
403 | Token lacks workflows:write (INSUFFICIENT_SCOPE). |
/flows/{flowId}/nodes/{nodeId}scope · read & writeEdit a node
config **replaces** the whole config; configPatch **shallow-merges** into it — prefer configPatch so unrelated settings survive.
| Parameter | Type | Description |
|---|---|---|
label | string | |
description | string | |
config | object | Replace. |
configPatch | object | Merge. |
position | { x, y } | Cosmetic; the canvas lays out left → right in steps of ~320. |
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 } }'{
"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 }
}| Status | When |
|---|---|
404 | Flow or node not found. |
403 | Token lacks workflows:write (INSUFFICIENT_SCOPE). |
/flows/{flowId}/nodes/{nodeId}scope · read & writeDelete a node
Removes the node and every edge touching it.
curl -X DELETE https://api.simplynice.ai/api/ai/simple-flow/flows/$FLOW_ID/nodes/node2 -H "Authorization: Bearer $DJC_TOKEN"{ "deleted": "node2", "removedEdges": ["e-node1-node2", "e-node2-node3"] }| Status | When |
|---|---|
404 | Flow or node not found. |
403 | Token lacks workflows:write (INSUFFICIENT_SCOPE). |
/flows/{flowId}/nodes/{nodeId}/testscope · read & writeTest 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.
| Parameter | Type | Description |
|---|---|---|
inputItems | Item[] | [{ "json": { … } }] — what the node receives. |
nodeOutputs | object | { [nodeId]: Item[] } — outputs of other nodes, for {{[nodeN].field}} references. |
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" } } ] }'{ "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.
| Status | When |
|---|---|
404 | Flow or node not found. |
402 | Your credit balance in this workspace is 0 (INSUFFICIENT_CREDITS, balance in details.balance). |
403 | Token lacks workflows:write (INSUFFICIENT_SCOPE). |
/flows/{flowId}/edgesscope · readList edges
No parameters
curl https://api.simplynice.ai/api/ai/simple-flow/flows/$FLOW_ID/edges -H "Authorization: Bearer $DJC_TOKEN"{ "count": 2, "edges": [ { "id": "e-node1-node2", "source": "node1", "target": "node2" }, { "id": "e-node2-node3", "source": "node2", "target": "node3" } ] }| Status | When |
|---|---|
404 | Flow not found (it must belong to you in this workspace). |
/flows/{flowId}/edgesscope · read & writeConnect two nodes
One edge carries both execution order and data: the source's output items flow into the target.
| Parameter | Type | Description |
|---|---|---|
sourcerequired | string | |
targetrequired | string | |
sourceHandle | string | true / false when the source is an If node (defaults to true). |
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" }'{ "id": "e-node4-false-node6", "source": "node4", "target": "node6", "sourceHandle": "false" }| Status | When |
|---|---|
400 | Self-loop, duplicate edge, a node without the needed pin, or a bad sourceHandle. |
404 | Flow not found (it must belong to you in this workspace). |
403 | Token lacks workflows:write (INSUFFICIENT_SCOPE). |
/flows/{flowId}/edges/{edgeId}scope · read & writeDelete an edge
By id — or use DELETE /flows/{flowId}/edges?source=&target=&sourceHandle= to delete by endpoints.
curl -X DELETE https://api.simplynice.ai/api/ai/simple-flow/flows/$FLOW_ID/edges/e-node1-node2 -H "Authorization: Bearer $DJC_TOKEN"{ "deleted": "e-node1-node2" }| Status | When |
|---|---|
404 | Flow or edge not found. |
403 | Token lacks workflows:write (INSUFFICIENT_SCOPE). |
/flows/{flowId}/executescope · read & writeRun 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
curl -X POST https://api.simplynice.ai/api/ai/simple-flow/flows/$FLOW_ID/execute -H "Authorization: Bearer $DJC_TOKEN"{ "executionId": "3f9c…", "poll": "/api/ai/simple-flow/flows/8d6ffd0f-…/executions/3f9c…" }| Status | When |
|---|---|
404 | Flow not found (it must belong to you in this workspace). |
402 | Your credit balance in this workspace is 0 (INSUFFICIENT_CREDITS, balance in details.balance). |
403 | Token lacks workflows:write (INSUFFICIENT_SCOPE). |
/flows/{flowId}/executionsscope · readRecent runs
The last 20 runs, newest first.
No parameters
curl https://api.simplynice.ai/api/ai/simple-flow/flows/$FLOW_ID/executions -H "Authorization: Bearer $DJC_TOKEN"[ { "id": "3f9c…", "workflowId": "8d6ffd0f-…", "status": "success", "startedAt": "…", "finishedAt": "…", "log": [ … ] } ]| Status | When |
|---|---|
404 | Flow not found (it must belong to you in this workspace). |
/flows/{flowId}/executions/{executionId}scope · readRun 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.
curl https://api.simplynice.ai/api/ai/simple-flow/flows/$FLOW_ID/executions/$EXECUTION_ID -H "Authorization: Bearer $DJC_TOKEN"{
"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.
| Status | When |
|---|---|
404 | Flow or execution not found. |