Sign in to run requests with your own sandbox key. Sign in

Update a workflow

PATCH /api/v1/workflows/{id}

Partial update: only the keys present in the body change. To edit the graph, read it with getWorkflow, modify the array, and send the full definition back. PUT /workflows/{id} is accepted as an alias with identical (partial) semantics.

Setting active: true from an account without production access is refused with 403 activation_forbidden rather than silently dropped. Requires workflows:write.

Path parameters

NameTypeDescription
idrequired integer

Workflow id. Only workflows owned by the token's account resolve; a foreign or deleted id returns 404.

Request body

application/json · WorkflowUpdateRequest · required

The fields to change. Omitted fields keep their current value.

  • name string
  • definition CascadeDefinition Replacement node graph (the full array, not a diff). Read the current one with `getWorkflow` first.
  • use_case string, nullable
  • trigger_type string Unknown values are ignored (the current value is kept). One of manual event scheduled
  • active boolean `true` activates, `false` makes it a draft. Activating requires production access (`403 activation_forbidden` otherwise).
Rename only
{
  "name": "Tenant Screening — Premium"
}

Responses

  • 200 Updated workflow with definition application/json
    • data Workflow

      Schema: WorkflowDetail

      • id integer required
      • object string required
      • code string, nullable Short human-readable code assigned by Cascades.
      • name string required
      • active boolean required `true` = activated and triggerable in live mode. Drafts (`false`) can still be triggered in test mode.
      • trigger_type string required One of manual event scheduled
      • use_case string, nullable
      • created_at string (date-time)
      • updated_at string (date-time)
      • definition array of CascadeNode A cascade's node graph: an ordered array of `CascadeNode` objects. Exactly one `ApplicantSource` node is the entry point; every other node is reached through the edge keys (`next_step`, `pass_steps`, `human_review_steps`, `fail_steps`), each of which is an array of node `id`s that must resolve within the same array. An empty array is accepted on create/update (an empty draft) but cannot be run.

        Schema: CascadeDefinition

        • id string required Unique within the definition, e.g. `step_credit`. Edge keys reference nodes by this value.
        • type string required One of ApplicantSource BillingProduct Product IfElse Condition Wait GoTo ShowResults Action
        • name string Human-readable label shown in the builder and in `step_outputs`.
        • next_step array of string Default forward edge — ids of the node(s) to run next.
        • billing_product_code string `BillingProduct` / `Product` only. The product to pull, e.g. `EQF1003` (Equifax credit), `TUC1001` (TransUnion credit), `CIC4002` (criminal), `CIC4003` (eviction). May also be nested as `config.billing_product_code`.
        • config object Optional per-node configuration. `store_result_as` names the key under which a product's output is stored.
          • store_result_as string
          • billing_product_code string Alternative location for `billing_product_code`.
        • branches object `IfElse` / `Condition` only. Conditions for the `pass` branch and (optionally) the `human_review` branch; anything that matches neither takes `fail_steps`.
          • pass CascadeBranch A branch of an `IfElse` node — one or more condition groups combined with `group_logic`.

            Schema: CascadeBranch

            • group_logic string How the condition groups combine. Defaults to `and`. One of and or
            • condition_groups array of object
              • logic string How the conditions inside this group combine. Defaults to `and`. One of and or
              • conditions array of CascadeCondition required
                • source_node_id string required The `id` of the product node whose output is compared.
                • field string required Exact output field path from that product's schema, e.g. `creditScore.fico9`.
                • operator string required One of equals not_equals greater_than greater_than_or_equal less_than less_than_or_equal contains not_contains starts_with ends_with is_empty is_not_empty is_true is_false
                • value one of The comparison value. Required for every operator except the unary ones (`is_empty`, `is_not_empty`, `is_true`, `is_false`), which accept `null` or no `value` at all.
          • human_review CascadeBranch A branch of an `IfElse` node — one or more condition groups combined with `group_logic`.

            Schema: CascadeBranch

            • group_logic string How the condition groups combine. Defaults to `and`. One of and or
            • condition_groups array of object
              • logic string How the conditions inside this group combine. Defaults to `and`. One of and or
              • conditions array of CascadeCondition required
                • source_node_id string required The `id` of the product node whose output is compared.
                • field string required Exact output field path from that product's schema, e.g. `creditScore.fico9`.
                • operator string required One of equals not_equals greater_than greater_than_or_equal less_than less_than_or_equal contains not_contains starts_with ends_with is_empty is_not_empty is_true is_false
                • value one of The comparison value. Required for every operator except the unary ones (`is_empty`, `is_not_empty`, `is_true`, `is_false`), which accept `null` or no `value` at all.
        • pass_steps array of string `IfElse` only. Node ids to run when the `pass` branch matches.
        • human_review_steps array of string `IfElse` only. Node ids to run when the `human_review` branch matches; the execution pauses with `needs_human_review: true` until a review decision resumes it.
        • fail_steps array of string `IfElse` only. Node ids to run when no branch matches.
        • action_type string `Action` only. One of Approve SendEmail AdverseAction InternalNotification
        • email object `Action` with `action_type: SendEmail`. Fields support `{{variable}}` interpolation from the execution context.
          • to string
          • subject string
          • body string
        • adverse_action object `Action` with `action_type: AdverseAction`. `send_strategy: draft_first` parks the notice for human review before sending.
          • recipient string
          • action_taken string The action box ticked on the notice: `denied` (application denied), `revoked` (credit revoked or terms changed unfavorably), `adverse_employment` (adverse employment action) or `other_action`. Cascades the AI designer generates always use `denied`. One of denied revoked adverse_employment other_action
          • send_strategy string One of draft_first auto_send
          • reason string
        • internal_notification object `Action` with `action_type: InternalNotification`. Operator-facing notification settings.
        • wait object `Wait` only. The delay before the next node runs.
          • duration number
          • unit string One of seconds minutes hours days weeks
        • target_step string `GoTo` only. The node id to jump to.
    • meta Meta

      Schema: Meta

      • request_id string required Correlation id for this request. Also sent as the `X-Request-Id` response header; quote it when contacting support.
    200 example
    {
      "data": {
        "id": 27,
        "object": "workflow",
        "code": "TSS-27",
        "name": "Tenant Screening Standard",
        "active": true,
        "trigger_type": "manual",
        "use_case": "tenant_screening",
        "created_at": "2026-05-08T18:41:05Z",
        "updated_at": "2026-05-08T18:41:05Z",
        "definition": [
          {
            "id": "step_applicant",
            "type": "ApplicantSource",
            "name": "Applicant",
            "next_step": [
              "step_credit"
            ]
          },
          {
            "id": "step_credit",
            "type": "BillingProduct",
            "name": "Credit report",
            "billing_product_code": "EQF1003",
            "next_step": [
              "step_score_check"
            ]
          },
          {
            "id": "step_score_check",
            "type": "IfElse",
            "name": "Score at least 650?",
            "branches": {
              "pass": {
                "group_logic": "and",
                "condition_groups": [
                  {
                    "logic": "and",
                    "conditions": [
                      {
                        "source_node_id": "step_credit",
                        "field": "creditScore.fico9",
                        "operator": "greater_than_or_equal",
                        "value": 650
                      }
                    ]
                  }
                ]
              }
            },
            "pass_steps": [
              "step_approve"
            ],
            "fail_steps": [
              "step_adverse_action"
            ]
          },
          {
            "id": "step_approve",
            "type": "Action",
            "name": "Approve",
            "action_type": "Approve"
          },
          {
            "id": "step_adverse_action",
            "type": "Action",
            "name": "Adverse action",
            "action_type": "AdverseAction",
            "adverse_action": {
              "recipient": "{{applicant.email}}",
              "action_taken": "denied",
              "send_strategy": "draft_first",
              "reason": "Credit score below the minimum required for this property."
            }
          }
        ]
      },
      "meta": {
        "request_id": "7d4c2f48-9a1b-4c3d-8e2f-1a2b3c4d5e6f"
      }
    }
  • 400 malformed_body application/json

    Schema: ErrorEnvelope

    400 example
    {
      "error": {
        "code": "validation_failed",
        "message": "The request could not be processed.",
        "details": [
          {
            "field": "execution_mode",
            "message": "must be test or live"
          }
        ],
        "request_id": "7d4c2f48-9a1b-4c3d-8e2f-1a2b3c4d5e6f",
        "doc_url": "https://cascades.crscreditapi.com/docs/api/errors/validation_failed"
      }
    }
  • 401 Missing, malformed, expired or revoked bearer token. The WWW-Authenticate header carries the RFC 6750 challenge. application/json

    Schema: ErrorEnvelope

    401 example
    {
      "error": {
        "code": "unauthorized",
        "message": "A valid bearer token is required.",
        "details": [],
        "request_id": "7d4c2f48-9a1b-4c3d-8e2f-1a2b3c4d5e6f",
        "doc_url": "https://cascades.crscreditapi.com/docs/api/errors/unauthorized"
      }
    }
  • 403 insufficient_scope or activation_forbidden application/json

    Schema: ErrorEnvelope

    403 example
    {
      "error": {
        "code": "activation_forbidden",
        "message": "Activating a cascade requires production access. It stays a draft, which runs in test mode.",
        "details": [
          {
            "field": "active",
            "message": "requires production access"
          }
        ],
        "request_id": "7d4c2f48-9a1b-4c3d-8e2f-1a2b3c4d5e6f",
        "doc_url": "https://cascades.crscreditapi.com/docs/api/errors/activation_forbidden"
      }
    }
  • 404 Resource does not exist or belongs to another tenant / api_client application/json

    Schema: ErrorEnvelope

    404 example
    {
      "error": {
        "code": "not_found",
        "message": "The requested resource was not found.",
        "details": [],
        "request_id": "7d4c2f48-9a1b-4c3d-8e2f-1a2b3c4d5e6f",
        "doc_url": "https://cascades.crscreditapi.com/docs/api/errors/not_found"
      }
    }
  • 422 validation_failed application/json

    Schema: ErrorEnvelope

    422 example
    {
      "error": {
        "code": "validation_failed",
        "message": "The workflow could not be updated.",
        "details": [
          {
            "field": "definition",
            "message": "can only have one Applicant Source node"
          }
        ],
        "request_id": "7d4c2f48-9a1b-4c3d-8e2f-1a2b3c4d5e6f",
        "doc_url": "https://cascades.crscreditapi.com/docs/api/errors/validation_failed"
      }
    }
  • 429 Rate limit exceeded (60 req/min per IP on /api/v1, 600 req/hour per token prefix, or 300 req/5 min per IP globally). The body is the standard error envelope and Retry-After gives the seconds until the window resets. application/json

    Schema: ErrorEnvelope

    429 example
    {
      "error": {
        "code": "rate_limited",
        "message": "Rate limit exceeded. Retry later.",
        "details": [],
        "request_id": "7d4c2f48-9a1b-4c3d-8e2f-1a2b3c4d5e6f",
        "doc_url": "https://cascades.crscreditapi.com/docs/api/errors/rate_limited"
      }
    }
Was this page helpful?