Skip to main content
POST
If you want to get the main sequence or a list of sequences for a campaign, you can call /api/campaigns/{campaignId}/sequences.

Adding Steps

To add a new step to a sequence, call the API with the sequence ID in the parameters and the step details in the request body. For example, adding a LinkedIn invite step:

Adding Conditions

To add a condition to a sequence, you must provide the conditionKey and type conditional along with the required fields. The API will return a condition with an array of condition sequences, where you can call the same API again to add steps to those sequences. For example, creating a LinkedIn invite condition:
This will return:
Then you can call /api/sequences/seq_jacL5GNH3YpNnuNQ2/steps to add a send step if the invite is accepted:

Branching on a lead variable

The customLeadInfo condition branches on a lead variable or a contact field instead of on a lead action. It takes three extra fields:
customField reads a bare name as a lead variable — jobTitle becomes variables.jobTitle. Prefix it with fields. to test a contact field instead. A company field is written company.<field> — company.name, or company.sector for a company custom field named Sector. companyName and variables.companyName are stored as company.name. customOperator is one of equal, contains, empty, notEmpty. The first two need a customValue; the last two refuse one.
A condition step created here has one branch plus the Else fallback. To give it more branches — “CEO or Founder here, CTO there, everyone else in Else” — use the condition branch endpoints.

Manual steps

A step that takes manual sends automatically by default. With manual: true it creates a task first, and the campaign sends the step on its schedule once that task is marked done, in lemlist or with Update Task. To close the task without sending, use Ignore Tasks: the lead moves on to the next step.
Marking the task done sends the step. Someone who sends the message by hand and then marks the task done sends it twice.
To adapt the message for one lead before marking the task done, use Personalize Step for Lead, which does not cover voice notes: the message of Update Task does not change what the campaign sends. A linkedinVoiceNote step needs its recording, unless its recordMode is ai. Attach it with Upload Audio or on the task in lemlist before marking the task done: without one, nothing is sent, the step fails for that lead, and its following LinkedIn steps are skipped. title names the task and priority ranks it: 0 low, 1 medium, 2 high. Omitted, the task has no priority.
A rejected field answers 400 Invalid request body. To switch an existing step, see Update Sequence Step.

Enrichment steps

An enrichment step enriches each lead that reaches it. workflowIds lists what it looks up, with at least one value:
Credits are charged per lookup that returns data: one that finds nothing costs 0. The price of the lookups that run is reserved when the step executes for a lead, and released for those that find nothing. What runs depends on the lead:
  • A lead with nothing left to look up skips the step at no cost: with find_phone_01 alone, a lead whose contact already has a phone number.
  • Otherwise the step’s workflows run together, so data the contact already holds can be charged again.
  • find_email_01 searches again on a lead that already has an email, so a step with it rarely skips a lead.
  • With both find_email_01 and verify_01, only one runs: verify_01 on a lead with a correctly formatted email, even one known as undeliverable, find_email_01 otherwise. In the example above, a lead with a correctly formatted email costs at most 1 credit, and any other lead at most 5.
  • When one workflow has work to do, a lead missing what another needs fails the step, and no credits are charged: with verify_01 and find_phone_01, a lead with neither an email nor a phone number.
A lead that fails the step still moves on in the sequence, without the data. When the team’s credits do not cover the price of the lookups that run, the lead waits on the step and the team gets a notification. Adding credits resumes the step. The wait is limited: after repeated attempts, the step fails for that lead, who moves on in the sequence. A missing workflowIds answers 400 workflowIds is required, an empty array or an unknown value answers 400 Invalid request body. workflowIds is set when the step is created: Update Sequence Step does not change it.
enrichment steps need the Multichannel Expert plan or above. Below it, the call answers 402 upper-plan-required.

Step Types and Required Fields

The table below summarizes the required and optional fields for each step type. Note that all step requests must include a common type field.
In conditional steps, if the delayType is not "within", the delay field is not required.
A linkedinInMail step sends a LinkedIn InMail, so it reaches leads who are not connected to the sender — the step to use in the “invite not accepted” branch of a linkedinInviteAccepted condition. It needs a LinkedIn Premium or Sales Navigator sender: a sender without one is skipped. Each send spends one of the sender’s InMail credits. A blank subject or message is saved but blocks the campaign launch, as for the other message steps. Both are sent as plain text: LinkedIn does not render HTML. The step takes no altMessage, images or videos.
linkedinVoiceNote steps are created as skeletons via the API: the audio payload itself is not accepted here and must be added afterwards, from the lemlist UI or for one lead with Upload Audio. The recordMode field controls how the audio is sourced — with manual (default), a user records the note themselves; with ai, a user provides a text template that lemlist converts to audio at send time.

All Request Body Fields

What happens to the transferred lead

