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

Generate a workflow from a prompt

POST /api/v1/workflows/generate

Builds a cascade definition from a plain-English policy description using the AI builder, validates it (with one automatic repair pass), and — by default — saves it as a new workflow exactly like createWorkflow (same draft rule for sandbox accounts, same note). Pass create: false to receive the generated definition as a preview without saving anything.

Generation shares a small concurrency budget with the in-app designer; when every slot is busy the call returns 503 designer_busy and should be retried after a short delay. Requires workflows:write.

Request body

application/json · WorkflowGenerateRequest · required

A plain-language description of the screening policy to turn into a cascade.

  • prompt string required Plain-English description of the decision policy to turn into a cascade (max 5 000 characters by default).
  • name string Optional name override; otherwise the generator names the cascade.
  • use_case string Optional use case label. Defaults to `tenant_screening`.
  • create boolean `true` (default) saves the generated cascade and returns `201`; `false` returns the generated definition as a `200` preview without saving.
Generate and save
{
  "prompt": "Pull an Equifax credit report. Approve if FICO is at least 650; otherwise send an adverse-action notice for review.",
  "use_case": "tenant_screening"
}

Responses

  • 201 Generated and saved. generation describes the AI pass; note appears for sandbox accounts (draft). application/json
    • data Workflow + SandboxDraftNote
      • 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)
      • generation CascadeGeneration Metadata about the AI generation that produced a definition.

        Schema: CascadeGeneration

        • name string The name the generator chose.
        • model string The model that produced the definition.
        • repaired boolean `true` when the first draft failed validation and a repair pass fixed it.
        • warnings array of CascadeGenerationWarning Non-blocking findings from the definition validator (unreachable nodes, compliance hints).
          • node_id string required The `id` of the node the finding is about.
          • code string required Machine-readable finding. Current codes: `unreachable_node`, `missing_adverse_action`, `generic_adverse_action_reason`, `folded_thresholds`, `jurisdiction_review`.
          • message string required Human-readable explanation with the suggested fix.
      • note string Present only when the account lacks production access and the cascade was therefore created as a draft.
    • 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.
    201 example
    {
      "data": {
        "id": 42,
        "object": "workflow",
        "code": "FCS-42",
        "name": "FICO 650 Screening",
        "active": true,
        "trigger_type": "manual",
        "use_case": "tenant_screening",
        "created_at": "2026-09-09T14:10:00Z",
        "updated_at": "2026-09-09T14:10:00Z",
        "generation": {
          "name": "FICO 650 Screening",
          "model": "claude-opus-4-8",
          "repaired": false,
          "warnings": []
        }
      },
      "meta": {
        "request_id": "7d4c2f48-9a1b-4c3d-8e2f-1a2b3c4d5e6f"
      }
    }
  • 200 Preview (create: false). Nothing was saved. application/json
    • data CascadeGenerationPreview Returned by `generateWorkflow` when `create` is `false`. Nothing is saved.

      Schema: CascadeGenerationPreview

      • object string One of cascade_generation
      • 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.
      • valid boolean Whether the definition passed the validator.
      • name string
      • model string
      • repaired boolean
      • warnings array of CascadeGenerationWarning
        • node_id string required The `id` of the node the finding is about.
        • code string required Machine-readable finding. Current codes: `unreachable_node`, `missing_adverse_action`, `generic_adverse_action_reason`, `folded_thresholds`, `jurisdiction_review`.
        • message string required Human-readable explanation with the suggested fix.
    • 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": {
        "object": "cascade_generation",
        "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."
            }
          }
        ],
        "valid": true,
        "name": "string",
        "model": "string",
        "repaired": true,
        "warnings": [
          {
            "node_id": "step_fico_check",
            "code": "missing_adverse_action",
            "message": "Decision node \"step_fico_check\" has a fail branch that does not end in an AdverseAction. FCRA declines should send an adverse-action notice."
          }
        ]
      },
      "meta": {
        "request_id": "7d4c2f48-9a1b-4c3d-8e2f-1a2b3c4d5e6f"
      }
    }
  • 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 Token does not hold the required scope. details lists the scope(s) that were checked. application/json

    Schema: ErrorEnvelope

    403 example
    {
      "error": {
        "code": "insufficient_scope",
        "message": "This token does not have the required scope.",
        "details": [
          {
            "field": "scope",
            "message": "executions:write"
          }
        ],
        "request_id": "7d4c2f48-9a1b-4c3d-8e2f-1a2b3c4d5e6f",
        "doc_url": "https://cascades.crscreditapi.com/docs/api/errors/insufficient_scope"
      }
    }
  • 422 validation_failed (blank or over-long prompt, or the saved workflow failed validation) or generation_failed (the model could not produce a valid definition; details lists the validator's findings). application/json

    Schema: ErrorEnvelope

    422 example
    {
      "error": {
        "code": "generation_failed",
        "message": "The generated cascade did not pass validation.",
        "details": [
          {
            "field": "definition",
            "message": "Decision node \"step_score_check\" uses operator \">=\", which is not valid."
          }
        ],
        "request_id": "7d4c2f48-9a1b-4c3d-8e2f-1a2b3c4d5e6f",
        "doc_url": "https://cascades.crscreditapi.com/docs/api/errors/generation_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"
      }
    }
  • 503 designer_busy — every generation slot is in use. Retry after a few seconds. application/json

    Schema: ErrorEnvelope

    503 example
    {
      "error": {
        "code": "designer_busy",
        "message": "The cascade designer is busy right now. Please try again in a moment.",
        "details": [],
        "request_id": "7d4c2f48-9a1b-4c3d-8e2f-1a2b3c4d5e6f",
        "doc_url": "https://cascades.crscreditapi.com/docs/api/errors/designer_busy"
      }
    }
Was this page helpful?