Kenso

Branching sequences

The Branching sequences endpoints of the Kenso API.

2 endpointsKen-Version: 1.1AuthenticationWorkspacesErrors

Get a campaign's sequence with conditions

GET/v1/campaigns/{campaignId}/branching-sequencebranching-sequences.get

Needs the sequence_conditions feature on your workspace. Until it is on, calls answer 404.

Try it on developer.ken.so

Returns the saved tree (segments), the draft workflow it compiles to (workflowId), modifiedAt, whether each condition kind is available on this campaign (conditions; email_opened is unavailable with reason open_tracking_off when the campaign does not track opens), and run counts per node (stats). A campaign with no sequence with conditions returns empty segments and no workflowId.

Errors:

- 404 not_found: the campaign does not exist in this workspace.

Requires Campaigns view.

Parameters

Name
In
Type
Required
Description
campaignId
In: path
integer (int64)
required
The campaign's id.
Ken-Version
In: header
string, one of: 2026-11-02, 1.1
optional
The API version, a date in YYYY-MM-DD form. 1.1 is another name for the first dated version. Leave it out to use your API key's pinned version. Keys created in the Kenso app are pinned to the newest version; keys minted by the CLI login are not. A key with no pinned version and no header gets the legacy shape where the path has one, and 404 where the path exists only in this version. A date that is not a version answers 400 unsupported_version; any other value that is not a version is treated as legacy.
X-Ken-Workspace-Id
In: header
integer (int64)
optional
The id of the workspace to act in. Leave it out when your API key reaches only one workspace. When the key reaches more than one, a request without this header answers 400 workspace_required. A workspace you are not a member of answers 404 not_found.

Response 200

data is a BranchingSequence.

Field
Type
Description
campaignId
integer (int64)
segments
array of BranchingSegment
The tree, one entry per segment. Empty when the campaign has no sequence with conditions.
workflowId
integer (int64)
The campaign workflow the tree compiles to, saved as a draft. Absent when nothing is saved.
modifiedAt
string (date-time)
When the tree was last saved. Send it back as expectedModifiedAt. Absent when nothing is saved.
conditions
array of BranchingConditionAvailability
Every condition kind and whether this campaign can use it.
stats
array of BranchingNodeStats
Run counts per node id of the tree.
Request
curl -X GET "https://api.ken.so/v1/campaigns/812/branching-sequence" \
  -H "Authorization: Bearer $KEN_API_KEY" \
  -H "Ken-Version: 1.1" \
  -H "X-Ken-Workspace-Id: $KEN_WORKSPACE_ID"
Response 200
{
  "success": true,
  "data": {
    "campaignId": 812,
    "segments": [
      {
        "segmentId": 812,
        "steps": [
          {
            "id": "string",
            "type": "string",
            "waitDays": 1,
            "subject": "string",
            "body": "string",
            "text": "string",
            "condition": {},
            "timing": {},
            "yes": [],
            "no": [],
            "campaignId": 812
          }
        ]
      }
    ],
    "workflowId": 812,
    "modifiedAt": "2026-09-23T15:02:11Z",
    "conditions": [
      {
        "kind": "string",
        "available": true,
        "reason": "string"
      }
    ],
    "stats": [
      {
        "nodeId": "string",
        "reached": 1,
        "completed": 1
      }
    ]
  }
}

Replace a campaign's sequence with conditions

PUT/v1/campaigns/{campaignId}/branching-sequencebranching-sequences.replace

Needs the sequence_conditions feature on your workspace. Until it is on, calls answer 404.

Try it on developer.ken.so

Saves the tree you send and compiles it to the campaign's workflow as a draft. Kenso never publishes that workflow here. Send the modifiedAt from your last read as expectedModifiedAt.

Each segment entry has a segmentId (a segment of the campaign, or null for the default sequence) and steps. Step types: email (waitDays, subject, body), linkedin_connect (waitDays, text up to 300 characters), linkedin_message (waitDays, text), condition (condition, timing, yes, no) and move_to_campaign (campaignId). A condition or a move ends its list. Node ids are 1 to 40 of a-z, 0-9 and _, unique in the tree. waitDays is 0 to 30. At most 100 nodes and 6 levels of conditions.

