Branching sequences
The Branching sequences endpoints of the Kenso API.
Get a campaign's sequence with conditions
/v1/campaigns/{campaignId}/branching-sequencebranching-sequences.getNeeds the sequence_conditions feature on your workspace. Until it is on, calls answer 404.
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
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.400 workspace_required. A workspace you are not a member of answers 404 not_found.Response 200
data is a BranchingSequence.
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"
{
"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
/v1/campaigns/{campaignId}/branching-sequencebranching-sequences.replaceNeeds the sequence_conditions feature on your workspace. Until it is on, calls answer 404.
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
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.400 workspace_required. A workspace you are not a member of answers 404 not_found.Request body
application/json, optional.
segmentId (null for the campaign's default sequence) and its steps. A tree with no condition removes the sequence with conditions.modifiedAt from your last read. Send it so you do not overwrite an edit made since.Response 200
data is a BranchingSequence.
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"
}'{
"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
}
]
}
}