Returning.AIDocs
v1

API reference / Workflow Builder

.md

Get a workflow

Returns one workflow with its trigger, its steps in canvas order, its current revision, and redactedPaths naming every credential the response replaced.

Last updated 28 Oct 2026API v1

Method
GET
Path
https://api.returning.ai/v1/workflow-builder/data-workflows/{workflowId}
Permission
workflowBuilder
Retries
Safe to retry: it writes nothing.

Authentication#

Header
Authorization: Bearer <API_KEY>
Permission
workflowBuilder

Authorization: Bearer <API_KEY> with workflowBuilder, for the community that owns the workflow. A workflow id from another community answers exactly like an id that does not exist, so a key cannot be used to discover another community's ids.

FailureMeaningRecovery
401 AUTHENTICATION_REQUIREDNo key, or an unknown keySend a valid key.
403 API_KEY_PERMISSION_DENIEDNo workflowBuilderGrant the permission.
404 WORKFLOW_NOT_FOUNDUnknown id, or a workflow of another communityUse an id from this community's list.

Behaviour#

It is the call that starts every edit: the revision it returns is the value to send as If-Match if you want a stale write refused.

It does not return run history, event ingests or in-clear credentials.

Request#

Path parameters#

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

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

Eg65f1a2b3c4d5e6f708192a3b

Headers#

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

EgBearer <API_KEY>

Watch for

  • revision is 64 hexadecimal characters. Send it back bare; a quoted ETag value is also accepted, with or without the W/ prefix.
  • Credentials are replaced by the whole marker array ["__REDACTED__"], even where the stored value is a plain string, and every replaced location is listed in redactedPaths.
  • A credential inside a raw request body template that an author typed in is returned as authored, exactly as the canvas shows it. Do not build a workflow whose secret only exists inside a body template.
  • trigger is null for a workflow that has none. Such a workflow can be read, edited and deployed; it never runs until a trigger is set, and POST /{workflowId}/validate reports TRIGGER_REQUIRED as a warning.
  • status is one of draft, deployed, undeployed. A deployed workflow accepts every edit, and the edit applies immediately: that is why status is worth reading before a write.
  • Step status may be present from an earlier run. It is run state, not authored configuration, and it is not part of the revision.
More examples and details

A workflow with one read-only step. The router case nests each branch's steps under the branch that owns them.

JSON
{
  "data": {
    "_id": "65f1a2b3c4d5e6f708192a3b",
    "communityId": "65f1a2b3c4d5e6f708192a50",
    "name": "VIP bonus",
    "status": "draft",
    "outgoingWebhookUrl": null,
    "createdAt": "2026-10-24T09:15:00.000Z",
    "updatedAt": "2026-10-24T09:20:11.000Z",
    "trigger": {
      "_id": "65f1a2b3c4d5e6f708192a41",
      "name": "Trade bonus trigger",
      "type": "event-ingest",
      "status": "idle",
      "options": { "batchIdPath": "metadata.batch_id", "recordIdPaths": ["trade_id"] }
    },
    "nodes": [
      {
        "_id": "65f1a2b3c4d5e6f708192a3c",
        "name": "Read member XP",
        "type": "platform-action",
        "order": 1,
        "continueOnFailure": false,
        "retryOnFailure": false,
        "options": { "action": "get-user-fields", "selectUser": { "type": "email", "value": ["{{65f1a2b3c4d5e6f708192a41.email}}"] }, "fields": [{ "label": "Total XP", "field": "total_xp" }] }
      },
      {
        "_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"], "nestedNodes": [{ "_id": "65f1a2b3c4d5e6f708192a3d", "name": "Add 10 XP", "type": "platform-action", "order": 3, "continueOnFailure": false, "retryOnFailure": false, "options": { "action": "post-user-fields" } }] },
            { "branchName": "Otherwise", "branchType": "FALLBACK", "workflowNodeIds": ["65f1a2b3c4d5e6f708192a3f"], "nestedNodes": [] }
          ]
        }
      }
    ],
    "revision": "162af81f5de4ff2b557a4087de9a9a73a0ed4e621f737787e35a93614cb50d1c",
    "redactedPaths": []
  }
}
curl --request GET \
  --url 'https://api.returning.ai/v1/workflow-builder/data-workflows/<workflowId>' \
  --header 'Authorization: Bearer <API_KEY>'

Response#