Conditions on what the contact does (email_opened, link_clicked, replied, meeting_booked, linkedin_invite_accepted, linkedin_message_engaged, unsubscribed) need a step before them and a timing: within 1 to 30 days, or wait_until, which has no no path. Conditions on the contact's data (has_email, has_linkedin_url, has_phone, lead_score with operator gte, lte or eq and a number value, and custom_variable with variable, operator equals or contains and a text value) take no timing.

A tree with no condition removes the sequence with conditions in any campaign status, and the campaign keeps its email and LinkedIn sequences. Only a draft campaign takes a tree with conditions.

Errors:

- 400 validation_failed: the tree breaks a rule above (each detail names the field and the step), email_opened on a campaign that does not track opens (open_tracking_off), or a tree with conditions on a campaign that is not a draft (campaign_not_draft). - 404 not_found: the campaign does not exist in this workspace. - 409 conflict with a stale_write detail on expectedModifiedAt: the sequence changed since your read.

Requires Campaigns edit.

Parameters

Name
In
Type
Required
Description
campaignId
In: path
integer (int64)
required
The campaign's id.
Ken-Version
In: header
string, one of: 2026-11-02, 1.1
optional
The API version, a date in YYYY-MM-DD form. 1.1 is another name for the first dated version. Leave it out to use your API key's pinned version. Keys created in the Kenso app are pinned to the newest version; keys minted by the CLI login are not. A key with no pinned version and no header gets the legacy shape where the path has one, and 404 where the path exists only in this version. A date that is not a version answers 400 unsupported_version; any other value that is not a version is treated as legacy.
X-Ken-Workspace-Id
In: header
integer (int64)
optional
The id of the workspace to act in. Leave it out when your API key reaches only one workspace. When the key reaches more than one, a request without this header answers 400 workspace_required. A workspace you are not a member of answers 404 not_found.

Request body

application/json, optional.

Field
Type
Required
Description
segments
array of BranchingSegment
optional
The tree, one entry per segment: segmentId (null for the campaign's default sequence) and its steps. A tree with no condition removes the sequence with conditions.
expectedModifiedAt
string (date-time)
optional
The modifiedAt from your last read. Send it so you do not overwrite an edit made since.

Response 200

data is a BranchingSequence.

Field
Type
Description
campaignId
integer (int64)
segments
array of BranchingSegment
The tree, one entry per segment. Empty when the campaign has no sequence with conditions.
workflowId
integer (int64)
The campaign workflow the tree compiles to, saved as a draft. Absent when nothing is saved.
modifiedAt
string (date-time)
When the tree was last saved. Send it back as expectedModifiedAt. Absent when nothing is saved.
conditions
array of BranchingConditionAvailability
Every condition kind and whether this campaign can use it.
stats
array of BranchingNodeStats
Run counts per node id of the tree.
Request
curl -X PUT "https://api.ken.so/v1/campaigns/812/branching-sequence" \
  -H "Authorization: Bearer $KEN_API_KEY" \
  -H "Ken-Version: 1.1" \
  -H "X-Ken-Workspace-Id: $KEN_WORKSPACE_ID" \
  -H "Content-Type: application/json" \
  -d '{
  "segments": [
    {
      "segmentId": 812,
      "steps": [
        {
          "id": "string",
          "type": "string",
          "waitDays": 1,
          "subject": "string",
          "body": "string",
          "text": "string",
          "condition": {
            "kind": "string",
            "variable": "string",
            "operator": "string",
            "value": null
          },
          "timing": {
            "mode": "string",
            "days": 1
          },
          "yes": [
            {}
          ],
          "no": [
            {}
          ],
          "campaignId": 812
        }
      ]
    }
  ],
  "expectedModifiedAt": "2026-09-23T15:02:11Z"
}'
Response 200
{
  "success": true,
  "data": {
    "campaignId": 812,
    "segments": [
      {
        "segmentId": 812,
        "steps": [
          {
            "id": "string",
            "type": "string",
            "waitDays": 1,
            "subject": "string",
            "body": "string",
            "text": "string",
            "condition": {},
            "timing": {},
            "yes": [],
            "no": [],
            "campaignId": 812
          }
        ]
      }
    ],
    "workflowId": 812,
    "modifiedAt": "2026-09-23T15:02:11Z",
    "conditions": [
      {
        "kind": "string",
        "available": true,
        "reason": "string"
      }
    ],
    "stats": [
      {
        "nodeId": "string",
        "reached": 1,
        "completed": 1
      }
    ]
  }
}