---
title: "Set the contact lists of a campaign"
method: PATCH
path: "/advanced/campaigns/{campaignId}/recipients"
tags: ["Campaigns"]
---

# Set the contact lists of a campaign

`PATCH /advanced/campaigns/{campaignId}/recipients`

## Request

- Base URL: `https://api.emelia.io`
- URL: `https://api.emelia.io/advanced/campaigns/{campaignId}/recipients`
- Auth: API key in header `Authorization`

Sets the FULL selection of lists (replace semantics): the campaign contacts become the contacts of `lists`, minus any contact whose email or LinkedIn URL appears in one of `excludedLists`. When `excludedLists` is omitted the current exclusion lists are kept. Allowed on a running campaign. A campaign cannot be started with more than 30,000 recipients. Create and fill lists with the Lists endpoints (`/lists/...`).

## Path parameters

- `campaignId` string, required: MongoDB ObjectId: 24 hexadecimal characters.

## Request body

- object
  - `lists` ObjectId[], required: Ids of the lists to use.
  - `excludedLists` ObjectId[]: Ids of exclusion lists.

## Response `200`

Success.

- object
  - `success` unknown
  - `campaign` Campaign: Full multichannel campaign as stored (internal fields such as `__v`, `hubspotIntegration`, `pipedriveIntegration` and `zapierData` are returned too).
    - `_id` string: MongoDB ObjectId: 24 hexadecimal characters.
    - `name` string
    - `status` 'DRAFT' | 'RUNNING' | 'PAUSED' | 'FINISHED' | 'ARCHIVED'
    - `tagIds` ObjectId[]
    - `identities` Identity[]
      - `_id` string: MongoDB ObjectId: 24 hexadecimal characters.
      - `userId` string: MongoDB ObjectId: 24 hexadecimal characters.
      - `name` string
      - `email` string: MongoDB ObjectId: 24 hexadecimal characters.
      - `linkedin` string: MongoDB ObjectId: 24 hexadecimal characters.
      - `whatsapp` string: MongoDB ObjectId: 24 hexadecimal characters.
      - `__v` integer
    - `schedule` CampaignSchedule: Sending settings of a multichannel campaign. Defaults of a new campaign are shown.
      - `dailyEmailAdded` integer: New contacts entering the email part of the sequence per day.
      - `dailyEmailLimit` integer: Maximum emails sent per day. Must be greater than or equal to `dailyEmailAdded`.
      - `dailyLinkedinAdded` integer: New contacts per day on LinkedIn. Real ceiling: 40 when the sequence contains a CONNECTION step, 80 otherwise.
      - `dailyWhatsappAdded` integer
      - `bcc` string: Blind carbon copy address added to every email (empty string to disable).
      - `trackLinks` boolean: Required for `CLICKED` conditions and click statistics.
      - `trackOpens` boolean: Required for `OPENED` conditions and open statistics.
      - `timeZone` string: IANA time zone, for example `Europe/Paris`.
      - `days` integer[]: Sending days, 0 = Monday ... 6 = Sunday.
      - `start` string
      - `end` string
      - `blacklistUnsub` boolean: Adds contacts who unsubscribe to your blacklist.
      - `excludeAlreadyMessaged` boolean
      - `eventToStop` ActivityEvent[]: A contact leaves the sequence as soon as one of these events happens. New campaigns start with `["MAIL_REPLIED", "LINKEDIN_REPLIED", "WHATSAPP_REPLIED"]`. Bounced and unsubscribed contacts always stop.
      - `alwaysOn` boolean: Keeps the campaign running when all contacts are done, so that contacts added later are processed.
      - `ignoreAutoReplies` boolean
    - `steps` CampaignStep: One node of the sequence tree. The root is always a `START` step. Each node points to the next one with `next`; a `CONDITION` node branches with `yes` and `no` (a missing branch ends the sequence for the contacts that fall into it). `END_OF_CAMPAIGN` stops the sequence. EMAIL versions are A/B variants (one version per contact); MESSAGE and WHATSAPP versions are successive messages sent in order. A MESSAGE step placed after a CONNECTION step waits for the invitation to be accepted.
      - `_id` string: Step identifier, generated by the server (ObjectId string) when missing; the root is `"START"`. Any unique string is accepted. Never regenerate the ids of a campaign that already ran.
      - `stepType` 'START' | 'EMAIL' | 'CONNECTION' | 'MESSAGE' | 'INMAIL' | 'VISIT' | 'LIKE' | 'FOLLOW' | 'AUDIO' | 'WHATSAPP' | 'TASK' | 'CONDITION' | 'API_CALL' | 'END_OF_CAMPAIGN', required: `FOLLOW`, `AUDIO` and `API_CALL` are accepted when saved, but nothing runs them: no action happens and the step is never marked as done. Do not use them. A LinkedIn voice note is a `MESSAGE` step whose first version carries an attachment with `mediaType: "AUDIO"`, uploaded with `POST /advanced/linkedin/audio`.
      - `delay` StepDelay, required: Wait time after the previous action before this step runs. The delay of the first action of the sequence is ignored (new contacts enter according to the daily quotas). With `DAYS`, days that are not in `schedule.days` are skipped. On a `CONDITION` step the delay is the observation window.
        - `amount` number, required
        - `unit` 'MINUTES' | 'HOURS' | 'DAYS', required
      - `identities` string[]: Legacy field, not read when sending. Send `[]`. Sending accounts are chosen automatically among the campaign identities.
      - `versions` StepVersion[]: Content of EMAIL, CONNECTION, MESSAGE, INMAIL, WHATSAPP and TASK steps.
        - `_id` string: Version identifier. Generated by the server (ObjectId string) when missing. Keep existing ids when you update a campaign that already ran: statistics and history are attached to them.
        - `subject` string: EMAIL: subject. Leave it empty on a follow up email to reply in the same thread ("Re: previous subject"). INMAIL: subject. TASK: the task label shown in manual tasks.
        - `message` string: EMAIL: HTML body. MESSAGE, INMAIL, CONNECTION (invitation note) and WHATSAPP: plain text. Supports `{{variable}}` placeholders and `{a|b|c}` spintax.
        - `disabled` boolean: Excludes the version from A/B rotation (EMAIL).
        - `rawHtml` boolean: Stored but not read by the multichannel sending path.
        - `attachments` StepAttachment[]
          - `name` string, required
          - `url` string, uri, required: Public http(s) URL, for example the `url` returned by `POST /advanced/attachments`. Non http(s) URLs make test emails fail.
          - `mediaType` 'MEDIA' | 'ATTACHMENT' | 'AUDIO': LinkedIn only.
          - `duration` number: Audio notes only. `POST /advanced/linkedin/audio` returns it in milliseconds.
      - `cc` string: EMAIL only: carbon copy address, may be a variable such as `{{assistantEmail}}`; ignored when the resolved value is not a valid email.
      - `conditions` StepCondition
        - `field` string, required: Either an activity condition in UPPER CASE (`ACCEPTED`, `LINKEDIN_REPLIED`, `MAIL_REPLIED`, `OPENED`, `CLICKED`, `UNSUBSCRIBED`, `BOUNCED`, `TASK_COMPLETED`), evaluated within the step delay window, or a contact field prefixed with `$` (`$firstName`, `$jobTitle`, `$myCustomVariable`), evaluated immediately.
        - `operator` 'EQUAL' | 'DOES_NOT_EQUAL' | 'GREATER' | 'LOWER' | 'CONTAINS' | 'DOES_NOT_CONTAIN' | 'IS_EMPTY' | 'IS_NOT_EMPTY', required: Only these values are evaluated by the scheduler; any other value (for example `NOT_EQUAL` or `GREATER_THAN`) always evaluates to false. For activity conditions use `EQUAL` with value `"true"`.
        - `value` string, required
      - `next` CampaignStep (recursive)
      - `yes` CampaignStep (recursive)
      - `no` CampaignStep (recursive)
    - `recipients` object
      - `lists` ListRef[]
        - `_id` string: MongoDB ObjectId: 24 hexadecimal characters.
        - `name` string
        - `contactCount` integer
      - `excludedLists` ListRef[]
        - `_id` string: MongoDB ObjectId: 24 hexadecimal characters.
        - `name` string
        - `contactCount` integer
      - `processing` boolean
    - `zapierData` object[]: Webhooks registered on this campaign.
      - `_id` string: MongoDB ObjectId: 24 hexadecimal characters.
      - `webhookUrl` string
      - `events` string[]
    - `hubspotIntegration` object
    - `pipedriveIntegration` object
    - `createdAt` string, date-time
    - `startAt` string, date-time
    - `estimatedEnd` string, date-time
    - `plannedStart` string, date-time
    - `__v` integer

## Other responses

- `400`: Invalid request.
- `401`: Missing, malformed, unknown or disabled API key. The key must be exactly 48 characters, otherwise it is treated as a session token and rejected the same way.
- `500`: Unexpected error. IMPORTANT: this is also what you receive today when the per minute quota of your account is exceeded (the quota error is not mapped to 429 for API keys). No `Retry-After` header is sent. Wait until the next minute window before retrying.

---

[API](https://skmtc.dev/emelia/apis/emelia-api.md) · [All operations](https://skmtc.dev/emelia/apis/emelia-api/llms.txt) · [OpenAPI document](https://skmtc.dev/emelia/apis/emelia-api/revisions/8c0cb435f2c4?raw)
