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

> Retrieves all sequences and their steps for a specific campaign.

# Get Campaign Sequences

export const SnippetObjectReference = ({objectName, objectPath = null}) => {
  const lowerCaseObjectName = objectName.toLowerCase();
  if (lowerCaseObjectName === 'lead' || lowerCaseObjectName === 'leads') {
    return <Note>
        This endpoint uses the <a href={`/api-reference/objects-definitions/${objectPath}`}>{objectName} object</a>. Make sure to also check the <a href={`/api-reference/objects-definitions/${lowerCaseObjectName === 'lead' ? 'contact' : 'lead'}`}>{lowerCaseObjectName === 'lead' ? 'Contact' : 'Lead'} object</a> to understand the distinction between the two.
      </Note>;
  }
  return <Note>
      This endpoint uses the <a href={`/api-reference/objects-definitions/${objectPath}`}>{objectName} object</a>.
    </Note>;
};

<SnippetObjectReference objectName="Sequence" objectPath="sequence" />

For example, if the main sequence includes a condition that contains two sequences, you will receive both the sequence tree and all condition sequences in the main sequences array.

On a step running an A/B test, `abTest` and `emailTemplateBId` are set, but the
step's `subject` and `message` are always **variant A's** — read variant B with
[Get A/B Test Variant](/api-reference/endpoints/sequences/get-ab-test-variant).

## Condition steps

A step of type `conditional` carries its branches in `conditions`, in execution order with the Else
branch last. Each entry names the sub-sequence its leads walk — look that `sequenceId` up as a key of
this same response to read the branch's own steps.

| Field | Description |
| - | - |
| `sequenceId` | The branch's sub-sequence id: the key to look up here, and the branch's address on the branch endpoints |
| `key` | The condition the step tests. Every branch shares it; absent on the Else branch |
| `label` | The server-stamped description of what is tested, e.g. `If lead variable "jobTitle" contains "CEO"`. On a step with several branches it doubles as the branch's name when `name` is unset |
| `name` | The name someone gave the branch, when they gave one. The "Branch 1", "Branch 2", … and "Else" labels lemlist displays are not stored |
| `fallback` | `true` on the Else branch, which catches every lead no other branch matched and always comes last |
| `delay`, `delayType` | The time window a lead-action condition waits on, in days. Present instead of `selector` once hydrated |
| `selector` | The raw stored selector, as JSON. `customLeadInfo` and `hasEmailAddress` keep it, since they carry no time window |

<Warning>
  A branch whose `delay` was hydrated has **no** `selector` left, so what it actually tests is not in
  this response at all — a `hasScore` branch shows its window but not its score band, an `aircallDone`
  branch not its call statuses.

  [`GET /sequences/{sequenceId}/steps/{stepId}/branches`](/api-reference/endpoints/sequences/list-condition-branches)
  returns the same branches with everything decoded into parameters (`customField`, `customOperator`,
  `customValues`, `scoreComparator`, `scoreThreshold`, `emailStatusFilter`, `callStatusFilter`,
  `delay`, `delayType`) instead of a raw Mongo fragment. Use it whenever you need to read or edit what
  a branch tests.
</Warning>


## OpenAPI

````yaml get /campaigns/{campaignId}/sequences
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: []
tags:
  - name: Enrichment Providers
    description: >-
      The data providers lemlist can call to find an email or a phone.


      Internal providers are paid with lemlist credits and always available.
      External providers run on your own account: connect one by saving its API
      key, and it becomes available to your waterfalls. `GET
      /enrichments/providers` is the catalog of provider ids accepted by the
      waterfall endpoints.
  - name: Enrichment Waterfalls
    description: >-
      Control which data providers lemlist calls when enriching a contact, and
      in which order.


      A waterfall is an ordered list of providers for one enrichment `type`
      (`email` or `phone`). Providers are tried one after the other until one
      returns a result.


      Every team has exactly one default waterfall per type (`isDefault: true`).
      While its `editor` is `lemlist` it follows the lemlist behaviour:
      providers you connected with your own API key are tried first, then
      internal providers in a random order. Once a team member edits its
      provider list, `editor` becomes that user's id and the list is followed as
      is; resetting it hands it back to `lemlist`.


      Custom waterfalls (`isDefault: false`) carry `conditions` on the contact
      being enriched, keyed by contact property; every key present must match.
      When a contact is enriched, lemlist runs a single waterfall: the custom
      waterfall of the requested type whose conditions match the contact, or the
      default waterfall when none does. If several match, the one with the most
      condition keys wins, then the most recently updated. Only that waterfall
      runs; when it finds nothing, the enrichment ends without falling back to
      another one.
