Returning.AIDocs
v1

API reference / Workflow Builder

.md

Update a router branch

Changes a branch's name, its type, or its condition groups.

Last updated 28 Oct 2026API v1

Method
PATCH
Path
https://api.returning.ai/v1/workflow-builder/data-workflows/{workflowId}/nodes/{nodeId}/branches/{branchIndex}
Permission
workflowBuilder
Retries
A retry with the same If-Match is refused with 409 VERSION_CONFLICT once the first attempt landed, so a duplicate edit cannot apply twice.

Authentication#

Header
Authorization: Bearer <API_KEY>
Permission
workflowBuilder

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.

The branch index is positional, so it shifts when another branch is added or deleted. Read the router before writing to be sure which branch you are changing.

FailureMeaningRecovery
404 BRANCH_NOT_FOUNDNo branch at that indexRead the router and use an existing index.

Behaviour#

Fields you omit are kept, so this is a partial update of one branch rather than a replacement of the router.

The branch keeps its index and its steps. Changing a branch from CONDITION to FALLBACK does not move or delete the steps attached to it.

Request#

Path parameters#

workflowId#stringREQUIRED
Workflow identifier: 24 hexadecimal characters, as returned in _id.

Rule^[0-9a-fA-F]{24}$

Eg65f1a2b3c4d5e6f708192a3b

nodeId#stringREQUIRED
Step identifier: 24 hexadecimal characters, as returned in the step's _id.

Rule^[0-9a-fA-F]{24}$

Eg65f1a2b3c4d5e6f708192a3c

branchIndex#integerREQUIRED
Zero-based index of the branch inside the router step, in stored order.

RuleMin 0

Eg0

Headers#

Authorization#stringREQUIRED
Community API key: Bearer <API_KEY>.

EgBearer <API_KEY>

If-Match#stringOPTIONAL
Optional. Send the revision the change is based on, bare or quoted, to avoid overwriting a concurrent change: a stale value is refused with 409 VERSION_CONFLICT. Omit it for last-write-wins.

Eg162af81f5de4ff2b557a4087de9a9a73a0ed4e621f737787e35a93614cb50d1c

Content-Type#stringREQUIRED
Request body format.

Ruleapplication/json

Body#

branchName#stringOPTIONAL
New branch name.

Rule1-200 chars

Eg"XP at least 100"

branchType#stringOPTIONAL
CONDITION or FALLBACK.

RuleCONDITION, FALLBACK

Eg"CONDITION"

conditions#object[]OPTIONAL
Replacement condition groups.

Eg[]

Watch for

  • conditions is replaced, not merged. Send the complete condition tree you want.
  • Conditions are AND inside a group. OR and WHERE groups are stored, and validation reports them as warnings rather than refusing the write or the deploy.
  • Renaming a branch does not change its index or its steps.
  • A branch index is not stable across adds and deletes. Never cache it across calls.
  • A router with only a fallback branch is valid, deploys, and simply always takes the fallback.
More examples and details

Replace the condition groups of the first branch:

BASH
curl --request PATCH \
  --url "https://api.returning.ai/v1/workflow-builder/data-workflows/65f1a2b3c4d5e6f708192a3b/nodes/65f1a2b3c4d5e6f708192a3e/branches/0" \
  --header "Authorization: Bearer <API_KEY>" \
  --header "Content-Type: application/json" \
  --header "If-Match: 162af81f5de4ff2b557a4087de9a9a73a0ed4e621f737787e35a93614cb50d1c" \
  --data '{"conditions":[{"id":"group-1","operator":"AND","nestedGroups":[{"id":"nested-1","operator":"AND","conditions":[{"id":"condition-1","key":["{{65f1a2b3c4d5e6f708192a3c.Total XP}}"],"type":"number","operator":"greater_than_or_equal","value":["100"]}]}]}]}'
JSON
{
  "data": {
    "node": {
      "_id": "65f1a2b3c4d5e6f708192a3e",
      "name": "XP over 100?",
      "type": "router",
      "order": 2,
      "continueOnFailure": false,
      "retryOnFailure": false,
      "options": {
        "executePaths": "first_matching",
        "branches": [
          { "branchName": "XP at least 100", "branchType": "CONDITION", "workflowNodeIds": ["65f1a2b3c4d5e6f708192a3d"] },
          { "branchName": "Otherwise", "branchType": "FALLBACK", "workflowNodeIds": [] }
        ]
      }
    },
    "revision": "68f78253046393414dec404e5442c140bb5db0393a7d1c389ff57bba71585501",
    "redactedPaths": []
  }
}
curl --request PATCH \
  --url 'https://api.returning.ai/v1/workflow-builder/data-workflows/<workflowId>/nodes/<nodeId>/branches/<branchIndex>' \
  --header 'Authorization: Bearer <API_KEY>' \
  --header 'Content-Type: application/json' \
  --data '{
    "branchName": "XP at least 100"
  }'