HTTP 200 with the workflow in data, and the same revision in the ETag header.

  • nodes is the main line in canvas order. A router carries its branches in options.branches, and each branch lists its member ids in workflowNodeIds with the steps themselves in nestedNodes.
  • revision changes when an authored field changes, including a save made in the canvas. It does not change when a run updates a step's status or the trigger's run state, so a revision read before a run is still valid after it.
  • This is the readback that proves every mutation: read the workflow, match the field you changed, and keep the new revision.
data#object
A workflow with its trigger, its steps in canvas order and its revision.

Eg{ ... }

_id#string
Workflow identifier.

Eg"65f1a2b3c4d5e6f708192a3b"

communityId#string
Community the workflow belongs to.

Eg"65f1a2b3c4d5e6f708192a50"

name#string
Workflow name.

Eg"VIP bonus"

status#string
draft, deployed or undeployed.

Eg"draft"

outgoingWebhookUrl#string
Failure webhook URL, when one is set.

RuleNullable

Egnull

createdAt#string
Creation time.

Eg"2026-10-24T09:15:00.000Z"

updatedAt#string
Last authored change.

Eg"2026-10-24T09:20:11.000Z"

trigger#object
The trigger, or null when the workflow has none.

RuleNullable

Eg{ ... }

_id#string
Trigger identifier. Use it as the source of a reference.

Eg"65f1a2b3c4d5e6f708192a41"

name#string
Display name.

Eg"Trade bonus trigger"

type#string
Trigger type.

Eg"webhook"

status#string
Trigger lifecycle state, for example idle.

Eg"idle"

options#object
Trigger options. A webhook key is shown only in the response that created it.

RuleNullable

Eg{ ... }

nodes#object[]
Main-line steps in canvas order, routers carrying their branches.

Eg[ ... ]

_id#string
Step identifier.

Eg"65f1a2b3c4d5e6f708192a3c"

name#string
Step name.

Eg"Read member XP"

type#string
Step type.

Eg"platform-action"

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
64 hexadecimal characters. Send it back as If-Match; it also arrives as the ETag header.

Eg"162af81f5de4ff2b557a4087de9a9a73a0ed4e621f737787e35a93614cb50d1c"

redactedPaths#string[]
Every location where a credential was replaced by ["__REDACTED__"].

Eg[]

{
  "data": {
    "_id": "65f1a2b3c4d5e6f708192a3b",
    "communityId": "65f1a2b3c4d5e6f708192a50",
    "name": "VIP bonus",
    "status": "draft",
    "outgoingWebhookUrl": null,
    "createdAt": "2026-10-24T09:15:00.000Z",
    "updatedAt": "2026-10-24T09:20:11.000Z",
    "trigger": {
      "_id": "65f1a2b3c4d5e6f708192a41",
      "name": "Trade bonus trigger",
      "type": "webhook",
      "status": "idle",
      "options": {
        "tokenExchangeEnabled": false,
        "apiKey": {
          "enabled": false
        },
        "aesKey": {
          "enabled": false
        }
      }
    },
    "nodes": [
      {
        "_id": "65f1a2b3c4d5e6f708192a3c",
        "name": "Read member XP",
        "type": "platform-action",
        "order": 1,
        "continueOnFailure": false,
        "retryOnFailure": false,
        "options": {
          "action": "get-user-fields",
          "selectUser": {
            "type": "email",
            "value": ["{{65f1a2b3c4d5e6f708192a41.email}}"]
          },
          "fields": [
            {
              "label": "Total XP",
              "field": "total_xp"
            }
          ]
        }
      }
    ],
    "revision": "162af81f5de4ff2b557a4087de9a9a73a0ed4e621f737787e35a93614cb50d1c",
    "redactedPaths": []
  }
}

Errors#

Fix the request04

400VALIDATION_FAILEDFix the request
The id is not 24 hexadecimal characters. Use the id exactly as returned.
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.

Fix the data01

404WORKFLOW_NOT_FOUNDFix the data
Unknown id, or a workflow of another community. Use an id from this community.

Retry with backoff02

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. Retry with bounded backoff.

Retries

Safe to retry: it writes nothing. The revision is stable between authored changes, so a retry returns the same value unless someone edited the workflow in between. If a later write answers 409 VERSION_CONFLICT, re-read here and rebuild the change against the new revision.

{
  "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#

Rename a workflow or set its failure webhookPATCH/v1/workflow-builder/data-workflows/{workflowId}