# Sequence

## List sequences

**get** `/v1/sequences`

Returns a paginated list of sequences, including ones that have never been published. Results are sorted by when the sequence was created (`createdAt`), newest first. Use `offset` and `limit` to paginate through results, and bracketed filters to narrow the list. See <u>[List endpoints](/using-the-api/list-endpoints/)</u> for more information about pagination.

Supported filters: `status[equal]` (DRAFT, ACTIVE, DEACTIVATED), `channels[contains]` (EMAIL, LINKEDIN), and `createdAt`, `firstActivatedAt` or `lastActivatedAt` with `[greaterThanOrEqual]` or `[lessThanOrEqual]` (ISO 8601 timestamps with a timezone). Filters are combined with AND.

**[Required scope](/using-the-api/scopes/):** `sequences:read`

**[Rate limit category](/using-the-api/rate-limits/):** Search

### Query Parameters

- `limit: optional number`

  Maximum number of records to return. Defaults to 25, maximum 25.

- `offset: optional number`

  Number of records to skip for pagination. Defaults to 0.

### Returns

- `SequenceListResponse object { data, object, totalCount }`

  - `data: array of object { id, channels, createdAt, 8 more }`

    - `id: string`

      Unique identifier of the sequence.

    - `channels: array of "EMAIL" or "LINKEDIN"`

      Channels the published steps send on; empty before the first publish.

      - `"EMAIL"`

      - `"LINKEDIN"`

    - `createdAt: string`

      ISO 8601 creation timestamp.

    - `definition: object { description, messaging, pacing, 3 more }`

      Published configuration, or null before the first publish.

      - `description: string`

        What this version of the sequence is for.

      - `messaging: object { callToAction, persona, trigger, valueProp }`

        Messaging inputs that frame every step.

        - `callToAction: string`

          What the recipient is asked to do.

        - `persona: string`

          Who the sequence targets.

        - `trigger: string`

          Why the outreach is timely.

        - `valueProp: string`

          The value proposition.

      - `pacing: object { EMAIL, LINKEDIN_INVITE, LINKEDIN_MESSAGE }`

        How the whole sequence paces each step type it sends, keyed by sequence step type.

        - `EMAIL: object { dailyLimit }`

          Email steps.

          - `dailyLimit: number`

            Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

        - `LINKEDIN_INVITE: object { dailyLimit }`

          LinkedIn connection requests.

          - `dailyLimit: number`

            Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

        - `LINKEDIN_MESSAGE: object { dailyLimit }`

          LinkedIn messages.

          - `dailyLimit: number`

            Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

      - `priority: "HIGH" or "NORMAL"`

        Send priority relative to other sequences.

        - `"HIGH"`

        - `"NORMAL"`

      - `sendWindow: object { daysOfWeek, endHour, startHour, timezone }`

        When the sequence may send.

        - `daysOfWeek: array of number`

          Days sends may go out, 0 = Sunday.

        - `endHour: number`

          Local hour sends stop, exclusive (1–24).

        - `startHour: number`

          First local hour sends may go out (0–23).

        - `timezone: string`

          IANA timezone of the window.

      - `steps: array of object { id, deliveryMode, mode, 3 more }  or object { id, deliveryMode, includeNote, 4 more }  or object { id, deliveryMode, mode, 3 more }  or 3 more`

        Email, LinkedIn and wait steps in execution order.

        - `object { id, deliveryMode, mode, 3 more }`

          - `id: string`

            Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

          - `deliveryMode: "AUTO" or "FOR_REVIEW"`

            `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

            - `"AUTO"`

            - `"FOR_REVIEW"`

          - `mode: "AGENT"`

            How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

            - `"AGENT"`

          - `name: string`

            Display name of the step.

          - `prompt: string`

            Instructions the agent follows when composing this message.

          - `type: "EMAIL" or "LINKEDIN_MESSAGE"`

            Step type.

            - `"EMAIL"`

            - `"LINKEDIN_MESSAGE"`

        - `object { id, deliveryMode, includeNote, 4 more }`

          - `id: string`

            Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

          - `deliveryMode: "AUTO" or "FOR_REVIEW"`

            `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

            - `"AUTO"`

            - `"FOR_REVIEW"`

          - `includeNote: boolean`

            Whether the connection request carries a note. A step authored before this setting existed reads as true.

          - `mode: "AGENT"`

            How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

            - `"AGENT"`

          - `name: string`

            Display name of the step.

          - `prompt: string`

            Instructions the agent follows when composing this message.

          - `type: "LINKEDIN_INVITE"`

            Step type.

            - `"LINKEDIN_INVITE"`

        - `object { id, deliveryMode, mode, 3 more }`

          - `id: string`

            Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

          - `deliveryMode: "AUTO" or "FOR_REVIEW"`

            `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

            - `"AUTO"`

            - `"FOR_REVIEW"`

          - `mode: "TEMPLATE"`

            How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

            - `"TEMPLATE"`

          - `name: string`

            Display name of the step.

          - `template: object { body, subject }`

            The email every contact receives.

            - `body: string`

              Email body as Markdown, without the sign-off or signature, which are added when the message is written. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

            - `subject: string`

              Plain-text subject line. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

          - `type: "EMAIL"`

            Step type.

            - `"EMAIL"`

        - `object { id, deliveryMode, mode, 3 more }`

          - `id: string`

            Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

          - `deliveryMode: "AUTO" or "FOR_REVIEW"`

            `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

            - `"AUTO"`

            - `"FOR_REVIEW"`

          - `mode: "TEMPLATE"`

            How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

            - `"TEMPLATE"`

          - `name: string`

            Display name of the step.

          - `template: object { body }`

            The message every contact receives; for an invite, its connection note, sent only with `includeNote`.

            - `body: string`

              Plain-text message. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

          - `type: "LINKEDIN_MESSAGE"`

            Step type.

            - `"LINKEDIN_MESSAGE"`

        - `object { id, deliveryMode, includeNote, 4 more }`

          - `id: string`

            Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

          - `deliveryMode: "AUTO" or "FOR_REVIEW"`

            `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

            - `"AUTO"`

            - `"FOR_REVIEW"`

          - `includeNote: boolean`

            Whether the connection request carries a note. A step authored before this setting existed reads as true.

          - `mode: "TEMPLATE"`

            How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

            - `"TEMPLATE"`

          - `name: string`

            Display name of the step.

          - `template: object { body }`

            The message every contact receives; for an invite, its connection note, sent only with `includeNote`.

            - `body: string`

              Plain-text message. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

          - `type: "LINKEDIN_INVITE"`

            Step type.

            - `"LINKEDIN_INVITE"`

        - `object { id, duration, type, unit }`

          - `id: string`

            Step identifier.

          - `duration: number`

            Length of the wait.

          - `type: "WAIT" or "WAIT_FOR_CONNECTION"`

            `WAIT` pauses for a fixed time; `WAIT_FOR_CONNECTION` waits up to that long for a LinkedIn invite to be accepted.

            - `"WAIT"`

            - `"WAIT_FOR_CONNECTION"`

          - `unit: "DAY" or "MINUTE"`

            Unit of `duration`.

            - `"DAY"`

            - `"MINUTE"`

    - `firstActivatedAt: string`

      When the sequence was first activated.

    - `lastActivatedAt: string`

      When the sequence was most recently activated.

    - `name: string`

      Name of the sequence.

    - `objectType: "sequence"`

      Always `sequence`.

      - `"sequence"`

    - `reviewers: array of object { id, objectType }`

      Extra members who may approve this sequence’s `FOR_REVIEW` messages before they send. The sending member and the sequence’s creator always review, whether or not they are listed.

      - `id: string`

        ID of the member.

      - `objectType: "member"`

        Always `member`.

        - `"member"`

    - `senders: array of object { id, objectType }`

      The senders this sequence sends from; new contacts rotate across them. An archived sender stays listed but never sends; any change to the list drops it.

      - `id: string`

        ID of the sender.

      - `objectType: "sender"`

        Always `sender`.

        - `"sender"`

    - `status: "DRAFT" or "ACTIVE" or "DEACTIVATED"`

      `DRAFT` has not been published; `ACTIVE` is enabled for sending; `DEACTIVATED` is published but paused.

      - `"DRAFT"`

      - `"ACTIVE"`

      - `"DEACTIVATED"`

  - `object: "list"`

    - `"list"`

  - `totalCount: number`

### Example

```http
curl https://api.lightfield.app/v1/sequences \
    -H 'Lightfield-Version: 2026-03-01' \
    -H "Authorization: Bearer $API_KEY"
