---
title: "Bulk mutate leads"
method: POST
path: "/v1/campaigns/{cid}/leads/mutate"
tags: ["Leads"]
---

# Bulk mutate leads

`POST /v1/campaigns/{cid}/leads/mutate`

## Request

- Base URL: `https://api.mailbeast.ai`
- URL: `https://api.mailbeast.ai/v1/campaigns/{cid}/leads/mutate`
- Auth: HTTP bearer

Apply one operation (`set_status`, `add_tags`, `remove_tags`, or `delete`) across many leads. Target them by `ids`; `delete` also accepts a `filter`, or `all: true` to remove every lead. Reply-based statuses can only be set on leads that have already replied.

Requires one of the following scopes: `leads:write`, `leads:all`, `all:all`.

## Path parameters

- `cid` string, uuid, required

## Headers

- `Idempotency-Key` string

## Request body

- MutateLeadsApiDto
  - `operation` 'set_status' | 'add_tags' | 'remove_tags' | 'delete', required
  - `ids` string[]: Target lead ids. Required for every operation except a filter-based `delete`.
  - `filter` MutateLeadsFilterApiDto
    - `search` string: Match on email / first name / last name / company.
    - `status` 'not_contacted' | 'scheduled' | 'email_sent' | 'failed' | 'skipped' | 'lead_replied_interested' | 'lead_replied_meeting_request' | 'lead_replied_out_of_office' | 'lead_replied_bounce' | 'lead_replied_wrong_person' | 'lead_replied_not_interested' | 'lead_replied_unsubscribed' | 'lead_replied_uncategorized' | 'lead_converted' | 'lead_lost' | 'blacklisted'
    - `tags` string[]
  - `all` boolean: Delete EVERY lead in the campaign. Only valid for `delete`, and mutually exclusive with `ids` / `filter`. Required as an explicit opt-in for mass deletion - an empty `filter` will NOT delete all.
  - `status` 'lead_replied_interested' | 'lead_replied_meeting_request' | 'lead_replied_out_of_office' | 'lead_replied_wrong_person' | 'lead_replied_not_interested' | 'lead_replied_unsubscribed' | 'lead_replied_uncategorized' | 'lead_converted' | 'lead_lost' | 'blacklisted': Required for `set_status`. Only user-settable statuses are allowed; platform-managed ones such as `email_sent` or `scheduled` are rejected. Reply-based statuses (`lead_replied_*`, `lead_converted`) require the lead to have already replied. `lead_lost` and `blacklisted` can be set at any time.
  - `tags` string[]: Required for `add_tags` / `remove_tags`.

## Response `200`

- MutateLeadsApiResponseDto
  - `operation` 'set_status' | 'add_tags' | 'remove_tags' | 'delete', required
  - `affected` number, required: Number of leads successfully affected.
  - `failed` number, required: Number of leads that could not be processed.
  - `errors` string[]: Per-lead error messages, if any.

## Other responses

- `400`: The request body or parameters failed validation.
- `401`: Missing or invalid API key.
- `403`: The key lacks a required scope, or the plan does not include API access.
- `404`: The resource does not exist in your workspace.
- `409`: The request conflicts with current state - e.g. a request with the same Idempotency-Key is still being processed, or the operation partially applied.
- `422`: The Idempotency-Key was already used with a different request body. Use a new key for a new operation.
- `429`: Rate limit exceeded - retry after the interval in the Retry-After header.

---

[API](https://skmtc.dev/mailbeast/apis/mailbeast-public-api.md) · [All operations](https://skmtc.dev/mailbeast/apis/mailbeast-public-api/llms.txt) · [OpenAPI document](https://skmtc.dev/mailbeast/apis/mailbeast-public-api/revisions/6440ce0738a4?raw)
