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

Create a workflow

POST /api/v1/workflows

Creates a cascade from a JSON definition (see CascadeDefinition for the node grammar), owned by the account behind the token. API-created cascades default to trigger_type: manual so they can be run through triggerWorkflow.

active defaults to true. Accounts without production access always get a draft (active: false) — silently, with a note in the response explaining why. Drafts can still be triggered in test mode; only live runs need an activated cascade and an approved account. Requires workflows:write.

Request body

application/json · WorkflowCreateRequest · required

The cascade to create: its name, use case and node definition.

  • name string required
  • definition CascadeDefinition The node graph. Omit or pass `[]` to create an empty draft you fill in later.
  • use_case string Optional use case label.
  • trigger_type string API-created cascades default to `manual` so they can be triggered through this API. Unknown values fall back to `manual`. One of manual event scheduled
  • active boolean Whether the cascade is immediately triggerable in live mode. Omitted or `null` means `true`; pass `false` for a draft. Accounts without production access always receive a draft regardless of this value, and the response carries a `note` explaining why.
Example request
{
  "name": "Tenant Screening Standard",
  "use_case": "tenant_screening",
  "trigger_type": "manual",
  "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": {
          "condition_groups": [
            {
              "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 property minimum."
      }
    }
  ]
}

Responses

  • 201 Created. note is present only when the account lacks production access and the cascade was saved as a 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)
      • 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": 41,
        "object": "workflow",
        "code": "TSS-41",
        "name": "Tenant Screening Standard",
        "active": true,
        "trigger_type": "manual",
        "use_case": "tenant_screening",
        "created_at": "2026-09-09T14:00:00Z",
        "updated_at": "2026-09-09T14:00:00Z"
      },
      "meta": {
        "request_id": "7d4c2f48-9a1b-4c3d-8e2f-1a2b3c4d5e6f"
      }
    }
  • 400 malformed_body (unparseable JSON) or bad_request application/json

    Schema: ErrorEnvelope

    400 example
    {
      "error": {
        "code": "malformed_body",
        "message": "The request body could not be parsed. Send valid JSON matching the Content-Type header.",
        "details": [],
        "request_id": "7d4c2f48-9a1b-4c3d-8e2f-1a2b3c4d5e6f",
        "doc_url": "https://cascades.crscreditapi.com/docs/api/errors/malformed_body"
      }
    }
  • 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 — e.g. blank name, a definition that is not an array of objects, or more than one ApplicantSource node. application/json

    Schema: ErrorEnvelope

    422 example
    {
      "error": {
        "code": "validation_failed",
        "message": "The workflow could not be created.",
        "details": [
          {
            "field": "name",
            "message": "can't be blank"
          }
        ],
        "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?