A sendToAnotherCampaign step adds the lead to the target campaign. leadAction decides what the source campaign then does with it.
A transfer that fails always pauses the lead, whatever leadAction says, so a lead that never moved does not walk on as if it had. A transfer fails when the target campaign is missing or archived, when it has reached its 40,000-lead limit, when the lead’s email address is unsubscribed, and when the lead is already in the target campaign — a re-run of the same step, or two campaigns feeding one target, both land there.
Omitting leadAction leaves the step without a value, which the runtime reads as continue. A step added from the lemlist UI defaults to stop instead; that default belongs to the editor, not to the API.
leadAction is read when the step runs, not when the lead reaches it. Updating it applies to every lead still waiting at that step, including leads whose transfer is already queued.

LinkedIn invitation notes

Three LinkedIn step types carry a second note besides message, and altMessage does not mean the same thing on each of them.
LinkedIn caps a connection-request note at 200 characters on a free account and 300 on Premium or Sales Navigator. These endpoints do not enforce those caps, but an over-long note is a blocking step error: the campaign refuses to launch until you shorten it. Sending either field here on a step type that does not take it is rejected with 400 Invalid request body.

Running campaigns

A campaign that leads have entered still accepts new steps. Where the step lands decides who receives it:
  • Appended after the last step of a sequence leads finish on: the leads parked on that last step move on to the new one.
  • Inserted before an existing step (with index): the leads waiting on that step are moved onto the new one and run it first. Leads already past that position never receive it.
The move is applied to the campaign’s leads right after the response. While it runs, another structural change on the same campaign answers 409 campaign-reroute-in-progress; nothing is written and the same call succeeds a minute later.

LinkedIn media constraints

When you pass images or videos to a linkedinInvite or linkedinSend step, each URL must be a publicly reachable HTTPS URL. lemlist fetches the file, validates it, and re-hosts it before attaching it to the LinkedIn message. If ingestion fails, the API returns a 4xx/5xx status with one of the following error codes:

Authorizations

Authorization
string
header
required

Basic authentication header of the form Basic <encoded-value>, where <encoded-value> is the base64-encoded string username:password.

Path Parameters

sequenceId
string
required

The unique identifier of the sequence

Body

application/json
type
enum<string>

The type of step to create

Available options:
email,
manual,
phone,
api,
linkedinVisit,
linkedinInvite,
linkedinSend,
linkedinInMail,
linkedinVoiceNote,
linkedinFollow,
linkedinLikeLastPost,
linkedinCommentLastPost,
linkedinEndorse,
linkedinWithdrawInvitation,
sendToAnotherCampaign,
conditional,
whatsappMessage,
sms,
enrichment
index
integer

The position within the sequence to insert the new step (≥ -1). If omitted or greater than the number of steps, the new step is added to the end. On a campaign leads have entered, a step inserted before an existing one moves the leads waiting on that step onto the new one; leads already past that position never receive it.

delay
integer

Delay in days before executing this step. Defaults to 0 for the first step and 1 for subsequent steps

subject
string

Email subject line (for email steps). Optional: omit it or send an empty string on a follow-up so the email replies in the thread of the previous one. If no email has been sent to the lead in this campaign yet, it goes out with an empty subject. Required on linkedinInMail steps, where it is the InMail subject: a blank one is saved but blocks the campaign launch

message
string

Content of the email or message (used for email, linkedinInvite, linkedinSend, linkedinInMail, manual, phone, whatsappMessage, sms steps, and as the AI script of a linkedinVoiceNote step in ai record mode). Required for linkedinSend, linkedinInMail, whatsappMessage, and sms. On a linkedinInMail step it is sent as plain text (LinkedIn does not render HTML), and a blank one is saved but blocks the campaign launch

altMessage
string

The LinkedIn note sent instead of message in specific cases, with a meaning that depends on the step type. On linkedinInvite: the premium invitation note attached to the connection request, used when the sending account has LinkedIn Premium. On linkedinSend and linkedinVoiceNote: the out-of-network note, sent as a connection request when the lead is not a 1st-degree connection. Rejected with 400 on any other step type. LinkedIn caps a connection-request note at 200 characters on a free account and 300 on Premium or Sales Navigator. This endpoint does not enforce those caps, but an over-long note is a blocking step error: the campaign refuses to launch until it is shortened

altMessagePremium
string

For linkedinSend steps only. The premium variant of the out-of-network note, sent instead of altMessage when the sending LinkedIn account is Premium or Sales Navigator (300-character LinkedIn cap). Rejected with 400 on any other step type

customName
string

The step's own name, shown instead of its type label ("Email", "Call") wherever the app names the step. Plain text, up to 70 characters once trimmed and once runs of spaces collapse to one; HTML tags count toward the 70, then are dropped. A longer name is rejected with 400. Accepted on every step type, ignored on conditional steps, which keep their type label

Maximum string length: 70
title
string

Title of the task the step creates. Required on manual steps, optional on phone steps and on a channel step with manual: true. Maximum 100 characters

manual
boolean

