> ## Documentation Index
> Fetch the complete documentation index at: https://cal.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Manage workflow paths

> Create and update conditional paths with API version 2026-09-22.

Send `cal-api-version: 2026-09-22` to author conditional paths and filters through the workflow POST and PATCH endpoints. All API versions return path definitions on GET. The endpoint reference documents the `2026-09-22` contract. Omitted or older version headers continue to use the legacy echo-only contract. The condition-fields discovery endpoints require `2026-09-22`.

## Create a workflow with paths

Generate a UUID for each branch you want to reference in the same request. This example creates two unconditional branches; add conditions using the field catalog described below. Replace the API key and event type ID with your own.

```bash theme={null}
curl --request POST 'https://api.cal.com/v2/workflows' \
  --header 'Authorization: Bearer cal_YOUR_API_KEY' \
  --header 'cal-api-version: 2026-09-22' \
  --header 'Content-Type: application/json' \
  --data '{
    "name": "Booking follow-up",
    "trigger": { "type": "newEvent" },
    "activation": { "isActiveOnAllEventTypes": false, "activeOnEventTypeIds": [123] },
    "steps": [
      {
        "action": "paths",
        "paths": [
          {
            "id": "11111111-1111-4111-8111-111111111111",
            "name": "First branch",
            "matches": "all",
            "conditions": []
          },
          {
            "id": "22222222-2222-4222-8222-222222222222",
            "name": "Second branch",
            "matches": "all",
            "conditions": []
          }
        ]
      },
      {
        "action": "email_attendee",
        "stepNumber": 1,
        "pathId": "11111111-1111-4111-8111-111111111111",
        "sender": "Cal",
        "recipient": "attendee",
        "template": "reminder",
        "message": {
          "subject": "Thanks for booking",
          "html": "We look forward to meeting you."
        }
      }
    ]
  }'
```

The same step shapes work on organization/team event-type workflows at `/v2/organizations/{orgId}/teams/{teamId}/workflows`. Routing-form workflows retain their existing echo-only API contract; author their paths in the canvas.

## Discover and write conditions

Read the catalog for the workflow you want to edit:

* `GET /v2/workflows/{workflowId}/condition-fields`
* `GET /v2/organizations/{orgId}/teams/{teamId}/workflows/{workflowId}/condition-fields`

Each field provides its `id`, `type`, supported `operators`, allowed `options`, `missingFrom` warnings and `hasTypeConflict`. Operator IDs are the canvas's raw keys: for example, a text comparison can use `equal`, while a select uses `select_equals`. Use IDs and option values from your catalog, not labels. For example, if your catalog includes a text field with ID `company`, a condition can be:

```json theme={null}
{ "field": "company", "operator": "equal", "values": ["Acme"] }
```

Condition IDs are generated when omitted. Send the returned IDs when updating conditions. New or changed conditions must be valid for the effective trigger and activation. Unchanged conditions can be echoed even if their field was subsequently removed.

The catalog includes at most 100 active entities. `truncated: true` means the catalog is incomplete; changed conditions cannot be authored against that partial catalog. Reduce the activation scope before authoring them. An empty activation scope returns no fields.

## Update the complete step list

On version `2026-09-22`, PATCH with `steps` replaces the desired step list:

* Include every sending step and gate you want to retain, using the IDs returned by GET.
* Omit a gate or sending step to delete it. Remove references to deleted paths from the remaining steps.
* Omit a sending step's `pathId` to make it unconditional.
* Omit `steps` entirely to leave the graph unchanged, for example when renaming a workflow.
* Omit `paths` on an existing paths step to preserve its branches and conditions. When supplying `paths`, include every branch you want to retain.
* Existing delay and lead enrichment steps must still be echoed by ID and keep their relative order; the API cannot create or edit them.
* A delay or lead enrichment step keeps its branch membership, so the gate owning that branch cannot be deleted through the API. Remove it on the canvas.
* A request accepts at most 100 steps.

The API numbers unconditional steps first, followed by gates and their descendants. Gates do not take `stepNumber`. A split requires at least two branches, and a workflow supports at most one split. Filters can be nested without cycles. Existing path IDs cannot move between gates, and condition IDs cannot move between paths.

Each branch or filter accepts four matching modes:

* `all`: every condition matches.
* `any`: at least one condition matches.
* `none`: no conditions match.
* `not_all`: at least one condition does not match. For example, with “country is US” and “company size is enterprise,” the branch matches unless both conditions are true.

Omitting `matches` preserves an existing mode and defaults to `all` for a new branch. GET returns the exact mode, including `not_all` for paths previously created in the canvas. Echoing it preserves the rule; sending another mode changes it. The API does not expose database conjunction or negation flags.

A filter carries `conditions`, `matches` and its owned `gatedPathId` on the step itself. Member steps reference that `gatedPathId` through `pathId`. Generate the UUID yourself when creating a filter and members in one request.

## Migrate older callers

Without the new version header, PATCH continues to require an echo of every existing paths/filter gate and member step by ID. Their definitions and memberships are preserved; path-authoring fields in an old-version echo are ignored. Old versions cannot create gates.

When opting into `2026-09-22`, update your client to send the complete desired step list and each retained member's `pathId`. Previously omitted steps could be protected by the legacy echo guard; the new contract treats omissions as deletions. Validation or ownership rejection leaves the workflow graph and activation unchanged.