paths:
  /campaigns/{campaignId}/sequences:
    parameters:
      - name: campaignId
        in: path
        required: true
        description: The unique identifier of the campaign
        example: cam_A1B2C3D4E5F6G7H8I9
        schema:
          type: string
    get:
      tags:
        - Sequences
      summary: Get Campaign Sequences
      parameters: []
      responses:
        '200':
          headers:
            Content-Type:
              schema:
                type: string
              example: application/json
          description: Success
          content:
            application/json:
              schema:
                type: object
                description: >-
                  Object where each key is a sequence ID and each value is a
                  sequence object
                additionalProperties:
                  type: object
                  properties:
                    _id:
                      type: string
                      description: The unique identifier of the sequence
                    steps:
                      type: array
                      description: Array of steps in the sequence
                      items:
                        type: object
                        properties:
                          _id:
                            type: string
                            description: The unique identifier of the step
                          delay:
                            type: integer
                            description: The delay in days before executing this step
                          emailTemplateId:
                            type: string
                            description: >-
                              The unique identifier of the email template used
                              for this step
                          type:
                            type: string
                            description: >-
                              The type of step (e.g., email, linkedinSend,
                              linkedinInvite, conditional)
                          index:
                            type: integer
                            description: The position of the step in the sequence
                          sequenceId:
                            type: string
                            description: The unique identifier of the parent sequence
                          sequenceStep:
                            type: integer
                            description: The step number in the sequence
                          message:
                            type: string
                            description: >-
                              The message content for the step (plain text for
                              LinkedIn, HTML for email)
                          subject:
                            type: string
                            description: The email subject line (only for email steps)
                          altMessage:
                            type: string
                            description: >-
                              The LinkedIn note sent instead of `message` in
                              specific cases. On a `linkedinInvite` step it is
                              the premium invitation note, used when the sending
                              account has LinkedIn Premium. On a `linkedinSend`
                              or `linkedinVoiceNote` step it is the
                              out-of-network note, sent as a connection request
                              when the lead is not a 1st-degree connection.
                              Returned only when the step carries one and it is
                              not empty
                          altMessagePremium:
                            type: string
                            description: >-
                              The premium variant of the out-of-network note,
                              sent instead of `altMessage` when the sending
                              LinkedIn account is Premium or Sales Navigator.
                              Only on `linkedinSend` steps, and returned only
                              when it is not empty
                          abTest:
                            description: >-
                              A/B test state for this step. `true` while the
                              test runs (leads are split between variant A and
                              B); `"A"` or `"B"` once a winner is selected;
                              absent or `false` when there is no A/B test.
                              `subject` and `message` are always variant A's —
                              read variant B via Get A/B Test Variant
                            oneOf:
                              - type: boolean
                              - type: string
                                enum:
                                  - A
                                  - B
                          emailTemplateBId:
                            type: string
                            description: >-
                              Email template ID of variant B (present when an
                              A/B test exists on the step)
                          conditions:
                            type: array
                            description: >-
                              The branches of a condition step, in execution
                              order with the Else branch last (only on steps of
                              type `conditional`). Each entry owns the
                              sub-sequence its leads walk; look that
                              `sequenceId` up in this same response to read the
                              branch's own steps. Use `GET
                              /sequences/{sequenceId}/steps/{stepId}/branches`
                              to read the same branches as structured parameters
                              instead of raw selectors.
                            items:
                              type: object
                              properties:
                                sequenceId:
                                  type: string
                                  description: >-
                                    The branch's sub-sequence id - the key to
                                    look up in this response, and the branch's
                                    address on the branch endpoints
                                key:
                                  type: string
                                  description: >-
                                    The condition the step tests. Every branch
                                    of a step shares it; absent on the Else
                                    branch
                                label:
                                  type: string
                                  description: >-
                                    The server-stamped description of what is
                                    tested ("If lead variable \"jobTitle\"
                                    contains \"CEO\""). On a step with several
                                    branches it doubles as the branch's name
                                    when `name` is unset
                                name:
                                  type: string
                                  description: >-
                                    The branch's display name, present only when
                                    someone has set one. The "Branch 1", "Branch
                                    2", … and "Else" defaults lemlist shows are
                                    not stored
                                fallback:
                                  type: boolean
                                  description: >-
                                    `true` on the Else branch, which catches
                                    every lead no other branch matched and
                                    always comes last
                                delay:
                                  type: integer
                                  description: >-
                                    Length of the time window the condition
                                    waits on the lead's action, in days. Only on
                                    lead-action conditions
                                delayType:
                                  type: string
                                  description: >-
                                    How the condition waits: `within` branches
                                    once the window is over, `waitUntil` parks
                                    the lead until the action happens
                                  enum:
                                    - within
                                    - waitUntil
                                selector:
                                  type: string
                                  description: >-
                                    The raw stored condition selector, as JSON.
                                    Present when the condition carries no time
                                    window to hydrate - `customLeadInfo` and
                                    `hasEmailAddress` always keep it
                    level:
                      type: integer
                      description: >-
                        The nesting level of the sequence (0 for main sequence,
                        1+ for nested conditional sequences)
                    parentId:
                      type: string
                      description: >-
                        The unique identifier of the parent sequence (only for
                        conditional sequences)
                    conditionalStepIndex:
                      type: integer
                      description: >-
                        The index of the conditional step that triggers this
                        sequence (only for conditional sequences)
              example:
                seq_rH5RD3fMkkt2gM3YC:
                  _id: seq_rH5RD3fMkkt2gM3YC
                  steps:
                    - _id: stp_sFUj6keaSz9wr049M
                      delay: 0
                      emailTemplateId: etp_ahlbc2yafFyu728H8
                      type: linkedinSend
                      index: 1
                      sequenceId: seq_rH5RD3fMkkt2gM3YC
                      sequenceStep: 0
                      message: >-
                        Hey {{firstName}}, 


                        we're launching an event, a place where people can
                        regularly meet, network, and learn from each other. We
                        would love it if you could join us for a drink & chat
                        next week. What do you say? 😊
                    - _id: stp_qsTl0LO6zkQQJQqsP
                      delay: 1
                      emailTemplateId: etp_HFjUGtyDxIOxgZYcG
                      index: 2
                      sequenceId: seq_rH5RD3fMkkt2gM3YC
                      sequenceStep: 1
                      subject: '{{firstName}}, do we count on you for the event?'
                      message: >-
                        <p style="margin: 0px; box-sizing: border-box;">Hey
                        {{firstName}},<br style="box-sizing: border-box;"><br
                        style="box-sizing: border-box;"></p>

                        <p style="margin: 0px; box-sizing: border-box;">Do you
                        have any plans for Thursday, 7pm?<br style="box-sizing:
                        border-box;"><br style="box-sizing: border-box;"></p>

                        <p style="margin: 0px; box-sizing: border-box;">What
                        about spending the evening with cool people by our
                        office?<br style="box-sizing: border-box;"><br
                        style="box-sizing: border-box;"></p>

                        <p style="margin: 0px; box-sizing: border-box;">We're
                        launching an event, a place where people can regularly
                        meet, network, and build connections that help them grow
                        further 😊<br style="box-sizing: border-box;"><br
                        style="box-sizing: border-box;"></p>

                        <p style="margin: 0px; box-sizing: border-box;">It would
                        be really nice if we could count on you for the
                        event-&nbsp;<a target="_blank" style="color: rgb(0, 123,
                        255); text-decoration: none; background-color:
                        transparent; user-select: auto; box-sizing: border-box;"
                        rel="noopener noreferrer"
                        href="{{event_link_to_send}}">here's your
                        invite</a>&nbsp;🔥</p><p style="margin: 0px; box-sizing:
                        border-box;"><br style="box-sizing: border-box;"></p>

                        <p style="margin: 0px; box-sizing: border-box;">Can you
                        make it?<br style="box-sizing: border-box;"><br
                        style="box-sizing: border-box;"></p>

                        <p style="margin: 0px; box-sizing:
                        border-box;">Sarah,</p><p style="margin: 0px;
                        box-sizing: border-box;">Head of Marketing</p>
                      type: email
                    - _id: stp_pRcXzJDmOrBkFtNc3
                      delay: 1
                      emailTemplateId: etp_3tjFTgdOMS6JL8U1g
                      index: 3
                      sequenceId: seq_rH5RD3fMkkt2gM3YC
                      sequenceStep: 2
                      subject: '{{firstName}}, do we count on you for the event?'
                      message: >-
                        <p style="margin: 0px; box-sizing: border-box;">So,
                        should I add you to the list of attendees?<br
                        style="box-sizing: border-box;"><br style="box-sizing:
                        border-box;"></p>

                        <p style="margin: 0px; box-sizing: border-box;">We'll
                        meet around 7pm, have a drink and exchange with
                        entrepreneurs, marketers, and salespeople.<br
                        style="box-sizing: border-box;"><br style="box-sizing:
                        border-box;"></p>

                        <p style="margin: 0px; box-sizing: border-box;"><a
                        target="_blank" style="color: rgb(0, 123, 255);
                        text-decoration: none; background-color: transparent;
                        user-select: auto; box-sizing: border-box;"
                        rel="noopener noreferrer"
                        href="{{event_link_to_send}}">Here's the link</a> if you
                        want to join!<br style="box-sizing: border-box;"><br
                        style="box-sizing: border-box;"></p>

                        <p style="margin: 0px; box-sizing: border-box;">We would
                        love to have you with us for this event!<br
                        style="box-sizing: border-box;"><br style="box-sizing:
                        border-box;">Sarah</p><p style="margin: 0px; box-sizing:
                        border-box;">Head of Marketing</p>
                      type: email
                    - _id: stp_Ae93hiemDkypHLys2
                      delay: 2
                      index: 4
                      sequenceId: seq_rH5RD3fMkkt2gM3YC
                      sequenceStep: 3
                      type: conditional
                      conditions:
                        - sequenceId: seq_jacL5GNH3YpNnuNQ2
                          key: customLeadInfo
                          name: Decision makers
                          label: If lead variable "jobTitle" contains "CEO, Founder"
                          selector: >-
                            {"$or":[{"variables.jobTitle":{"$regex":"CEO","$options":"i"}},{"variables.jobTitle":{"$regex":"Founder","$options":"i"}}]}
                        - sequenceId: seq_xzrGLxhZwoo5oxukc
                          key: customLeadInfo
                          label: If lead variable "jobTitle" contains "CTO"
                          selector: >-
                            {"variables.jobTitle":{"$regex":"CTO","$options":"i"}}
                        - sequenceId: seq_Kd8pQrLm3Nv6Tz0Wy
                          fallback: true
                  level: 0
                seq_jacL5GNH3YpNnuNQ2:
                  _id: seq_jacL5GNH3YpNnuNQ2
                  steps:
                    - _id: stp_Tq5mWx8Rn2Kd7Yz3B
                      delay: 0
                      index: 1
                      sequenceId: seq_jacL5GNH3YpNnuNQ2
                      sequenceStep: 0
                      type: linkedinInvite
                      message: >-
                        Hi {{firstName}}, would love to connect ahead of the
                        event!
                  level: 1
                  parentId: seq_rH5RD3fMkkt2gM3YC
                  conditionalStepIndex: 4
        '400':
          description: 'Possible errors: Bad team / Campaign has no sequence'
          content:
            text/plain:
              example: Bad team
        '401':
          description: The authentication you supplied is incorrect
          content:
            text/plain:
              example: The authentication you supplied is incorrect
        '404':
          description: Campaign not found
          content:
            text/plain:
              example: Campaign not found
        '405':
          description: Method not allowed
components:
  securitySchemes:
    basicAuth:
      type: http
      scheme: basic

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.