Holds a channel step behind a task: true creates a task, named by title and ranked by priority, and the campaign sends the step once the task is marked done. A linkedinVoiceNote step also needs its recording, see Manual steps. Accepted on email, linkedinInvite, linkedinSend, linkedinInMail, linkedinVoiceNote, whatsappMessage and sms steps. Rejected with 400 on every other type, manual and phone steps included: they are always tasks

priority
enum<integer>

Priority of the task the step creates: 0 low, 1 medium, 2 high. Omitted, the task has no priority. Accepted on manual and phone steps and on the channel steps that take manual, where it applies once the step is manual

Available options:
0,
1,
2
method
enum<string>

HTTP method for API steps

Available options:
GET,
POST,
PUT,
DELETE,
PATCH
url
string

URL of the API endpoint to call (required for api steps). Must start with http:// or https://

conditionKey
enum<string>

Condition key for conditional steps

Available options:
hasEmailAddress,
hasLinkedinUrl,
hasPhoneNumber,
customLeadInfo,
hasScore,
emailsOpened,
emailsClicked,
emailsUnsubscribed,
meetingBooked,
linkedinInviteAccepted,
linkedinOpened,
aircallDone,
linkedinNetworkCheck,
hasWhatsappAccount
delayType
enum<string>

Delay type for conditional steps

Available options:
within,
waitUntil
customField
string

For conditional steps keyed customLeadInfo only. The field to test. A bare name reads as a lead variable (jobTitle becomes variables.jobTitle); prefix with fields. to test a contact field. A company field is written company.<field> - company.name, or company.sector for a company custom field named Sector - and companyName or variables.companyName is stored as company.name. $ and the reserved keys _id, teamId, campaignId, leadId, __proto__, constructor and prototype are refused.

customOperator
enum<string>

For conditional steps keyed customLeadInfo only. How the field is compared.

Available options:
equal,
contains,
empty,
notEmpty
customValue
string

For conditional steps keyed customLeadInfo only. The value the field is compared to. Required for equal and contains, and refused for empty and notEmpty.

campaignId
string

Target campaign ID for sendToAnotherCampaign steps. The campaign must exist and not be archived

leadAction
enum<string>

Applies to sendToAnotherCampaign steps only. What happens to the lead in the SOURCE campaign once it has been moved to the target one. continue keeps it running the remaining steps, pause pauses it, stop ends the source campaign for it. Omitted leaves the step without a value, which behaves as continue; a step added from the lemlist UI defaults to stop. A transfer that fails always pauses the lead, whatever this says.

Available options:
continue,
pause,
stop
images
string<uri>[]

Public HTTPS URLs of images to attach to a linkedinInvite or linkedinSend step. lemlist downloads each file and re-hosts it. Allowed MIME types: image/png, image/jpeg, image/gif. Up to 20 MB per file, and up to 6 items total combined with videos.

videos
string<uri>[]

Public HTTPS URLs of videos to attach to a linkedinInvite or linkedinSend step. lemlist downloads each file and re-hosts it. Allowed MIME types: video/mp4, video/quicktime. Up to 20 MB per file, and up to 6 items total combined with images.

skillName
string

Name of the LinkedIn skill to endorse on the lead's profile. Applies to linkedinEndorse steps only.

endorseAnyFallback
boolean

Applies to linkedinEndorse steps only. When true and the named skill is not on the lead's profile, lemlist falls back to endorsing any available skill.

recordMode
enum<string>

Applies to linkedinVoiceNote steps only. Determines how the audio is sourced. manual (default) means the user records the audio themselves from the lemlist UI after step creation; ai means lemlist generates the audio from a text template provided in the lemlist UI.

Available options:
manual,
ai
workflowIds
enum<string>[]

Required on enrichment steps, with at least one value. What the step looks up for each lead that reaches it: find_email_01 (the email address, 5 credits per email found), find_phone_01 (the phone number, 20 credits per phone number found), verify_01 (the deliverability of the email, 1 credit per email verified), linkedin_01 (the LinkedIn profile, 1 credit per profile enriched). A lookup is charged only when it returns data. With both find_email_01 and verify_01, only one runs for a lead: verify_01 if it has a correctly formatted email, find_email_01 otherwise. An unknown value or an empty array is rejected with 400. enrichment steps need the Multichannel Expert plan or above

Minimum array length: 1
Available options:
find_email_01,
find_phone_01,
verify_01,
linkedin_01

Response

Success

_id
string
type
string
customName
string

The step's own name, shown instead of its type label ("Email", "Call") wherever the app names the step. Absent when the step has none

delay
integer
emailTemplateId
string
message
string
title
string

Title of the task the step creates. On manual and phone steps, and on a channel step when one was set

manual
boolean

true on a channel step held behind a task: the campaign sends the step once the task is marked done. manual and phone steps are always tasks, whatever this field says

priority
enum<integer>

Priority of the task the step creates: 0 low, 1 medium, 2 high. Absent when none was set

Available options:
0,
1,
2
workflowIds
enum<string>[]

On enrichment steps only. What the step looks up for each lead that reaches it

Available options:
find_email_01,
find_phone_01,
verify_01,
linkedin_01