Response#

HTTP 200 with the router step and the workflow's new revision. The response is the readback for the branch you changed: name, type and condition groups as stored, and the same member ids as before.

Run POST /{workflowId}/validate after a condition change. A group that uses OR or WHERE is reported as ROUTER_OPERATOR_UNSAFE, as a warning: the runtime treats those groups as always true, so the branch fires more often than you meant. Deploy proceeds either way, so act on the warning.

data#object
One step with the workflow revision it left behind.

Eg{ ... }

node#object
A step as returned by the API.

Eg{ ... }

_id#string
Step identifier.

Eg"65f1a2b3c4d5e6f708192a3c"

name#string
Step name.

Eg"XP over 100?"

type#string
Step type.

Eg"router"

order#integer
Position on the main line, from 1.

Eg1

continueOnFailure#boolean
Whether a failure stops the run.

Egfalse

retryOnFailure#boolean
Whether the step is retried on failure.

Egfalse

options#object
Stored step options, with every credential replaced by ["__REDACTED__"].

RuleNullable

Eg{ ... }

status#string
Last run state of the step, when one exists.

Eg"success"

nestedNodes#object[]
Present on a router: each branch carries its own workflowNodeIds and nestedNodes.
revision#string
Revision after the write.

Eg"68f78253046393414dec404e5442c140bb5db0393a7d1c389ff57bba71585501"

redactedPaths#string[]
Credential locations replaced in this response.

Eg[]

{
  "data": {
    "node": {
      "_id": "65f1a2b3c4d5e6f708192a3c",
      "name": "XP over 100?",
      "type": "router",
      "order": 1,
      "continueOnFailure": false,
      "retryOnFailure": false,
      "options": {
        "executePaths": "first_matching",
        "branches": [
          {
            "branchName": "XP at least 100",
            "branchType": "CONDITION",
            "workflowNodeIds": []
          }
        ]
      }
    },
    "revision": "68f78253046393414dec404e5442c140bb5db0393a7d1c389ff57bba71585501",
    "redactedPaths": []
  }
}

Errors#

Fix the request06

400VALIDATION_FAILEDFix the request
An empty body, or a field with an invalid value. Send at least one of branchName, branchType, conditions.
401AUTHENTICATION_REQUIREDFix the request
No key, or an unknown key. Send a valid key.
401API_KEY_REQUIREDFix the request
A valid admin session was used, because this API accepts community API keys only. Use a community API key.
403API_KEY_PERMISSION_DENIEDFix the request
No workflowBuilder. Grant the permission.
413VALIDATION_FAILEDFix the request
The request body is too large to read. Nothing was written. Send a smaller body; a large import is better split into a create plus step writes.
415UNSUPPORTED_MEDIA_TYPEFix the request
The body was not declared application/json. Send the header.

Fix the data04

404NODE_NOT_FOUNDFix the data
The step is not part of this workflow. Read the workflow for its step ids.
404BRANCH_NOT_FOUNDFix the data
No branch at that index. Read the router and use an existing index.
409VERSION_CONFLICTFix the data
You sent an If-Match that is not the current revision. meta.currentRevision carries the live value. Re-read and resend.
409WORKFLOW_LOCKEDFix the data
Another write to this workflow held the lock for too long, and this write was not applied. Re-read and retry.

Retry with backoff03

429RATE_LIMITEDRetry with backoff
The community's API rate limit was reached. Wait for the window to reset, then retry.
500INTERNAL_ERRORRetry with backoff
Unexpected failure. Re-read the router before retrying.
503LOCK_UNAVAILABLERetry with backoff
The write lock store did not answer, so nothing was written. Retry shortly.

Retries

A retry with the same If-Match is refused with 409 VERSION_CONFLICT once the first attempt landed, so a duplicate edit cannot apply twice. Sending the same body again against the new revision is a no-op that changes nothing.

{
  "meta": {
    "status": "error",
    "statusCode": 400,
    "code": "VALIDATION_FAILED",
    "errors": [
      {
        "path": "params.workflowId",
        "message": "Id must be a 24 character hex string"
      }
    ],
    "requestId": "3f4d0e8b-7a6c-4f1e-9b2d-5a7c8e1f0a3b"
  },
  "message": "API request rejected error.",
  "detail": "The request body is not valid.",
  "solution": "Read error detail and try again."
}

Next step#

Delete a router branchDELETE/v1/workflow-builder/data-workflows/{workflowId}/nodes/{nodeId}/branches/{branchIndex}