POST /{workflowId}/nodes/{nodeId}/branches needs workflowBuilder.POST /{workflowId}/nodes and position: {routerNodeId, branchIndex}.Authorization: Bearer <API_KEY> with workflowBuilder, on a workflow of the key's community. If-Match is optional. Send the revision you read to avoid overwriting a concurrent change (a stale value is refused with 409 VERSION_CONFLICT); omit it and your write wins as the last one. A deployed workflow is edited with the same call: the change applies immediately.| Failure | Meaning | Recovery |
|---|---|---|
400 VALIDATION_FAILED | The step is not a router, branchName is empty, or branchType is neither CONDITION nor FALLBACK | Send a branch for a router step, with both required fields. |
conditions array:{
"data": {
"node": {
"_id": "65f1a2b3c4d5e6f708192a3e",
"name": "XP over 100?",
"type": "router",
"order": 2,
"continueOnFailure": false,
"retryOnFailure": false,
"options": {
"executePaths": "first_matching",
"branches": [
{ "branchName": "XP > 100", "branchType": "CONDITION", "workflowNodeIds": ["65f1a2b3c4d5e6f708192a3d"] },
{ "branchName": "Otherwise", "branchType": "FALLBACK", "workflowNodeIds": [] }
]
}
},
"revision": "68f78253046393414dec404e5442c140bb5db0393a7d1c389ff57bba71585501",
"redactedPaths": []
}
}201 with the router step in { node, revision, redactedPaths }, and the revision in the ETag header. The response is the readback: options.branches shows the new branch at the index you will use to add steps to it.options.branches, counted from 0.| Status and code | When | Recovery |
|---|---|---|
400 VALIDATION_FAILED | The step is not a router, or a required field is missing or invalid | Send branchName and branchType, and conditions for a condition branch. |
401 AUTHENTICATION_REQUIRED | No key, or an unknown key | Send a valid key. |
403 API_KEY_PERMISSION_DENIED | No workflowBuilder | Grant the permission. |
404 NODE_NOT_FOUND | The step is not part of this workflow | Read the workflow for its step ids. |
409 VERSION_CONFLICT | You sent an If-Match that is not the current revision. meta.currentRevision carries the live value | Re-read and resend. |
415 UNSUPPORTED_MEDIA_TYPE | The body was not declared application/json | Send the header. |429 RATE_LIMITED | The community's API rate limit was reached | Wait for the window to reset, then retry. |500 INTERNAL_ERROR | Unexpected failure | Re-read the router before retrying. |503 LOCK_UNAVAILABLE | The write lock store did not answer, so nothing was written | Retry shortly. |AND groups. A group with OR or WHERE is stored, and POST /{workflowId}/validate reports ROUTER_OPERATOR_UNSAFE as a warning: the runtime treats those groups as always true, so the branch fires more often than you meant. Deploy still proceeds, so use AND groups and read the warnings.id, a key, a type, an operator and a value, all as non-empty arrays for key and value.workflowNodeIds. A branch that names a step of another workflow is 400 NODE_NOT_IN_WORKFLOW: that is a tenant check, not a validation warning.POST /{workflowId}/validate reports BRANCH_REQUIRED as a warning when it has none, and deploy still proceeds. executePaths decides whether the first match wins or every match runs; a fallback only runs when no condition matched.POST /{workflowId}/nodes with position: {routerNodeId, branchIndex} to fill the branch.PATCH /{workflowId}/nodes/{nodeId}/branches/{branchIndex} to change its conditions.POST /{workflowId}/validate before deploying.curl --location 'https://api.returning.ai/v1/workflow-builder/data-workflows/65f1a2b3c4d5e6f708192a3b/nodes/65f1a2b3c4d5e6f708192a3c/branches' \
--header 'Authorization: Bearer <API_KEY>' \
--header 'If-Match: 162af81f5de4ff2b557a4087de9a9a73a0ed4e621f737787e35a93614cb50d1c' \
--header 'Content-Type: application/json' \
--data '{
"branchName": "Coins > 500",
"branchType": "CONDITION",
"conditions": [
{
"id": "group-2",
"operator": "AND",
"nestedGroups": [
{
"id": "nested-2",
"operator": "AND",
"conditions": [
{
"id": "condition-2",
"key": [
"{{65f1a2b3c4d5e6f708192a3c.Total Coins}}"
],
"type": "number",
"operator": "greater_than",
"value": [
"500"
]
}
]
}
]
}
]
}'{
"data": {
"node": {
"_id": "65f1a2b3c4d5e6f708192a3c",
"name": "XP over 100?",
"type": "router",
"order": 1,
"continueOnFailure": false,
"retryOnFailure": false,
"options": {
"executePaths": "first_matching",
"branches": [
{
"branchName": "XP > 100",
"branchType": "CONDITION",
"workflowNodeIds": []
}
]
}
},
"revision": "68f78253046393414dec404e5442c140bb5db0393a7d1c389ff57bba71585501",
"redactedPaths": []
}
}