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

> Lists the branches of a condition step, in execution order.

# List Condition Branches

## How a condition step branches

A condition step (`type: "conditional"`) holds an ordered list of branches. Each branch owns a
sub-sequence — the steps a lead walks once it matches — and the last entry is the **Else** branch,
which catches every lead no other branch matched.

Order is execution priority: lemlist tests the branches top to bottom and the **first match wins**.
The Else branch always runs last and is never part of that race.

A branch is addressed by its `sequenceId`, never by its position. A reorder moves positions around;
the sub-sequence id is what the runtime routes leads to, and what every branch endpoint takes as its
`branchSequenceId`. That same id is also the one you pass to
[`POST /sequences/{sequenceId}/steps`](/api-reference/endpoints/sequences/add-step-to-sequence) to
put steps inside the branch.

## Reading a branch

The `key` is the condition the **step** tests — every branch of a step shares it, so a branch never
carries a condition of its own. What differs from one branch to the next is the value it tests,
returned as structured parameters rather than as a raw Mongo selector:

| Condition                                                            | Fields returned                                 |
| -------------------------------------------------------------------- | ----------------------------------------------- |
| `customLeadInfo`                                                     | `customField`, `customOperator`, `customValues` |
| `hasScore`                                                           | `scoreComparator`, `scoreThreshold`             |
| `hasEmailAddress`                                                    | `emailStatusFilter`                             |
| `aircallDone`                                                        | `callStatusFilter`                              |
| lead-action conditions (`emailsOpened`, `linkedinInviteAccepted`, …) | `delay`, `delayType`                            |

`selector` comes back only when none of those could describe the branch — an unknown or hand-written
shape. Everything else is expressed as parameters you can send straight back to the write endpoints.

<Note>
  `customValues` is an array because a `customLeadInfo` branch may test **several** values: it matches
  when any one of them does. The write endpoints currently take a single `customValue`; a branch
  testing several values is built from the lemlist campaign editor.
</Note>

## Names

`name` is the name someone gave the branch, and it is only present when someone did. lemlist labels
the unnamed branches "Branch 1", "Branch 2", … by rank, and the last one "Else" — those defaults are
display copy, not stored data, so this endpoint does not invent them for you.

## Access

Reading branches is open to everyone. **Writing** them — add, rename, re-select, reorder, delete —
is in closed beta and answers `403` unless the beta is enabled for your team.

## Editing a running campaign

Once leads have entered the campaign, lemlist locks the part of the tree they walk. Adding, removing
and reordering branches, and changing what a branch tests, are then refused with
`409 SEQUENCE_BRANCH_CAMPAIGN_RUNNING` — re-routing live leads would strand those already sent down
the old path.

Two things stay editable on a running campaign:

* **renaming** a branch, which never re-routes anyone;
* the `delay` **value** of a lead-action condition (`hasScore`, `aircallDone`) — how long it waits,
  not what it waits for. Changing `delayType`, or anything else about the selector, still locks.

Deleting a branch has one further guard: it is refused while any lead sits anywhere inside the
branch's sub-tree, checked before anything is written.


## OpenAPI

