Skip to main content

Overview

Use POST /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

  1. Start steps with the first action that should happen.
  2. Add each next action in the exact order it should run.
  3. Use condition to branch on lead data.
  4. Use linkedin_connection to send a connection request and then branch on acceptance.
  5. Put shared continuation steps after the branch instead of duplicating them inside both sides.

Rules

  • Build the campaign as an ordered steps array from first action to last action.
  • Use condition and linkedin_connection when 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.unit must always be days.
  • waitForAcceptance.value must be an integer greater than or equal to 1.
  • Validation errors return full paths such as steps[0].onTrue[1].subject.

Step Types

Step typeRequired fieldsOptional fields
emailsubject, contentdelay
linkedin_messagecontentdelay
linkedin_inmailsubject, contentdelay
linkedin_visit_profileNonedelay
linkedin_like_last_postNonedelay, reactionType
conditionconditiononTrue, onFalse
linkedin_connectionwaitForAcceptancedelay, content, onAccepted, onNotAccepted
tasktaskType, titlenote, ownerId, delay
endNoneNone

Branching Step Types

Use this stepWhen you need itBranch fields
conditionBranch based on what Enginy already knows about the leadonTrue, onFalse
linkedin_connectionSend a connection request and branch based on acceptanceonAccepted, onNotAccepted

Condition Types

condition.type supports exactly these values:
Condition typeonTrue branch runs whenonFalse branch runs when
has_linkedin_profileThe lead has a LinkedIn profileThe lead does not have a LinkedIn profile
has_professional_emailThe lead has a professional emailThe lead does not have a professional email
is_already_connectedThe lead is already a LinkedIn connectionThe lead is not already a LinkedIn connection
has_been_contactedThe lead has already been contactedThe lead has not been contacted yet

Validation Checklist

  • steps must 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.unit must always be days.
  • waitForAcceptance.value must be a whole integer greater than or equal to 1.
  • If GET /v1/tasks/owners returns owners, every task step must include a valid ownerId.

Task Owners

If your campaign contains task steps, call GET /v1/tasks/owners first.
  • If that endpoint returns owners, every task step must include a valid ownerId.
  • If no owners are returned, ownerId can be omitted.
  • POST /v1/campaigns creates the draft campaign.
  • GET /v1/campaigns lists campaigns after creation.
  • GET /v1/tasks/owners returns the valid task owners for task steps.
  • POST /v1/add-contact-to-campaign adds one contact to an existing campaign.
  • POST /v1/add-contact-group-to-campaign adds 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-campaign is for one contact at a time.
  • POST /v1/add-contact-group-to-campaign is for an entire contact group and returns counts for newly added, reactivated, already-present, and skipped contacts.

Example: Add a Contact Group to a Campaign

{
  "campaignId": 456,
  "contactGroupId": 123
}

Example: Condition First

{
  "name": "Email or fallback task",
  "identityId": 323,
  "steps": [
    {
      "type": "condition",
      "condition": {
        "type": "has_professional_email"
      },
      "onTrue": [
        {
          "type": "email",
          "subject": "Great to connect",
          "content": "Sharing a quick overview."
        }
      ],
      "onFalse": [
        {
          "type": "task",
          "taskType": "TODO",
          "title": "Find email first",
          "ownerId": "owner-1"
        }
      ]
    }
  ]
}

Example: LinkedIn Acceptance Branch

{
  "name": "LinkedIn acceptance flow",
  "identityId": 323,
  "steps": [
    {
      "type": "linkedin_connection",
      "delay": {
        "value": 1,
        "unit": "days"
      },
      "waitForAcceptance": {
        "value": 5,
        "unit": "days"
      },
      "onAccepted": [
        {
          "type": "linkedin_message",
          "content": "Thanks for accepting.",
          "delay": {
            "value": 2,
            "unit": "hours"
          }
        }
      ],
      "onNotAccepted": [
        {
          "type": "task",
          "taskType": "TODO",
          "title": "Review no-response path",
          "ownerId": "owner-1"
        }
      ]
    },
    {
      "type": "email",
      "subject": "Following up",
      "content": "Continuing after the LinkedIn decision.",
      "delay": {
        "value": 1,
        "unit": "days"
      }
    }
  ]
}

Example: Explicitly Stop One Branch

{
  "name": "Accepted-or-stop flow",
  "identityId": 323,
  "steps": [
    {
      "type": "linkedin_connection",
      "content": "Would love to connect and share a few ideas.",
      "waitForAcceptance": {
        "value": 3,
        "unit": "days"
      },
      "onAccepted": [
        {
          "type": "linkedin_message",
          "content": "Thanks for accepting. Sharing a quick follow-up.",
          "delay": {
            "value": 4,
            "unit": "hours"
          }
        }
      ],
      "onNotAccepted": [
        {
          "type": "end"
        }
      ]
    },
    {
      "type": "email",
      "subject": "Resources after connecting",
      "content": "Continuing only for contacts who accepted the connection request.",
      "delay": {
        "value": 1,
        "unit": "days"
      }
    }
  ]
}