curl --request POST \
--url https://api.mailbeast.ai/v1/campaigns/{cid}/leads/mutate \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"ids": [
"c9e5b1a3-7f24-4d80-a6b9-2e4f8c0d1a37",
"d1a8f4c6-2b93-4e70-8c15-9f0e3a7d6b52"
],
"filter": {
"search": "acme",
"tags": [
"vip",
"q4"
]
},
"all": false,
"tags": [
"vip",
"q4"
]
}
'import requests
url = "https://api.mailbeast.ai/v1/campaigns/{cid}/leads/mutate"
payload = {
"ids": ["c9e5b1a3-7f24-4d80-a6b9-2e4f8c0d1a37", "d1a8f4c6-2b93-4e70-8c15-9f0e3a7d6b52"],
"filter": {
"search": "acme",
"tags": ["vip", "q4"]
},
"all": False,
"tags": ["vip", "q4"]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
ids: ['c9e5b1a3-7f24-4d80-a6b9-2e4f8c0d1a37', 'd1a8f4c6-2b93-4e70-8c15-9f0e3a7d6b52'],
filter: {search: 'acme', tags: ['vip', 'q4']},
all: false,
tags: ['vip', 'q4']
})
};
fetch('https://api.mailbeast.ai/v1/campaigns/{cid}/leads/mutate', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.mailbeast.ai/v1/campaigns/{cid}/leads/mutate",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'ids' => [
'c9e5b1a3-7f24-4d80-a6b9-2e4f8c0d1a37',
'd1a8f4c6-2b93-4e70-8c15-9f0e3a7d6b52'
],
'filter' => [
'search' => 'acme',
'tags' => [
'vip',
'q4'
]
],
'all' => false,
'tags' => [
'vip',
'q4'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.mailbeast.ai/v1/campaigns/{cid}/leads/mutate"
payload := strings.NewReader("{\n \"ids\": [\n \"c9e5b1a3-7f24-4d80-a6b9-2e4f8c0d1a37\",\n \"d1a8f4c6-2b93-4e70-8c15-9f0e3a7d6b52\"\n ],\n \"filter\": {\n \"search\": \"acme\",\n \"tags\": [\n \"vip\",\n \"q4\"\n ]\n },\n \"all\": false,\n \"tags\": [\n \"vip\",\n \"q4\"\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.mailbeast.ai/v1/campaigns/{cid}/leads/mutate")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"ids\": [\n \"c9e5b1a3-7f24-4d80-a6b9-2e4f8c0d1a37\",\n \"d1a8f4c6-2b93-4e70-8c15-9f0e3a7d6b52\"\n ],\n \"filter\": {\n \"search\": \"acme\",\n \"tags\": [\n \"vip\",\n \"q4\"\n ]\n },\n \"all\": false,\n \"tags\": [\n \"vip\",\n \"q4\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.mailbeast.ai/v1/campaigns/{cid}/leads/mutate")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"ids\": [\n \"c9e5b1a3-7f24-4d80-a6b9-2e4f8c0d1a37\",\n \"d1a8f4c6-2b93-4e70-8c15-9f0e3a7d6b52\"\n ],\n \"filter\": {\n \"search\": \"acme\",\n \"tags\": [\n \"vip\",\n \"q4\"\n ]\n },\n \"all\": false,\n \"tags\": [\n \"vip\",\n \"q4\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"operation": "set_status",
"affected": 42,
"failed": 0,
"errors": [
"2 lead(s) not found in this campaign"
]
}{
"error": {
"type": "invalid_request_error",
"code": "validation_failed",
"message": "One or more fields are invalid.",
"status": 400,
"requestId": "e4f1c0b2-6a3d-4b8e-9f21-0a1b2c3d4e5f",
"details": [
"name should not be empty"
]
}
}{
"error": {
"type": "authentication_error",
"code": "unauthenticated",
"message": "Missing or invalid API key.",
"status": 401,
"requestId": "e4f1c0b2-6a3d-4b8e-9f21-0a1b2c3d4e5f"
}
}{
"error": {
"type": "authorization_error",
"code": "permission_denied",
"message": "This API key is missing the required scope.",
"status": 403,
"requestId": "e4f1c0b2-6a3d-4b8e-9f21-0a1b2c3d4e5f"
}
}{
"error": {
"type": "invalid_request_error",
"code": "not_found",
"message": "Resource not found.",
"status": 404,
"requestId": "e4f1c0b2-6a3d-4b8e-9f21-0a1b2c3d4e5f"
}
}{
"error": {
"type": "invalid_request_error",
"code": "conflict",
"message": "The request conflicts with an existing resource.",
"status": 409,
"requestId": "e4f1c0b2-6a3d-4b8e-9f21-0a1b2c3d4e5f"
}
}{
"error": {
"type": "invalid_request_error",
"code": "idempotency_key_reused",
"message": "The Idempotency-Key was already used with a different request body. Use a new key for a new operation.",
"status": 422,
"requestId": "e4f1c0b2-6a3d-4b8e-9f21-0a1b2c3d4e5f"
}
}{
"error": {
"type": "rate_limit_error",
"code": "rate_limited",
"message": "Too many requests. Retry after the interval in the Retry-After header.",
"status": 429,
"requestId": "e4f1c0b2-6a3d-4b8e-9f21-0a1b2c3d4e5f",
"retryAfter": 30
}
}Bulk mutate leads
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.
curl --request POST \
--url https://api.mailbeast.ai/v1/campaigns/{cid}/leads/mutate \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"ids": [
"c9e5b1a3-7f24-4d80-a6b9-2e4f8c0d1a37",
"d1a8f4c6-2b93-4e70-8c15-9f0e3a7d6b52"
],
"filter": {
"search": "acme",
"tags": [
"vip",
"q4"
]
},
"all": false,
"tags": [
"vip",
"q4"
]
}
'import requests
url = "https://api.mailbeast.ai/v1/campaigns/{cid}/leads/mutate"
payload = {
"ids": ["c9e5b1a3-7f24-4d80-a6b9-2e4f8c0d1a37", "d1a8f4c6-2b93-4e70-8c15-9f0e3a7d6b52"],
"filter": {
"search": "acme",
"tags": ["vip", "q4"]
},
"all": False,
"tags": ["vip", "q4"]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
ids: ['c9e5b1a3-7f24-4d80-a6b9-2e4f8c0d1a37', 'd1a8f4c6-2b93-4e70-8c15-9f0e3a7d6b52'],
filter: {search: 'acme', tags: ['vip', 'q4']},
all: false,
tags: ['vip', 'q4']
})
};
fetch('https://api.mailbeast.ai/v1/campaigns/{cid}/leads/mutate', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.mailbeast.ai/v1/campaigns/{cid}/leads/mutate",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'ids' => [
'c9e5b1a3-7f24-4d80-a6b9-2e4f8c0d1a37',
'd1a8f4c6-2b93-4e70-8c15-9f0e3a7d6b52'
],
'filter' => [
'search' => 'acme',
'tags' => [
'vip',
'q4'
]
],
'all' => false,
'tags' => [
'vip',
'q4'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.mailbeast.ai/v1/campaigns/{cid}/leads/mutate"
payload := strings.NewReader("{\n \"ids\": [\n \"c9e5b1a3-7f24-4d80-a6b9-2e4f8c0d1a37\",\n \"d1a8f4c6-2b93-4e70-8c15-9f0e3a7d6b52\"\n ],\n \"filter\": {\n \"search\": \"acme\",\n \"tags\": [\n \"vip\",\n \"q4\"\n ]\n },\n \"all\": false,\n \"tags\": [\n \"vip\",\n \"q4\"\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.mailbeast.ai/v1/campaigns/{cid}/leads/mutate")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"ids\": [\n \"c9e5b1a3-7f24-4d80-a6b9-2e4f8c0d1a37\",\n \"d1a8f4c6-2b93-4e70-8c15-9f0e3a7d6b52\"\n ],\n \"filter\": {\n \"search\": \"acme\",\n \"tags\": [\n \"vip\",\n \"q4\"\n ]\n },\n \"all\": false,\n \"tags\": [\n \"vip\",\n \"q4\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.mailbeast.ai/v1/campaigns/{cid}/leads/mutate")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"ids\": [\n \"c9e5b1a3-7f24-4d80-a6b9-2e4f8c0d1a37\",\n \"d1a8f4c6-2b93-4e70-8c15-9f0e3a7d6b52\"\n ],\n \"filter\": {\n \"search\": \"acme\",\n \"tags\": [\n \"vip\",\n \"q4\"\n ]\n },\n \"all\": false,\n \"tags\": [\n \"vip\",\n \"q4\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"operation": "set_status",
"affected": 42,
"failed": 0,
"errors": [
"2 lead(s) not found in this campaign"
]
}{
"error": {
"type": "invalid_request_error",
"code": "validation_failed",
"message": "One or more fields are invalid.",
"status": 400,
"requestId": "e4f1c0b2-6a3d-4b8e-9f21-0a1b2c3d4e5f",
"details": [
"name should not be empty"
]
}
}{
"error": {
"type": "authentication_error",
"code": "unauthenticated",
"message": "Missing or invalid API key.",
"status": 401,
"requestId": "e4f1c0b2-6a3d-4b8e-9f21-0a1b2c3d4e5f"
}
}{
"error": {
"type": "authorization_error",
"code": "permission_denied",
"message": "This API key is missing the required scope.",
"status": 403,
"requestId": "e4f1c0b2-6a3d-4b8e-9f21-0a1b2c3d4e5f"
}
}{
"error": {
"type": "invalid_request_error",
"code": "not_found",
"message": "Resource not found.",
"status": 404,
"requestId": "e4f1c0b2-6a3d-4b8e-9f21-0a1b2c3d4e5f"
}
}{
"error": {
"type": "invalid_request_error",
"code": "conflict",
"message": "The request conflicts with an existing resource.",
"status": 409,
"requestId": "e4f1c0b2-6a3d-4b8e-9f21-0a1b2c3d4e5f"
}
}{
"error": {
"type": "invalid_request_error",
"code": "idempotency_key_reused",
"message": "The Idempotency-Key was already used with a different request body. Use a new key for a new operation.",
"status": 422,
"requestId": "e4f1c0b2-6a3d-4b8e-9f21-0a1b2c3d4e5f"
}
}{
"error": {
"type": "rate_limit_error",
"code": "rate_limited",
"message": "Too many requests. Retry after the interval in the Retry-After header.",
"status": 429,
"requestId": "e4f1c0b2-6a3d-4b8e-9f21-0a1b2c3d4e5f",
"retryAfter": 30
}
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Headers
Optional. A unique key you generate (max 255 chars, such as a UUID) that makes this request safe to retry. Retrying with the same key replays the original response instead of repeating the operation. Reusing a key with a different body returns 422.
255"a1b2c3d4-e5f6-7890-abcd-ef1234567890"
Path Parameters
"a7d4e2f1-08b3-4c65-9e7a-1b2c3d4e5f60"
Body
set_status, add_tags, remove_tags, delete Target lead ids. Required for every operation except a filter-based delete.
1000[
"c9e5b1a3-7f24-4d80-a6b9-2e4f8c0d1a37",
"d1a8f4c6-2b93-4e70-8c15-9f0e3a7d6b52"
]
Select targets by filter instead of ids - supported ONLY for delete, and must contain at least one condition (an empty filter is rejected).
Show child attributes
Show child attributes
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.
false
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.
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 add_tags / remove_tags.
["vip", "q4"]
Response
set_status, add_tags, remove_tags, delete Number of leads successfully affected.
42
Number of leads that could not be processed.
0
Per-lead error messages, if any.
["2 lead(s) not found in this campaign"]