````yaml get /sequences/{sequenceId}/steps/{stepId}/branches
openapi: 3.0.0
info:
  title: lemlist API
  version: 1.0.0
  description: >-
    Welcome to the lemlist Developer Documentation.


    lemlist is very customizable and open. You'll find on this page all the API
    and integration you can do with lemlist.


    # Rate Limit


    lemlist's API rate limits requests in order to prevent abuse and overload of
    our services.  

    Rate limits are applied on all routes and per API key performing the
    request.  

    The rate limits are **20** requests per **2** seconds.  

    The response provides any information you may need about it:


    | Header | Description |

    | --- | --- |

    | Retry-After | The number of seconds in which you can retry |

    | X-RateLimit-Limit | The maximum requests in that time |

    | X-RateLimit-Remaining | The number of remaining requests you can make |

    | X-RateLimit-Reset | The date when the rate limit will reset |


    _Example of values for the rate limit headers_


    ``` json

    {
        "Retry-After": 2,
        "X-RateLimit-Limit": 20,
        "X-RateLimit-Remaining": 7,
        "X-RateLimit-Reset" : "Tue Feb 16 2021 09:02:42 GMT+0100 (Central European Standard Time)"
    }

     ```

    # Definitions


    ## Team


    A team is the entity of lemlist that can handle users and billing.


    ## Credits


    Credits are the coins a team uses to enrich emails, LinkedIn URLs, etc. via
    the enrich route. Each enrichment feature needs a certain amount of credits
    to run.


    ## User


    You use a user account to connect to lemlist and send messages via the
    connected emails or LinkedIn account.


    ## Campaign


    A campaign is the entity to automate outreach. A campaign has multiple
    sequences composed of steps.


    ## Lead


    A lead is a person that you try to contact via a campaign.


    ## Activity


    An activity is the history of all the steps.


    ## Unsubscribe


    An unsubscribe occurs when a person decides they don't want to receive
    emails from you anymore.


    # Authentication


    All API routes use the dedicated subdomain `api.lemlist.com`.


    lemlist uses API keys to allow access to the API. You can get your lemlist
    API key at our [integration
    page](https://app.lemlist.com/settings/integrations).


    You need to add the `Authorization` header using the `Basic` authentication
    type. `login:password` **where the login is always empty and the password is
    the API key**.


    ⚠️ **Don't forget to add the semicolon (**`:`**) before your API key in curl
    command.**


    > To authorize, use this code: 
      

    ``` shell

    curl https://api.lemlist.com/api/team \
      --user ":YourApiKey"

     ```

    **Make sure to replace** **`YourApiKey`** **with your API key.**


    # Give feedback


    If you want to report a bug, ask for data, or share with us a use case,
    please fill this [form](https://lemlist.typeform.com/to/mfVlkyGf). It will
    help us centralize your needs!
servers:
  - url: https://api.lemlist.com/api
security:
  - basicAuth: []
paths:
  /sequences/{sequenceId}/steps/{stepId}/branches:
    parameters:
      - name: sequenceId
        in: path
        required: true
        description: The unique identifier of the sequence holding the condition step
        example: seq_lkCSKd32qSZZTe5Ru
        schema:
          type: string
      - name: stepId
        in: path
        required: true
        description: >-
          The unique identifier of the condition step, from `GET
          /campaigns/{campaignId}/sequences`
        example: stp_Ae93hiemDkypHLys2
        schema:
          type: string
    get:
      tags:
        - Sequences
      summary: List Condition Branches
      description: >-
        Every branch of a condition step, in execution order, with the Else
        branch last. A condition step holds an ordered list of branches, each
        owning the sub-sequence the leads it matches walk into. Array order is
        execution priority: the first branch whose test matches takes the lead,
        and the Else branch at the end catches everyone no branch matched. A
        branch is addressed by its `sequenceId`, never by position - a reorder
        moves positions, the sub-sequence id is what the runtime routes leads
        to.


        Reading branches is not gated; only the writes are in closed beta.
      parameters: []
      responses:
        '200':
          description: The step's branches, ordered.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ConditionBranch'
              example:
                - sequenceId: seq_jacL5GNH3YpNnuNQ2
                  index: 0
                  key: customLeadInfo
                  name: Decision makers
                  customField: variables.jobTitle
                  customOperator: contains
                  customValues:
                    - CEO
                    - Founder
                - sequenceId: seq_xzrGLxhZwoo5oxukc
                  index: 1
                  key: customLeadInfo
                  customField: variables.jobTitle
                  customOperator: contains
                  customValues:
                    - CTO
                - sequenceId: seq_Kd8pQrLm3Nv6Tz0Wy
                  fallback: true
        '400':
          description: >-
            `SEQUENCE_BRANCH_STEP_NOT_CONDITIONAL` - the step exists but is not
            of type `conditional`. `SEQUENCE_BRANCH_INVALID_PARAM` - a path
            identifier is malformed.
          content:
            application/json:
              example:
                error: This step is not a condition step
                code: SEQUENCE_BRANCH_STEP_NOT_CONDITIONAL
        '401':
          description: Unauthorized - invalid or missing API key
          content:
            text/plain:
              example: The authentication you supplied is incorrect
        '402':
          description: >-
            The team's plan is below the Email Pro floor every sequence route
            sits on.
          content:
            text/plain:
              example: route is available starting emailPro plan
        '404':
          description: >-
            `SEQUENCE_NOT_FOUND` or `SEQUENCE_STEP_NOT_FOUND` - no such sequence
            in this workspace, or no such step on it.
          content:
            application/json:
              example:
                error: Step not found
                code: SEQUENCE_STEP_NOT_FOUND
        '405':
          description: Method not allowed - this path accepts GET, POST and PATCH
        '429':
          description: Rate limit exceeded - 20 requests per 2 seconds per API key
components:
  schemas:
    ConditionBranch:
      type: object
      description: >-
        One branch of a condition step. Addressed by `sequenceId` - the
        sub-sequence its leads walk - never by position. The fields describing
        what the branch tests depend on the step's condition; the ones that do
        not apply are absent.
      properties:
        sequenceId:
          type: string
          description: >-
            The branch's sub-sequence id, and its address on every branch
            endpoint. Pass it to `POST /sequences/{sequenceId}/steps` to add
            steps inside the branch.
        index:
          type: integer
          description: >-
            Execution rank among the non-fallback branches, starting at 0. The
            first branch whose test matches takes the lead. Absent on the Else
            branch, which always runs last.
        fallback:
          type: boolean
          description: >-
            `true` on the Else branch - the one that catches every lead no other
            branch matched. Absent on the others.
        key:
          type: string
          description: >-
            The condition the step tests. Every branch of a step shares it: a
            branch never carries a condition of its own.
        name:
          type: string
          description: >-
            The branch's display name, present only when someone has set one.
            lemlist labels the unnamed ones "Branch 1", "Branch 2", … and
            "Else"; those defaults are not stored and are not returned here.
        delay:
          type: integer
          description: >-
            Length of the time window the condition waits on the lead's action,
            in days. Only on the lead-action conditions that store one.
        delayType:
          type: string
          enum:
            - within
            - waitUntil
          description: >-
            How the condition waits: `within` branches once the window is over,
            `waitUntil` parks the lead until the action happens, with no time
            bound.
        scoreComparator:
          type: string
          enum:
            - $gte
            - $lt
          description: >-
            `hasScore` only - how the lead's score is compared to
            `scoreThreshold`.
        scoreThreshold:
          type: integer
          description: '`hasScore` only - the score this branch tests against.'
        emailStatusFilter:
          type: array
          items:
            type: string
            enum:
              - deliverable
              - risky
              - undeliverable
              - unverified
          description: '`hasEmailAddress` only - the email statuses this branch matches.'
        callStatusFilter:
          type: array
          items:
            type: string
          description: '`aircallDone` only - the call-status keys this branch matches.'
        customField:
          type: string
          description: >-
            `customLeadInfo` only - the tested field, normalized: a lead
            variable reads back as `variables.<name>`, a contact field as
            `fields.<name>`. Every branch of the step tests the same field.
        customOperator:
          type: string
          enum:
            - equal
            - contains
            - empty
            - notEmpty
          description: >-
            `customLeadInfo` only - how the field is compared to the tested
            values.
        customValues:
          type: array
          items:
            type: string
          description: >-
            `customLeadInfo` only - every value this branch tests; the branch
            matches when any of them does. Empty for the `empty` and `notEmpty`
            operators.
        selector:
          type: string
          description: >-
            The raw stored condition selector, as JSON. Returned only when none
            of the fields above could describe the branch.
  securitySchemes:
    basicAuth:
      type: http
      scheme: basic

````