Overview
UsePOST /v1/campaigns to create a draft campaign from the public steps format.
This endpoint is designed for external integrations. You send a single ordered steps array and Enginy compiles it into the internal campaign graph.
Quick Start
- Start
stepswith the first action that should happen. - Add each next action in the exact order it should run.
- Use
conditionto branch on lead data. - Use
linkedin_connectionto send a connection request and then branch on acceptance. - Put shared continuation steps after the branch instead of duplicating them inside both sides.
Rules
- Build the campaign as an ordered
stepsarray from first action to last action. - Use
conditionandlinkedin_connectionwhen you need branches. - Put shared follow-up work after the branching step instead of duplicating the same steps in both branches.
- Use
{ "type": "end" }only when that branch should stop completely. waitForAcceptance.unitmust always bedays.waitForAcceptance.valuemust be an integer greater than or equal to1.- Validation errors return full paths such as
steps[0].onTrue[1].subject.
Step Types
| Step type | Required fields | Optional fields |
|---|---|---|
email | subject, content | delay |
linkedin_message | content | delay |
linkedin_inmail | subject, content | delay |
linkedin_visit_profile | None | delay |
linkedin_like_last_post | None | delay, reactionType |
condition | condition | onTrue, onFalse |
linkedin_connection | waitForAcceptance | delay, content, onAccepted, onNotAccepted |
task | taskType, title | note, ownerId, delay |
end | None | None |
Branching Step Types
| Use this step | When you need it | Branch fields |
|---|---|---|
condition | Branch based on what Enginy already knows about the lead | onTrue, onFalse |
linkedin_connection | Send a connection request and branch based on acceptance | onAccepted, onNotAccepted |
Condition Types
condition.type supports exactly these values:
| Condition type | onTrue branch runs when | onFalse branch runs when |
|---|---|---|
has_linkedin_profile | The lead has a LinkedIn profile | The lead does not have a LinkedIn profile |
has_professional_email | The lead has a professional email | The lead does not have a professional email |
is_already_connected | The lead is already a LinkedIn connection | The lead is not already a LinkedIn connection |
has_been_contacted | The lead has already been contacted | The lead has not been contacted yet |
Validation Checklist
stepsmust contain at least one step.- Every branch array you provide must contain at least one step.
- Use
{ "type": "end" }if a branch should stop explicitly. waitForAcceptance.unitmust always bedays.waitForAcceptance.valuemust be a whole integer greater than or equal to1.- If
GET /v1/tasks/ownersreturns owners, everytaskstep must include a validownerId.
Task Owners
If your campaign containstask steps, call GET /v1/tasks/owners first.
- If that endpoint returns owners, every
taskstep must include a validownerId. - If no owners are returned,
ownerIdcan be omitted.
Related Endpoints
POST /v1/campaignscreates the draft campaign.GET /v1/campaignslists campaigns after creation.GET /v1/tasks/ownersreturns the valid task owners fortasksteps.POST /v1/add-contact-to-campaignadds one contact to an existing campaign.POST /v1/add-contact-group-to-campaignadds every contact in a contact group to an existing campaign.
Adding Contacts After Creation
Use the campaign creation endpoint to build the sequence first, then use one of the audience endpoints below to start adding contacts to it.POST /v1/add-contact-to-campaignis for one contact at a time.POST /v1/add-contact-group-to-campaignis for an entire contact group and returns counts for newly added, reactivated, already-present, and skipped contacts.