> ## 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.

> Renames a branch and/or changes what it tests.

# Update Condition Branch

<Note>
  New to condition branches? Start with
  [List Condition Branches](/api-reference/endpoints/sequences/list-condition-branches), which explains
  how a step branches and how a branch is addressed.
</Note>

Send only the halves you want to change. A body that changes nothing is refused with
`SEQUENCE_BRANCH_NO_UPDATE`.

## Renaming

`name` is the branch's display name. An empty string clears it, and lemlist goes back to labelling
the branch by its rank ("Branch 1", "Branch 2", …). The Else branch cannot be renamed:
`SEQUENCE_BRANCH_IS_FALLBACK`.

## Changing what the branch tests

Send the same parameters
[`POST /sequences/{sequenceId}/steps`](/api-reference/endpoints/sequences/add-step-to-sequence) takes
for a condition — `customField`, `customOperator`, `customValue`, `scoreComparator`,
`scoreThreshold`, `emailStatusFilter`, `callStatusFilter`. `conditionKey` is refused: every branch of
a step shares the step's condition, and changing it is a change to the step, not to one branch.

On a `customLeadInfo` step, changing `customField` changes it on **every** branch — a step tests one
field, and each branch keeps its own operator and values.

## The two halves are gated differently

Once leads have entered the campaign:

| Body                                           | Result                                                                           |
| ---------------------------------------------- | -------------------------------------------------------------------------------- |
| `{ "name": "Founders" }`                       | applied — a rename never re-routes a lead                                        |
| `{ "customValue": "CTO" }`                     | `409` — re-routing live leads would strand those already sent down the old value |
| `{ "name": "Founders", "customValue": "CTO" }` | `409`, **and the rename does not land either**                                   |

The request is atomic, so a mixed body is refused whole. Send the rename on its own when that is all
you need.

One selector edit escapes the lock: on a lead-action condition (`hasScore`, `aircallDone`), a body
carrying only `delay` changes how long the condition waits, not what it waits for, and is applied.
Adding any other selector field to that body locks it again.


## OpenAPI