```

#### Response

```json
{
  "data": [
    {
      "id": "id",
      "channels": [
        "EMAIL"
      ],
      "createdAt": "createdAt",
      "definition": {
        "description": "description",
        "messaging": {
          "callToAction": "callToAction",
          "persona": "persona",
          "trigger": "trigger",
          "valueProp": "valueProp"
        },
        "pacing": {
          "EMAIL": {
            "dailyLimit": -9007199254740991
          },
          "LINKEDIN_INVITE": {
            "dailyLimit": -9007199254740991
          },
          "LINKEDIN_MESSAGE": {
            "dailyLimit": -9007199254740991
          }
        },
        "priority": "HIGH",
        "sendWindow": {
          "daysOfWeek": [
            -9007199254740991
          ],
          "endHour": -9007199254740991,
          "startHour": -9007199254740991,
          "timezone": "timezone"
        },
        "steps": [
          {
            "id": "id",
            "deliveryMode": "AUTO",
            "mode": "AGENT",
            "name": "name",
            "prompt": "prompt",
            "type": "EMAIL"
          }
        ]
      },
      "firstActivatedAt": "firstActivatedAt",
      "lastActivatedAt": "lastActivatedAt",
      "name": "name",
      "objectType": "sequence",
      "reviewers": [
        {
          "id": "x",
          "objectType": "member"
        }
      ],
      "senders": [
        {
          "id": "x",
          "objectType": "sender"
        }
      ],
      "status": "DRAFT"
    }
  ],
  "object": "list",
  "totalCount": -9007199254740991
}
```

## Retrieve a sequence

**get** `/v1/sequences/{id}`

Retrieves a single sequence by its ID. Edits that have not been published are not included; those can be read with [Retrieve a sequence draft](/api/resources/sequence/methods/retrieveDraft).

**[Required scope](/using-the-api/scopes/):** `sequences:read`

**[Rate limit category](/using-the-api/rate-limits/):** Read

### Path Parameters

- `id: string`

  Unique identifier of the sequence to retrieve.

### Returns

- `SequenceRetrieveResponse object { id, channels, createdAt, 8 more }`

  - `id: string`

    Unique identifier of the sequence.

  - `channels: array of "EMAIL" or "LINKEDIN"`

    Channels the published steps send on; empty before the first publish.

    - `"EMAIL"`

    - `"LINKEDIN"`

  - `createdAt: string`

    ISO 8601 creation timestamp.

  - `definition: object { description, messaging, pacing, 3 more }`

    Published configuration, or null before the first publish.

    - `description: string`

      What this version of the sequence is for.

    - `messaging: object { callToAction, persona, trigger, valueProp }`

      Messaging inputs that frame every step.

      - `callToAction: string`

        What the recipient is asked to do.

      - `persona: string`

        Who the sequence targets.

      - `trigger: string`

        Why the outreach is timely.

      - `valueProp: string`

        The value proposition.

    - `pacing: object { EMAIL, LINKEDIN_INVITE, LINKEDIN_MESSAGE }`

      How the whole sequence paces each step type it sends, keyed by sequence step type.

      - `EMAIL: object { dailyLimit }`

        Email steps.

        - `dailyLimit: number`

          Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

      - `LINKEDIN_INVITE: object { dailyLimit }`

        LinkedIn connection requests.

        - `dailyLimit: number`

          Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

      - `LINKEDIN_MESSAGE: object { dailyLimit }`

        LinkedIn messages.

        - `dailyLimit: number`

          Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

    - `priority: "HIGH" or "NORMAL"`

      Send priority relative to other sequences.

      - `"HIGH"`

      - `"NORMAL"`

    - `sendWindow: object { daysOfWeek, endHour, startHour, timezone }`

      When the sequence may send.

      - `daysOfWeek: array of number`

        Days sends may go out, 0 = Sunday.

      - `endHour: number`

        Local hour sends stop, exclusive (1–24).

      - `startHour: number`

        First local hour sends may go out (0–23).

      - `timezone: string`

        IANA timezone of the window.

    - `steps: array of object { id, deliveryMode, mode, 3 more }  or object { id, deliveryMode, includeNote, 4 more }  or object { id, deliveryMode, mode, 3 more }  or 3 more`

      Email, LinkedIn and wait steps in execution order.

      - `object { id, deliveryMode, mode, 3 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `mode: "AGENT"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"AGENT"`

        - `name: string`

          Display name of the step.

        - `prompt: string`

          Instructions the agent follows when composing this message.

        - `type: "EMAIL" or "LINKEDIN_MESSAGE"`

          Step type.

          - `"EMAIL"`

          - `"LINKEDIN_MESSAGE"`

      - `object { id, deliveryMode, includeNote, 4 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `includeNote: boolean`

          Whether the connection request carries a note. A step authored before this setting existed reads as true.

        - `mode: "AGENT"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"AGENT"`

        - `name: string`

          Display name of the step.

        - `prompt: string`

          Instructions the agent follows when composing this message.

        - `type: "LINKEDIN_INVITE"`

          Step type.

          - `"LINKEDIN_INVITE"`

      - `object { id, deliveryMode, mode, 3 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `mode: "TEMPLATE"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"TEMPLATE"`

        - `name: string`

          Display name of the step.

        - `template: object { body, subject }`

          The email every contact receives.

          - `body: string`

            Email body as Markdown, without the sign-off or signature, which are added when the message is written. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

          - `subject: string`

            Plain-text subject line. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

        - `type: "EMAIL"`

          Step type.

          - `"EMAIL"`

      - `object { id, deliveryMode, mode, 3 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `mode: "TEMPLATE"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"TEMPLATE"`

        - `name: string`

          Display name of the step.

        - `template: object { body }`

          The message every contact receives; for an invite, its connection note, sent only with `includeNote`.

          - `body: string`

            Plain-text message. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

        - `type: "LINKEDIN_MESSAGE"`

          Step type.

          - `"LINKEDIN_MESSAGE"`

      - `object { id, deliveryMode, includeNote, 4 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `includeNote: boolean`

          Whether the connection request carries a note. A step authored before this setting existed reads as true.

        - `mode: "TEMPLATE"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"TEMPLATE"`

        - `name: string`

          Display name of the step.

        - `template: object { body }`

          The message every contact receives; for an invite, its connection note, sent only with `includeNote`.

          - `body: string`

            Plain-text message. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

        - `type: "LINKEDIN_INVITE"`

          Step type.

          - `"LINKEDIN_INVITE"`

      - `object { id, duration, type, unit }`

        - `id: string`

          Step identifier.

        - `duration: number`

          Length of the wait.

        - `type: "WAIT" or "WAIT_FOR_CONNECTION"`

          `WAIT` pauses for a fixed time; `WAIT_FOR_CONNECTION` waits up to that long for a LinkedIn invite to be accepted.

          - `"WAIT"`

          - `"WAIT_FOR_CONNECTION"`

        - `unit: "DAY" or "MINUTE"`

          Unit of `duration`.

          - `"DAY"`

          - `"MINUTE"`

  - `firstActivatedAt: string`

    When the sequence was first activated.

  - `lastActivatedAt: string`

    When the sequence was most recently activated.

  - `name: string`

    Name of the sequence.

  - `objectType: "sequence"`

    Always `sequence`.

    - `"sequence"`

  - `reviewers: array of object { id, objectType }`

    Extra members who may approve this sequence’s `FOR_REVIEW` messages before they send. The sending member and the sequence’s creator always review, whether or not they are listed.

    - `id: string`

      ID of the member.

    - `objectType: "member"`

      Always `member`.

      - `"member"`

  - `senders: array of object { id, objectType }`

    The senders this sequence sends from; new contacts rotate across them. An archived sender stays listed but never sends; any change to the list drops it.

    - `id: string`

      ID of the sender.

    - `objectType: "sender"`

      Always `sender`.

      - `"sender"`

  - `status: "DRAFT" or "ACTIVE" or "DEACTIVATED"`

    `DRAFT` has not been published; `ACTIVE` is enabled for sending; `DEACTIVATED` is published but paused.

    - `"DRAFT"`

    - `"ACTIVE"`

    - `"DEACTIVATED"`

### Example

```http
curl https://api.lightfield.app/v1/sequences/$ID \
    -H 'Lightfield-Version: 2026-03-01' \
    -H "Authorization: Bearer $API_KEY"
```

#### Response

```json
{
  "id": "id",
  "channels": [
    "EMAIL"
  ],
  "createdAt": "createdAt",
  "definition": {
    "description": "description",
    "messaging": {
      "callToAction": "callToAction",
      "persona": "persona",
      "trigger": "trigger",
      "valueProp": "valueProp"
    },
    "pacing": {
      "EMAIL": {
        "dailyLimit": -9007199254740991
      },
      "LINKEDIN_INVITE": {
        "dailyLimit": -9007199254740991
      },
      "LINKEDIN_MESSAGE": {
        "dailyLimit": -9007199254740991
      }
    },
    "priority": "HIGH",
    "sendWindow": {
      "daysOfWeek": [
        -9007199254740991
      ],
      "endHour": -9007199254740991,
      "startHour": -9007199254740991,
      "timezone": "timezone"
    },
    "steps": [
      {
        "id": "id",
        "deliveryMode": "AUTO",
        "mode": "AGENT",
        "name": "name",
        "prompt": "prompt",
        "type": "EMAIL"
      }
    ]
  },
  "firstActivatedAt": "firstActivatedAt",
  "lastActivatedAt": "lastActivatedAt",
  "name": "name",
  "objectType": "sequence",
  "reviewers": [
    {
      "id": "x",
      "objectType": "member"
    }
  ],
  "senders": [
    {
      "id": "x",
      "objectType": "sender"
    }
  ],
  "status": "DRAFT"
}
```

## Retrieve sequence performance

**get** `/v1/sequences/{id}/performance`

Retrieves a sequence’s lifetime engagement, totalled by step type and broken down per step, with the live enrollments currently on each step. Test runs are not counted. A sequence that has never been published reports zero counts and no steps.

**[Required scope](/using-the-api/scopes/):** `sequences:read`

**[Rate limit category](/using-the-api/rate-limits/):** Read

### Path Parameters

- `id: string`

  Unique identifier of the sequence.

### Returns

- `SequenceRetrievePerformanceResponse object { byStepType, perStep }`

  - `byStepType: object { EMAIL, LINKEDIN_INVITE, LINKEDIN_MESSAGE, 2 more }`

    Lifetime totals for each step type, across all of its steps.

    - `EMAIL: object { bounced, bounceRate, currentEnrollments, 6 more }`

      Email steps.

      - `bounced: number`

        Sent emails that bounced.

      - `bounceRate: number`

        Bounced divided by sent; null if none sent.

      - `currentEnrollments: number`

        Enrollments currently on steps of this type, paused ones included.

      - `delivered: number`

        Sent minus bounced, never below zero.

      - `opened: number`

        Sent emails that were opened.

      - `openRate: number`

        Opened divided by delivered; null if none delivered.

      - `replied: number`

        Sent messages that received a reply.

      - `replyRate: number`

        Replied divided by delivered; null if none delivered.

      - `sent: number`

        Messages sent.

    - `LINKEDIN_INVITE: object { acceptanceRate, accepted, currentEnrollments, 3 more }`

      LinkedIn connection request steps.

      - `acceptanceRate: number`

        Accepted divided by sent; null if none sent.

      - `accepted: number`

        Connection requests that were accepted.

      - `currentEnrollments: number`

        Enrollments currently on steps of this type, paused ones included.

      - `replied: number`

        Sent messages that received a reply.

      - `replyRate: number`

        Replied divided by sent; null if none sent.

      - `sent: number`

        Messages sent.

    - `LINKEDIN_MESSAGE: object { currentEnrollments, read, readRate, 3 more }`

      LinkedIn message steps.

      - `currentEnrollments: number`

        Enrollments currently on steps of this type, paused ones included.

      - `read: number`

        Sent messages that were read.

      - `readRate: number`

        Read divided by sent; null if none sent.

      - `replied: number`

        Sent messages that received a reply.

      - `replyRate: number`

        Replied divided by sent; null if none sent.

      - `sent: number`

        Messages sent.

    - `WAIT: object { currentEnrollments }`

      Wait steps.

      - `currentEnrollments: number`

        Enrollments currently on steps of this type, paused ones included.

    - `WAIT_FOR_CONNECTION: object { currentEnrollments }`

      Wait-for-connection steps.

      - `currentEnrollments: number`

        Enrollments currently on steps of this type, paused ones included.

  - `perStep: array of object { bounced, bounceRate, currentEnrollments, 8 more }  or object { currentEnrollments, read, readRate, 5 more }  or object { acceptanceRate, accepted, currentEnrollments, 5 more }  or 2 more`

    Per-step statistics in published sequence order, including steps with no activity. Steps no longer in the published definition are included if they have sent messages.

    - `EmailStep object { bounced, bounceRate, currentEnrollments, 8 more }`

      - `bounced: number`

        Sent emails that bounced.

      - `bounceRate: number`

        Bounced divided by sent; null if none sent.

      - `currentEnrollments: number`

        Enrollments currently on this step, paused ones included.

      - `delivered: number`

        Sent minus bounced, never below zero.

      - `opened: number`

        Sent emails that were opened.

      - `openRate: number`

        Opened divided by delivered; null if none delivered.

      - `replied: number`

        Sent messages that received a reply.

      - `replyRate: number`

        Replied divided by delivered; null if none delivered.

      - `sent: number`

        Messages sent.

      - `sequenceStepId: string`

        ID of the step. A step no longer in the published definition keeps its original ID.

      - `sequenceStepType: "EMAIL"`

        - `"EMAIL"`

    - `LinkedInMessageStep object { currentEnrollments, read, readRate, 5 more }`

      - `currentEnrollments: number`

        Enrollments currently on this step, paused ones included.

      - `read: number`

        Sent messages that were read.

      - `readRate: number`

        Read divided by sent; null if none sent.

      - `replied: number`

        Sent messages that received a reply.

      - `replyRate: number`

        Replied divided by sent; null if none sent.

      - `sent: number`

        Messages sent.

      - `sequenceStepId: string`

        ID of the step. A step no longer in the published definition keeps its original ID.

      - `sequenceStepType: "LINKEDIN_MESSAGE"`

        - `"LINKEDIN_MESSAGE"`

    - `LinkedInInviteStep object { acceptanceRate, accepted, currentEnrollments, 5 more }`

      - `acceptanceRate: number`

        Accepted divided by sent; null if none sent.

      - `accepted: number`

        Connection requests that were accepted.

      - `currentEnrollments: number`

        Enrollments currently on this step, paused ones included.

      - `replied: number`

        Sent messages that received a reply.

      - `replyRate: number`

        Replied divided by sent; null if none sent.

      - `sent: number`

        Messages sent.

      - `sequenceStepId: string`

        ID of the step. A step no longer in the published definition keeps its original ID.

      - `sequenceStepType: "LINKEDIN_INVITE"`

        - `"LINKEDIN_INVITE"`

    - `WaitStep object { currentEnrollments, sequenceStepId, sequenceStepType }`

      - `currentEnrollments: number`

        Enrollments currently on this step, paused ones included.

      - `sequenceStepId: string`

        ID of the step. A step no longer in the published definition keeps its original ID.

      - `sequenceStepType: "WAIT"`

        - `"WAIT"`

    - `WaitForConnectionStep object { currentEnrollments, sequenceStepId, sequenceStepType }`

      - `currentEnrollments: number`

        Enrollments currently on this step, paused ones included.

      - `sequenceStepId: string`

        ID of the step. A step no longer in the published definition keeps its original ID.

      - `sequenceStepType: "WAIT_FOR_CONNECTION"`

        - `"WAIT_FOR_CONNECTION"`

### Example

```http
curl https://api.lightfield.app/v1/sequences/$ID/performance \
    -H 'Lightfield-Version: 2026-03-01' \
    -H "Authorization: Bearer $API_KEY"
```

#### Response

```json
{
  "byStepType": {
    "EMAIL": {
      "bounced": -9007199254740991,
      "bounceRate": 0,
      "currentEnrollments": -9007199254740991,
      "delivered": -9007199254740991,
      "opened": -9007199254740991,
      "openRate": 0,
      "replied": -9007199254740991,
      "replyRate": 0,
      "sent": -9007199254740991
    },
    "LINKEDIN_INVITE": {
      "acceptanceRate": 0,
      "accepted": -9007199254740991,
      "currentEnrollments": -9007199254740991,
      "replied": -9007199254740991,
      "replyRate": 0,
      "sent": -9007199254740991
    },
    "LINKEDIN_MESSAGE": {
      "currentEnrollments": -9007199254740991,
      "read": -9007199254740991,
      "readRate": 0,
      "replied": -9007199254740991,
      "replyRate": 0,
      "sent": -9007199254740991
    },
    "WAIT": {
      "currentEnrollments": -9007199254740991
    },
    "WAIT_FOR_CONNECTION": {
      "currentEnrollments": -9007199254740991
    }
  },
  "perStep": [
    {
      "bounced": -9007199254740991,
      "bounceRate": 0,
      "currentEnrollments": -9007199254740991,
      "delivered": -9007199254740991,
      "opened": -9007199254740991,
      "openRate": 0,
      "replied": -9007199254740991,
      "replyRate": 0,
      "sent": -9007199254740991,
      "sequenceStepId": "sequenceStepId",
      "sequenceStepType": "EMAIL"
    }
  ]
}
```

## Retrieve a sequence enrollment

**get** `/v1/sequences/{id}/enrollments/{enrollmentId}`

Retrieves a single enrollment by its ID: the contact’s position in the cadence and its latest activity. Test-run enrollments are not returned.

**[Required scope](/using-the-api/scopes/):** `sequences:read`

**[Rate limit category](/using-the-api/rate-limits/):** Read

### Path Parameters

- `id: string`

  Unique identifier of the sequence.

- `enrollmentId: string`

  Unique identifier of the enrollment to retrieve.

### Returns

- `SequenceRetrieveEnrollmentResponse object { id, cancelledAt, completedAt, 10 more }`

  - `id: string`

    Unique identifier of the enrollment.

  - `cancelledAt: string`

    When the enrollment was cancelled, or null if it was not.

  - `completedAt: string`

    When the enrollment completed, or null if it has not.

  - `contactId: string`

    ID of the enrolled contact.

  - `currentStepId: string`

    ID of the step the contact is on, matching `definition.steps`; null when the contact has no current step the API returns.

  - `enrolledAt: string`

    When the contact was enrolled.

  - `enrolledBy: string`

    Member ID of whoever enrolled the contact; null when they are no longer a member or the enrollment was automatic.

  - `lastActivityAt: string`

    When `lastActivityKind` happened; null when there has been no activity.

  - `lastActivityKind: "SENT" or "OPENED" or "REPLIED" or 4 more`

    The latest activity on the enrollment. A reply or bounce that ended the enrollment is reported over a later open.

    - `"SENT"`

    - `"OPENED"`

    - `"REPLIED"`

    - `"BOUNCED"`

    - `"INVITED"`

    - `"CONNECTED"`

    - `"SEEN"`

  - `nextSendAt: string`

    Estimated time of the next send, from the cadence, send window, pacing and sender; queue order and random gaps can push it later. Null while a message awaits review or is sending, while paused, or when it cannot be estimated.

  - `remainingSends: number`

    Email and LinkedIn steps not yet sent, connection requests included.

  - `repliedAt: string`

    When the contact first replied, on email or LinkedIn; null if they have not.

  - `status: "ACTIVE" or "AWAITING_REVIEW" or "NEEDS_ATTENTION" or 5 more`

    `ACTIVE` is progressing; `AWAITING_REVIEW` has a message waiting for approval; `NEEDS_ATTENTION` is held by a failed step, a held draft or an unavailable sender; `PAUSED` is stopped because the sequence is deactivated or it was paused in Lightfield. `REPLIED`, `COMPLETED`, `CANCELLED` and `FAILED` are final.

    - `"ACTIVE"`

    - `"AWAITING_REVIEW"`

    - `"NEEDS_ATTENTION"`

    - `"REPLIED"`

    - `"COMPLETED"`

    - `"PAUSED"`

    - `"CANCELLED"`

    - `"FAILED"`

### Example

```http
curl https://api.lightfield.app/v1/sequences/$ID/enrollments/$ENROLLMENT_ID \
    -H 'Lightfield-Version: 2026-03-01' \
    -H "Authorization: Bearer $API_KEY"
```

#### Response

```json
{
  "id": "id",
  "cancelledAt": "cancelledAt",
  "completedAt": "completedAt",
  "contactId": "contactId",
  "currentStepId": "currentStepId",
  "enrolledAt": "enrolledAt",
  "enrolledBy": "enrolledBy",
  "lastActivityAt": "lastActivityAt",
  "lastActivityKind": "SENT",
  "nextSendAt": "nextSendAt",
  "remainingSends": -9007199254740991,
  "repliedAt": "repliedAt",
  "status": "ACTIVE"
}
```

## List sequence enrollments

**get** `/v1/sequences/{id}/enrollments`

Returns a paginated list of a sequence’s enrollments, including completed and cancelled ones. Results are sorted by when the contact was enrolled (`enrolledAt`), newest first. Test-run enrollments are not included. Use `offset` and `limit` to paginate through results, and bracketed filters to narrow the list. See <u>[List endpoints](/using-the-api/list-endpoints/)</u> for more information about pagination.

Supported filters: `status[equal]` (ACTIVE, AWAITING_REVIEW, NEEDS_ATTENTION, REPLIED, COMPLETED, PAUSED, CANCELLED, FAILED), `contactId[equal]`, `currentStepId[equal]`, and `enrolledAt`, `lastActivityAt` or `repliedAt` with `[greaterThanOrEqual]` or `[lessThanOrEqual]` (ISO 8601 timestamps with a timezone). Filters are combined with AND.

**[Required scope](/using-the-api/scopes/):** `sequences:read`

**[Rate limit category](/using-the-api/rate-limits/):** Search

### Path Parameters

- `id: string`

  Unique identifier of the sequence.

### Query Parameters

- `limit: optional number`

  Maximum number of records to return. Defaults to 25, maximum 25.

- `offset: optional number`

  Number of records to skip for pagination. Defaults to 0.

### Returns

- `SequenceListEnrollmentsResponse object { data, object, totalCount }`

  - `data: array of object { id, cancelledAt, completedAt, 10 more }`

    - `id: string`

      Unique identifier of the enrollment.

    - `cancelledAt: string`

      When the enrollment was cancelled, or null if it was not.

    - `completedAt: string`

      When the enrollment completed, or null if it has not.

    - `contactId: string`

      ID of the enrolled contact.

    - `currentStepId: string`

      ID of the step the contact is on, matching `definition.steps`; null when the contact has no current step the API returns.

    - `enrolledAt: string`

      When the contact was enrolled.

    - `enrolledBy: string`

      Member ID of whoever enrolled the contact; null when they are no longer a member or the enrollment was automatic.

    - `lastActivityAt: string`

      When `lastActivityKind` happened; null when there has been no activity.

    - `lastActivityKind: "SENT" or "OPENED" or "REPLIED" or 4 more`

      The latest activity on the enrollment. A reply or bounce that ended the enrollment is reported over a later open.

      - `"SENT"`

      - `"OPENED"`

      - `"REPLIED"`

      - `"BOUNCED"`

      - `"INVITED"`

      - `"CONNECTED"`

      - `"SEEN"`

    - `nextSendAt: string`

      Estimated time of the next send, from the cadence, send window, pacing and sender; queue order and random gaps can push it later. Null while a message awaits review or is sending, while paused, or when it cannot be estimated.

    - `remainingSends: number`

      Email and LinkedIn steps not yet sent, connection requests included.

    - `repliedAt: string`

      When the contact first replied, on email or LinkedIn; null if they have not.

    - `status: "ACTIVE" or "AWAITING_REVIEW" or "NEEDS_ATTENTION" or 5 more`

      `ACTIVE` is progressing; `AWAITING_REVIEW` has a message waiting for approval; `NEEDS_ATTENTION` is held by a failed step, a held draft or an unavailable sender; `PAUSED` is stopped because the sequence is deactivated or it was paused in Lightfield. `REPLIED`, `COMPLETED`, `CANCELLED` and `FAILED` are final.

      - `"ACTIVE"`

      - `"AWAITING_REVIEW"`

      - `"NEEDS_ATTENTION"`

      - `"REPLIED"`

      - `"COMPLETED"`

      - `"PAUSED"`

      - `"CANCELLED"`

      - `"FAILED"`

  - `object: "list"`

    - `"list"`

  - `totalCount: number`

### Example

```http
curl https://api.lightfield.app/v1/sequences/$ID/enrollments \
    -H 'Lightfield-Version: 2026-03-01' \
    -H "Authorization: Bearer $API_KEY"
```

#### Response

```json
{
  "data": [
    {
      "id": "id",
      "cancelledAt": "cancelledAt",
      "completedAt": "completedAt",
      "contactId": "contactId",
      "currentStepId": "currentStepId",
      "enrolledAt": "enrolledAt",
      "enrolledBy": "enrolledBy",
      "lastActivityAt": "lastActivityAt",
      "lastActivityKind": "SENT",
      "nextSendAt": "nextSendAt",
      "remainingSends": -9007199254740991,
      "repliedAt": "repliedAt",
      "status": "ACTIVE"
    }
  ],
  "object": "list",
  "totalCount": -9007199254740991
}
```

## List sequence messages

**get** `/v1/sequences/{id}/messages`

Returns a paginated list of a sequence’s messages: every outbound email and LinkedIn message, and each enrollment’s first reply. Results are sorted by `createdAt`, newest first. Superseded outbound attempts are not included, and list items omit content; retrieve a message to read it. Use `offset` and `limit` to paginate through results, and bracketed filters to narrow the list. See <u>[List endpoints](/using-the-api/list-endpoints/)</u> for more information about pagination.

Supported filters: `contactId`, `enrollmentId`, `sequenceStepId`, `sequenceStepType` (EMAIL, LINKEDIN_MESSAGE, LINKEDIN_INVITE), `channel` (EMAIL, LINKEDIN), `direction` (OUTBOUND, INBOUND) and `status` (AWAITING_REVIEW, SCHEDULED, QUEUED, SENT, SKIPPED, FAILED, CANCELLED), with `[equal]` or no operator; and `sentAt`, `openedAt`, `readAt`, `repliedAt`, `bouncedAt`, `acceptedAt` or `receivedAt` with `[greaterThan]`, `[greaterThanOrEqual]`, `[lessThan]` or `[lessThanOrEqual]` (ISO 8601 timestamps with a timezone). Filters are combined with AND; a `status` filter excludes incoming replies.

**[Required scope](/using-the-api/scopes/):** `sequences:read`

**[Rate limit category](/using-the-api/rate-limits/):** Search

### Path Parameters

- `id: string`

  Unique identifier of the sequence.

### Query Parameters

- `limit: optional number`

  Maximum number of records to return. Defaults to 25, maximum 25.

- `offset: optional number`

  Number of records to skip for pagination. Defaults to 0.

### Returns

- `SequenceListMessagesResponse object { data, object, totalCount }`

  - `data: array of object { id, acceptedAt, bouncedAt, 14 more }  or object { id, channel, contactId, 7 more }`

    - `OutboundMessage object { id, acceptedAt, bouncedAt, 14 more }`

      - `id: string`

        Unique identifier of the message.

      - `acceptedAt: string`

        When the connection request was accepted; null until then.

      - `bouncedAt: string`

        When the email bounced; null until then.

      - `channel: "EMAIL" or "LINKEDIN"`

        Channel the message went over.

        - `"EMAIL"`

        - `"LINKEDIN"`

      - `contactId: string`

        ID of the contact.

      - `createdAt: string`

        When the message was created, or when a reply was received. Lists sort by this field, newest first.

      - `direction: "OUTBOUND"`

        Always `OUTBOUND`.

        - `"OUTBOUND"`

      - `enrollmentId: string`

        ID of the enrollment the message belongs to.

      - `openedAt: string`

        When the email was opened; null until then.

      - `readAt: string`

        When the LinkedIn message was read; null until then.

      - `reference: object { id, objectType }  or object { id, objectType }`

        The email or LinkedIn message record behind this sequence message, readable with <u>[Retrieve an email](/api/resources/email/methods/retrieve)</u> or <u>[Retrieve a message](/api/resources/message/methods/retrieve)</u> under their own scopes; null when there is none.

        - `Email object { id, objectType }`

          - `id: string`

            ID of the email.

          - `objectType: "email"`

            Always `email`.

            - `"email"`

        - `Message object { id, objectType }`

          - `id: string`

            ID of the message.

          - `objectType: "message"`

            Always `message`.

            - `"message"`

      - `repliedAt: string`

        When the contact replied to this message; null until then.

      - `sentAt: string`

        When the message was sent; null until then.

      - `sequenceStepId: string`

        ID of the step that sent the message or, for a reply, the step it replied to.

      - `sequenceStepType: "EMAIL" or "LINKEDIN_MESSAGE" or "LINKEDIN_INVITE"`

        Type of that step.

        - `"EMAIL"`

        - `"LINKEDIN_MESSAGE"`

        - `"LINKEDIN_INVITE"`

      - `status: "AWAITING_REVIEW" or "SCHEDULED" or "QUEUED" or 4 more`

        `AWAITING_REVIEW` is waiting for approval; `SCHEDULED` is composed and waiting for its send time; `QUEUED` is due and waiting on the sender. `SENT`, `SKIPPED`, `FAILED` and `CANCELLED` are final.

        - `"AWAITING_REVIEW"`

        - `"SCHEDULED"`

        - `"QUEUED"`

        - `"SENT"`

        - `"SKIPPED"`

        - `"FAILED"`

        - `"CANCELLED"`

      - `statusChangedAt: string`

        When `status` last changed.

    - `Reply object { id, channel, contactId, 7 more }`

      - `id: string`

        Unique identifier of the message.

      - `channel: "EMAIL" or "LINKEDIN"`

        Channel the message went over.

        - `"EMAIL"`

        - `"LINKEDIN"`

      - `contactId: string`

        ID of the contact.

      - `createdAt: string`

        When the message was created, or when a reply was received. Lists sort by this field, newest first.

      - `direction: "INBOUND"`

        Always `INBOUND`.

        - `"INBOUND"`

      - `enrollmentId: string`

        ID of the enrollment the message belongs to.

      - `receivedAt: string`

        When the reply was received.

      - `reference: object { id, objectType }  or object { id, objectType }`

        The email or LinkedIn message record behind this sequence message, readable with <u>[Retrieve an email](/api/resources/email/methods/retrieve)</u> or <u>[Retrieve a message](/api/resources/message/methods/retrieve)</u> under their own scopes; null when there is none.

        - `Email object { id, objectType }`

          - `id: string`

            ID of the email.

          - `objectType: "email"`

            Always `email`.

            - `"email"`

        - `Message object { id, objectType }`

          - `id: string`

            ID of the message.

          - `objectType: "message"`

            Always `message`.

            - `"message"`

      - `sequenceStepId: string`

        ID of the step that sent the message or, for a reply, the step it replied to.

      - `sequenceStepType: "EMAIL" or "LINKEDIN_MESSAGE" or "LINKEDIN_INVITE"`

        Type of that step.

        - `"EMAIL"`

        - `"LINKEDIN_MESSAGE"`

        - `"LINKEDIN_INVITE"`

  - `object: "list"`

    - `"list"`

  - `totalCount: number`

### Example

```http
curl https://api.lightfield.app/v1/sequences/$ID/messages \
    -H 'Lightfield-Version: 2026-03-01' \
    -H "Authorization: Bearer $API_KEY"
```

#### Response

```json
{
  "data": [
    {
      "id": "id",
      "acceptedAt": "acceptedAt",
      "bouncedAt": "bouncedAt",
      "channel": "EMAIL",
      "contactId": "contactId",
      "createdAt": "createdAt",
      "direction": "OUTBOUND",
      "enrollmentId": "enrollmentId",
      "openedAt": "openedAt",
      "readAt": "readAt",
      "reference": {
        "id": "id",
        "objectType": "email"
      },
      "repliedAt": "repliedAt",
      "sentAt": "sentAt",
      "sequenceStepId": "sequenceStepId",
      "sequenceStepType": "EMAIL",
      "status": "AWAITING_REVIEW",
      "statusChangedAt": "statusChangedAt"
    }
  ],
  "object": "list",
  "totalCount": -9007199254740991
}
```

## Retrieve a sequence message

**get** `/v1/sequences/{id}/messages/{messageId}`

Retrieves a single sequence message by its ID: an outbound email or LinkedIn message, or an enrollment’s first reply, with its plain-text content. Content is returned with `sequences:read` regardless of the email’s privacy; see <u>[Sequence message access](/using-the-api/scopes/#sequence-message-access)</u>.

**[Required scope](/using-the-api/scopes/):** `sequences:read`

**[Rate limit category](/using-the-api/rate-limits/):** Read

### Path Parameters

- `id: string`

  Unique identifier of the sequence.

- `messageId: string`

  Unique identifier of the message to retrieve.

### Returns

- `SequenceRetrieveMessageResponse = object { id, acceptedAt, bouncedAt, 15 more }  or object { id, channel, contactId, 8 more }`

  - `OutboundMessage object { id, acceptedAt, bouncedAt, 15 more }`

    - `id: string`

      Unique identifier of the message.

    - `acceptedAt: string`

      When the connection request was accepted; null until then.

    - `bouncedAt: string`

      When the email bounced; null until then.

    - `channel: "EMAIL" or "LINKEDIN"`

      Channel the message went over.

      - `"EMAIL"`

      - `"LINKEDIN"`

    - `contactId: string`

      ID of the contact.

    - `content: object { body, subject }`

      Plain-text content of the message. Null when the underlying record is no longer available; not included in list responses.

      - `body: string`

        Plain-text body; null for a connection request sent without a note.

      - `subject: string`

        Email subject; null for LinkedIn.

    - `createdAt: string`

      When the message was created, or when a reply was received. Lists sort by this field, newest first.

    - `direction: "OUTBOUND"`

      Always `OUTBOUND`.

      - `"OUTBOUND"`

    - `enrollmentId: string`

      ID of the enrollment the message belongs to.

    - `openedAt: string`

      When the email was opened; null until then.

    - `readAt: string`

      When the LinkedIn message was read; null until then.

    - `reference: object { id, objectType }  or object { id, objectType }`

      The email or LinkedIn message record behind this sequence message, readable with <u>[Retrieve an email](/api/resources/email/methods/retrieve)</u> or <u>[Retrieve a message](/api/resources/message/methods/retrieve)</u> under their own scopes; null when there is none.

      - `Email object { id, objectType }`

        - `id: string`

          ID of the email.

        - `objectType: "email"`

          Always `email`.

          - `"email"`

      - `Message object { id, objectType }`

        - `id: string`

          ID of the message.

        - `objectType: "message"`

          Always `message`.

          - `"message"`

    - `repliedAt: string`

      When the contact replied to this message; null until then.

    - `sentAt: string`

      When the message was sent; null until then.

    - `sequenceStepId: string`

      ID of the step that sent the message or, for a reply, the step it replied to.

    - `sequenceStepType: "EMAIL" or "LINKEDIN_MESSAGE" or "LINKEDIN_INVITE"`

      Type of that step.

      - `"EMAIL"`

      - `"LINKEDIN_MESSAGE"`

      - `"LINKEDIN_INVITE"`

    - `status: "AWAITING_REVIEW" or "SCHEDULED" or "QUEUED" or 4 more`

      `AWAITING_REVIEW` is waiting for approval; `SCHEDULED` is composed and waiting for its send time; `QUEUED` is due and waiting on the sender. `SENT`, `SKIPPED`, `FAILED` and `CANCELLED` are final.

      - `"AWAITING_REVIEW"`

      - `"SCHEDULED"`

      - `"QUEUED"`

      - `"SENT"`

      - `"SKIPPED"`

      - `"FAILED"`

      - `"CANCELLED"`

    - `statusChangedAt: string`

      When `status` last changed.

  - `Reply object { id, channel, contactId, 8 more }`

    - `id: string`

      Unique identifier of the message.

    - `channel: "EMAIL" or "LINKEDIN"`

      Channel the message went over.

      - `"EMAIL"`

      - `"LINKEDIN"`

    - `contactId: string`

      ID of the contact.

    - `content: object { body, subject }`

      Plain-text content of the message. Null when the underlying record is no longer available; not included in list responses.

      - `body: string`

        Plain-text body; null for a connection request sent without a note.

      - `subject: string`

        Email subject; null for LinkedIn.

    - `createdAt: string`

      When the message was created, or when a reply was received. Lists sort by this field, newest first.

    - `direction: "INBOUND"`

      Always `INBOUND`.

      - `"INBOUND"`

    - `enrollmentId: string`

      ID of the enrollment the message belongs to.

    - `receivedAt: string`

      When the reply was received.

    - `reference: object { id, objectType }  or object { id, objectType }`

      The email or LinkedIn message record behind this sequence message, readable with <u>[Retrieve an email](/api/resources/email/methods/retrieve)</u> or <u>[Retrieve a message](/api/resources/message/methods/retrieve)</u> under their own scopes; null when there is none.

      - `Email object { id, objectType }`

        - `id: string`

          ID of the email.

        - `objectType: "email"`

          Always `email`.

          - `"email"`

      - `Message object { id, objectType }`

        - `id: string`

          ID of the message.

        - `objectType: "message"`

          Always `message`.

          - `"message"`

    - `sequenceStepId: string`

      ID of the step that sent the message or, for a reply, the step it replied to.

    - `sequenceStepType: "EMAIL" or "LINKEDIN_MESSAGE" or "LINKEDIN_INVITE"`

      Type of that step.

      - `"EMAIL"`

      - `"LINKEDIN_MESSAGE"`

      - `"LINKEDIN_INVITE"`

### Example

```http
curl https://api.lightfield.app/v1/sequences/$ID/messages/$MESSAGE_ID \
    -H 'Lightfield-Version: 2026-03-01' \
    -H "Authorization: Bearer $API_KEY"
```

#### Response

```json
{
  "id": "id",
  "acceptedAt": "acceptedAt",
  "bouncedAt": "bouncedAt",
  "channel": "EMAIL",
  "contactId": "contactId",
  "content": {
    "body": "body",
    "subject": "subject"
  },
  "createdAt": "createdAt",
  "direction": "OUTBOUND",
  "enrollmentId": "enrollmentId",
  "openedAt": "openedAt",
  "readAt": "readAt",
  "reference": {
    "id": "id",
    "objectType": "email"
  },
  "repliedAt": "repliedAt",
  "sentAt": "sentAt",
  "sequenceStepId": "sequenceStepId",
  "sequenceStepType": "EMAIL",
  "status": "AWAITING_REVIEW",
  "statusChangedAt": "statusChangedAt"
}
```

## Enroll and cancel contacts

**post** `/v1/sequences/{id}/enrollments`

Enrolls the contacts in `add` and cancels the open enrollments of the contacts in `remove`, in one request: if any addition is invalid, nothing changes. Send add, remove or both, with at most 25 contact IDs in total; duplicate IDs are ignored, and an ID cannot be in both lists. The response has one result per contact: `enrolled`, `already_enrolled`, `unenrolled`, or `no_active_enrollment` for a removal with nothing open.

A contact already enrolled, paused included, is left as is; one whose earlier enrollment ended is enrolled again. Cancelling stops the contact’s remaining steps and leaves the enrollment readable with status `CANCELLED`. A paused sequence accepts enrollments and sends to them once it is activated; sending starts asynchronously.

Returns 400 `sequence_not_published` for a sequence that has never been published, and 400 `invalid_configuration` with `invalidContacts` naming each contact that cannot be enrolled and why. See <u>[Sequence errors](/using-the-api/errors/#sequence-errors)</u>.

**[Required scope](/using-the-api/scopes/):** `sequences:update`

**[Rate limit category](/using-the-api/rate-limits/):** Write

### Path Parameters

- `id: string`

  Unique identifier of the sequence.

### Body Parameters

- `add: optional array of string`

  Contact IDs to enroll. Open enrollments are unchanged; contacts whose prior enrollment ended are enrolled again.

- `remove: optional array of string`

  Contact IDs to unenroll. Cancels open enrollments and preserves their history.

### Returns

- `SequenceUpdateEnrollmentsResponse object { results }`

  - `results: array of object { contactId, enrollmentId, outcome }  or object { contactId, enrollmentId, outcome }`

    One result per distinct contact, additions first, then removals.

    - `EnrollmentChanged object { contactId, enrollmentId, outcome }`

      - `contactId: string`

        ID of the contact.

      - `enrollmentId: string`

        ID of the enrollment the outcome applies to.

      - `outcome: "enrolled" or "already_enrolled" or "unenrolled"`

        `enrolled` created the enrollment, `already_enrolled` left an open one as is, `unenrolled` cancelled it.

        - `"enrolled"`

        - `"already_enrolled"`

        - `"unenrolled"`

    - `NothingToCancel object { contactId, enrollmentId, outcome }`

      - `contactId: string`

        ID of the contact.

      - `enrollmentId: unknown`

        Always null.

      - `outcome: "no_active_enrollment"`

        The contact had no open enrollment to cancel.

        - `"no_active_enrollment"`

### Example

```http
curl https://api.lightfield.app/v1/sequences/$ID/enrollments \
    -H 'Content-Type: application/json' \
    -H 'Lightfield-Version: 2026-03-01' \
    -H "Authorization: Bearer $API_KEY" \
    -d '{}'
```

#### Response

```json
{
  "results": [
    {
      "contactId": "contactId",
      "enrollmentId": "enrollmentId",
      "outcome": "enrolled"
    }
  ]
}
```

## Start a sequence test

**post** `/v1/sequences/{id}/tests`

Tries the sequence on one contact without sending anything: the contact is enrolled in a test, its steps run back to back with waits skipped, and each message is composed from the contact’s real data and kept as a draft. Use it to check what a step, a template variable or its fallback produces before publishing.

Tests the open draft when there is one or the sequence has never been published, otherwise the published version; `target` in the response says which. Send `expectedVersion` to test exactly the draft you last read. The test continues after the response, so the request returns right away with status `RUNNING`.

Returns 400 `invalid_configuration` with `invalidContacts` naming a contact that does not exist or lacks what a step needs (an email address, a LinkedIn URL or a phone number), or with `issues` when the draft cannot run, 400 `permissions_not_granted` when the draft has agent steps whose permissions are not granted (grant them in Lightfield), 400 `no_selectable_sender` when a channel has no available sender, 409 when `expectedVersion` is not the open draft’s `version`; retrieve the draft and retry, and 429 when a test limit is reached, with a message naming it: the workspace already has 10 tests running (retry once one is `COMPLETED` or `FAILED`), or it started more than 5 tests a minute (retry after `Retry-After` seconds). See <u>[Sequence errors](/using-the-api/errors/#sequence-errors)</u>.

Each call creates a test enrollment and drafts, and agent steps use model credits.

**[Required scope](/using-the-api/scopes/):** `sequences:update`

**[Rate limit category](/using-the-api/rate-limits/):** Write

### Path Parameters

- `id: string`

  Unique identifier of the sequence.

### Body Parameters

- `contactId: string`

  ID of the contact to test the sequence on. The test composes each message from this contact’s real data and sends nothing.

- `expectedVersion: optional string`

  The open draft’s `version` as last read. When sent, the test runs exactly that draft, and is refused with 409 if the draft has changed or none is open. Omit it to test whatever is open now.

### Returns

- `SequenceStartTestResponse object { id, contactId, status, target }`

  - `id: string`

    ID of the test, an enrollment ID. Use it to read the result.

  - `contactId: string`

    ID of the contact being tested.

  - `status: "RUNNING"`

    Always `RUNNING`: the test continues after the response.

    - `"RUNNING"`

  - `target: "DRAFT" or "PUBLISHED"`

    Which version is being tested: the open `DRAFT` when there is one or the sequence was never published, otherwise the `PUBLISHED` version.

    - `"DRAFT"`

    - `"PUBLISHED"`

### Example

```http
curl https://api.lightfield.app/v1/sequences/$ID/tests \
    -H 'Content-Type: application/json' \
    -H 'Lightfield-Version: 2026-03-01' \
    -H "Authorization: Bearer $API_KEY" \
    -d '{
          "contactId": "x"
        }'
```

#### Response

```json
{
  "id": "id",
  "contactId": "contactId",
  "status": "RUNNING",
  "target": "DRAFT"
}
```

## Retrieve a sequence test

**get** `/v1/sequences/{id}/tests/{testId}`

Retrieves the result of a test started with [Start a sequence test](/api/resources/sequence/methods/startTest): its status, and for every step of the tested version whether it composed a message, was skipped or failed. Poll it until `status` is `COMPLETED` or `FAILED`.

An email step’s message is its subject and a markdown body, and a LinkedIn step’s message is its text. A step that failed carries the reason under `error`; a template step whose variable could not be filled for the contact fails this way, naming the fields. Steps that have not run are `PENDING`, including a step a finished test never reached; a step that produced nothing is `SKIPPED`. A test never waits, so a wait is always `SKIPPED`; a send step is `SKIPPED` when it has nothing to send, such as a LinkedIn invite another step already sent. A test never sends anything.

Returns 404 for a test that does not exist, belongs to another sequence, or is a live enrollment: use [Retrieve a sequence enrollment](/api/resources/sequence/methods/retrieveEnrollment) for those.

**[Required scope](/using-the-api/scopes/):** `sequences:read`

**[Rate limit category](/using-the-api/rate-limits/):** Read

### Path Parameters

- `id: string`

  Unique identifier of the sequence.

- `testId: string`

  The `id` returned when the test was started.

### Returns

- `SequenceRetrieveTestResponse object { id, contactId, status, 2 more }`

  - `id: string`

    ID of the test, an enrollment ID.

  - `contactId: string`

    ID of the contact tested.

  - `status: "RUNNING" or "COMPLETED" or "FAILED"`

    `RUNNING` until every step has finished, then `COMPLETED`, or `FAILED` when the test ended on a failure.

    - `"RUNNING"`

    - `"COMPLETED"`

    - `"FAILED"`

  - `steps: array of object { error, message, mode, 4 more }`

    Every step of the tested version that the Sequences API lists, in run order. Call steps are not part of the API yet, so a test reports nothing for them.

    - `error: object { code, message }`

      Why the step failed; null unless `outcome` is `FAILED`.

      - `code: "CONFIGURATION_ERROR" or "SYSTEM_ERROR"`

        `CONFIGURATION_ERROR` when the sequence or the contact needs a change, `SYSTEM_ERROR` when Lightfield failed.

        - `"CONFIGURATION_ERROR"`

        - `"SYSTEM_ERROR"`

      - `message: string`

        What went wrong, in plain words.

    - `message: object { body, subject }  or object { body }`

      The composed message; null when the step has not composed one.

      - `EmailMessage object { body, subject }`

        - `body: string`

          Body as markdown, the same form a template step reads back in.

        - `subject: string`

          Subject line, as composed.

      - `LinkedInMessage object { body }`

        - `body: string`

          Message text, as composed.

    - `mode: "AGENT" or "TEMPLATE"`

      How a send step’s content is composed; null for a wait step.

      - `"AGENT"`

      - `"TEMPLATE"`

    - `name: string`

      Name of the step, as in `definition.steps`; null for a wait step.

    - `outcome: "PENDING" or "COMPOSED" or "SKIPPED" or "FAILED"`

      `PENDING` while the step has not run, including a step a finished test never reached, `COMPOSED` when it produced a message, `SKIPPED` when it produced nothing: a test never waits, so a wait is always `SKIPPED`, and a send step is `SKIPPED` when it has nothing to send, such as a LinkedIn invite another step already sent. `FAILED` when it failed: see `error`.

      - `"PENDING"`

      - `"COMPOSED"`

      - `"SKIPPED"`

      - `"FAILED"`

    - `stepId: string`

      ID of the step, as in the sequence’s `definition.steps`.

    - `type: "EMAIL" or "LINKEDIN_MESSAGE" or "LINKEDIN_INVITE" or 2 more`

      Step type.

      - `"EMAIL"`

      - `"LINKEDIN_MESSAGE"`

      - `"LINKEDIN_INVITE"`

      - `"WAIT"`

      - `"WAIT_FOR_CONNECTION"`

  - `target: "DRAFT" or "PUBLISHED"`

    Which version was tested.

    - `"DRAFT"`

    - `"PUBLISHED"`

### Example

```http
curl https://api.lightfield.app/v1/sequences/$ID/tests/$TEST_ID \
    -H 'Lightfield-Version: 2026-03-01' \
    -H "Authorization: Bearer $API_KEY"
```

#### Response

```json
{
  "id": "id",
  "contactId": "contactId",
  "status": "RUNNING",
  "steps": [
    {
      "error": {
        "code": "CONFIGURATION_ERROR",
        "message": "message"
      },
      "message": {
        "body": "body",
        "subject": "subject"
      },
      "mode": "AGENT",
      "name": "name",
      "outcome": "PENDING",
      "stepId": "stepId",
      "type": "EMAIL"
    }
  ],
  "target": "DRAFT"
}
```

## Create a sequence

**post** `/v1/sequences`

Creates a new sequence and its first draft, and returns the draft. The sequence sends nothing until the draft is published and the sequence is activated.

Supports idempotency via the `Idempotency-Key` header.

Returns 400 `invalid_configuration` listing the draft’s problems under `issues`, and 400 `referenced_resource_missing` for a reviewer or sender that does not exist. See <u>[Sequence errors](/using-the-api/errors/#sequence-errors)</u>.

**[Required scope](/using-the-api/scopes/):** `sequences:create`

**[Rate limit category](/using-the-api/rate-limits/):** Write

### Body Parameters

- `definition: object { description, steps, messaging, 3 more }`

  Configuration of the first draft. `description` and `steps` are required.

  - `description: string`

    What this version of the sequence is for.

  - `steps: array of object { deliveryMode, name, prompt, 2 more }  or object { deliveryMode, name, prompt, 3 more }  or object { deliveryMode, name, template, 2 more }  or 3 more`

    The ordered step list.

    - `object { deliveryMode, name, prompt, 2 more }`

      - `deliveryMode: "AUTO" or "FOR_REVIEW"`

        `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

        - `"AUTO"`

        - `"FOR_REVIEW"`

      - `name: string`

        Display name of the step.

      - `prompt: string`

        Instructions the agent follows when composing this message.

      - `type: "EMAIL" or "LINKEDIN_MESSAGE"`

        Step type.

        - `"EMAIL"`

        - `"LINKEDIN_MESSAGE"`

      - `mode: optional "AGENT"`

        How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in. Optional: the content decides, a `prompt` for `AGENT` and a `template` for `TEMPLATE`. A kept template step sent with a `prompt` is refused unless `mode` is `AGENT`, so its template is never dropped by accident.

        - `"AGENT"`

    - `object { deliveryMode, name, prompt, 3 more }`

      - `deliveryMode: "AUTO" or "FOR_REVIEW"`

        `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

        - `"AUTO"`

        - `"FOR_REVIEW"`

      - `name: string`

        Display name of the step.

      - `prompt: string`

        Instructions the agent follows when composing this message.

      - `type: "LINKEDIN_INVITE"`

        Step type.

        - `"LINKEDIN_INVITE"`

      - `includeNote: optional boolean`

        Whether the connection request carries a note. Defaults to false.

      - `mode: optional "AGENT"`

        How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in. Optional: the content decides, a `prompt` for `AGENT` and a `template` for `TEMPLATE`. A kept template step sent with a `prompt` is refused unless `mode` is `AGENT`, so its template is never dropped by accident.

        - `"AGENT"`

    - `object { deliveryMode, name, template, 2 more }`

      - `deliveryMode: "AUTO" or "FOR_REVIEW"`

        `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

        - `"AUTO"`

        - `"FOR_REVIEW"`

      - `name: string`

        Display name of the step.

      - `template: object { body, subject }`

        The email every contact receives. Requires template steps for the workspace.

        - `body: string`

          Email body as Markdown; paragraphs, bold, italics, links and lists keep their formatting. Leave out the sign-off and signature, which are added when the message is written. A variable cannot be part of a link address. Write each variable as {{ coalesce(<variable>, "fallback") }}, with a fallback for contacts missing the value. A variable reads a contact field as {attr:<id>}, the contact's first or last name as {col:firstName} or {col:lastName}, the contact's first account's field as {rel:account.<id>}, that account's name as {rel:account.col:name}, and the sender's name or email as {rel:sender.col:name} or {rel:sender.col:email}; a SINGLE_SELECT field reads its option's label, as {attr:<id>.label} or {rel:account.<id>.label}. <id> is the literal id of a CrmContact or CrmAccount field in the CRM schema whose type is one of TEXT, NUMBER, CURRENCY, DATETIME, SINGLE_SELECT, FULL_NAME, EMAIL, URL; never a slug, a name, or an id starting with __synthetic_. Nothing else is a variable: leave such a value out rather than reading a different field. A {{ }} that is not a variable would send as written, so it is refused. A field's <id> may be the `ad_` ID the field-definitions endpoints list.

        - `subject: string`

          Plain-text subject line. Write each variable as {{ coalesce(<variable>, "fallback") }}, with a fallback for contacts missing the value. A variable reads a contact field as {attr:<id>}, the contact's first or last name as {col:firstName} or {col:lastName}, the contact's first account's field as {rel:account.<id>}, that account's name as {rel:account.col:name}, and the sender's name or email as {rel:sender.col:name} or {rel:sender.col:email}; a SINGLE_SELECT field reads its option's label, as {attr:<id>.label} or {rel:account.<id>.label}. <id> is the literal id of a CrmContact or CrmAccount field in the CRM schema whose type is one of TEXT, NUMBER, CURRENCY, DATETIME, SINGLE_SELECT, FULL_NAME, EMAIL, URL; never a slug, a name, or an id starting with __synthetic_. Nothing else is a variable: leave such a value out rather than reading a different field. A {{ }} that is not a variable would send as written, so it is refused. A field's <id> may be the `ad_` ID the field-definitions endpoints list.

      - `type: "EMAIL"`

        Step type.

        - `"EMAIL"`

      - `mode: optional "TEMPLATE"`

        How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in. Optional: the content decides, a `prompt` for `AGENT` and a `template` for `TEMPLATE`. A kept template step sent with a `prompt` is refused unless `mode` is `AGENT`, so its template is never dropped by accident.

        - `"TEMPLATE"`

    - `object { deliveryMode, name, template, 2 more }`

      - `deliveryMode: "AUTO" or "FOR_REVIEW"`

        `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

        - `"AUTO"`

        - `"FOR_REVIEW"`

      - `name: string`

        Display name of the step.

      - `template: object { body }`

        The message every contact receives; for an invite, its connection note, sent only with `includeNote` and otherwise left empty. Requires template steps for the workspace.

        - `body: string`

          Plain-text message. Write each variable as {{ coalesce(<variable>, "fallback") }}, with a fallback for contacts missing the value. A variable reads a contact field as {attr:<id>}, the contact's first or last name as {col:firstName} or {col:lastName}, the contact's first account's field as {rel:account.<id>}, that account's name as {rel:account.col:name}, and the sender's name or email as {rel:sender.col:name} or {rel:sender.col:email}; a SINGLE_SELECT field reads its option's label, as {attr:<id>.label} or {rel:account.<id>.label}. <id> is the literal id of a CrmContact or CrmAccount field in the CRM schema whose type is one of TEXT, NUMBER, CURRENCY, DATETIME, SINGLE_SELECT, FULL_NAME, EMAIL, URL; never a slug, a name, or an id starting with __synthetic_. Nothing else is a variable: leave such a value out rather than reading a different field. A {{ }} that is not a variable would send as written, so it is refused. A field's <id> may be the `ad_` ID the field-definitions endpoints list.

      - `type: "LINKEDIN_MESSAGE"`

        Step type.

        - `"LINKEDIN_MESSAGE"`

      - `mode: optional "TEMPLATE"`

        How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in. Optional: the content decides, a `prompt` for `AGENT` and a `template` for `TEMPLATE`. A kept template step sent with a `prompt` is refused unless `mode` is `AGENT`, so its template is never dropped by accident.

        - `"TEMPLATE"`

    - `object { deliveryMode, name, template, 3 more }`

      - `deliveryMode: "AUTO" or "FOR_REVIEW"`

        `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

        - `"AUTO"`

        - `"FOR_REVIEW"`

      - `name: string`

        Display name of the step.

      - `template: object { body }`

        The message every contact receives; for an invite, its connection note, sent only with `includeNote` and otherwise left empty. Requires template steps for the workspace.

        - `body: string`

          Plain-text message. Write each variable as {{ coalesce(<variable>, "fallback") }}, with a fallback for contacts missing the value. A variable reads a contact field as {attr:<id>}, the contact's first or last name as {col:firstName} or {col:lastName}, the contact's first account's field as {rel:account.<id>}, that account's name as {rel:account.col:name}, and the sender's name or email as {rel:sender.col:name} or {rel:sender.col:email}; a SINGLE_SELECT field reads its option's label, as {attr:<id>.label} or {rel:account.<id>.label}. <id> is the literal id of a CrmContact or CrmAccount field in the CRM schema whose type is one of TEXT, NUMBER, CURRENCY, DATETIME, SINGLE_SELECT, FULL_NAME, EMAIL, URL; never a slug, a name, or an id starting with __synthetic_. Nothing else is a variable: leave such a value out rather than reading a different field. A {{ }} that is not a variable would send as written, so it is refused. A field's <id> may be the `ad_` ID the field-definitions endpoints list.

      - `type: "LINKEDIN_INVITE"`

        Step type.

        - `"LINKEDIN_INVITE"`

      - `includeNote: optional boolean`

        Whether the connection request carries a note. Defaults to false.

      - `mode: optional "TEMPLATE"`

        How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in. Optional: the content decides, a `prompt` for `AGENT` and a `template` for `TEMPLATE`. A kept template step sent with a `prompt` is refused unless `mode` is `AGENT`, so its template is never dropped by accident.

        - `"TEMPLATE"`

    - `object { duration, type, unit }`

      - `duration: number`

        Length of the wait.

      - `type: "WAIT" or "WAIT_FOR_CONNECTION"`

        `WAIT` pauses for a fixed time; `WAIT_FOR_CONNECTION` waits up to that long for a LinkedIn invite to be accepted.

        - `"WAIT"`

        - `"WAIT_FOR_CONNECTION"`

      - `unit: "DAY" or "MINUTE"`

        Unit of `duration`.

        - `"DAY"`

        - `"MINUTE"`

  - `messaging: optional object { callToAction, persona, trigger, valueProp }`

    Messaging inputs that frame every step. Omitted or null fields are left unset.

    - `callToAction: optional string`

      What the recipient is asked to do.

    - `persona: optional string`

      Who the sequence targets.

    - `trigger: optional string`

      Why the outreach is timely.

    - `valueProp: optional string`

      The value proposition.

  - `pacing: optional object { EMAIL, LINKEDIN_INVITE, LINKEDIN_MESSAGE }`

    How the whole sequence paces each step type it sends, keyed by sequence step type. Omitted step types have no daily cap.

    - `EMAIL: optional object { dailyLimit }`

      Email steps.

      - `dailyLimit: number`

        Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

    - `LINKEDIN_INVITE: optional object { dailyLimit }`

      LinkedIn connection requests.

      - `dailyLimit: number`

        Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

    - `LINKEDIN_MESSAGE: optional object { dailyLimit }`

      LinkedIn messages.

      - `dailyLimit: number`

        Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

  - `priority: optional "HIGH" or "NORMAL"`

    Send priority relative to other sequences. Defaults to `NORMAL`.

    - `"HIGH"`

    - `"NORMAL"`

  - `sendWindow: optional object { daysOfWeek, endHour, startHour, timezone }`

    When the sequence may send. Omitted fields take the default: 9:00–17:00, Monday to Friday, UTC.

    - `daysOfWeek: optional array of number`

      Days sends may go out, 0 = Sunday.

    - `endHour: optional number`

      Local hour sends stop, exclusive (1–24).

    - `startHour: optional number`

      First local hour sends may go out (0–23).

    - `timezone: optional string`

      IANA timezone of the window.

- `name: string`

  Name of the sequence.

- `reviewers: optional array of string`

  Extra members who may approve this sequence’s `FOR_REVIEW` messages before they send. The sending member and the sequence’s creator always review, whether or not they are listed. Member IDs of active members. Omit for none.

- `senders: optional array of string`

  The senders this sequence sends from; new contacts rotate across them. Sender IDs of unarchived senders. Omit for none; activating needs a sender for each channel the steps use.

### Returns

- `SequenceCreateResponse object { channels, definition, name, 6 more }`

  - `channels: array of "EMAIL" or "LINKEDIN"`

    Channels the draft's steps send on.

    - `"EMAIL"`

    - `"LINKEDIN"`

  - `definition: object { description, messaging, pacing, 3 more }`

    The draft configuration, in the same shape as a published definition.

    - `description: string`

      What this version of the sequence is for.

    - `messaging: object { callToAction, persona, trigger, valueProp }`

      Messaging inputs that frame every step.

      - `callToAction: string`

        What the recipient is asked to do.

      - `persona: string`

        Who the sequence targets.

      - `trigger: string`

        Why the outreach is timely.

      - `valueProp: string`

        The value proposition.

    - `pacing: object { EMAIL, LINKEDIN_INVITE, LINKEDIN_MESSAGE }`

      How the whole sequence paces each step type it sends, keyed by sequence step type.

      - `EMAIL: object { dailyLimit }`

        Email steps.

        - `dailyLimit: number`

          Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

      - `LINKEDIN_INVITE: object { dailyLimit }`

        LinkedIn connection requests.

        - `dailyLimit: number`

          Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

      - `LINKEDIN_MESSAGE: object { dailyLimit }`

        LinkedIn messages.

        - `dailyLimit: number`

          Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

    - `priority: "HIGH" or "NORMAL"`

      Send priority relative to other sequences.

      - `"HIGH"`

      - `"NORMAL"`

    - `sendWindow: object { daysOfWeek, endHour, startHour, timezone }`

      When the sequence may send.

      - `daysOfWeek: array of number`

        Days sends may go out, 0 = Sunday.

      - `endHour: number`

        Local hour sends stop, exclusive (1–24).

      - `startHour: number`

        First local hour sends may go out (0–23).

      - `timezone: string`

        IANA timezone of the window.

    - `steps: array of object { id, deliveryMode, mode, 3 more }  or object { id, deliveryMode, includeNote, 4 more }  or object { id, deliveryMode, mode, 3 more }  or 3 more`

      Email, LinkedIn and wait steps in execution order.

      - `object { id, deliveryMode, mode, 3 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `mode: "AGENT"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"AGENT"`

        - `name: string`

          Display name of the step.

        - `prompt: string`

          Instructions the agent follows when composing this message.

        - `type: "EMAIL" or "LINKEDIN_MESSAGE"`

          Step type.

          - `"EMAIL"`

          - `"LINKEDIN_MESSAGE"`

      - `object { id, deliveryMode, includeNote, 4 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `includeNote: boolean`

          Whether the connection request carries a note. A step authored before this setting existed reads as true.

        - `mode: "AGENT"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"AGENT"`

        - `name: string`

          Display name of the step.

        - `prompt: string`

          Instructions the agent follows when composing this message.

        - `type: "LINKEDIN_INVITE"`

          Step type.

          - `"LINKEDIN_INVITE"`

      - `object { id, deliveryMode, mode, 3 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `mode: "TEMPLATE"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"TEMPLATE"`

        - `name: string`

          Display name of the step.

        - `template: object { body, subject }`

          The email every contact receives.

          - `body: string`

            Email body as Markdown, without the sign-off or signature, which are added when the message is written. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

          - `subject: string`

            Plain-text subject line. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

        - `type: "EMAIL"`

          Step type.

          - `"EMAIL"`

      - `object { id, deliveryMode, mode, 3 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `mode: "TEMPLATE"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"TEMPLATE"`

        - `name: string`

          Display name of the step.

        - `template: object { body }`

          The message every contact receives; for an invite, its connection note, sent only with `includeNote`.

          - `body: string`

            Plain-text message. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

        - `type: "LINKEDIN_MESSAGE"`

          Step type.

          - `"LINKEDIN_MESSAGE"`

      - `object { id, deliveryMode, includeNote, 4 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `includeNote: boolean`

          Whether the connection request carries a note. A step authored before this setting existed reads as true.

        - `mode: "TEMPLATE"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"TEMPLATE"`

        - `name: string`

          Display name of the step.

        - `template: object { body }`

          The message every contact receives; for an invite, its connection note, sent only with `includeNote`.

          - `body: string`

            Plain-text message. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

        - `type: "LINKEDIN_INVITE"`

          Step type.

          - `"LINKEDIN_INVITE"`

      - `object { id, duration, type, unit }`

        - `id: string`

          Step identifier.

        - `duration: number`

          Length of the wait.

        - `type: "WAIT" or "WAIT_FOR_CONNECTION"`

          `WAIT` pauses for a fixed time; `WAIT_FOR_CONNECTION` waits up to that long for a LinkedIn invite to be accepted.

          - `"WAIT"`

          - `"WAIT_FOR_CONNECTION"`

        - `unit: "DAY" or "MINUTE"`

          Unit of `duration`.

          - `"DAY"`

          - `"MINUTE"`

  - `name: string`

    Name the sequence takes when the draft is published.

  - `publishWarnings: array of object { code, message, severity, stepIds }`

    What publishing this draft would change for contacts already in the sequence; empty when nothing is affected. Before the first publish, the only possible warning is a proposed sender that was archived and would be left off.

    - `code: "delay_shortened" or "delay_lengthened" or "connection_wait_shortened" or 18 more`

      What publishing would change.

      - `"delay_shortened"`

      - `"delay_lengthened"`

      - `"connection_wait_shortened"`

      - `"connection_wait_lengthened"`

      - `"send_schedule_changed"`

      - `"send_configuration_changed"`

      - `"send_priority_changed"`

      - `"senders_changed"`

      - `"email_sender_pool_emptied"`

      - `"linkedin_account_pool_emptied"`

      - `"assigned_sender_removed"`

      - `"delivery_became_automatic"`

      - `"invite_note_enabled"`

      - `"invite_note_disabled"`

      - `"step_inserted"`

      - `"automatic_send_step_inserted"`

      - `"step_removed"`

      - `"step_type_changed"`

      - `"step_order_changed"`

      - `"full_identity_rewrite"`

      - `"low_identity_overlap"`

    - `message: string`

      What would change, in plain language.

    - `severity: "warning" or "destructive"`

      `destructive` when contacts already in the sequence may skip, repeat or receive a step they would not have; `warning` otherwise.

      - `"warning"`

      - `"destructive"`

    - `stepIds: array of string`

      The steps involved; empty for a sequence-wide change.

  - `reviewers: array of object { id, objectType }`

    Extra members who may approve this sequence’s `FOR_REVIEW` messages before they send. The sending member and the sequence’s creator always review, whether or not they are listed.

    - `id: string`

      ID of the member.

    - `objectType: "member"`

      Always `member`.

      - `"member"`

  - `senders: array of object { id, objectType }`

    The senders this draft will publish; new contacts rotate across them. Until a save changes it, this is the sequence’s live list. An archived sender stays listed but never sends; any change to the list drops it.

    - `id: string`

      ID of the sender.

    - `objectType: "sender"`

      Always `sender`.

      - `"sender"`

  - `sequenceId: string`

    The sequence this draft belongs to.

  - `updatedAt: string`

    When the draft last changed.

  - `version: string`

    Opaque token for the current state of the draft. Send it as `expectedVersion` on the next save, publish or discard; it changes whenever anyone edits the draft.

### Example

```http
curl https://api.lightfield.app/v1/sequences \
    -H 'Content-Type: application/json' \
    -H 'Lightfield-Version: 2026-03-01' \
    -H "Authorization: Bearer $API_KEY" \
    -d '{
          "definition": {
            "description": "x",
            "steps": [
              {
                "deliveryMode": "AUTO",
                "name": "x",
                "prompt": "x",
                "type": "EMAIL"
              }
            ]
          },
          "name": "x"
        }'
```

#### Response

```json
{
  "channels": [
    "EMAIL"
  ],
  "definition": {
    "description": "description",
    "messaging": {
      "callToAction": "callToAction",
      "persona": "persona",
      "trigger": "trigger",
      "valueProp": "valueProp"
    },
    "pacing": {
      "EMAIL": {
        "dailyLimit": -9007199254740991
      },
      "LINKEDIN_INVITE": {
        "dailyLimit": -9007199254740991
      },
      "LINKEDIN_MESSAGE": {
        "dailyLimit": -9007199254740991
      }
    },
    "priority": "HIGH",
    "sendWindow": {
      "daysOfWeek": [
        -9007199254740991
      ],
      "endHour": -9007199254740991,
      "startHour": -9007199254740991,
      "timezone": "timezone"
    },
    "steps": [
      {
        "id": "id",
        "deliveryMode": "AUTO",
        "mode": "AGENT",
        "name": "name",
        "prompt": "prompt",
        "type": "EMAIL"
      }
    ]
  },
  "name": "name",
  "publishWarnings": [
    {
      "code": "delay_shortened",
      "message": "message",
      "severity": "warning",
      "stepIds": [
        "string"
      ]
    }
  ],
  "reviewers": [
    {
      "id": "x",
      "objectType": "member"
    }
  ],
  "senders": [
    {
      "id": "x",
      "objectType": "sender"
    }
  ],
  "sequenceId": "sequenceId",
  "updatedAt": "updatedAt",
  "version": "version"
}
```

## Activate a sequence

**post** `/v1/sequences/{id}/activate`

Starts sending a published sequence to its enrolled contacts and returns it. Requires a published version and an available sender for each channel the steps use; senders are added through the draft. An active sequence is returned unchanged. The sequence’s status changes immediately; its enrollments’ statuses follow asynchronously. Returns 400 `sequence_not_published` before the first publish, 400 `no_selectable_sender` when a channel has no available sender, and 409 when the sequence changed while the request ran: re-read it to see the change, then retry.

**[Required scope](/using-the-api/scopes/):** `sequences:update`

**[Rate limit category](/using-the-api/rate-limits/):** Write

### Path Parameters

- `id: string`

  Unique identifier of the sequence.

### Body Parameters

- `body: optional object {  }`

### Returns

- `SequenceActivateResponse object { id, channels, createdAt, 8 more }`

  - `id: string`

    Unique identifier of the sequence.

  - `channels: array of "EMAIL" or "LINKEDIN"`

    Channels the published steps send on; empty before the first publish.

    - `"EMAIL"`

    - `"LINKEDIN"`

  - `createdAt: string`

    ISO 8601 creation timestamp.

  - `definition: object { description, messaging, pacing, 3 more }`

    Published configuration, or null before the first publish.

    - `description: string`

      What this version of the sequence is for.

    - `messaging: object { callToAction, persona, trigger, valueProp }`

      Messaging inputs that frame every step.

      - `callToAction: string`

        What the recipient is asked to do.

      - `persona: string`

        Who the sequence targets.

      - `trigger: string`

        Why the outreach is timely.

      - `valueProp: string`

        The value proposition.

    - `pacing: object { EMAIL, LINKEDIN_INVITE, LINKEDIN_MESSAGE }`

      How the whole sequence paces each step type it sends, keyed by sequence step type.

      - `EMAIL: object { dailyLimit }`

        Email steps.

        - `dailyLimit: number`

          Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

      - `LINKEDIN_INVITE: object { dailyLimit }`

        LinkedIn connection requests.

        - `dailyLimit: number`

          Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

      - `LINKEDIN_MESSAGE: object { dailyLimit }`

        LinkedIn messages.

        - `dailyLimit: number`

          Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

    - `priority: "HIGH" or "NORMAL"`

      Send priority relative to other sequences.

      - `"HIGH"`

      - `"NORMAL"`

    - `sendWindow: object { daysOfWeek, endHour, startHour, timezone }`

      When the sequence may send.

      - `daysOfWeek: array of number`

        Days sends may go out, 0 = Sunday.

      - `endHour: number`

        Local hour sends stop, exclusive (1–24).

      - `startHour: number`

        First local hour sends may go out (0–23).

      - `timezone: string`

        IANA timezone of the window.

    - `steps: array of object { id, deliveryMode, mode, 3 more }  or object { id, deliveryMode, includeNote, 4 more }  or object { id, deliveryMode, mode, 3 more }  or 3 more`

      Email, LinkedIn and wait steps in execution order.

      - `object { id, deliveryMode, mode, 3 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `mode: "AGENT"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"AGENT"`

        - `name: string`

          Display name of the step.

        - `prompt: string`

          Instructions the agent follows when composing this message.

        - `type: "EMAIL" or "LINKEDIN_MESSAGE"`

          Step type.

          - `"EMAIL"`

          - `"LINKEDIN_MESSAGE"`

      - `object { id, deliveryMode, includeNote, 4 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `includeNote: boolean`

          Whether the connection request carries a note. A step authored before this setting existed reads as true.

        - `mode: "AGENT"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"AGENT"`

        - `name: string`

          Display name of the step.

        - `prompt: string`

          Instructions the agent follows when composing this message.

        - `type: "LINKEDIN_INVITE"`

          Step type.

          - `"LINKEDIN_INVITE"`

      - `object { id, deliveryMode, mode, 3 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `mode: "TEMPLATE"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"TEMPLATE"`

        - `name: string`

          Display name of the step.

        - `template: object { body, subject }`

          The email every contact receives.

          - `body: string`

            Email body as Markdown, without the sign-off or signature, which are added when the message is written. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

          - `subject: string`

            Plain-text subject line. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

        - `type: "EMAIL"`

          Step type.

          - `"EMAIL"`

      - `object { id, deliveryMode, mode, 3 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `mode: "TEMPLATE"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"TEMPLATE"`

        - `name: string`

          Display name of the step.

        - `template: object { body }`

          The message every contact receives; for an invite, its connection note, sent only with `includeNote`.

          - `body: string`

            Plain-text message. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

        - `type: "LINKEDIN_MESSAGE"`

          Step type.

          - `"LINKEDIN_MESSAGE"`

      - `object { id, deliveryMode, includeNote, 4 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `includeNote: boolean`

          Whether the connection request carries a note. A step authored before this setting existed reads as true.

        - `mode: "TEMPLATE"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"TEMPLATE"`

        - `name: string`

          Display name of the step.

        - `template: object { body }`

          The message every contact receives; for an invite, its connection note, sent only with `includeNote`.

          - `body: string`

            Plain-text message. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

        - `type: "LINKEDIN_INVITE"`

          Step type.

          - `"LINKEDIN_INVITE"`

      - `object { id, duration, type, unit }`

        - `id: string`

          Step identifier.

        - `duration: number`

          Length of the wait.

        - `type: "WAIT" or "WAIT_FOR_CONNECTION"`

          `WAIT` pauses for a fixed time; `WAIT_FOR_CONNECTION` waits up to that long for a LinkedIn invite to be accepted.

          - `"WAIT"`

          - `"WAIT_FOR_CONNECTION"`

        - `unit: "DAY" or "MINUTE"`

          Unit of `duration`.

          - `"DAY"`

          - `"MINUTE"`

  - `firstActivatedAt: string`

    When the sequence was first activated.

  - `lastActivatedAt: string`

    When the sequence was most recently activated.

  - `name: string`

    Name of the sequence.

  - `objectType: "sequence"`

    Always `sequence`.

    - `"sequence"`

  - `reviewers: array of object { id, objectType }`

    Extra members who may approve this sequence’s `FOR_REVIEW` messages before they send. The sending member and the sequence’s creator always review, whether or not they are listed.

    - `id: string`

      ID of the member.

    - `objectType: "member"`

      Always `member`.

      - `"member"`

  - `senders: array of object { id, objectType }`

    The senders this sequence sends from; new contacts rotate across them. An archived sender stays listed but never sends; any change to the list drops it.

    - `id: string`

      ID of the sender.

    - `objectType: "sender"`

      Always `sender`.

      - `"sender"`

  - `status: "DRAFT" or "ACTIVE" or "DEACTIVATED"`

    `DRAFT` has not been published; `ACTIVE` is enabled for sending; `DEACTIVATED` is published but paused.

    - `"DRAFT"`

    - `"ACTIVE"`

    - `"DEACTIVATED"`

### Example

```http
curl https://api.lightfield.app/v1/sequences/$ID/activate \
    -X POST \
    -H 'Lightfield-Version: 2026-03-01' \
    -H "Authorization: Bearer $API_KEY"
```

#### Response

```json
{
  "id": "id",
  "channels": [
    "EMAIL"
  ],
  "createdAt": "createdAt",
  "definition": {
    "description": "description",
    "messaging": {
      "callToAction": "callToAction",
      "persona": "persona",
      "trigger": "trigger",
      "valueProp": "valueProp"
    },
    "pacing": {
      "EMAIL": {
        "dailyLimit": -9007199254740991
      },
      "LINKEDIN_INVITE": {
        "dailyLimit": -9007199254740991
      },
      "LINKEDIN_MESSAGE": {
        "dailyLimit": -9007199254740991
      }
    },
    "priority": "HIGH",
    "sendWindow": {
      "daysOfWeek": [
        -9007199254740991
      ],
      "endHour": -9007199254740991,
      "startHour": -9007199254740991,
      "timezone": "timezone"
    },
    "steps": [
      {
        "id": "id",
        "deliveryMode": "AUTO",
        "mode": "AGENT",
        "name": "name",
        "prompt": "prompt",
        "type": "EMAIL"
      }
    ]
  },
  "firstActivatedAt": "firstActivatedAt",
  "lastActivatedAt": "lastActivatedAt",
  "name": "name",
  "objectType": "sequence",
  "reviewers": [
    {
      "id": "x",
      "objectType": "member"
    }
  ],
  "senders": [
    {
      "id": "x",
      "objectType": "sender"
    }
  ],
  "status": "DRAFT"
}
```

## Deactivate a sequence

**post** `/v1/sequences/{id}/deactivate`

Pauses sending for a published sequence and returns it. Enrollments stay in place and resume when the sequence is activated again; a paused sequence is returned unchanged. The sequence’s status changes immediately; its enrollments’ statuses follow asynchronously. Returns 400 `sequence_not_published` before the first publish, and 409 when the sequence changed while the request ran: re-read it to see the change, then retry.

**[Required scope](/using-the-api/scopes/):** `sequences:update`

**[Rate limit category](/using-the-api/rate-limits/):** Write

### Path Parameters

- `id: string`

  Unique identifier of the sequence.

### Body Parameters

- `body: optional object {  }`

### Returns

- `SequenceDeactivateResponse object { id, channels, createdAt, 8 more }`

  - `id: string`

    Unique identifier of the sequence.

  - `channels: array of "EMAIL" or "LINKEDIN"`

    Channels the published steps send on; empty before the first publish.

    - `"EMAIL"`

    - `"LINKEDIN"`

  - `createdAt: string`

    ISO 8601 creation timestamp.

  - `definition: object { description, messaging, pacing, 3 more }`

    Published configuration, or null before the first publish.

    - `description: string`

      What this version of the sequence is for.

    - `messaging: object { callToAction, persona, trigger, valueProp }`

      Messaging inputs that frame every step.

      - `callToAction: string`

        What the recipient is asked to do.

      - `persona: string`

        Who the sequence targets.

      - `trigger: string`

        Why the outreach is timely.

      - `valueProp: string`

        The value proposition.

    - `pacing: object { EMAIL, LINKEDIN_INVITE, LINKEDIN_MESSAGE }`

      How the whole sequence paces each step type it sends, keyed by sequence step type.

      - `EMAIL: object { dailyLimit }`

        Email steps.

        - `dailyLimit: number`

          Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

      - `LINKEDIN_INVITE: object { dailyLimit }`

        LinkedIn connection requests.

        - `dailyLimit: number`

          Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

      - `LINKEDIN_MESSAGE: object { dailyLimit }`

        LinkedIn messages.

        - `dailyLimit: number`

          Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

    - `priority: "HIGH" or "NORMAL"`

      Send priority relative to other sequences.

      - `"HIGH"`

      - `"NORMAL"`

    - `sendWindow: object { daysOfWeek, endHour, startHour, timezone }`

      When the sequence may send.

      - `daysOfWeek: array of number`

        Days sends may go out, 0 = Sunday.

      - `endHour: number`

        Local hour sends stop, exclusive (1–24).

      - `startHour: number`

        First local hour sends may go out (0–23).

      - `timezone: string`

        IANA timezone of the window.

    - `steps: array of object { id, deliveryMode, mode, 3 more }  or object { id, deliveryMode, includeNote, 4 more }  or object { id, deliveryMode, mode, 3 more }  or 3 more`

      Email, LinkedIn and wait steps in execution order.

      - `object { id, deliveryMode, mode, 3 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `mode: "AGENT"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"AGENT"`

        - `name: string`

          Display name of the step.

        - `prompt: string`

          Instructions the agent follows when composing this message.

        - `type: "EMAIL" or "LINKEDIN_MESSAGE"`

          Step type.

          - `"EMAIL"`

          - `"LINKEDIN_MESSAGE"`

      - `object { id, deliveryMode, includeNote, 4 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `includeNote: boolean`

          Whether the connection request carries a note. A step authored before this setting existed reads as true.

        - `mode: "AGENT"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"AGENT"`

        - `name: string`

          Display name of the step.

        - `prompt: string`

          Instructions the agent follows when composing this message.

        - `type: "LINKEDIN_INVITE"`

          Step type.

          - `"LINKEDIN_INVITE"`

      - `object { id, deliveryMode, mode, 3 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `mode: "TEMPLATE"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"TEMPLATE"`

        - `name: string`

          Display name of the step.

        - `template: object { body, subject }`

          The email every contact receives.

          - `body: string`

            Email body as Markdown, without the sign-off or signature, which are added when the message is written. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

          - `subject: string`

            Plain-text subject line. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

        - `type: "EMAIL"`

          Step type.

          - `"EMAIL"`

      - `object { id, deliveryMode, mode, 3 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `mode: "TEMPLATE"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"TEMPLATE"`

        - `name: string`

          Display name of the step.

        - `template: object { body }`

          The message every contact receives; for an invite, its connection note, sent only with `includeNote`.

          - `body: string`

            Plain-text message. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

        - `type: "LINKEDIN_MESSAGE"`

          Step type.

          - `"LINKEDIN_MESSAGE"`

      - `object { id, deliveryMode, includeNote, 4 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `includeNote: boolean`

          Whether the connection request carries a note. A step authored before this setting existed reads as true.

        - `mode: "TEMPLATE"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"TEMPLATE"`

        - `name: string`

          Display name of the step.

        - `template: object { body }`

          The message every contact receives; for an invite, its connection note, sent only with `includeNote`.

          - `body: string`

            Plain-text message. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

        - `type: "LINKEDIN_INVITE"`

          Step type.

          - `"LINKEDIN_INVITE"`

      - `object { id, duration, type, unit }`

        - `id: string`

          Step identifier.

        - `duration: number`

          Length of the wait.

        - `type: "WAIT" or "WAIT_FOR_CONNECTION"`

          `WAIT` pauses for a fixed time; `WAIT_FOR_CONNECTION` waits up to that long for a LinkedIn invite to be accepted.

          - `"WAIT"`

          - `"WAIT_FOR_CONNECTION"`

        - `unit: "DAY" or "MINUTE"`

          Unit of `duration`.

          - `"DAY"`

          - `"MINUTE"`

  - `firstActivatedAt: string`

    When the sequence was first activated.

  - `lastActivatedAt: string`

    When the sequence was most recently activated.

  - `name: string`

    Name of the sequence.

  - `objectType: "sequence"`

    Always `sequence`.

    - `"sequence"`

  - `reviewers: array of object { id, objectType }`

    Extra members who may approve this sequence’s `FOR_REVIEW` messages before they send. The sending member and the sequence’s creator always review, whether or not they are listed.

    - `id: string`

      ID of the member.

    - `objectType: "member"`

      Always `member`.

      - `"member"`

  - `senders: array of object { id, objectType }`

    The senders this sequence sends from; new contacts rotate across them. An archived sender stays listed but never sends; any change to the list drops it.

    - `id: string`

      ID of the sender.

    - `objectType: "sender"`

      Always `sender`.

      - `"sender"`

  - `status: "DRAFT" or "ACTIVE" or "DEACTIVATED"`

    `DRAFT` has not been published; `ACTIVE` is enabled for sending; `DEACTIVATED` is published but paused.

    - `"DRAFT"`

    - `"ACTIVE"`

    - `"DEACTIVATED"`

### Example

```http
curl https://api.lightfield.app/v1/sequences/$ID/deactivate \
    -X POST \
    -H 'Lightfield-Version: 2026-03-01' \
    -H "Authorization: Bearer $API_KEY"
```

#### Response

```json
{
  "id": "id",
  "channels": [
    "EMAIL"
  ],
  "createdAt": "createdAt",
  "definition": {
    "description": "description",
    "messaging": {
      "callToAction": "callToAction",
      "persona": "persona",
      "trigger": "trigger",
      "valueProp": "valueProp"
    },
    "pacing": {
      "EMAIL": {
        "dailyLimit": -9007199254740991
      },
      "LINKEDIN_INVITE": {
        "dailyLimit": -9007199254740991
      },
      "LINKEDIN_MESSAGE": {
        "dailyLimit": -9007199254740991
      }
    },
    "priority": "HIGH",
    "sendWindow": {
      "daysOfWeek": [
        -9007199254740991
      ],
      "endHour": -9007199254740991,
      "startHour": -9007199254740991,
      "timezone": "timezone"
    },
    "steps": [
      {
        "id": "id",
        "deliveryMode": "AUTO",
        "mode": "AGENT",
        "name": "name",
        "prompt": "prompt",
        "type": "EMAIL"
      }
    ]
  },
  "firstActivatedAt": "firstActivatedAt",
  "lastActivatedAt": "lastActivatedAt",
  "name": "name",
  "objectType": "sequence",
  "reviewers": [
    {
      "id": "x",
      "objectType": "member"
    }
  ],
  "senders": [
    {
      "id": "x",
      "objectType": "sender"
    }
  ],
  "status": "DRAFT"
}
```

## Retrieve a sequence draft

**get** `/v1/sequences/{id}/draft`

Retrieves the sequence’s open draft, the same one editors see in Lightfield. Returns 404 `draft_not_found` when no draft is open.

**[Required scope](/using-the-api/scopes/):** `sequences:read`

**[Rate limit category](/using-the-api/rate-limits/):** Read

### Path Parameters

- `id: string`

  Unique identifier of the sequence.

### Returns

- `SequenceRetrieveDraftResponse object { channels, definition, name, 6 more }`

  - `channels: array of "EMAIL" or "LINKEDIN"`

    Channels the draft's steps send on.

    - `"EMAIL"`

    - `"LINKEDIN"`

  - `definition: object { description, messaging, pacing, 3 more }`

    The draft configuration, in the same shape as a published definition.

    - `description: string`

      What this version of the sequence is for.

    - `messaging: object { callToAction, persona, trigger, valueProp }`

      Messaging inputs that frame every step.

      - `callToAction: string`

        What the recipient is asked to do.

      - `persona: string`

        Who the sequence targets.

      - `trigger: string`

        Why the outreach is timely.

      - `valueProp: string`

        The value proposition.

    - `pacing: object { EMAIL, LINKEDIN_INVITE, LINKEDIN_MESSAGE }`

      How the whole sequence paces each step type it sends, keyed by sequence step type.

      - `EMAIL: object { dailyLimit }`

        Email steps.

        - `dailyLimit: number`

          Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

      - `LINKEDIN_INVITE: object { dailyLimit }`

        LinkedIn connection requests.

        - `dailyLimit: number`

          Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

      - `LINKEDIN_MESSAGE: object { dailyLimit }`

        LinkedIn messages.

        - `dailyLimit: number`

          Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

    - `priority: "HIGH" or "NORMAL"`

      Send priority relative to other sequences.

      - `"HIGH"`

      - `"NORMAL"`

    - `sendWindow: object { daysOfWeek, endHour, startHour, timezone }`

      When the sequence may send.

      - `daysOfWeek: array of number`

        Days sends may go out, 0 = Sunday.

      - `endHour: number`

        Local hour sends stop, exclusive (1–24).

      - `startHour: number`

        First local hour sends may go out (0–23).

      - `timezone: string`

        IANA timezone of the window.

    - `steps: array of object { id, deliveryMode, mode, 3 more }  or object { id, deliveryMode, includeNote, 4 more }  or object { id, deliveryMode, mode, 3 more }  or 3 more`

      Email, LinkedIn and wait steps in execution order.

      - `object { id, deliveryMode, mode, 3 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `mode: "AGENT"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"AGENT"`

        - `name: string`

          Display name of the step.

        - `prompt: string`

          Instructions the agent follows when composing this message.

        - `type: "EMAIL" or "LINKEDIN_MESSAGE"`

          Step type.

          - `"EMAIL"`

          - `"LINKEDIN_MESSAGE"`

      - `object { id, deliveryMode, includeNote, 4 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `includeNote: boolean`

          Whether the connection request carries a note. A step authored before this setting existed reads as true.

        - `mode: "AGENT"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"AGENT"`

        - `name: string`

          Display name of the step.

        - `prompt: string`

          Instructions the agent follows when composing this message.

        - `type: "LINKEDIN_INVITE"`

          Step type.

          - `"LINKEDIN_INVITE"`

      - `object { id, deliveryMode, mode, 3 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `mode: "TEMPLATE"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"TEMPLATE"`

        - `name: string`

          Display name of the step.

        - `template: object { body, subject }`

          The email every contact receives.

          - `body: string`

            Email body as Markdown, without the sign-off or signature, which are added when the message is written. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

          - `subject: string`

            Plain-text subject line. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

        - `type: "EMAIL"`

          Step type.

          - `"EMAIL"`

      - `object { id, deliveryMode, mode, 3 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `mode: "TEMPLATE"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"TEMPLATE"`

        - `name: string`

          Display name of the step.

        - `template: object { body }`

          The message every contact receives; for an invite, its connection note, sent only with `includeNote`.

          - `body: string`

            Plain-text message. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

        - `type: "LINKEDIN_MESSAGE"`

          Step type.

          - `"LINKEDIN_MESSAGE"`

      - `object { id, deliveryMode, includeNote, 4 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `includeNote: boolean`

          Whether the connection request carries a note. A step authored before this setting existed reads as true.

        - `mode: "TEMPLATE"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"TEMPLATE"`

        - `name: string`

          Display name of the step.

        - `template: object { body }`

          The message every contact receives; for an invite, its connection note, sent only with `includeNote`.

          - `body: string`

            Plain-text message. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

        - `type: "LINKEDIN_INVITE"`

          Step type.

          - `"LINKEDIN_INVITE"`

      - `object { id, duration, type, unit }`

        - `id: string`

          Step identifier.

        - `duration: number`

          Length of the wait.

        - `type: "WAIT" or "WAIT_FOR_CONNECTION"`

          `WAIT` pauses for a fixed time; `WAIT_FOR_CONNECTION` waits up to that long for a LinkedIn invite to be accepted.

          - `"WAIT"`

          - `"WAIT_FOR_CONNECTION"`

        - `unit: "DAY" or "MINUTE"`

          Unit of `duration`.

          - `"DAY"`

          - `"MINUTE"`

  - `name: string`

    Name the sequence takes when the draft is published.

  - `publishWarnings: array of object { code, message, severity, stepIds }`

    What publishing this draft would change for contacts already in the sequence; empty when nothing is affected. Before the first publish, the only possible warning is a proposed sender that was archived and would be left off.

    - `code: "delay_shortened" or "delay_lengthened" or "connection_wait_shortened" or 18 more`

      What publishing would change.

      - `"delay_shortened"`

      - `"delay_lengthened"`

      - `"connection_wait_shortened"`

      - `"connection_wait_lengthened"`

      - `"send_schedule_changed"`

      - `"send_configuration_changed"`

      - `"send_priority_changed"`

      - `"senders_changed"`

      - `"email_sender_pool_emptied"`

      - `"linkedin_account_pool_emptied"`

      - `"assigned_sender_removed"`

      - `"delivery_became_automatic"`

      - `"invite_note_enabled"`

      - `"invite_note_disabled"`

      - `"step_inserted"`

      - `"automatic_send_step_inserted"`

      - `"step_removed"`

      - `"step_type_changed"`

      - `"step_order_changed"`

      - `"full_identity_rewrite"`

      - `"low_identity_overlap"`

    - `message: string`

      What would change, in plain language.

    - `severity: "warning" or "destructive"`

      `destructive` when contacts already in the sequence may skip, repeat or receive a step they would not have; `warning` otherwise.

      - `"warning"`

      - `"destructive"`

    - `stepIds: array of string`

      The steps involved; empty for a sequence-wide change.

  - `reviewers: array of object { id, objectType }`

    Extra members who may approve this sequence’s `FOR_REVIEW` messages before they send. The sending member and the sequence’s creator always review, whether or not they are listed.

    - `id: string`

      ID of the member.

    - `objectType: "member"`

      Always `member`.

      - `"member"`

  - `senders: array of object { id, objectType }`

    The senders this draft will publish; new contacts rotate across them. Until a save changes it, this is the sequence’s live list. An archived sender stays listed but never sends; any change to the list drops it.

    - `id: string`

      ID of the sender.

    - `objectType: "sender"`

      Always `sender`.

      - `"sender"`

  - `sequenceId: string`

    The sequence this draft belongs to.

  - `updatedAt: string`

    When the draft last changed.

  - `version: string`

    Opaque token for the current state of the draft. Send it as `expectedVersion` on the next save, publish or discard; it changes whenever anyone edits the draft.

### Example

```http
curl https://api.lightfield.app/v1/sequences/$ID/draft \
    -H 'Lightfield-Version: 2026-03-01' \
    -H "Authorization: Bearer $API_KEY"
```

#### Response

```json
{
  "channels": [
    "EMAIL"
  ],
  "definition": {
    "description": "description",
    "messaging": {
      "callToAction": "callToAction",
      "persona": "persona",
      "trigger": "trigger",
      "valueProp": "valueProp"
    },
    "pacing": {
      "EMAIL": {
        "dailyLimit": -9007199254740991
      },
      "LINKEDIN_INVITE": {
        "dailyLimit": -9007199254740991
      },
      "LINKEDIN_MESSAGE": {
        "dailyLimit": -9007199254740991
      }
    },
    "priority": "HIGH",
    "sendWindow": {
      "daysOfWeek": [
        -9007199254740991
      ],
      "endHour": -9007199254740991,
      "startHour": -9007199254740991,
      "timezone": "timezone"
    },
    "steps": [
      {
        "id": "id",
        "deliveryMode": "AUTO",
        "mode": "AGENT",
        "name": "name",
        "prompt": "prompt",
        "type": "EMAIL"
      }
    ]
  },
  "name": "name",
  "publishWarnings": [
    {
      "code": "delay_shortened",
      "message": "message",
      "severity": "warning",
      "stepIds": [
        "string"
      ]
    }
  ],
  "reviewers": [
    {
      "id": "x",
      "objectType": "member"
    }
  ],
  "senders": [
    {
      "id": "x",
      "objectType": "sender"
    }
  ],
  "sequenceId": "sequenceId",
  "updatedAt": "updatedAt",
  "version": "version"
}
```

## Update a sequence draft

**post** `/v1/sequences/{id}/draft`

Saves changes to the sequence’s open draft, or opens one from the published version when none is open. Only the fields sent are changed; `definition.steps` replaces the whole step list. Changes take effect when the draft is published. See <u>[Using sequences with the API](/sequences/using-the-api#editing-a-draft)</u> for the draft and version model.

Returns 409 when `expectedVersion` is not the open draft’s `version`, or for a `steps` save while the draft has unfinished edits in Lightfield; retrieve the draft and retry. A refused save changes nothing: 400 `invalid_configuration` lists every problem under `issues`, 400 `referenced_resource_missing` names a reviewer or sender that does not exist, and a value outside its field’s documented bounds returns 400 naming the field in `param`. See <u>[Sequence errors](/using-the-api/errors/#sequence-errors)</u>.

**[Required scope](/using-the-api/scopes/):** `sequences:update`

**[Rate limit category](/using-the-api/rate-limits/):** Write

### Path Parameters

- `id: string`

  Unique identifier of the sequence.

### Body Parameters

- `definition: optional object { description, messaging, pacing, 3 more }`

  Fields to change. Omitted fields are unchanged.

  - `description: optional string`

    What this version of the sequence is for.

  - `messaging: optional object { callToAction, persona, trigger, valueProp }`

    Messaging inputs that frame every step. Omitted fields are unchanged; null clears a field.

    - `callToAction: optional string`

      What the recipient is asked to do.

    - `persona: optional string`

      Who the sequence targets.

    - `trigger: optional string`

      Why the outreach is timely.

    - `valueProp: optional string`

      The value proposition.

  - `pacing: optional object { EMAIL, LINKEDIN_INVITE, LINKEDIN_MESSAGE }`

    How the whole sequence paces each step type it sends, keyed by sequence step type. Omitted step types are unchanged.

    - `EMAIL: optional object { dailyLimit }`

      Email steps.

      - `dailyLimit: number`

        Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

    - `LINKEDIN_INVITE: optional object { dailyLimit }`

      LinkedIn connection requests.

      - `dailyLimit: number`

        Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

    - `LINKEDIN_MESSAGE: optional object { dailyLimit }`

      LinkedIn messages.

      - `dailyLimit: number`

        Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

  - `priority: optional "HIGH" or "NORMAL"`

    Send priority relative to other sequences.

    - `"HIGH"`

    - `"NORMAL"`

  - `sendWindow: optional object { daysOfWeek, endHour, startHour, timezone }`

    When the sequence may send. Omitted fields are unchanged.

    - `daysOfWeek: optional array of number`

      Days sends may go out, 0 = Sunday.

    - `endHour: optional number`

      Local hour sends stop, exclusive (1–24).

    - `startHour: optional number`

      First local hour sends may go out (0–23).

    - `timezone: optional string`

      IANA timezone of the window.

  - `steps: optional array of object { deliveryMode, name, prompt, 3 more }  or object { deliveryMode, name, prompt, 4 more }  or object { deliveryMode, name, template, 3 more }  or 3 more`

    The complete ordered step list, replacing the current one. Keep a step by sending its `id`; omit `id` for a new step.

    - `object { deliveryMode, name, prompt, 3 more }`

      - `deliveryMode: "AUTO" or "FOR_REVIEW"`

        `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

        - `"AUTO"`

        - `"FOR_REVIEW"`

      - `name: string`

        Display name of the step.

      - `prompt: string`

        Instructions the agent follows when composing this message.

      - `type: "EMAIL" or "LINKEDIN_MESSAGE"`

        Step type.

        - `"EMAIL"`

        - `"LINKEDIN_MESSAGE"`

      - `id: optional string`

        ID of a step in the current draft to keep. Omit for a new step. Kept steps must stay in their relative order and keep their type.

      - `mode: optional "AGENT"`

        How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in. Optional: the content decides, a `prompt` for `AGENT` and a `template` for `TEMPLATE`. A kept template step sent with a `prompt` is refused unless `mode` is `AGENT`, so its template is never dropped by accident.

        - `"AGENT"`

    - `object { deliveryMode, name, prompt, 4 more }`

      - `deliveryMode: "AUTO" or "FOR_REVIEW"`

        `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

        - `"AUTO"`

        - `"FOR_REVIEW"`

      - `name: string`

        Display name of the step.

      - `prompt: string`

        Instructions the agent follows when composing this message.

      - `type: "LINKEDIN_INVITE"`

        Step type.

        - `"LINKEDIN_INVITE"`

      - `id: optional string`

        ID of a step in the current draft to keep. Omit for a new step. Kept steps must stay in their relative order and keep their type.

      - `includeNote: optional boolean`

        Whether the connection request carries a note. Omit to keep the current setting; a new step defaults to false.

      - `mode: optional "AGENT"`

        How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in. Optional: the content decides, a `prompt` for `AGENT` and a `template` for `TEMPLATE`. A kept template step sent with a `prompt` is refused unless `mode` is `AGENT`, so its template is never dropped by accident.

        - `"AGENT"`

    - `object { deliveryMode, name, template, 3 more }`

      - `deliveryMode: "AUTO" or "FOR_REVIEW"`

        `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

        - `"AUTO"`

        - `"FOR_REVIEW"`

      - `name: string`

        Display name of the step.

      - `template: object { body, subject }`

        The email every contact receives. Requires template steps for the workspace.

        - `body: string`

          Email body as Markdown; paragraphs, bold, italics, links and lists keep their formatting. Leave out the sign-off and signature, which are added when the message is written. A variable cannot be part of a link address. Write each variable as {{ coalesce(<variable>, "fallback") }}, with a fallback for contacts missing the value. A variable reads a contact field as {attr:<id>}, the contact's first or last name as {col:firstName} or {col:lastName}, the contact's first account's field as {rel:account.<id>}, that account's name as {rel:account.col:name}, and the sender's name or email as {rel:sender.col:name} or {rel:sender.col:email}; a SINGLE_SELECT field reads its option's label, as {attr:<id>.label} or {rel:account.<id>.label}. <id> is the literal id of a CrmContact or CrmAccount field in the CRM schema whose type is one of TEXT, NUMBER, CURRENCY, DATETIME, SINGLE_SELECT, FULL_NAME, EMAIL, URL; never a slug, a name, or an id starting with __synthetic_. Nothing else is a variable: leave such a value out rather than reading a different field. A {{ }} that is not a variable would send as written, so it is refused. A field's <id> may be the `ad_` ID the field-definitions endpoints list.

        - `subject: string`

          Plain-text subject line. Write each variable as {{ coalesce(<variable>, "fallback") }}, with a fallback for contacts missing the value. A variable reads a contact field as {attr:<id>}, the contact's first or last name as {col:firstName} or {col:lastName}, the contact's first account's field as {rel:account.<id>}, that account's name as {rel:account.col:name}, and the sender's name or email as {rel:sender.col:name} or {rel:sender.col:email}; a SINGLE_SELECT field reads its option's label, as {attr:<id>.label} or {rel:account.<id>.label}. <id> is the literal id of a CrmContact or CrmAccount field in the CRM schema whose type is one of TEXT, NUMBER, CURRENCY, DATETIME, SINGLE_SELECT, FULL_NAME, EMAIL, URL; never a slug, a name, or an id starting with __synthetic_. Nothing else is a variable: leave such a value out rather than reading a different field. A {{ }} that is not a variable would send as written, so it is refused. A field's <id> may be the `ad_` ID the field-definitions endpoints list.

      - `type: "EMAIL"`

        Step type.

        - `"EMAIL"`

      - `id: optional string`

        ID of a step in the current draft to keep. Omit for a new step. Kept steps must stay in their relative order and keep their type.

      - `mode: optional "TEMPLATE"`

        How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in. Optional: the content decides, a `prompt` for `AGENT` and a `template` for `TEMPLATE`. A kept template step sent with a `prompt` is refused unless `mode` is `AGENT`, so its template is never dropped by accident.

        - `"TEMPLATE"`

    - `object { deliveryMode, name, template, 3 more }`

      - `deliveryMode: "AUTO" or "FOR_REVIEW"`

        `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

        - `"AUTO"`

        - `"FOR_REVIEW"`

      - `name: string`

        Display name of the step.

      - `template: object { body }`

        The message every contact receives; for an invite, its connection note, sent only with `includeNote` and otherwise left empty. Requires template steps for the workspace.

        - `body: string`

          Plain-text message. Write each variable as {{ coalesce(<variable>, "fallback") }}, with a fallback for contacts missing the value. A variable reads a contact field as {attr:<id>}, the contact's first or last name as {col:firstName} or {col:lastName}, the contact's first account's field as {rel:account.<id>}, that account's name as {rel:account.col:name}, and the sender's name or email as {rel:sender.col:name} or {rel:sender.col:email}; a SINGLE_SELECT field reads its option's label, as {attr:<id>.label} or {rel:account.<id>.label}. <id> is the literal id of a CrmContact or CrmAccount field in the CRM schema whose type is one of TEXT, NUMBER, CURRENCY, DATETIME, SINGLE_SELECT, FULL_NAME, EMAIL, URL; never a slug, a name, or an id starting with __synthetic_. Nothing else is a variable: leave such a value out rather than reading a different field. A {{ }} that is not a variable would send as written, so it is refused. A field's <id> may be the `ad_` ID the field-definitions endpoints list.

      - `type: "LINKEDIN_MESSAGE"`

        Step type.

        - `"LINKEDIN_MESSAGE"`

      - `id: optional string`

        ID of a step in the current draft to keep. Omit for a new step. Kept steps must stay in their relative order and keep their type.

      - `mode: optional "TEMPLATE"`

        How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in. Optional: the content decides, a `prompt` for `AGENT` and a `template` for `TEMPLATE`. A kept template step sent with a `prompt` is refused unless `mode` is `AGENT`, so its template is never dropped by accident.

        - `"TEMPLATE"`

    - `object { deliveryMode, name, template, 4 more }`

      - `deliveryMode: "AUTO" or "FOR_REVIEW"`

        `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

        - `"AUTO"`

        - `"FOR_REVIEW"`

      - `name: string`

        Display name of the step.

      - `template: object { body }`

        The message every contact receives; for an invite, its connection note, sent only with `includeNote` and otherwise left empty. Requires template steps for the workspace.

        - `body: string`

          Plain-text message. Write each variable as {{ coalesce(<variable>, "fallback") }}, with a fallback for contacts missing the value. A variable reads a contact field as {attr:<id>}, the contact's first or last name as {col:firstName} or {col:lastName}, the contact's first account's field as {rel:account.<id>}, that account's name as {rel:account.col:name}, and the sender's name or email as {rel:sender.col:name} or {rel:sender.col:email}; a SINGLE_SELECT field reads its option's label, as {attr:<id>.label} or {rel:account.<id>.label}. <id> is the literal id of a CrmContact or CrmAccount field in the CRM schema whose type is one of TEXT, NUMBER, CURRENCY, DATETIME, SINGLE_SELECT, FULL_NAME, EMAIL, URL; never a slug, a name, or an id starting with __synthetic_. Nothing else is a variable: leave such a value out rather than reading a different field. A {{ }} that is not a variable would send as written, so it is refused. A field's <id> may be the `ad_` ID the field-definitions endpoints list.

      - `type: "LINKEDIN_INVITE"`

        Step type.

        - `"LINKEDIN_INVITE"`

      - `id: optional string`

        ID of a step in the current draft to keep. Omit for a new step. Kept steps must stay in their relative order and keep their type.

      - `includeNote: optional boolean`

        Whether the connection request carries a note. Omit to keep the current setting; a new step defaults to false.

      - `mode: optional "TEMPLATE"`

        How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in. Optional: the content decides, a `prompt` for `AGENT` and a `template` for `TEMPLATE`. A kept template step sent with a `prompt` is refused unless `mode` is `AGENT`, so its template is never dropped by accident.

        - `"TEMPLATE"`

    - `object { duration, type, unit, id }`

      - `duration: number`

        Length of the wait.

      - `type: "WAIT" or "WAIT_FOR_CONNECTION"`

        `WAIT` pauses for a fixed time; `WAIT_FOR_CONNECTION` waits up to that long for a LinkedIn invite to be accepted.

        - `"WAIT"`

        - `"WAIT_FOR_CONNECTION"`

      - `unit: "DAY" or "MINUTE"`

        Unit of `duration`.

        - `"DAY"`

        - `"MINUTE"`

      - `id: optional string`

        ID of a step in the current draft to keep. Omit for a new step. Kept steps must stay in their relative order and keep their type.

- `expectedVersion: optional string`

  The open draft’s `version` as last read. Required when a draft is open; omit it only when none is, to start one from the published version.

- `name: optional string`

  Name of the sequence.

- `reviewers: optional object { add, remove }`

  Extra members who may approve this sequence’s `FOR_REVIEW` messages before they send. The sending member and the sequence’s creator always review, whether or not they are listed. Changes the list by adding and removing members; omit to keep it.

  - `add: optional array of string`

    Member IDs of active members to add. A member already listed is unchanged.

  - `remove: optional array of string`

    Member IDs to remove, including members who have left the workspace. A member not listed is unchanged.

- `senders: optional object { add, remove }`

  The senders this sequence sends from; new contacts rotate across them. Changes the list by adding and removing senders; omit to keep it.

  - `add: optional array of string`

    Sender IDs of unarchived senders to add. A sender already listed is unchanged.

  - `remove: optional array of string`

    Sender IDs to remove, including archived senders. A sender not listed is unchanged.

### Returns

- `SequenceUpdateDraftResponse object { channels, definition, name, 6 more }`

  - `channels: array of "EMAIL" or "LINKEDIN"`

    Channels the draft's steps send on.

    - `"EMAIL"`

    - `"LINKEDIN"`

  - `definition: object { description, messaging, pacing, 3 more }`

    The draft configuration, in the same shape as a published definition.

    - `description: string`

      What this version of the sequence is for.

    - `messaging: object { callToAction, persona, trigger, valueProp }`

      Messaging inputs that frame every step.

      - `callToAction: string`

        What the recipient is asked to do.

      - `persona: string`

        Who the sequence targets.

      - `trigger: string`

        Why the outreach is timely.

      - `valueProp: string`

        The value proposition.

    - `pacing: object { EMAIL, LINKEDIN_INVITE, LINKEDIN_MESSAGE }`

      How the whole sequence paces each step type it sends, keyed by sequence step type.

      - `EMAIL: object { dailyLimit }`

        Email steps.

        - `dailyLimit: number`

          Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

      - `LINKEDIN_INVITE: object { dailyLimit }`

        LinkedIn connection requests.

        - `dailyLimit: number`

          Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

      - `LINKEDIN_MESSAGE: object { dailyLimit }`

        LinkedIn messages.

        - `dailyLimit: number`

          Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

    - `priority: "HIGH" or "NORMAL"`

      Send priority relative to other sequences.

      - `"HIGH"`

      - `"NORMAL"`

    - `sendWindow: object { daysOfWeek, endHour, startHour, timezone }`

      When the sequence may send.

      - `daysOfWeek: array of number`

        Days sends may go out, 0 = Sunday.

      - `endHour: number`

        Local hour sends stop, exclusive (1–24).

      - `startHour: number`

        First local hour sends may go out (0–23).

      - `timezone: string`

        IANA timezone of the window.

    - `steps: array of object { id, deliveryMode, mode, 3 more }  or object { id, deliveryMode, includeNote, 4 more }  or object { id, deliveryMode, mode, 3 more }  or 3 more`

      Email, LinkedIn and wait steps in execution order.

      - `object { id, deliveryMode, mode, 3 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `mode: "AGENT"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"AGENT"`

        - `name: string`

          Display name of the step.

        - `prompt: string`

          Instructions the agent follows when composing this message.

        - `type: "EMAIL" or "LINKEDIN_MESSAGE"`

          Step type.

          - `"EMAIL"`

          - `"LINKEDIN_MESSAGE"`

      - `object { id, deliveryMode, includeNote, 4 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `includeNote: boolean`

          Whether the connection request carries a note. A step authored before this setting existed reads as true.

        - `mode: "AGENT"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"AGENT"`

        - `name: string`

          Display name of the step.

        - `prompt: string`

          Instructions the agent follows when composing this message.

        - `type: "LINKEDIN_INVITE"`

          Step type.

          - `"LINKEDIN_INVITE"`

      - `object { id, deliveryMode, mode, 3 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `mode: "TEMPLATE"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"TEMPLATE"`

        - `name: string`

          Display name of the step.

        - `template: object { body, subject }`

          The email every contact receives.

          - `body: string`

            Email body as Markdown, without the sign-off or signature, which are added when the message is written. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

          - `subject: string`

            Plain-text subject line. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

        - `type: "EMAIL"`

          Step type.

          - `"EMAIL"`

      - `object { id, deliveryMode, mode, 3 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `mode: "TEMPLATE"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"TEMPLATE"`

        - `name: string`

          Display name of the step.

        - `template: object { body }`

          The message every contact receives; for an invite, its connection note, sent only with `includeNote`.

          - `body: string`

            Plain-text message. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

        - `type: "LINKEDIN_MESSAGE"`

          Step type.

          - `"LINKEDIN_MESSAGE"`

      - `object { id, deliveryMode, includeNote, 4 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `includeNote: boolean`

          Whether the connection request carries a note. A step authored before this setting existed reads as true.

        - `mode: "TEMPLATE"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"TEMPLATE"`

        - `name: string`

          Display name of the step.

        - `template: object { body }`

          The message every contact receives; for an invite, its connection note, sent only with `includeNote`.

          - `body: string`

            Plain-text message. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

        - `type: "LINKEDIN_INVITE"`

          Step type.

          - `"LINKEDIN_INVITE"`

      - `object { id, duration, type, unit }`

        - `id: string`

          Step identifier.

        - `duration: number`

          Length of the wait.

        - `type: "WAIT" or "WAIT_FOR_CONNECTION"`

          `WAIT` pauses for a fixed time; `WAIT_FOR_CONNECTION` waits up to that long for a LinkedIn invite to be accepted.

          - `"WAIT"`

          - `"WAIT_FOR_CONNECTION"`

        - `unit: "DAY" or "MINUTE"`

          Unit of `duration`.

          - `"DAY"`

          - `"MINUTE"`

  - `name: string`

    Name the sequence takes when the draft is published.

  - `publishWarnings: array of object { code, message, severity, stepIds }`

    What publishing this draft would change for contacts already in the sequence; empty when nothing is affected. Before the first publish, the only possible warning is a proposed sender that was archived and would be left off.

    - `code: "delay_shortened" or "delay_lengthened" or "connection_wait_shortened" or 18 more`

      What publishing would change.

      - `"delay_shortened"`

      - `"delay_lengthened"`

      - `"connection_wait_shortened"`

      - `"connection_wait_lengthened"`

      - `"send_schedule_changed"`

      - `"send_configuration_changed"`

      - `"send_priority_changed"`

      - `"senders_changed"`

      - `"email_sender_pool_emptied"`

      - `"linkedin_account_pool_emptied"`

      - `"assigned_sender_removed"`

      - `"delivery_became_automatic"`

      - `"invite_note_enabled"`

      - `"invite_note_disabled"`

      - `"step_inserted"`

      - `"automatic_send_step_inserted"`

      - `"step_removed"`

      - `"step_type_changed"`

      - `"step_order_changed"`

      - `"full_identity_rewrite"`

      - `"low_identity_overlap"`

    - `message: string`

      What would change, in plain language.

    - `severity: "warning" or "destructive"`

      `destructive` when contacts already in the sequence may skip, repeat or receive a step they would not have; `warning` otherwise.

      - `"warning"`

      - `"destructive"`

    - `stepIds: array of string`

      The steps involved; empty for a sequence-wide change.

  - `reviewers: array of object { id, objectType }`

    Extra members who may approve this sequence’s `FOR_REVIEW` messages before they send. The sending member and the sequence’s creator always review, whether or not they are listed.

    - `id: string`

      ID of the member.

    - `objectType: "member"`

      Always `member`.

      - `"member"`

  - `senders: array of object { id, objectType }`

    The senders this draft will publish; new contacts rotate across them. Until a save changes it, this is the sequence’s live list. An archived sender stays listed but never sends; any change to the list drops it.

    - `id: string`

      ID of the sender.

    - `objectType: "sender"`

      Always `sender`.

      - `"sender"`

  - `sequenceId: string`

    The sequence this draft belongs to.

  - `updatedAt: string`

    When the draft last changed.

  - `version: string`

    Opaque token for the current state of the draft. Send it as `expectedVersion` on the next save, publish or discard; it changes whenever anyone edits the draft.

### Example

```http
curl https://api.lightfield.app/v1/sequences/$ID/draft \
    -H 'Content-Type: application/json' \
    -H 'Lightfield-Version: 2026-03-01' \
    -H "Authorization: Bearer $API_KEY" \
    -d '{}'
```

#### Response

```json
{
  "channels": [
    "EMAIL"
  ],
  "definition": {
    "description": "description",
    "messaging": {
      "callToAction": "callToAction",
      "persona": "persona",
      "trigger": "trigger",
      "valueProp": "valueProp"
    },
    "pacing": {
      "EMAIL": {
        "dailyLimit": -9007199254740991
      },
      "LINKEDIN_INVITE": {
        "dailyLimit": -9007199254740991
      },
      "LINKEDIN_MESSAGE": {
        "dailyLimit": -9007199254740991
      }
    },
    "priority": "HIGH",
    "sendWindow": {
      "daysOfWeek": [
        -9007199254740991
      ],
      "endHour": -9007199254740991,
      "startHour": -9007199254740991,
      "timezone": "timezone"
    },
    "steps": [
      {
        "id": "id",
        "deliveryMode": "AUTO",
        "mode": "AGENT",
        "name": "name",
        "prompt": "prompt",
        "type": "EMAIL"
      }
    ]
  },
  "name": "name",
  "publishWarnings": [
    {
      "code": "delay_shortened",
      "message": "message",
      "severity": "warning",
      "stepIds": [
        "string"
      ]
    }
  ],
  "reviewers": [
    {
      "id": "x",
      "objectType": "member"
    }
  ],
  "senders": [
    {
      "id": "x",
      "objectType": "sender"
    }
  ],
  "sequenceId": "sequenceId",
  "updatedAt": "updatedAt",
  "version": "version"
}
```

## Publish a sequence draft

**post** `/v1/sequences/{id}/draft/publish`

Publishes the open draft at `expectedVersion` and returns the sequence. A first publish leaves the sequence `DEACTIVATED`; activate it to start sending. Contacts already enrolled continue on the new version.

A refused publish changes nothing. Returns 400 `invalid_configuration` with the problems under `issues`, 400 `permissions_not_granted` or `no_selectable_sender` when the steps cannot send yet, 404 `draft_not_found` when no draft is open, and 409 when `expectedVersion` is not the open draft’s `version`; retrieve the draft and retry. See <u>[Sequence errors](/using-the-api/errors/#sequence-errors)</u> for what each code means and how to resolve it.

**[Required scope](/using-the-api/scopes/):** `sequences:update`

**[Rate limit category](/using-the-api/rate-limits/):** Write

### Path Parameters

- `id: string`

  Unique identifier of the sequence.

### Body Parameters

- `expectedVersion: string`

  The open draft’s `version` as last read.

### Returns

- `SequencePublishDraftResponse object { id, channels, createdAt, 8 more }`

  - `id: string`

    Unique identifier of the sequence.

  - `channels: array of "EMAIL" or "LINKEDIN"`

    Channels the published steps send on; empty before the first publish.

    - `"EMAIL"`

    - `"LINKEDIN"`

  - `createdAt: string`

    ISO 8601 creation timestamp.

  - `definition: object { description, messaging, pacing, 3 more }`

    Published configuration, or null before the first publish.

    - `description: string`

      What this version of the sequence is for.

    - `messaging: object { callToAction, persona, trigger, valueProp }`

      Messaging inputs that frame every step.

      - `callToAction: string`

        What the recipient is asked to do.

      - `persona: string`

        Who the sequence targets.

      - `trigger: string`

        Why the outreach is timely.

      - `valueProp: string`

        The value proposition.

    - `pacing: object { EMAIL, LINKEDIN_INVITE, LINKEDIN_MESSAGE }`

      How the whole sequence paces each step type it sends, keyed by sequence step type.

      - `EMAIL: object { dailyLimit }`

        Email steps.

        - `dailyLimit: number`

          Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

      - `LINKEDIN_INVITE: object { dailyLimit }`

        LinkedIn connection requests.

        - `dailyLimit: number`

          Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

      - `LINKEDIN_MESSAGE: object { dailyLimit }`

        LinkedIn messages.

        - `dailyLimit: number`

          Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

    - `priority: "HIGH" or "NORMAL"`

      Send priority relative to other sequences.

      - `"HIGH"`

      - `"NORMAL"`

    - `sendWindow: object { daysOfWeek, endHour, startHour, timezone }`

      When the sequence may send.

      - `daysOfWeek: array of number`

        Days sends may go out, 0 = Sunday.

      - `endHour: number`

        Local hour sends stop, exclusive (1–24).

      - `startHour: number`

        First local hour sends may go out (0–23).

      - `timezone: string`

        IANA timezone of the window.

    - `steps: array of object { id, deliveryMode, mode, 3 more }  or object { id, deliveryMode, includeNote, 4 more }  or object { id, deliveryMode, mode, 3 more }  or 3 more`

      Email, LinkedIn and wait steps in execution order.

      - `object { id, deliveryMode, mode, 3 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `mode: "AGENT"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"AGENT"`

        - `name: string`

          Display name of the step.

        - `prompt: string`

          Instructions the agent follows when composing this message.

        - `type: "EMAIL" or "LINKEDIN_MESSAGE"`

          Step type.

          - `"EMAIL"`

          - `"LINKEDIN_MESSAGE"`

      - `object { id, deliveryMode, includeNote, 4 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `includeNote: boolean`

          Whether the connection request carries a note. A step authored before this setting existed reads as true.

        - `mode: "AGENT"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"AGENT"`

        - `name: string`

          Display name of the step.

        - `prompt: string`

          Instructions the agent follows when composing this message.

        - `type: "LINKEDIN_INVITE"`

          Step type.

          - `"LINKEDIN_INVITE"`

      - `object { id, deliveryMode, mode, 3 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `mode: "TEMPLATE"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"TEMPLATE"`

        - `name: string`

          Display name of the step.

        - `template: object { body, subject }`

          The email every contact receives.

          - `body: string`

            Email body as Markdown, without the sign-off or signature, which are added when the message is written. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

          - `subject: string`

            Plain-text subject line. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

        - `type: "EMAIL"`

          Step type.

          - `"EMAIL"`

      - `object { id, deliveryMode, mode, 3 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `mode: "TEMPLATE"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"TEMPLATE"`

        - `name: string`

          Display name of the step.

        - `template: object { body }`

          The message every contact receives; for an invite, its connection note, sent only with `includeNote`.

          - `body: string`

            Plain-text message. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

        - `type: "LINKEDIN_MESSAGE"`

          Step type.

          - `"LINKEDIN_MESSAGE"`

      - `object { id, deliveryMode, includeNote, 4 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `includeNote: boolean`

          Whether the connection request carries a note. A step authored before this setting existed reads as true.

        - `mode: "TEMPLATE"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"TEMPLATE"`

        - `name: string`

          Display name of the step.

        - `template: object { body }`

          The message every contact receives; for an invite, its connection note, sent only with `includeNote`.

          - `body: string`

            Plain-text message. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

        - `type: "LINKEDIN_INVITE"`

          Step type.

          - `"LINKEDIN_INVITE"`

      - `object { id, duration, type, unit }`

        - `id: string`

          Step identifier.

        - `duration: number`

          Length of the wait.

        - `type: "WAIT" or "WAIT_FOR_CONNECTION"`

          `WAIT` pauses for a fixed time; `WAIT_FOR_CONNECTION` waits up to that long for a LinkedIn invite to be accepted.

          - `"WAIT"`

          - `"WAIT_FOR_CONNECTION"`

        - `unit: "DAY" or "MINUTE"`

          Unit of `duration`.

          - `"DAY"`

          - `"MINUTE"`

  - `firstActivatedAt: string`

    When the sequence was first activated.

  - `lastActivatedAt: string`

    When the sequence was most recently activated.

  - `name: string`

    Name of the sequence.

  - `objectType: "sequence"`

    Always `sequence`.

    - `"sequence"`

  - `reviewers: array of object { id, objectType }`

    Extra members who may approve this sequence’s `FOR_REVIEW` messages before they send. The sending member and the sequence’s creator always review, whether or not they are listed.

    - `id: string`

      ID of the member.

    - `objectType: "member"`

      Always `member`.

      - `"member"`

  - `senders: array of object { id, objectType }`

    The senders this sequence sends from; new contacts rotate across them. An archived sender stays listed but never sends; any change to the list drops it.

    - `id: string`

      ID of the sender.

    - `objectType: "sender"`

      Always `sender`.

      - `"sender"`

  - `status: "DRAFT" or "ACTIVE" or "DEACTIVATED"`

    `DRAFT` has not been published; `ACTIVE` is enabled for sending; `DEACTIVATED` is published but paused.

    - `"DRAFT"`

    - `"ACTIVE"`

    - `"DEACTIVATED"`

### Example

```http
curl https://api.lightfield.app/v1/sequences/$ID/draft/publish \
    -H 'Content-Type: application/json' \
    -H 'Lightfield-Version: 2026-03-01' \
    -H "Authorization: Bearer $API_KEY" \
    -d '{
          "expectedVersion": "expectedVersion"
        }'
```

#### Response

```json
{
  "id": "id",
  "channels": [
    "EMAIL"
  ],
  "createdAt": "createdAt",
  "definition": {
    "description": "description",
    "messaging": {
      "callToAction": "callToAction",
      "persona": "persona",
      "trigger": "trigger",
      "valueProp": "valueProp"
    },
    "pacing": {
      "EMAIL": {
        "dailyLimit": -9007199254740991
      },
      "LINKEDIN_INVITE": {
        "dailyLimit": -9007199254740991
      },
      "LINKEDIN_MESSAGE": {
        "dailyLimit": -9007199254740991
      }
    },
    "priority": "HIGH",
    "sendWindow": {
      "daysOfWeek": [
        -9007199254740991
      ],
      "endHour": -9007199254740991,
      "startHour": -9007199254740991,
      "timezone": "timezone"
    },
    "steps": [
      {
        "id": "id",
        "deliveryMode": "AUTO",
        "mode": "AGENT",
        "name": "name",
        "prompt": "prompt",
        "type": "EMAIL"
      }
    ]
  },
  "firstActivatedAt": "firstActivatedAt",
  "lastActivatedAt": "lastActivatedAt",
  "name": "name",
  "objectType": "sequence",
  "reviewers": [
    {
      "id": "x",
      "objectType": "member"
    }
  ],
  "senders": [
    {
      "id": "x",
      "objectType": "sender"
    }
  ],
  "status": "DRAFT"
}
```

## List template variables

**get** `/v1/sequences/template/variables`

Lists the variables a sequence template may use: the first and last name, the contact’s and its first account’s fields of a type a message can print, and the sender’s name and email. Use an entry’s `ref` in a send step’s subject or body. A variable needs a fallback for contacts missing the value: `{{ {attr:ad_…} }}` is written `{{ coalesce({attr:ad_…}, "fallback") }}`, and one without a fallback is refused when the draft is saved. Anything else inside `{{ }}` is refused too.

**[Required scopes](/using-the-api/scopes/):** `sequences:read`, `contacts:read` and `accounts:read`

**[Rate limit category](/using-the-api/rate-limits/):** Read

### Returns

- `SequenceListTemplateVariablesResponse object { data, object, totalCount }`

  - `data: array of object { field, group, label, ref }`

    - `field: object { id, valueType }`

      The field the variable reads; null for built-in variables.

      - `id: string`

        The `ad_` id of the field, as the field-definitions endpoints list it.

      - `valueType: "ADDRESS" or "CHECKBOX" or "CURRENCY" or 12 more`

        Type of the field.

        - `"ADDRESS"`

        - `"CHECKBOX"`

        - `"CURRENCY"`

        - `"DATETIME"`

        - `"EMAIL"`

        - `"FULL_NAME"`

        - `"MARKDOWN"`

        - `"MULTI_SELECT"`

        - `"NUMBER"`

        - `"SINGLE_SELECT"`

        - `"SOCIAL_HANDLE"`

        - `"TELEPHONE"`

        - `"TEXT"`

        - `"URL"`

        - `"HTML"`

    - `group: "contact" or "account" or "sender"`

      Whose value the variable prints: the enrolled contact, its first account, or the step’s sender.

      - `"contact"`

      - `"account"`

      - `"sender"`

    - `label: string`

      Name of the variable, as the editor shows it.

    - `ref: string`

      The variable, e.g. `{{ {attr:ad_…} }}`. A variable needs a fallback for contacts missing the value: `{{ {attr:ad_…} }}` is written `{{ coalesce({attr:ad_…}, "fallback") }}`, and one without a fallback is refused when the draft is saved.

  - `object: "list"`

    - `"list"`

  - `totalCount: number`

### Example

```http
curl https://api.lightfield.app/v1/sequences/template/variables \
    -H 'Lightfield-Version: 2026-03-01' \
    -H "Authorization: Bearer $API_KEY"
```

#### Response

```json
{
  "data": [
    {
      "field": {
        "id": "id",
        "valueType": "ADDRESS"
      },
      "group": "contact",
      "label": "label",
      "ref": "ref"
    }
  ],
  "object": "list",
  "totalCount": -9007199254740991
}
```

## Discard a sequence draft

**post** `/v1/sequences/{id}/draft/discard`

Discards the open draft at `expectedVersion`. A published sequence keeps its published version. A sequence that has never been published is deleted with its draft, and `sequenceDeleted` is true. Returns 404 `draft_not_found` when no draft is open, and 409 when `expectedVersion` is not the open draft’s `version`; retrieve the draft and retry.

**[Required scope](/using-the-api/scopes/):** `sequences:update`

**[Rate limit category](/using-the-api/rate-limits/):** Write

### Path Parameters

- `id: string`

  Unique identifier of the sequence.

### Body Parameters

- `expectedVersion: string`

  The open draft’s `version` as last read.

### Returns

- `SequenceDiscardDraftResponse object { sequenceDeleted, sequenceId }`

  - `sequenceDeleted: boolean`

    True when the sequence had never been published, so discarding its only draft deleted it.

  - `sequenceId: string`

    The sequence whose draft was discarded.

### Example

```http
curl https://api.lightfield.app/v1/sequences/$ID/draft/discard \
    -H 'Content-Type: application/json' \
    -H 'Lightfield-Version: 2026-03-01' \
    -H "Authorization: Bearer $API_KEY" \
    -d '{
          "expectedVersion": "expectedVersion"
        }'
```

#### Response

```json
{
  "sequenceDeleted": true,
  "sequenceId": "sequenceId"
}
```

## Domain Types

### Sequence Activate Response

- `SequenceActivateResponse object { id, channels, createdAt, 8 more }`

  - `id: string`

    Unique identifier of the sequence.

  - `channels: array of "EMAIL" or "LINKEDIN"`

    Channels the published steps send on; empty before the first publish.

    - `"EMAIL"`

    - `"LINKEDIN"`

  - `createdAt: string`

    ISO 8601 creation timestamp.

  - `definition: object { description, messaging, pacing, 3 more }`

    Published configuration, or null before the first publish.

    - `description: string`

      What this version of the sequence is for.

    - `messaging: object { callToAction, persona, trigger, valueProp }`

      Messaging inputs that frame every step.

      - `callToAction: string`

        What the recipient is asked to do.

      - `persona: string`

        Who the sequence targets.

      - `trigger: string`

        Why the outreach is timely.

      - `valueProp: string`

        The value proposition.

    - `pacing: object { EMAIL, LINKEDIN_INVITE, LINKEDIN_MESSAGE }`

      How the whole sequence paces each step type it sends, keyed by sequence step type.

      - `EMAIL: object { dailyLimit }`

        Email steps.

        - `dailyLimit: number`

          Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

      - `LINKEDIN_INVITE: object { dailyLimit }`

        LinkedIn connection requests.

        - `dailyLimit: number`

          Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

      - `LINKEDIN_MESSAGE: object { dailyLimit }`

        LinkedIn messages.

        - `dailyLimit: number`

          Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

    - `priority: "HIGH" or "NORMAL"`

      Send priority relative to other sequences.

      - `"HIGH"`

      - `"NORMAL"`

    - `sendWindow: object { daysOfWeek, endHour, startHour, timezone }`

      When the sequence may send.

      - `daysOfWeek: array of number`

        Days sends may go out, 0 = Sunday.

      - `endHour: number`

        Local hour sends stop, exclusive (1–24).

      - `startHour: number`

        First local hour sends may go out (0–23).

      - `timezone: string`

        IANA timezone of the window.

    - `steps: array of object { id, deliveryMode, mode, 3 more }  or object { id, deliveryMode, includeNote, 4 more }  or object { id, deliveryMode, mode, 3 more }  or 3 more`

      Email, LinkedIn and wait steps in execution order.

      - `object { id, deliveryMode, mode, 3 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `mode: "AGENT"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"AGENT"`

        - `name: string`

          Display name of the step.

        - `prompt: string`

          Instructions the agent follows when composing this message.

        - `type: "EMAIL" or "LINKEDIN_MESSAGE"`

          Step type.

          - `"EMAIL"`

          - `"LINKEDIN_MESSAGE"`

      - `object { id, deliveryMode, includeNote, 4 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `includeNote: boolean`

          Whether the connection request carries a note. A step authored before this setting existed reads as true.

        - `mode: "AGENT"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"AGENT"`

        - `name: string`

          Display name of the step.

        - `prompt: string`

          Instructions the agent follows when composing this message.

        - `type: "LINKEDIN_INVITE"`

          Step type.

          - `"LINKEDIN_INVITE"`

      - `object { id, deliveryMode, mode, 3 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `mode: "TEMPLATE"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"TEMPLATE"`

        - `name: string`

          Display name of the step.

        - `template: object { body, subject }`

          The email every contact receives.

          - `body: string`

            Email body as Markdown, without the sign-off or signature, which are added when the message is written. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

          - `subject: string`

            Plain-text subject line. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

        - `type: "EMAIL"`

          Step type.

          - `"EMAIL"`

      - `object { id, deliveryMode, mode, 3 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `mode: "TEMPLATE"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"TEMPLATE"`

        - `name: string`

          Display name of the step.

        - `template: object { body }`

          The message every contact receives; for an invite, its connection note, sent only with `includeNote`.

          - `body: string`

            Plain-text message. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

        - `type: "LINKEDIN_MESSAGE"`

          Step type.

          - `"LINKEDIN_MESSAGE"`

      - `object { id, deliveryMode, includeNote, 4 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `includeNote: boolean`

          Whether the connection request carries a note. A step authored before this setting existed reads as true.

        - `mode: "TEMPLATE"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"TEMPLATE"`

        - `name: string`

          Display name of the step.

        - `template: object { body }`

          The message every contact receives; for an invite, its connection note, sent only with `includeNote`.

          - `body: string`

            Plain-text message. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

        - `type: "LINKEDIN_INVITE"`

          Step type.

          - `"LINKEDIN_INVITE"`

      - `object { id, duration, type, unit }`

        - `id: string`

          Step identifier.

        - `duration: number`

          Length of the wait.

        - `type: "WAIT" or "WAIT_FOR_CONNECTION"`

          `WAIT` pauses for a fixed time; `WAIT_FOR_CONNECTION` waits up to that long for a LinkedIn invite to be accepted.

          - `"WAIT"`

          - `"WAIT_FOR_CONNECTION"`

        - `unit: "DAY" or "MINUTE"`

          Unit of `duration`.

          - `"DAY"`

          - `"MINUTE"`

  - `firstActivatedAt: string`

    When the sequence was first activated.

  - `lastActivatedAt: string`

    When the sequence was most recently activated.

  - `name: string`

    Name of the sequence.

  - `objectType: "sequence"`

    Always `sequence`.

    - `"sequence"`

  - `reviewers: array of object { id, objectType }`

    Extra members who may approve this sequence’s `FOR_REVIEW` messages before they send. The sending member and the sequence’s creator always review, whether or not they are listed.

    - `id: string`

      ID of the member.

    - `objectType: "member"`

      Always `member`.

      - `"member"`

  - `senders: array of object { id, objectType }`

    The senders this sequence sends from; new contacts rotate across them. An archived sender stays listed but never sends; any change to the list drops it.

    - `id: string`

      ID of the sender.

    - `objectType: "sender"`

      Always `sender`.

      - `"sender"`

  - `status: "DRAFT" or "ACTIVE" or "DEACTIVATED"`

    `DRAFT` has not been published; `ACTIVE` is enabled for sending; `DEACTIVATED` is published but paused.

    - `"DRAFT"`

    - `"ACTIVE"`

    - `"DEACTIVATED"`

### Sequence Create Response

- `SequenceCreateResponse object { channels, definition, name, 6 more }`

  - `channels: array of "EMAIL" or "LINKEDIN"`

    Channels the draft's steps send on.

    - `"EMAIL"`

    - `"LINKEDIN"`

  - `definition: object { description, messaging, pacing, 3 more }`

    The draft configuration, in the same shape as a published definition.

    - `description: string`

      What this version of the sequence is for.

    - `messaging: object { callToAction, persona, trigger, valueProp }`

      Messaging inputs that frame every step.

      - `callToAction: string`

        What the recipient is asked to do.

      - `persona: string`

        Who the sequence targets.

      - `trigger: string`

        Why the outreach is timely.

      - `valueProp: string`

        The value proposition.

    - `pacing: object { EMAIL, LINKEDIN_INVITE, LINKEDIN_MESSAGE }`

      How the whole sequence paces each step type it sends, keyed by sequence step type.

      - `EMAIL: object { dailyLimit }`

        Email steps.

        - `dailyLimit: number`

          Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

      - `LINKEDIN_INVITE: object { dailyLimit }`

        LinkedIn connection requests.

        - `dailyLimit: number`

          Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

      - `LINKEDIN_MESSAGE: object { dailyLimit }`

        LinkedIn messages.

        - `dailyLimit: number`

          Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

    - `priority: "HIGH" or "NORMAL"`

      Send priority relative to other sequences.

      - `"HIGH"`

      - `"NORMAL"`

    - `sendWindow: object { daysOfWeek, endHour, startHour, timezone }`

      When the sequence may send.

      - `daysOfWeek: array of number`

        Days sends may go out, 0 = Sunday.

      - `endHour: number`

        Local hour sends stop, exclusive (1–24).

      - `startHour: number`

        First local hour sends may go out (0–23).

      - `timezone: string`

        IANA timezone of the window.

    - `steps: array of object { id, deliveryMode, mode, 3 more }  or object { id, deliveryMode, includeNote, 4 more }  or object { id, deliveryMode, mode, 3 more }  or 3 more`

      Email, LinkedIn and wait steps in execution order.

      - `object { id, deliveryMode, mode, 3 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `mode: "AGENT"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"AGENT"`

        - `name: string`

          Display name of the step.

        - `prompt: string`

          Instructions the agent follows when composing this message.

        - `type: "EMAIL" or "LINKEDIN_MESSAGE"`

          Step type.

          - `"EMAIL"`

          - `"LINKEDIN_MESSAGE"`

      - `object { id, deliveryMode, includeNote, 4 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `includeNote: boolean`

          Whether the connection request carries a note. A step authored before this setting existed reads as true.

        - `mode: "AGENT"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"AGENT"`

        - `name: string`

          Display name of the step.

        - `prompt: string`

          Instructions the agent follows when composing this message.

        - `type: "LINKEDIN_INVITE"`

          Step type.

          - `"LINKEDIN_INVITE"`

      - `object { id, deliveryMode, mode, 3 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `mode: "TEMPLATE"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"TEMPLATE"`

        - `name: string`

          Display name of the step.

        - `template: object { body, subject }`

          The email every contact receives.

          - `body: string`

            Email body as Markdown, without the sign-off or signature, which are added when the message is written. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

          - `subject: string`

            Plain-text subject line. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

        - `type: "EMAIL"`

          Step type.

          - `"EMAIL"`

      - `object { id, deliveryMode, mode, 3 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `mode: "TEMPLATE"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"TEMPLATE"`

        - `name: string`

          Display name of the step.

        - `template: object { body }`

          The message every contact receives; for an invite, its connection note, sent only with `includeNote`.

          - `body: string`

            Plain-text message. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

        - `type: "LINKEDIN_MESSAGE"`

          Step type.

          - `"LINKEDIN_MESSAGE"`

      - `object { id, deliveryMode, includeNote, 4 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `includeNote: boolean`

          Whether the connection request carries a note. A step authored before this setting existed reads as true.

        - `mode: "TEMPLATE"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"TEMPLATE"`

        - `name: string`

          Display name of the step.

        - `template: object { body }`

          The message every contact receives; for an invite, its connection note, sent only with `includeNote`.

          - `body: string`

            Plain-text message. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

        - `type: "LINKEDIN_INVITE"`

          Step type.

          - `"LINKEDIN_INVITE"`

      - `object { id, duration, type, unit }`

        - `id: string`

          Step identifier.

        - `duration: number`

          Length of the wait.

        - `type: "WAIT" or "WAIT_FOR_CONNECTION"`

          `WAIT` pauses for a fixed time; `WAIT_FOR_CONNECTION` waits up to that long for a LinkedIn invite to be accepted.

          - `"WAIT"`

          - `"WAIT_FOR_CONNECTION"`

        - `unit: "DAY" or "MINUTE"`

          Unit of `duration`.

          - `"DAY"`

          - `"MINUTE"`

  - `name: string`

    Name the sequence takes when the draft is published.

  - `publishWarnings: array of object { code, message, severity, stepIds }`

    What publishing this draft would change for contacts already in the sequence; empty when nothing is affected. Before the first publish, the only possible warning is a proposed sender that was archived and would be left off.

    - `code: "delay_shortened" or "delay_lengthened" or "connection_wait_shortened" or 18 more`

      What publishing would change.

      - `"delay_shortened"`

      - `"delay_lengthened"`

      - `"connection_wait_shortened"`

      - `"connection_wait_lengthened"`

      - `"send_schedule_changed"`

      - `"send_configuration_changed"`

      - `"send_priority_changed"`

      - `"senders_changed"`

      - `"email_sender_pool_emptied"`

      - `"linkedin_account_pool_emptied"`

      - `"assigned_sender_removed"`

      - `"delivery_became_automatic"`

      - `"invite_note_enabled"`

      - `"invite_note_disabled"`

      - `"step_inserted"`

      - `"automatic_send_step_inserted"`

      - `"step_removed"`

      - `"step_type_changed"`

      - `"step_order_changed"`

      - `"full_identity_rewrite"`

      - `"low_identity_overlap"`

    - `message: string`

      What would change, in plain language.

    - `severity: "warning" or "destructive"`

      `destructive` when contacts already in the sequence may skip, repeat or receive a step they would not have; `warning` otherwise.

      - `"warning"`

      - `"destructive"`

    - `stepIds: array of string`

      The steps involved; empty for a sequence-wide change.

  - `reviewers: array of object { id, objectType }`

    Extra members who may approve this sequence’s `FOR_REVIEW` messages before they send. The sending member and the sequence’s creator always review, whether or not they are listed.

    - `id: string`

      ID of the member.

    - `objectType: "member"`

      Always `member`.

      - `"member"`

  - `senders: array of object { id, objectType }`

    The senders this draft will publish; new contacts rotate across them. Until a save changes it, this is the sequence’s live list. An archived sender stays listed but never sends; any change to the list drops it.

    - `id: string`

      ID of the sender.

    - `objectType: "sender"`

      Always `sender`.

      - `"sender"`

  - `sequenceId: string`

    The sequence this draft belongs to.

  - `updatedAt: string`

    When the draft last changed.

  - `version: string`

    Opaque token for the current state of the draft. Send it as `expectedVersion` on the next save, publish or discard; it changes whenever anyone edits the draft.

### Sequence Deactivate Response

- `SequenceDeactivateResponse object { id, channels, createdAt, 8 more }`

  - `id: string`

    Unique identifier of the sequence.

  - `channels: array of "EMAIL" or "LINKEDIN"`

    Channels the published steps send on; empty before the first publish.

    - `"EMAIL"`

    - `"LINKEDIN"`

  - `createdAt: string`

    ISO 8601 creation timestamp.

  - `definition: object { description, messaging, pacing, 3 more }`

    Published configuration, or null before the first publish.

    - `description: string`

      What this version of the sequence is for.

    - `messaging: object { callToAction, persona, trigger, valueProp }`

      Messaging inputs that frame every step.

      - `callToAction: string`

        What the recipient is asked to do.

      - `persona: string`

        Who the sequence targets.

      - `trigger: string`

        Why the outreach is timely.

      - `valueProp: string`

        The value proposition.

    - `pacing: object { EMAIL, LINKEDIN_INVITE, LINKEDIN_MESSAGE }`

      How the whole sequence paces each step type it sends, keyed by sequence step type.

      - `EMAIL: object { dailyLimit }`

        Email steps.

        - `dailyLimit: number`

          Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

      - `LINKEDIN_INVITE: object { dailyLimit }`

        LinkedIn connection requests.

        - `dailyLimit: number`

          Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

      - `LINKEDIN_MESSAGE: object { dailyLimit }`

        LinkedIn messages.

        - `dailyLimit: number`

          Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

    - `priority: "HIGH" or "NORMAL"`

      Send priority relative to other sequences.

      - `"HIGH"`

      - `"NORMAL"`

    - `sendWindow: object { daysOfWeek, endHour, startHour, timezone }`

      When the sequence may send.

      - `daysOfWeek: array of number`

        Days sends may go out, 0 = Sunday.

      - `endHour: number`

        Local hour sends stop, exclusive (1–24).

      - `startHour: number`

        First local hour sends may go out (0–23).

      - `timezone: string`

        IANA timezone of the window.

    - `steps: array of object { id, deliveryMode, mode, 3 more }  or object { id, deliveryMode, includeNote, 4 more }  or object { id, deliveryMode, mode, 3 more }  or 3 more`

      Email, LinkedIn and wait steps in execution order.

      - `object { id, deliveryMode, mode, 3 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `mode: "AGENT"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"AGENT"`

        - `name: string`

          Display name of the step.

        - `prompt: string`

          Instructions the agent follows when composing this message.

        - `type: "EMAIL" or "LINKEDIN_MESSAGE"`

          Step type.

          - `"EMAIL"`

          - `"LINKEDIN_MESSAGE"`

      - `object { id, deliveryMode, includeNote, 4 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `includeNote: boolean`

          Whether the connection request carries a note. A step authored before this setting existed reads as true.

        - `mode: "AGENT"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"AGENT"`

        - `name: string`

          Display name of the step.

        - `prompt: string`

          Instructions the agent follows when composing this message.

        - `type: "LINKEDIN_INVITE"`

          Step type.

          - `"LINKEDIN_INVITE"`

      - `object { id, deliveryMode, mode, 3 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `mode: "TEMPLATE"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"TEMPLATE"`

        - `name: string`

          Display name of the step.

        - `template: object { body, subject }`

          The email every contact receives.

          - `body: string`

            Email body as Markdown, without the sign-off or signature, which are added when the message is written. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

          - `subject: string`

            Plain-text subject line. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

        - `type: "EMAIL"`

          Step type.

          - `"EMAIL"`

      - `object { id, deliveryMode, mode, 3 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `mode: "TEMPLATE"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"TEMPLATE"`

        - `name: string`

          Display name of the step.

        - `template: object { body }`

          The message every contact receives; for an invite, its connection note, sent only with `includeNote`.

          - `body: string`

            Plain-text message. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

        - `type: "LINKEDIN_MESSAGE"`

          Step type.

          - `"LINKEDIN_MESSAGE"`

      - `object { id, deliveryMode, includeNote, 4 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `includeNote: boolean`

          Whether the connection request carries a note. A step authored before this setting existed reads as true.

        - `mode: "TEMPLATE"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"TEMPLATE"`

        - `name: string`

          Display name of the step.

        - `template: object { body }`

          The message every contact receives; for an invite, its connection note, sent only with `includeNote`.

          - `body: string`

            Plain-text message. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

        - `type: "LINKEDIN_INVITE"`

          Step type.

          - `"LINKEDIN_INVITE"`

      - `object { id, duration, type, unit }`

        - `id: string`

          Step identifier.

        - `duration: number`

          Length of the wait.

        - `type: "WAIT" or "WAIT_FOR_CONNECTION"`

          `WAIT` pauses for a fixed time; `WAIT_FOR_CONNECTION` waits up to that long for a LinkedIn invite to be accepted.

          - `"WAIT"`

          - `"WAIT_FOR_CONNECTION"`

        - `unit: "DAY" or "MINUTE"`

          Unit of `duration`.

          - `"DAY"`

          - `"MINUTE"`

  - `firstActivatedAt: string`

    When the sequence was first activated.

  - `lastActivatedAt: string`

    When the sequence was most recently activated.

  - `name: string`

    Name of the sequence.

  - `objectType: "sequence"`

    Always `sequence`.

    - `"sequence"`

  - `reviewers: array of object { id, objectType }`

    Extra members who may approve this sequence’s `FOR_REVIEW` messages before they send. The sending member and the sequence’s creator always review, whether or not they are listed.

    - `id: string`

      ID of the member.

    - `objectType: "member"`

      Always `member`.

      - `"member"`

  - `senders: array of object { id, objectType }`

    The senders this sequence sends from; new contacts rotate across them. An archived sender stays listed but never sends; any change to the list drops it.

    - `id: string`

      ID of the sender.

    - `objectType: "sender"`

      Always `sender`.

      - `"sender"`

  - `status: "DRAFT" or "ACTIVE" or "DEACTIVATED"`

    `DRAFT` has not been published; `ACTIVE` is enabled for sending; `DEACTIVATED` is published but paused.

    - `"DRAFT"`

    - `"ACTIVE"`

    - `"DEACTIVATED"`

### Sequence Discard Draft Response

- `SequenceDiscardDraftResponse object { sequenceDeleted, sequenceId }`

  - `sequenceDeleted: boolean`

    True when the sequence had never been published, so discarding its only draft deleted it.

  - `sequenceId: string`

    The sequence whose draft was discarded.

### Sequence List Enrollments Response

- `SequenceListEnrollmentsResponse object { data, object, totalCount }`

  - `data: array of object { id, cancelledAt, completedAt, 10 more }`

    - `id: string`

      Unique identifier of the enrollment.

    - `cancelledAt: string`

      When the enrollment was cancelled, or null if it was not.

    - `completedAt: string`

      When the enrollment completed, or null if it has not.

    - `contactId: string`

      ID of the enrolled contact.

    - `currentStepId: string`

      ID of the step the contact is on, matching `definition.steps`; null when the contact has no current step the API returns.

    - `enrolledAt: string`

      When the contact was enrolled.

    - `enrolledBy: string`

      Member ID of whoever enrolled the contact; null when they are no longer a member or the enrollment was automatic.

    - `lastActivityAt: string`

      When `lastActivityKind` happened; null when there has been no activity.

    - `lastActivityKind: "SENT" or "OPENED" or "REPLIED" or 4 more`

      The latest activity on the enrollment. A reply or bounce that ended the enrollment is reported over a later open.

      - `"SENT"`

      - `"OPENED"`

      - `"REPLIED"`

      - `"BOUNCED"`

      - `"INVITED"`

      - `"CONNECTED"`

      - `"SEEN"`

    - `nextSendAt: string`

      Estimated time of the next send, from the cadence, send window, pacing and sender; queue order and random gaps can push it later. Null while a message awaits review or is sending, while paused, or when it cannot be estimated.

    - `remainingSends: number`

      Email and LinkedIn steps not yet sent, connection requests included.

    - `repliedAt: string`

      When the contact first replied, on email or LinkedIn; null if they have not.

    - `status: "ACTIVE" or "AWAITING_REVIEW" or "NEEDS_ATTENTION" or 5 more`

      `ACTIVE` is progressing; `AWAITING_REVIEW` has a message waiting for approval; `NEEDS_ATTENTION` is held by a failed step, a held draft or an unavailable sender; `PAUSED` is stopped because the sequence is deactivated or it was paused in Lightfield. `REPLIED`, `COMPLETED`, `CANCELLED` and `FAILED` are final.

      - `"ACTIVE"`

      - `"AWAITING_REVIEW"`

      - `"NEEDS_ATTENTION"`

      - `"REPLIED"`

      - `"COMPLETED"`

      - `"PAUSED"`

      - `"CANCELLED"`

      - `"FAILED"`

  - `object: "list"`

    - `"list"`

  - `totalCount: number`

### Sequence List Messages Response

- `SequenceListMessagesResponse object { data, object, totalCount }`

  - `data: array of object { id, acceptedAt, bouncedAt, 14 more }  or object { id, channel, contactId, 7 more }`

    - `OutboundMessage object { id, acceptedAt, bouncedAt, 14 more }`

      - `id: string`

        Unique identifier of the message.

      - `acceptedAt: string`

        When the connection request was accepted; null until then.

      - `bouncedAt: string`

        When the email bounced; null until then.

      - `channel: "EMAIL" or "LINKEDIN"`

        Channel the message went over.

        - `"EMAIL"`

        - `"LINKEDIN"`

      - `contactId: string`

        ID of the contact.

      - `createdAt: string`

        When the message was created, or when a reply was received. Lists sort by this field, newest first.

      - `direction: "OUTBOUND"`

        Always `OUTBOUND`.

        - `"OUTBOUND"`

      - `enrollmentId: string`

        ID of the enrollment the message belongs to.

      - `openedAt: string`

        When the email was opened; null until then.

      - `readAt: string`

        When the LinkedIn message was read; null until then.

      - `reference: object { id, objectType }  or object { id, objectType }`

        The email or LinkedIn message record behind this sequence message, readable with <u>[Retrieve an email](/api/resources/email/methods/retrieve)</u> or <u>[Retrieve a message](/api/resources/message/methods/retrieve)</u> under their own scopes; null when there is none.

        - `Email object { id, objectType }`

          - `id: string`

            ID of the email.

          - `objectType: "email"`

            Always `email`.

            - `"email"`

        - `Message object { id, objectType }`

          - `id: string`

            ID of the message.

          - `objectType: "message"`

            Always `message`.

            - `"message"`

      - `repliedAt: string`

        When the contact replied to this message; null until then.

      - `sentAt: string`

        When the message was sent; null until then.

      - `sequenceStepId: string`

        ID of the step that sent the message or, for a reply, the step it replied to.

      - `sequenceStepType: "EMAIL" or "LINKEDIN_MESSAGE" or "LINKEDIN_INVITE"`

        Type of that step.

        - `"EMAIL"`

        - `"LINKEDIN_MESSAGE"`

        - `"LINKEDIN_INVITE"`

      - `status: "AWAITING_REVIEW" or "SCHEDULED" or "QUEUED" or 4 more`

        `AWAITING_REVIEW` is waiting for approval; `SCHEDULED` is composed and waiting for its send time; `QUEUED` is due and waiting on the sender. `SENT`, `SKIPPED`, `FAILED` and `CANCELLED` are final.

        - `"AWAITING_REVIEW"`

        - `"SCHEDULED"`

        - `"QUEUED"`

        - `"SENT"`

        - `"SKIPPED"`

        - `"FAILED"`

        - `"CANCELLED"`

      - `statusChangedAt: string`

        When `status` last changed.

    - `Reply object { id, channel, contactId, 7 more }`

      - `id: string`

        Unique identifier of the message.

      - `channel: "EMAIL" or "LINKEDIN"`

        Channel the message went over.

        - `"EMAIL"`

        - `"LINKEDIN"`

      - `contactId: string`

        ID of the contact.

      - `createdAt: string`

        When the message was created, or when a reply was received. Lists sort by this field, newest first.

      - `direction: "INBOUND"`

        Always `INBOUND`.

        - `"INBOUND"`

      - `enrollmentId: string`

        ID of the enrollment the message belongs to.

      - `receivedAt: string`

        When the reply was received.

      - `reference: object { id, objectType }  or object { id, objectType }`

        The email or LinkedIn message record behind this sequence message, readable with <u>[Retrieve an email](/api/resources/email/methods/retrieve)</u> or <u>[Retrieve a message](/api/resources/message/methods/retrieve)</u> under their own scopes; null when there is none.

        - `Email object { id, objectType }`

          - `id: string`

            ID of the email.

          - `objectType: "email"`

            Always `email`.

            - `"email"`

        - `Message object { id, objectType }`

          - `id: string`

            ID of the message.

          - `objectType: "message"`

            Always `message`.

            - `"message"`

      - `sequenceStepId: string`

        ID of the step that sent the message or, for a reply, the step it replied to.

      - `sequenceStepType: "EMAIL" or "LINKEDIN_MESSAGE" or "LINKEDIN_INVITE"`

        Type of that step.

        - `"EMAIL"`

        - `"LINKEDIN_MESSAGE"`

        - `"LINKEDIN_INVITE"`

  - `object: "list"`

    - `"list"`

  - `totalCount: number`

### Sequence List Response

- `SequenceListResponse object { data, object, totalCount }`

  - `data: array of object { id, channels, createdAt, 8 more }`

    - `id: string`

      Unique identifier of the sequence.

    - `channels: array of "EMAIL" or "LINKEDIN"`

      Channels the published steps send on; empty before the first publish.

      - `"EMAIL"`

      - `"LINKEDIN"`

    - `createdAt: string`

      ISO 8601 creation timestamp.

    - `definition: object { description, messaging, pacing, 3 more }`

      Published configuration, or null before the first publish.

      - `description: string`

        What this version of the sequence is for.

      - `messaging: object { callToAction, persona, trigger, valueProp }`

        Messaging inputs that frame every step.

        - `callToAction: string`

          What the recipient is asked to do.

        - `persona: string`

          Who the sequence targets.

        - `trigger: string`

          Why the outreach is timely.

        - `valueProp: string`

          The value proposition.

      - `pacing: object { EMAIL, LINKEDIN_INVITE, LINKEDIN_MESSAGE }`

        How the whole sequence paces each step type it sends, keyed by sequence step type.

        - `EMAIL: object { dailyLimit }`

          Email steps.

          - `dailyLimit: number`

            Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

        - `LINKEDIN_INVITE: object { dailyLimit }`

          LinkedIn connection requests.

          - `dailyLimit: number`

            Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

        - `LINKEDIN_MESSAGE: object { dailyLimit }`

          LinkedIn messages.

          - `dailyLimit: number`

            Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

      - `priority: "HIGH" or "NORMAL"`

        Send priority relative to other sequences.

        - `"HIGH"`

        - `"NORMAL"`

      - `sendWindow: object { daysOfWeek, endHour, startHour, timezone }`

        When the sequence may send.

        - `daysOfWeek: array of number`

          Days sends may go out, 0 = Sunday.

        - `endHour: number`

          Local hour sends stop, exclusive (1–24).

        - `startHour: number`

          First local hour sends may go out (0–23).

        - `timezone: string`

          IANA timezone of the window.

      - `steps: array of object { id, deliveryMode, mode, 3 more }  or object { id, deliveryMode, includeNote, 4 more }  or object { id, deliveryMode, mode, 3 more }  or 3 more`

        Email, LinkedIn and wait steps in execution order.

        - `object { id, deliveryMode, mode, 3 more }`

          - `id: string`

            Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

          - `deliveryMode: "AUTO" or "FOR_REVIEW"`

            `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

            - `"AUTO"`

            - `"FOR_REVIEW"`

          - `mode: "AGENT"`

            How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

            - `"AGENT"`

          - `name: string`

            Display name of the step.

          - `prompt: string`

            Instructions the agent follows when composing this message.

          - `type: "EMAIL" or "LINKEDIN_MESSAGE"`

            Step type.

            - `"EMAIL"`

            - `"LINKEDIN_MESSAGE"`

        - `object { id, deliveryMode, includeNote, 4 more }`

          - `id: string`

            Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

          - `deliveryMode: "AUTO" or "FOR_REVIEW"`

            `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

            - `"AUTO"`

            - `"FOR_REVIEW"`

          - `includeNote: boolean`

            Whether the connection request carries a note. A step authored before this setting existed reads as true.

          - `mode: "AGENT"`

            How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

            - `"AGENT"`

          - `name: string`

            Display name of the step.

          - `prompt: string`

            Instructions the agent follows when composing this message.

          - `type: "LINKEDIN_INVITE"`

            Step type.

            - `"LINKEDIN_INVITE"`

        - `object { id, deliveryMode, mode, 3 more }`

          - `id: string`

            Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

          - `deliveryMode: "AUTO" or "FOR_REVIEW"`

            `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

            - `"AUTO"`

            - `"FOR_REVIEW"`

          - `mode: "TEMPLATE"`

            How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

            - `"TEMPLATE"`

          - `name: string`

            Display name of the step.

          - `template: object { body, subject }`

            The email every contact receives.

            - `body: string`

              Email body as Markdown, without the sign-off or signature, which are added when the message is written. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

            - `subject: string`

              Plain-text subject line. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

          - `type: "EMAIL"`

            Step type.

            - `"EMAIL"`

        - `object { id, deliveryMode, mode, 3 more }`

          - `id: string`

            Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

          - `deliveryMode: "AUTO" or "FOR_REVIEW"`

            `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

            - `"AUTO"`

            - `"FOR_REVIEW"`

          - `mode: "TEMPLATE"`

            How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

            - `"TEMPLATE"`

          - `name: string`

            Display name of the step.

          - `template: object { body }`

            The message every contact receives; for an invite, its connection note, sent only with `includeNote`.

            - `body: string`

              Plain-text message. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

          - `type: "LINKEDIN_MESSAGE"`

            Step type.

            - `"LINKEDIN_MESSAGE"`

        - `object { id, deliveryMode, includeNote, 4 more }`

          - `id: string`

            Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

          - `deliveryMode: "AUTO" or "FOR_REVIEW"`

            `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

            - `"AUTO"`

            - `"FOR_REVIEW"`

          - `includeNote: boolean`

            Whether the connection request carries a note. A step authored before this setting existed reads as true.

          - `mode: "TEMPLATE"`

            How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

            - `"TEMPLATE"`

          - `name: string`

            Display name of the step.

          - `template: object { body }`

            The message every contact receives; for an invite, its connection note, sent only with `includeNote`.

            - `body: string`

              Plain-text message. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

          - `type: "LINKEDIN_INVITE"`

            Step type.

            - `"LINKEDIN_INVITE"`

        - `object { id, duration, type, unit }`

          - `id: string`

            Step identifier.

          - `duration: number`

            Length of the wait.

          - `type: "WAIT" or "WAIT_FOR_CONNECTION"`

            `WAIT` pauses for a fixed time; `WAIT_FOR_CONNECTION` waits up to that long for a LinkedIn invite to be accepted.

            - `"WAIT"`

            - `"WAIT_FOR_CONNECTION"`

          - `unit: "DAY" or "MINUTE"`

            Unit of `duration`.

            - `"DAY"`

            - `"MINUTE"`

    - `firstActivatedAt: string`

      When the sequence was first activated.

    - `lastActivatedAt: string`

      When the sequence was most recently activated.

    - `name: string`

      Name of the sequence.

    - `objectType: "sequence"`

      Always `sequence`.

      - `"sequence"`

    - `reviewers: array of object { id, objectType }`

      Extra members who may approve this sequence’s `FOR_REVIEW` messages before they send. The sending member and the sequence’s creator always review, whether or not they are listed.

      - `id: string`

        ID of the member.

      - `objectType: "member"`

        Always `member`.

        - `"member"`

    - `senders: array of object { id, objectType }`

      The senders this sequence sends from; new contacts rotate across them. An archived sender stays listed but never sends; any change to the list drops it.

      - `id: string`

        ID of the sender.

      - `objectType: "sender"`

        Always `sender`.

        - `"sender"`

    - `status: "DRAFT" or "ACTIVE" or "DEACTIVATED"`

      `DRAFT` has not been published; `ACTIVE` is enabled for sending; `DEACTIVATED` is published but paused.

      - `"DRAFT"`

      - `"ACTIVE"`

      - `"DEACTIVATED"`

  - `object: "list"`

    - `"list"`

  - `totalCount: number`

### Sequence List Template Variables Response

- `SequenceListTemplateVariablesResponse object { data, object, totalCount }`

  - `data: array of object { field, group, label, ref }`

    - `field: object { id, valueType }`

      The field the variable reads; null for built-in variables.

      - `id: string`

        The `ad_` id of the field, as the field-definitions endpoints list it.

      - `valueType: "ADDRESS" or "CHECKBOX" or "CURRENCY" or 12 more`

        Type of the field.

        - `"ADDRESS"`

        - `"CHECKBOX"`

        - `"CURRENCY"`

        - `"DATETIME"`

        - `"EMAIL"`

        - `"FULL_NAME"`

        - `"MARKDOWN"`

        - `"MULTI_SELECT"`

        - `"NUMBER"`

        - `"SINGLE_SELECT"`

        - `"SOCIAL_HANDLE"`

        - `"TELEPHONE"`

        - `"TEXT"`

        - `"URL"`

        - `"HTML"`

    - `group: "contact" or "account" or "sender"`

      Whose value the variable prints: the enrolled contact, its first account, or the step’s sender.

      - `"contact"`

      - `"account"`

      - `"sender"`

    - `label: string`

      Name of the variable, as the editor shows it.

    - `ref: string`

      The variable, e.g. `{{ {attr:ad_…} }}`. A variable needs a fallback for contacts missing the value: `{{ {attr:ad_…} }}` is written `{{ coalesce({attr:ad_…}, "fallback") }}`, and one without a fallback is refused when the draft is saved.

  - `object: "list"`

    - `"list"`

  - `totalCount: number`

### Sequence Publish Draft Response

- `SequencePublishDraftResponse object { id, channels, createdAt, 8 more }`

  - `id: string`

    Unique identifier of the sequence.

  - `channels: array of "EMAIL" or "LINKEDIN"`

    Channels the published steps send on; empty before the first publish.

    - `"EMAIL"`

    - `"LINKEDIN"`

  - `createdAt: string`

    ISO 8601 creation timestamp.

  - `definition: object { description, messaging, pacing, 3 more }`

    Published configuration, or null before the first publish.

    - `description: string`

      What this version of the sequence is for.

    - `messaging: object { callToAction, persona, trigger, valueProp }`

      Messaging inputs that frame every step.

      - `callToAction: string`

        What the recipient is asked to do.

      - `persona: string`

        Who the sequence targets.

      - `trigger: string`

        Why the outreach is timely.

      - `valueProp: string`

        The value proposition.

    - `pacing: object { EMAIL, LINKEDIN_INVITE, LINKEDIN_MESSAGE }`

      How the whole sequence paces each step type it sends, keyed by sequence step type.

      - `EMAIL: object { dailyLimit }`

        Email steps.

        - `dailyLimit: number`

          Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

      - `LINKEDIN_INVITE: object { dailyLimit }`

        LinkedIn connection requests.

        - `dailyLimit: number`

          Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

      - `LINKEDIN_MESSAGE: object { dailyLimit }`

        LinkedIn messages.

        - `dailyLimit: number`

          Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

    - `priority: "HIGH" or "NORMAL"`

      Send priority relative to other sequences.

      - `"HIGH"`

      - `"NORMAL"`

    - `sendWindow: object { daysOfWeek, endHour, startHour, timezone }`

      When the sequence may send.

      - `daysOfWeek: array of number`

        Days sends may go out, 0 = Sunday.

      - `endHour: number`

        Local hour sends stop, exclusive (1–24).

      - `startHour: number`

        First local hour sends may go out (0–23).

      - `timezone: string`

        IANA timezone of the window.

    - `steps: array of object { id, deliveryMode, mode, 3 more }  or object { id, deliveryMode, includeNote, 4 more }  or object { id, deliveryMode, mode, 3 more }  or 3 more`

      Email, LinkedIn and wait steps in execution order.

      - `object { id, deliveryMode, mode, 3 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `mode: "AGENT"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"AGENT"`

        - `name: string`

          Display name of the step.

        - `prompt: string`

          Instructions the agent follows when composing this message.

        - `type: "EMAIL" or "LINKEDIN_MESSAGE"`

          Step type.

          - `"EMAIL"`

          - `"LINKEDIN_MESSAGE"`

      - `object { id, deliveryMode, includeNote, 4 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `includeNote: boolean`

          Whether the connection request carries a note. A step authored before this setting existed reads as true.

        - `mode: "AGENT"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"AGENT"`

        - `name: string`

          Display name of the step.

        - `prompt: string`

          Instructions the agent follows when composing this message.

        - `type: "LINKEDIN_INVITE"`

          Step type.

          - `"LINKEDIN_INVITE"`

      - `object { id, deliveryMode, mode, 3 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `mode: "TEMPLATE"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"TEMPLATE"`

        - `name: string`

          Display name of the step.

        - `template: object { body, subject }`

          The email every contact receives.

          - `body: string`

            Email body as Markdown, without the sign-off or signature, which are added when the message is written. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

          - `subject: string`

            Plain-text subject line. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

        - `type: "EMAIL"`

          Step type.

          - `"EMAIL"`

      - `object { id, deliveryMode, mode, 3 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `mode: "TEMPLATE"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"TEMPLATE"`

        - `name: string`

          Display name of the step.

        - `template: object { body }`

          The message every contact receives; for an invite, its connection note, sent only with `includeNote`.

          - `body: string`

            Plain-text message. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

        - `type: "LINKEDIN_MESSAGE"`

          Step type.

          - `"LINKEDIN_MESSAGE"`

      - `object { id, deliveryMode, includeNote, 4 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `includeNote: boolean`

          Whether the connection request carries a note. A step authored before this setting existed reads as true.

        - `mode: "TEMPLATE"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"TEMPLATE"`

        - `name: string`

          Display name of the step.

        - `template: object { body }`

          The message every contact receives; for an invite, its connection note, sent only with `includeNote`.

          - `body: string`

            Plain-text message. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

        - `type: "LINKEDIN_INVITE"`

          Step type.

          - `"LINKEDIN_INVITE"`

      - `object { id, duration, type, unit }`

        - `id: string`

          Step identifier.

        - `duration: number`

          Length of the wait.

        - `type: "WAIT" or "WAIT_FOR_CONNECTION"`

          `WAIT` pauses for a fixed time; `WAIT_FOR_CONNECTION` waits up to that long for a LinkedIn invite to be accepted.

          - `"WAIT"`

          - `"WAIT_FOR_CONNECTION"`

        - `unit: "DAY" or "MINUTE"`

          Unit of `duration`.

          - `"DAY"`

          - `"MINUTE"`

  - `firstActivatedAt: string`

    When the sequence was first activated.

  - `lastActivatedAt: string`

    When the sequence was most recently activated.

  - `name: string`

    Name of the sequence.

  - `objectType: "sequence"`

    Always `sequence`.

    - `"sequence"`

  - `reviewers: array of object { id, objectType }`

    Extra members who may approve this sequence’s `FOR_REVIEW` messages before they send. The sending member and the sequence’s creator always review, whether or not they are listed.

    - `id: string`

      ID of the member.

    - `objectType: "member"`

      Always `member`.

      - `"member"`

  - `senders: array of object { id, objectType }`

    The senders this sequence sends from; new contacts rotate across them. An archived sender stays listed but never sends; any change to the list drops it.

    - `id: string`

      ID of the sender.

    - `objectType: "sender"`

      Always `sender`.

      - `"sender"`

  - `status: "DRAFT" or "ACTIVE" or "DEACTIVATED"`

    `DRAFT` has not been published; `ACTIVE` is enabled for sending; `DEACTIVATED` is published but paused.

    - `"DRAFT"`

    - `"ACTIVE"`

    - `"DEACTIVATED"`

### Sequence Retrieve Draft Response

- `SequenceRetrieveDraftResponse object { channels, definition, name, 6 more }`

  - `channels: array of "EMAIL" or "LINKEDIN"`

    Channels the draft's steps send on.

    - `"EMAIL"`

    - `"LINKEDIN"`

  - `definition: object { description, messaging, pacing, 3 more }`

    The draft configuration, in the same shape as a published definition.

    - `description: string`

      What this version of the sequence is for.

    - `messaging: object { callToAction, persona, trigger, valueProp }`

      Messaging inputs that frame every step.

      - `callToAction: string`

        What the recipient is asked to do.

      - `persona: string`

        Who the sequence targets.

      - `trigger: string`

        Why the outreach is timely.

      - `valueProp: string`

        The value proposition.

    - `pacing: object { EMAIL, LINKEDIN_INVITE, LINKEDIN_MESSAGE }`

      How the whole sequence paces each step type it sends, keyed by sequence step type.

      - `EMAIL: object { dailyLimit }`

        Email steps.

        - `dailyLimit: number`

          Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

      - `LINKEDIN_INVITE: object { dailyLimit }`

        LinkedIn connection requests.

        - `dailyLimit: number`

          Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

      - `LINKEDIN_MESSAGE: object { dailyLimit }`

        LinkedIn messages.

        - `dailyLimit: number`

          Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

    - `priority: "HIGH" or "NORMAL"`

      Send priority relative to other sequences.

      - `"HIGH"`

      - `"NORMAL"`

    - `sendWindow: object { daysOfWeek, endHour, startHour, timezone }`

      When the sequence may send.

      - `daysOfWeek: array of number`

        Days sends may go out, 0 = Sunday.

      - `endHour: number`

        Local hour sends stop, exclusive (1–24).

      - `startHour: number`

        First local hour sends may go out (0–23).

      - `timezone: string`

        IANA timezone of the window.

    - `steps: array of object { id, deliveryMode, mode, 3 more }  or object { id, deliveryMode, includeNote, 4 more }  or object { id, deliveryMode, mode, 3 more }  or 3 more`

      Email, LinkedIn and wait steps in execution order.

      - `object { id, deliveryMode, mode, 3 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `mode: "AGENT"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"AGENT"`

        - `name: string`

          Display name of the step.

        - `prompt: string`

          Instructions the agent follows when composing this message.

        - `type: "EMAIL" or "LINKEDIN_MESSAGE"`

          Step type.

          - `"EMAIL"`

          - `"LINKEDIN_MESSAGE"`

      - `object { id, deliveryMode, includeNote, 4 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `includeNote: boolean`

          Whether the connection request carries a note. A step authored before this setting existed reads as true.

        - `mode: "AGENT"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"AGENT"`

        - `name: string`

          Display name of the step.

        - `prompt: string`

          Instructions the agent follows when composing this message.

        - `type: "LINKEDIN_INVITE"`

          Step type.

          - `"LINKEDIN_INVITE"`

      - `object { id, deliveryMode, mode, 3 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `mode: "TEMPLATE"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"TEMPLATE"`

        - `name: string`

          Display name of the step.

        - `template: object { body, subject }`

          The email every contact receives.

          - `body: string`

            Email body as Markdown, without the sign-off or signature, which are added when the message is written. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

          - `subject: string`

            Plain-text subject line. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

        - `type: "EMAIL"`

          Step type.

          - `"EMAIL"`

      - `object { id, deliveryMode, mode, 3 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `mode: "TEMPLATE"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"TEMPLATE"`

        - `name: string`

          Display name of the step.

        - `template: object { body }`

          The message every contact receives; for an invite, its connection note, sent only with `includeNote`.

          - `body: string`

            Plain-text message. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

        - `type: "LINKEDIN_MESSAGE"`

          Step type.

          - `"LINKEDIN_MESSAGE"`

      - `object { id, deliveryMode, includeNote, 4 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `includeNote: boolean`

          Whether the connection request carries a note. A step authored before this setting existed reads as true.

        - `mode: "TEMPLATE"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"TEMPLATE"`

        - `name: string`

          Display name of the step.

        - `template: object { body }`

          The message every contact receives; for an invite, its connection note, sent only with `includeNote`.

          - `body: string`

            Plain-text message. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

        - `type: "LINKEDIN_INVITE"`

          Step type.

          - `"LINKEDIN_INVITE"`

      - `object { id, duration, type, unit }`

        - `id: string`

          Step identifier.

        - `duration: number`

          Length of the wait.

        - `type: "WAIT" or "WAIT_FOR_CONNECTION"`

          `WAIT` pauses for a fixed time; `WAIT_FOR_CONNECTION` waits up to that long for a LinkedIn invite to be accepted.

          - `"WAIT"`

          - `"WAIT_FOR_CONNECTION"`

        - `unit: "DAY" or "MINUTE"`

          Unit of `duration`.

          - `"DAY"`

          - `"MINUTE"`

  - `name: string`

    Name the sequence takes when the draft is published.

  - `publishWarnings: array of object { code, message, severity, stepIds }`

    What publishing this draft would change for contacts already in the sequence; empty when nothing is affected. Before the first publish, the only possible warning is a proposed sender that was archived and would be left off.

    - `code: "delay_shortened" or "delay_lengthened" or "connection_wait_shortened" or 18 more`

      What publishing would change.

      - `"delay_shortened"`

      - `"delay_lengthened"`

      - `"connection_wait_shortened"`

      - `"connection_wait_lengthened"`

      - `"send_schedule_changed"`

      - `"send_configuration_changed"`

      - `"send_priority_changed"`

      - `"senders_changed"`

      - `"email_sender_pool_emptied"`

      - `"linkedin_account_pool_emptied"`

      - `"assigned_sender_removed"`

      - `"delivery_became_automatic"`

      - `"invite_note_enabled"`

      - `"invite_note_disabled"`

      - `"step_inserted"`

      - `"automatic_send_step_inserted"`

      - `"step_removed"`

      - `"step_type_changed"`

      - `"step_order_changed"`

      - `"full_identity_rewrite"`

      - `"low_identity_overlap"`

    - `message: string`

      What would change, in plain language.

    - `severity: "warning" or "destructive"`

      `destructive` when contacts already in the sequence may skip, repeat or receive a step they would not have; `warning` otherwise.

      - `"warning"`

      - `"destructive"`

    - `stepIds: array of string`

      The steps involved; empty for a sequence-wide change.

  - `reviewers: array of object { id, objectType }`

    Extra members who may approve this sequence’s `FOR_REVIEW` messages before they send. The sending member and the sequence’s creator always review, whether or not they are listed.

    - `id: string`

      ID of the member.

    - `objectType: "member"`

      Always `member`.

      - `"member"`

  - `senders: array of object { id, objectType }`

    The senders this draft will publish; new contacts rotate across them. Until a save changes it, this is the sequence’s live list. An archived sender stays listed but never sends; any change to the list drops it.

    - `id: string`

      ID of the sender.

    - `objectType: "sender"`

      Always `sender`.

      - `"sender"`

  - `sequenceId: string`

    The sequence this draft belongs to.

  - `updatedAt: string`

    When the draft last changed.

  - `version: string`

    Opaque token for the current state of the draft. Send it as `expectedVersion` on the next save, publish or discard; it changes whenever anyone edits the draft.

### Sequence Retrieve Enrollment Response

- `SequenceRetrieveEnrollmentResponse object { id, cancelledAt, completedAt, 10 more }`

  - `id: string`

    Unique identifier of the enrollment.

  - `cancelledAt: string`

    When the enrollment was cancelled, or null if it was not.

  - `completedAt: string`

    When the enrollment completed, or null if it has not.

  - `contactId: string`

    ID of the enrolled contact.

  - `currentStepId: string`

    ID of the step the contact is on, matching `definition.steps`; null when the contact has no current step the API returns.

  - `enrolledAt: string`

    When the contact was enrolled.

  - `enrolledBy: string`

    Member ID of whoever enrolled the contact; null when they are no longer a member or the enrollment was automatic.

  - `lastActivityAt: string`

    When `lastActivityKind` happened; null when there has been no activity.

  - `lastActivityKind: "SENT" or "OPENED" or "REPLIED" or 4 more`

    The latest activity on the enrollment. A reply or bounce that ended the enrollment is reported over a later open.

    - `"SENT"`

    - `"OPENED"`

    - `"REPLIED"`

    - `"BOUNCED"`

    - `"INVITED"`

    - `"CONNECTED"`

    - `"SEEN"`

  - `nextSendAt: string`

    Estimated time of the next send, from the cadence, send window, pacing and sender; queue order and random gaps can push it later. Null while a message awaits review or is sending, while paused, or when it cannot be estimated.

  - `remainingSends: number`

    Email and LinkedIn steps not yet sent, connection requests included.

  - `repliedAt: string`

    When the contact first replied, on email or LinkedIn; null if they have not.

  - `status: "ACTIVE" or "AWAITING_REVIEW" or "NEEDS_ATTENTION" or 5 more`

    `ACTIVE` is progressing; `AWAITING_REVIEW` has a message waiting for approval; `NEEDS_ATTENTION` is held by a failed step, a held draft or an unavailable sender; `PAUSED` is stopped because the sequence is deactivated or it was paused in Lightfield. `REPLIED`, `COMPLETED`, `CANCELLED` and `FAILED` are final.

    - `"ACTIVE"`

    - `"AWAITING_REVIEW"`

    - `"NEEDS_ATTENTION"`

    - `"REPLIED"`

    - `"COMPLETED"`

    - `"PAUSED"`

    - `"CANCELLED"`

    - `"FAILED"`

### Sequence Retrieve Message Response

- `SequenceRetrieveMessageResponse = object { id, acceptedAt, bouncedAt, 15 more }  or object { id, channel, contactId, 8 more }`

  - `OutboundMessage object { id, acceptedAt, bouncedAt, 15 more }`

    - `id: string`

      Unique identifier of the message.

    - `acceptedAt: string`

      When the connection request was accepted; null until then.

    - `bouncedAt: string`

      When the email bounced; null until then.

    - `channel: "EMAIL" or "LINKEDIN"`

      Channel the message went over.

      - `"EMAIL"`

      - `"LINKEDIN"`

    - `contactId: string`

      ID of the contact.

    - `content: object { body, subject }`

      Plain-text content of the message. Null when the underlying record is no longer available; not included in list responses.

      - `body: string`

        Plain-text body; null for a connection request sent without a note.

      - `subject: string`

        Email subject; null for LinkedIn.

    - `createdAt: string`

      When the message was created, or when a reply was received. Lists sort by this field, newest first.

    - `direction: "OUTBOUND"`

      Always `OUTBOUND`.

      - `"OUTBOUND"`

    - `enrollmentId: string`

      ID of the enrollment the message belongs to.

    - `openedAt: string`

      When the email was opened; null until then.

    - `readAt: string`

      When the LinkedIn message was read; null until then.

    - `reference: object { id, objectType }  or object { id, objectType }`

      The email or LinkedIn message record behind this sequence message, readable with <u>[Retrieve an email](/api/resources/email/methods/retrieve)</u> or <u>[Retrieve a message](/api/resources/message/methods/retrieve)</u> under their own scopes; null when there is none.

      - `Email object { id, objectType }`

        - `id: string`

          ID of the email.

        - `objectType: "email"`

          Always `email`.

          - `"email"`

      - `Message object { id, objectType }`

        - `id: string`

          ID of the message.

        - `objectType: "message"`

          Always `message`.

          - `"message"`

    - `repliedAt: string`

      When the contact replied to this message; null until then.

    - `sentAt: string`

      When the message was sent; null until then.

    - `sequenceStepId: string`

      ID of the step that sent the message or, for a reply, the step it replied to.

    - `sequenceStepType: "EMAIL" or "LINKEDIN_MESSAGE" or "LINKEDIN_INVITE"`

      Type of that step.

      - `"EMAIL"`

      - `"LINKEDIN_MESSAGE"`

      - `"LINKEDIN_INVITE"`

    - `status: "AWAITING_REVIEW" or "SCHEDULED" or "QUEUED" or 4 more`

      `AWAITING_REVIEW` is waiting for approval; `SCHEDULED` is composed and waiting for its send time; `QUEUED` is due and waiting on the sender. `SENT`, `SKIPPED`, `FAILED` and `CANCELLED` are final.

      - `"AWAITING_REVIEW"`

      - `"SCHEDULED"`

      - `"QUEUED"`

      - `"SENT"`

      - `"SKIPPED"`

      - `"FAILED"`

      - `"CANCELLED"`

    - `statusChangedAt: string`

      When `status` last changed.

  - `Reply object { id, channel, contactId, 8 more }`

    - `id: string`

      Unique identifier of the message.

    - `channel: "EMAIL" or "LINKEDIN"`

      Channel the message went over.

      - `"EMAIL"`

      - `"LINKEDIN"`

    - `contactId: string`

      ID of the contact.

    - `content: object { body, subject }`

      Plain-text content of the message. Null when the underlying record is no longer available; not included in list responses.

      - `body: string`

        Plain-text body; null for a connection request sent without a note.

      - `subject: string`

        Email subject; null for LinkedIn.

    - `createdAt: string`

      When the message was created, or when a reply was received. Lists sort by this field, newest first.

    - `direction: "INBOUND"`

      Always `INBOUND`.

      - `"INBOUND"`

    - `enrollmentId: string`

      ID of the enrollment the message belongs to.

    - `receivedAt: string`

      When the reply was received.

    - `reference: object { id, objectType }  or object { id, objectType }`

      The email or LinkedIn message record behind this sequence message, readable with <u>[Retrieve an email](/api/resources/email/methods/retrieve)</u> or <u>[Retrieve a message](/api/resources/message/methods/retrieve)</u> under their own scopes; null when there is none.

      - `Email object { id, objectType }`

        - `id: string`

          ID of the email.

        - `objectType: "email"`

          Always `email`.

          - `"email"`

      - `Message object { id, objectType }`

        - `id: string`

          ID of the message.

        - `objectType: "message"`

          Always `message`.

          - `"message"`

    - `sequenceStepId: string`

      ID of the step that sent the message or, for a reply, the step it replied to.

    - `sequenceStepType: "EMAIL" or "LINKEDIN_MESSAGE" or "LINKEDIN_INVITE"`

      Type of that step.

      - `"EMAIL"`

      - `"LINKEDIN_MESSAGE"`

      - `"LINKEDIN_INVITE"`

### Sequence Retrieve Performance Response

- `SequenceRetrievePerformanceResponse object { byStepType, perStep }`

  - `byStepType: object { EMAIL, LINKEDIN_INVITE, LINKEDIN_MESSAGE, 2 more }`

    Lifetime totals for each step type, across all of its steps.

    - `EMAIL: object { bounced, bounceRate, currentEnrollments, 6 more }`

      Email steps.

      - `bounced: number`

        Sent emails that bounced.

      - `bounceRate: number`

        Bounced divided by sent; null if none sent.

      - `currentEnrollments: number`

        Enrollments currently on steps of this type, paused ones included.

      - `delivered: number`

        Sent minus bounced, never below zero.

      - `opened: number`

        Sent emails that were opened.

      - `openRate: number`

        Opened divided by delivered; null if none delivered.

      - `replied: number`

        Sent messages that received a reply.

      - `replyRate: number`

        Replied divided by delivered; null if none delivered.

      - `sent: number`

        Messages sent.

    - `LINKEDIN_INVITE: object { acceptanceRate, accepted, currentEnrollments, 3 more }`

      LinkedIn connection request steps.

      - `acceptanceRate: number`

        Accepted divided by sent; null if none sent.

      - `accepted: number`

        Connection requests that were accepted.

      - `currentEnrollments: number`

        Enrollments currently on steps of this type, paused ones included.

      - `replied: number`

        Sent messages that received a reply.

      - `replyRate: number`

        Replied divided by sent; null if none sent.

      - `sent: number`

        Messages sent.

    - `LINKEDIN_MESSAGE: object { currentEnrollments, read, readRate, 3 more }`

      LinkedIn message steps.

      - `currentEnrollments: number`

        Enrollments currently on steps of this type, paused ones included.

      - `read: number`

        Sent messages that were read.

      - `readRate: number`

        Read divided by sent; null if none sent.

      - `replied: number`

        Sent messages that received a reply.

      - `replyRate: number`

        Replied divided by sent; null if none sent.

      - `sent: number`

        Messages sent.

    - `WAIT: object { currentEnrollments }`

      Wait steps.

      - `currentEnrollments: number`

        Enrollments currently on steps of this type, paused ones included.

    - `WAIT_FOR_CONNECTION: object { currentEnrollments }`

      Wait-for-connection steps.

      - `currentEnrollments: number`

        Enrollments currently on steps of this type, paused ones included.

  - `perStep: array of object { bounced, bounceRate, currentEnrollments, 8 more }  or object { currentEnrollments, read, readRate, 5 more }  or object { acceptanceRate, accepted, currentEnrollments, 5 more }  or 2 more`

    Per-step statistics in published sequence order, including steps with no activity. Steps no longer in the published definition are included if they have sent messages.

    - `EmailStep object { bounced, bounceRate, currentEnrollments, 8 more }`

      - `bounced: number`

        Sent emails that bounced.

      - `bounceRate: number`

        Bounced divided by sent; null if none sent.

      - `currentEnrollments: number`

        Enrollments currently on this step, paused ones included.

      - `delivered: number`

        Sent minus bounced, never below zero.

      - `opened: number`

        Sent emails that were opened.

      - `openRate: number`

        Opened divided by delivered; null if none delivered.

      - `replied: number`

        Sent messages that received a reply.

      - `replyRate: number`

        Replied divided by delivered; null if none delivered.

      - `sent: number`

        Messages sent.

      - `sequenceStepId: string`

        ID of the step. A step no longer in the published definition keeps its original ID.

      - `sequenceStepType: "EMAIL"`

        - `"EMAIL"`

    - `LinkedInMessageStep object { currentEnrollments, read, readRate, 5 more }`

      - `currentEnrollments: number`

        Enrollments currently on this step, paused ones included.

      - `read: number`

        Sent messages that were read.

      - `readRate: number`

        Read divided by sent; null if none sent.

      - `replied: number`

        Sent messages that received a reply.

      - `replyRate: number`

        Replied divided by sent; null if none sent.

      - `sent: number`

        Messages sent.

      - `sequenceStepId: string`

        ID of the step. A step no longer in the published definition keeps its original ID.

      - `sequenceStepType: "LINKEDIN_MESSAGE"`

        - `"LINKEDIN_MESSAGE"`

    - `LinkedInInviteStep object { acceptanceRate, accepted, currentEnrollments, 5 more }`

      - `acceptanceRate: number`

        Accepted divided by sent; null if none sent.

      - `accepted: number`

        Connection requests that were accepted.

      - `currentEnrollments: number`

        Enrollments currently on this step, paused ones included.

      - `replied: number`

        Sent messages that received a reply.

      - `replyRate: number`

        Replied divided by sent; null if none sent.

      - `sent: number`

        Messages sent.

      - `sequenceStepId: string`

        ID of the step. A step no longer in the published definition keeps its original ID.

      - `sequenceStepType: "LINKEDIN_INVITE"`

        - `"LINKEDIN_INVITE"`

    - `WaitStep object { currentEnrollments, sequenceStepId, sequenceStepType }`

      - `currentEnrollments: number`

        Enrollments currently on this step, paused ones included.

      - `sequenceStepId: string`

        ID of the step. A step no longer in the published definition keeps its original ID.

      - `sequenceStepType: "WAIT"`

        - `"WAIT"`

    - `WaitForConnectionStep object { currentEnrollments, sequenceStepId, sequenceStepType }`

      - `currentEnrollments: number`

        Enrollments currently on this step, paused ones included.

      - `sequenceStepId: string`

        ID of the step. A step no longer in the published definition keeps its original ID.

      - `sequenceStepType: "WAIT_FOR_CONNECTION"`

        - `"WAIT_FOR_CONNECTION"`

### Sequence Retrieve Response

- `SequenceRetrieveResponse object { id, channels, createdAt, 8 more }`

  - `id: string`

    Unique identifier of the sequence.

  - `channels: array of "EMAIL" or "LINKEDIN"`

    Channels the published steps send on; empty before the first publish.

    - `"EMAIL"`

    - `"LINKEDIN"`

  - `createdAt: string`

    ISO 8601 creation timestamp.

  - `definition: object { description, messaging, pacing, 3 more }`

    Published configuration, or null before the first publish.

    - `description: string`

      What this version of the sequence is for.

    - `messaging: object { callToAction, persona, trigger, valueProp }`

      Messaging inputs that frame every step.

      - `callToAction: string`

        What the recipient is asked to do.

      - `persona: string`

        Who the sequence targets.

      - `trigger: string`

        Why the outreach is timely.

      - `valueProp: string`

        The value proposition.

    - `pacing: object { EMAIL, LINKEDIN_INVITE, LINKEDIN_MESSAGE }`

      How the whole sequence paces each step type it sends, keyed by sequence step type.

      - `EMAIL: object { dailyLimit }`

        Email steps.

        - `dailyLimit: number`

          Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

      - `LINKEDIN_INVITE: object { dailyLimit }`

        LinkedIn connection requests.

        - `dailyLimit: number`

          Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

      - `LINKEDIN_MESSAGE: object { dailyLimit }`

        LinkedIn messages.

        - `dailyLimit: number`

          Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

    - `priority: "HIGH" or "NORMAL"`

      Send priority relative to other sequences.

      - `"HIGH"`

      - `"NORMAL"`

    - `sendWindow: object { daysOfWeek, endHour, startHour, timezone }`

      When the sequence may send.

      - `daysOfWeek: array of number`

        Days sends may go out, 0 = Sunday.

      - `endHour: number`

        Local hour sends stop, exclusive (1–24).

      - `startHour: number`

        First local hour sends may go out (0–23).

      - `timezone: string`

        IANA timezone of the window.

    - `steps: array of object { id, deliveryMode, mode, 3 more }  or object { id, deliveryMode, includeNote, 4 more }  or object { id, deliveryMode, mode, 3 more }  or 3 more`

      Email, LinkedIn and wait steps in execution order.

      - `object { id, deliveryMode, mode, 3 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `mode: "AGENT"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"AGENT"`

        - `name: string`

          Display name of the step.

        - `prompt: string`

          Instructions the agent follows when composing this message.

        - `type: "EMAIL" or "LINKEDIN_MESSAGE"`

          Step type.

          - `"EMAIL"`

          - `"LINKEDIN_MESSAGE"`

      - `object { id, deliveryMode, includeNote, 4 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `includeNote: boolean`

          Whether the connection request carries a note. A step authored before this setting existed reads as true.

        - `mode: "AGENT"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"AGENT"`

        - `name: string`

          Display name of the step.

        - `prompt: string`

          Instructions the agent follows when composing this message.

        - `type: "LINKEDIN_INVITE"`

          Step type.

          - `"LINKEDIN_INVITE"`

      - `object { id, deliveryMode, mode, 3 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `mode: "TEMPLATE"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"TEMPLATE"`

        - `name: string`

          Display name of the step.

        - `template: object { body, subject }`

          The email every contact receives.

          - `body: string`

            Email body as Markdown, without the sign-off or signature, which are added when the message is written. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

          - `subject: string`

            Plain-text subject line. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

        - `type: "EMAIL"`

          Step type.

          - `"EMAIL"`

      - `object { id, deliveryMode, mode, 3 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `mode: "TEMPLATE"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"TEMPLATE"`

        - `name: string`

          Display name of the step.

        - `template: object { body }`

          The message every contact receives; for an invite, its connection note, sent only with `includeNote`.

          - `body: string`

            Plain-text message. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

        - `type: "LINKEDIN_MESSAGE"`

          Step type.

          - `"LINKEDIN_MESSAGE"`

      - `object { id, deliveryMode, includeNote, 4 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `includeNote: boolean`

          Whether the connection request carries a note. A step authored before this setting existed reads as true.

        - `mode: "TEMPLATE"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"TEMPLATE"`

        - `name: string`

          Display name of the step.

        - `template: object { body }`

          The message every contact receives; for an invite, its connection note, sent only with `includeNote`.

          - `body: string`

            Plain-text message. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

        - `type: "LINKEDIN_INVITE"`

          Step type.

          - `"LINKEDIN_INVITE"`

      - `object { id, duration, type, unit }`

        - `id: string`

          Step identifier.

        - `duration: number`

          Length of the wait.

        - `type: "WAIT" or "WAIT_FOR_CONNECTION"`

          `WAIT` pauses for a fixed time; `WAIT_FOR_CONNECTION` waits up to that long for a LinkedIn invite to be accepted.

          - `"WAIT"`

          - `"WAIT_FOR_CONNECTION"`

        - `unit: "DAY" or "MINUTE"`

          Unit of `duration`.

          - `"DAY"`

          - `"MINUTE"`

  - `firstActivatedAt: string`

    When the sequence was first activated.

  - `lastActivatedAt: string`

    When the sequence was most recently activated.

  - `name: string`

    Name of the sequence.

  - `objectType: "sequence"`

    Always `sequence`.

    - `"sequence"`

  - `reviewers: array of object { id, objectType }`

    Extra members who may approve this sequence’s `FOR_REVIEW` messages before they send. The sending member and the sequence’s creator always review, whether or not they are listed.

    - `id: string`

      ID of the member.

    - `objectType: "member"`

      Always `member`.

      - `"member"`

  - `senders: array of object { id, objectType }`

    The senders this sequence sends from; new contacts rotate across them. An archived sender stays listed but never sends; any change to the list drops it.

    - `id: string`

      ID of the sender.

    - `objectType: "sender"`

      Always `sender`.

      - `"sender"`

  - `status: "DRAFT" or "ACTIVE" or "DEACTIVATED"`

    `DRAFT` has not been published; `ACTIVE` is enabled for sending; `DEACTIVATED` is published but paused.

    - `"DRAFT"`

    - `"ACTIVE"`

    - `"DEACTIVATED"`

### Sequence Retrieve Test Response

- `SequenceRetrieveTestResponse object { id, contactId, status, 2 more }`

  - `id: string`

    ID of the test, an enrollment ID.

  - `contactId: string`

    ID of the contact tested.

  - `status: "RUNNING" or "COMPLETED" or "FAILED"`

    `RUNNING` until every step has finished, then `COMPLETED`, or `FAILED` when the test ended on a failure.

    - `"RUNNING"`

    - `"COMPLETED"`

    - `"FAILED"`

  - `steps: array of object { error, message, mode, 4 more }`

    Every step of the tested version that the Sequences API lists, in run order. Call steps are not part of the API yet, so a test reports nothing for them.

    - `error: object { code, message }`

      Why the step failed; null unless `outcome` is `FAILED`.

      - `code: "CONFIGURATION_ERROR" or "SYSTEM_ERROR"`

        `CONFIGURATION_ERROR` when the sequence or the contact needs a change, `SYSTEM_ERROR` when Lightfield failed.

        - `"CONFIGURATION_ERROR"`

        - `"SYSTEM_ERROR"`

      - `message: string`

        What went wrong, in plain words.

    - `message: object { body, subject }  or object { body }`

      The composed message; null when the step has not composed one.

      - `EmailMessage object { body, subject }`

        - `body: string`

          Body as markdown, the same form a template step reads back in.

        - `subject: string`

          Subject line, as composed.

      - `LinkedInMessage object { body }`

        - `body: string`

          Message text, as composed.

    - `mode: "AGENT" or "TEMPLATE"`

      How a send step’s content is composed; null for a wait step.

      - `"AGENT"`

      - `"TEMPLATE"`

    - `name: string`

      Name of the step, as in `definition.steps`; null for a wait step.

    - `outcome: "PENDING" or "COMPOSED" or "SKIPPED" or "FAILED"`

      `PENDING` while the step has not run, including a step a finished test never reached, `COMPOSED` when it produced a message, `SKIPPED` when it produced nothing: a test never waits, so a wait is always `SKIPPED`, and a send step is `SKIPPED` when it has nothing to send, such as a LinkedIn invite another step already sent. `FAILED` when it failed: see `error`.

      - `"PENDING"`

      - `"COMPOSED"`

      - `"SKIPPED"`

      - `"FAILED"`

    - `stepId: string`

      ID of the step, as in the sequence’s `definition.steps`.

    - `type: "EMAIL" or "LINKEDIN_MESSAGE" or "LINKEDIN_INVITE" or 2 more`

      Step type.

      - `"EMAIL"`

      - `"LINKEDIN_MESSAGE"`

      - `"LINKEDIN_INVITE"`

      - `"WAIT"`

      - `"WAIT_FOR_CONNECTION"`

  - `target: "DRAFT" or "PUBLISHED"`

    Which version was tested.

    - `"DRAFT"`

    - `"PUBLISHED"`

### Sequence Start Test Response

- `SequenceStartTestResponse object { id, contactId, status, target }`

  - `id: string`

    ID of the test, an enrollment ID. Use it to read the result.

  - `contactId: string`

    ID of the contact being tested.

  - `status: "RUNNING"`

    Always `RUNNING`: the test continues after the response.

    - `"RUNNING"`

  - `target: "DRAFT" or "PUBLISHED"`

    Which version is being tested: the open `DRAFT` when there is one or the sequence was never published, otherwise the `PUBLISHED` version.

    - `"DRAFT"`

    - `"PUBLISHED"`

### Sequence Update Draft Response

- `SequenceUpdateDraftResponse object { channels, definition, name, 6 more }`

  - `channels: array of "EMAIL" or "LINKEDIN"`

    Channels the draft's steps send on.

    - `"EMAIL"`

    - `"LINKEDIN"`

  - `definition: object { description, messaging, pacing, 3 more }`

    The draft configuration, in the same shape as a published definition.

    - `description: string`

      What this version of the sequence is for.

    - `messaging: object { callToAction, persona, trigger, valueProp }`

      Messaging inputs that frame every step.

      - `callToAction: string`

        What the recipient is asked to do.

      - `persona: string`

        Who the sequence targets.

      - `trigger: string`

        Why the outreach is timely.

      - `valueProp: string`

        The value proposition.

    - `pacing: object { EMAIL, LINKEDIN_INVITE, LINKEDIN_MESSAGE }`

      How the whole sequence paces each step type it sends, keyed by sequence step type.

      - `EMAIL: object { dailyLimit }`

        Email steps.

        - `dailyLimit: number`

          Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

      - `LINKEDIN_INVITE: object { dailyLimit }`

        LinkedIn connection requests.

        - `dailyLimit: number`

          Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

      - `LINKEDIN_MESSAGE: object { dailyLimit }`

        LinkedIn messages.

        - `dailyLimit: number`

          Most sends of this step type across the whole sequence in any rolling 24 hours, or null when the sequence sets no daily cap. Workspace and sender limits still apply.

    - `priority: "HIGH" or "NORMAL"`

      Send priority relative to other sequences.

      - `"HIGH"`

      - `"NORMAL"`

    - `sendWindow: object { daysOfWeek, endHour, startHour, timezone }`

      When the sequence may send.

      - `daysOfWeek: array of number`

        Days sends may go out, 0 = Sunday.

      - `endHour: number`

        Local hour sends stop, exclusive (1–24).

      - `startHour: number`

        First local hour sends may go out (0–23).

      - `timezone: string`

        IANA timezone of the window.

    - `steps: array of object { id, deliveryMode, mode, 3 more }  or object { id, deliveryMode, includeNote, 4 more }  or object { id, deliveryMode, mode, 3 more }  or 3 more`

      Email, LinkedIn and wait steps in execution order.

      - `object { id, deliveryMode, mode, 3 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `mode: "AGENT"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"AGENT"`

        - `name: string`

          Display name of the step.

        - `prompt: string`

          Instructions the agent follows when composing this message.

        - `type: "EMAIL" or "LINKEDIN_MESSAGE"`

          Step type.

          - `"EMAIL"`

          - `"LINKEDIN_MESSAGE"`

      - `object { id, deliveryMode, includeNote, 4 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `includeNote: boolean`

          Whether the connection request carries a note. A step authored before this setting existed reads as true.

        - `mode: "AGENT"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"AGENT"`

        - `name: string`

          Display name of the step.

        - `prompt: string`

          Instructions the agent follows when composing this message.

        - `type: "LINKEDIN_INVITE"`

          Step type.

          - `"LINKEDIN_INVITE"`

      - `object { id, deliveryMode, mode, 3 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `mode: "TEMPLATE"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"TEMPLATE"`

        - `name: string`

          Display name of the step.

        - `template: object { body, subject }`

          The email every contact receives.

          - `body: string`

            Email body as Markdown, without the sign-off or signature, which are added when the message is written. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

          - `subject: string`

            Plain-text subject line. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

        - `type: "EMAIL"`

          Step type.

          - `"EMAIL"`

      - `object { id, deliveryMode, mode, 3 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `mode: "TEMPLATE"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"TEMPLATE"`

        - `name: string`

          Display name of the step.

        - `template: object { body }`

          The message every contact receives; for an invite, its connection note, sent only with `includeNote`.

          - `body: string`

            Plain-text message. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

        - `type: "LINKEDIN_MESSAGE"`

          Step type.

          - `"LINKEDIN_MESSAGE"`

      - `object { id, deliveryMode, includeNote, 4 more }`

        - `id: string`

          Step identifier, referenced by enrollment `currentStepId` and message `sequenceStepId`.

        - `deliveryMode: "AUTO" or "FOR_REVIEW"`

          `AUTO` sends without manual approval, subject to the send window and limits; `FOR_REVIEW` requires a person to approve the draft before sending.

          - `"AUTO"`

          - `"FOR_REVIEW"`

        - `includeNote: boolean`

          Whether the connection request carries a note. A step authored before this setting existed reads as true.

        - `mode: "TEMPLATE"`

          How each message is written: `AGENT` composes it from `prompt`; `TEMPLATE` sends `template` to every contact, with its variables filled in.

          - `"TEMPLATE"`

        - `name: string`

          Display name of the step.

        - `template: object { body }`

          The message every contact receives; for an invite, its connection note, sent only with `includeNote`.

          - `body: string`

            Plain-text message. Each `{{ }}` is a variable filled in per contact, with a fallback for a contact missing the value; a field variable names the field by the `ad_` ID the field-definitions endpoints list.

        - `type: "LINKEDIN_INVITE"`

          Step type.

          - `"LINKEDIN_INVITE"`

      - `object { id, duration, type, unit }`

        - `id: string`

          Step identifier.

        - `duration: number`

          Length of the wait.

        - `type: "WAIT" or "WAIT_FOR_CONNECTION"`

          `WAIT` pauses for a fixed time; `WAIT_FOR_CONNECTION` waits up to that long for a LinkedIn invite to be accepted.

          - `"WAIT"`

          - `"WAIT_FOR_CONNECTION"`

        - `unit: "DAY" or "MINUTE"`

          Unit of `duration`.

          - `"DAY"`

          - `"MINUTE"`

  - `name: string`

    Name the sequence takes when the draft is published.

  - `publishWarnings: array of object { code, message, severity, stepIds }`

    What publishing this draft would change for contacts already in the sequence; empty when nothing is affected. Before the first publish, the only possible warning is a proposed sender that was archived and would be left off.

    - `code: "delay_shortened" or "delay_lengthened" or "connection_wait_shortened" or 18 more`

      What publishing would change.

      - `"delay_shortened"`

      - `"delay_lengthened"`

      - `"connection_wait_shortened"`

      - `"connection_wait_lengthened"`

      - `"send_schedule_changed"`

      - `"send_configuration_changed"`

      - `"send_priority_changed"`

      - `"senders_changed"`

      - `"email_sender_pool_emptied"`

      - `"linkedin_account_pool_emptied"`

      - `"assigned_sender_removed"`

      - `"delivery_became_automatic"`

      - `"invite_note_enabled"`

      - `"invite_note_disabled"`

      - `"step_inserted"`

      - `"automatic_send_step_inserted"`

      - `"step_removed"`

      - `"step_type_changed"`

      - `"step_order_changed"`

      - `"full_identity_rewrite"`

      - `"low_identity_overlap"`

    - `message: string`

      What would change, in plain language.

    - `severity: "warning" or "destructive"`

      `destructive` when contacts already in the sequence may skip, repeat or receive a step they would not have; `warning` otherwise.

      - `"warning"`

      - `"destructive"`

    - `stepIds: array of string`

      The steps involved; empty for a sequence-wide change.

  - `reviewers: array of object { id, objectType }`

    Extra members who may approve this sequence’s `FOR_REVIEW` messages before they send. The sending member and the sequence’s creator always review, whether or not they are listed.

    - `id: string`

      ID of the member.

    - `objectType: "member"`

      Always `member`.

      - `"member"`

  - `senders: array of object { id, objectType }`

    The senders this draft will publish; new contacts rotate across them. Until a save changes it, this is the sequence’s live list. An archived sender stays listed but never sends; any change to the list drops it.

    - `id: string`

      ID of the sender.

    - `objectType: "sender"`

      Always `sender`.

      - `"sender"`

  - `sequenceId: string`

    The sequence this draft belongs to.

  - `updatedAt: string`

    When the draft last changed.

  - `version: string`

    Opaque token for the current state of the draft. Send it as `expectedVersion` on the next save, publish or discard; it changes whenever anyone edits the draft.

### Sequence Update Enrollments Response

- `SequenceUpdateEnrollmentsResponse object { results }`

  - `results: array of object { contactId, enrollmentId, outcome }  or object { contactId, enrollmentId, outcome }`

    One result per distinct contact, additions first, then removals.

    - `EnrollmentChanged object { contactId, enrollmentId, outcome }`

      - `contactId: string`

        ID of the contact.

      - `enrollmentId: string`

        ID of the enrollment the outcome applies to.

      - `outcome: "enrolled" or "already_enrolled" or "unenrolled"`

        `enrolled` created the enrollment, `already_enrolled` left an open one as is, `unenrolled` cancelled it.

        - `"enrolled"`

        - `"already_enrolled"`

        - `"unenrolled"`

    - `NothingToCancel object { contactId, enrollmentId, outcome }`

      - `contactId: string`

        ID of the contact.

      - `enrollmentId: unknown`

        Always null.

      - `outcome: "no_active_enrollment"`

        The contact had no open enrollment to cancel.

        - `"no_active_enrollment"`
