Campaigns
PATCH
/campaigns/{id}/sequence/{stepId}

Partially updates one existing sequence step's copy and/or media while preserving its id, wiring, delays and other A/B variants. Use the step and variant ids returned by GET /campaigns/{id}. When variantId is omitted, variant A is updated; pass another existing variantId to update that variant without changing variant A. This endpoint is preferred over replacing the full sequence for copy, attachment and recorded-voice edits, except for a recorded voice note that records per sender: those recordings are replaced through the campaign's sequence.

Authorization

bearerAuth
AuthorizationBearer <token>

An API key created under Settings → API & Webhooks.

In: header

Path Parameters

id*string
stepId*string

Stable sequence step id returned by the campaign detail.

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Content fields depend on the target step type: message uses text/fallbackText; invite uses note/fallbackNote; InMail also accepts subject/fallbackSubject; AI voice note uses script/fallbackScript; comment post uses prompt. Message accepts attachments and voice; InMail accepts attachments only (LinkedIn does not deliver voice notes on InMails); recorded voice note accepts voice. A recorded voice note that records per sender (its config carries voiceAssignments) is rejected here: its recordings live per sender, not per variant, so replace them through the campaign's sequence instead.

Content fields depend on the target step type: message uses text/fallbackText; invite uses note/fallbackNote; InMail also accepts subject/fallbackSubject; AI voice note uses script/fallbackScript; comment post uses prompt. Message accepts attachments and voice; InMail accepts attachments only (LinkedIn does not deliver voice notes on InMails); recorded voice note accepts voice. A recorded voice note that records per sender (its config carries voiceAssignments) is rejected here: its recordings live per sender, not per variant, so replace them through the campaign's sequence instead.

Response Body

application/json

application/json

application/json

application/json

curl -X PATCH "https://example.com/campaigns/string/sequence/string" \  -H "Content-Type: application/json" \  -d '{    "text": "{{firstName}}, is that the kind of gap you run into too?"  }'
{  "data": {    "id": "string",    "name": "string",    "status": "draft",    "stats": {      "total": 0,      "done": 0,      "failed": 0    },    "aiInterestEnabled": true,    "unsubscribe": {      "enabled": true,      "text": "string"    },    "tracking": {      "opens": "mailbox",      "clicks": "mailbox"    },    "linkedinAccountIds": [      "string"    ],    "emailAccountIds": [      "string"    ],    "excludeListIds": [      "string"    ],    "listId": "string",    "excludeOtherCampaigns": true,    "excludeOtherSenders": true,    "excludeSameSenderOtherCampaigns": true,    "schedule": {      "startDate": "2019-08-24T14:15:22Z",      "endDate": "2019-08-24T14:15:22Z",      "timezone": "string",      "activeHours": {        "from": "string",        "to": "string"      },      "activeDays": [        0      ]    },    "createdAt": "2019-08-24T14:15:22Z",    "updatedAt": "2019-08-24T14:15:22Z",    "sequence": {      "steps": [        {          "id": "string",          "type": "if_connected",          "parent": "string",          "branch": "yes",          "config": {},          "nextDelayHours": 0,          "branchDelays": {            "yes": 0,            "no": 0          }        }      ]    }  }}

Update a campaign PATCH

Updates any subset of a campaign's writable fields: `name`, `status` (set `active` to start sending, `paused` to stop), the sender pool (`linkedinAccountIds`), the outreach `sequence`, the send `schedule`, `aiInterestEnabled`, the email `unsubscribe` line and `tracking`, and the lead-exclusion rules (`excludeListIds` plus the `exclude*` flags). `sequence` and `schedule` are replaced wholesale — send the complete object you want, not a partial patch of it. A full `sequence` replacement can update the content of any step or A/B variant. For variant A, keep the step's legacy flat copy/media fields identical to the corresponding values in `config.variants[0]`; conflicting values are rejected with `400`. Updating a later variant only requires changing that variant object. For a single existing step or variant, prefer `PATCH /campaigns/{id}/sequence/{stepId}` so unrelated sequence structure cannot be overwritten. Once a campaign has leads in progress, the `sequence` may only be edited safely: you can change step messages and delays and append new steps, but removing, reordering or retyping existing steps is rejected with `400` (a lead's progress is pinned to a step id). Duplicate the campaign to rework its sequence from scratch. An `active` campaign must keep at least one sender: sending an empty `linkedinAccountIds` while the campaign is (or is being set) `active` is rejected with `400`.

List supported filters GET

The filters, company sorts and suggestion fields the database supports for this workspace. The set can be narrower than the full filter list documented on the search endpoints; a search using a filter that is not listed here is rejected with 400 and the filter named. Free, no credits. An entity is `null` when the database is unavailable for it.