````yaml patch /sequences/{sequenceId}/steps/{stepId}/branches/{branchSequenceId}
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/{branchSequenceId}:
    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
      - name: branchSequenceId
        in: path
        required: true
        description: >-
          The branch's own sub-sequence id, from `GET
          /sequences/{sequenceId}/steps/{stepId}/branches`. A branch is never
          addressed by its position.
        example: seq_jacL5GNH3YpNnuNQ2
        schema:
          type: string
    patch:
      tags:
        - Sequences
      summary: Update Condition Branch
      description: >-
        Renames a branch and/or changes what it tests. Send only the halves you
        want to change.


        The two halves are gated differently once leads have entered the
        campaign: a rename still goes through, while re-selecting what the
        branch tests is refused with `409`. A body that does both on a running
        campaign is refused whole - the request is atomic, so the rename does
        not land either. Send the rename on its own if that is what you need.


        `conditionKey` is refused: every branch of a step shares the step's
        condition. The Else branch is neither renamable nor editable.
      parameters: []
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  description: >-
                    The branch's display name. An empty string clears it, and
                    lemlist falls back to labelling the branch "Branch 1",
                    "Branch 2", … by rank. The Else branch cannot be named.
                delayType:
                  type: string
                  enum:
                    - within
                    - waitUntil
                  description: >-
                    How a lead-action condition waits: `within` branches once
                    the `delay` window is over, `waitUntil` parks the lead until
                    the action happens, with no time bound. Ignored by the
                    conditions that store no time window (`customLeadInfo`,
                    `hasEmailAddress`).
                delay:
                  type: integer
                  description: Length of that time window, in days.
                scoreComparator:
                  type: string
                  enum:
                    - $gte
                    - $lt
                  description: >-
                    `hasScore` only - how the lead's score is compared to
                    `scoreThreshold`.
                scoreThreshold:
                  type: integer
                  minimum: 0
                  maximum: 100
                  description: '`hasScore` only - the score this branch tests against.'
                emailStatusFilter:
                  type: array
                  minItems: 1
                  items:
                    type: string
                    enum:
                      - deliverable
                      - risky
                      - undeliverable
                      - unverified
                  description: >-
                    `hasEmailAddress` only - the email statuses this branch
                    matches. Required to add a branch on that condition.
                callStatusFilter:
                  type: array
                  minItems: 1
                  items:
                    type: string
                  description: >-
                    `aircallDone` only - the call-status keys this branch
                    matches. The keys are the team's own (defaults plus custom
                    dispositions), so any non-empty string is accepted. Required
                    to add a branch on that condition.
                customField:
                  type: string
                  description: >-
                    `customLeadInfo` only - the field to test. A bare name reads
                    as a lead variable (`jobTitle` becomes
                    `variables.jobTitle`); prefix with `fields.` to test a
                    contact field. Every branch of a step tests the same field,
                    so changing it here changes it on all of them.
                customOperator:
                  type: string
                  enum:
                    - equal
                    - contains
                    - empty
                    - notEmpty
                  description: >-
                    `customLeadInfo` only - how the field is compared. `equal`
                    and `contains` need a `customValue`; `empty` and `notEmpty`
                    refuse one.
                customValue:
                  type: string
                  description: >-
                    `customLeadInfo` only - the value the field is compared to.
                    Required for `equal` and `contains`, and refused for `empty`
                    and `notEmpty`.
            examples:
              Rename only:
                value:
                  name: Founders and CEOs
              Clear the name:
                value:
                  name: ''
              Change the tested value:
                value:
                  customOperator: equal
                  customValue: CTO
              Widen the score band:
                value:
                  scoreComparator: $gte
                  scoreThreshold: 60
      responses:
        '200':
          description: The branch as it now stands.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ConditionBranch'
              example:
                sequenceId: seq_jacL5GNH3YpNnuNQ2
                index: 0
                key: customLeadInfo
                name: Founders and CEOs
                customField: variables.jobTitle
                customOperator: contains
                customValues:
                  - CEO
                  - Founder
        '400':
          description: >-
            `SEQUENCE_BRANCH_NO_UPDATE` - the body changed nothing.
            `SEQUENCE_BRANCH_IS_FALLBACK` - the Else branch cannot be renamed or
            edited. `SEQUENCE_BRANCH_CONDITION_KEY_NOT_ALLOWED` - `conditionKey`
            was sent. `SEQUENCE_BRANCH_UPDATE_REJECTED` - the change did not
            apply. `SEQUENCE_BRANCH_INVALID_PARAM` - a malformed body or path
            identifier. A bad `customField`, `customOperator` or `customValue`
            answers with a plain message and no `code` - for instance
            `customValue is required for operator "contains"`.
          content:
            application/json:
              example:
                error: Nothing to update
                code: SEQUENCE_BRANCH_NO_UPDATE
        '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
        '403':
          description: >-
            `SEQUENCE_BRANCH_BETA_REQUIRED` - branch writes are in closed beta
            and answer `403` unless the beta is enabled for your team. Reading
            branches is not gated.
          content:
            application/json:
              example:
                error: Condition branches are not enabled for this team
                code: SEQUENCE_BRANCH_BETA_REQUIRED
        '404':
          description: >-
            `SEQUENCE_NOT_FOUND`, `SEQUENCE_STEP_NOT_FOUND` or
            `SEQUENCE_BRANCH_NOT_FOUND` - no such sequence, step, or branch on
            that step.
          content:
            application/json:
              example:
                error: No branch with this sequenceId on this step
                code: SEQUENCE_BRANCH_NOT_FOUND
        '405':
          description: Method not allowed - this path accepts PATCH and DELETE
        '409':
          description: >-
            `SEQUENCE_BRANCH_CAMPAIGN_RUNNING` - leads have entered the
            campaign, which freezes the branch structure. Renaming a branch
            stays allowed.
          content:
            application/json:
              example:
                error: >-
                  You cannot add, remove or reorder branches once leads have
                  entered the campaign
                code: SEQUENCE_BRANCH_CAMPAIGN_RUNNING
        '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

````