On this page

POST/campaigns/:campaignId/leads/batch-update

Credits: 0
LinkedIn risk: None
Rate limit: 6 / minute (max 100 items)

Optional Idempotency-Key (TTL 24h).


Purpose

Update tag and/or excluded for up to 100 leads in one call. Prefer this over many PATCH …/leads/:leadId calls.

Exclude is workspace-global (exclusion list + matching leads across campaigns) via one bulk exclude when a LinkedIn URL is available. If there is no LinkedIn URL, only the campaign lead’s excluded flag is set locally (same as single PATCH). Auto-exclude tags (Not interested, Wrong person) apply immediately — no pending acknowledgement / polite-close deferral (differs from single PATCH / inbox).


Request

POST /campaigns/search_abc/leads/batch-update
X-API-Key: sk_live_...
Idempotency-Key: optional-key
Content-Type: application/json
{
  "updates": [
    { "leadId": "lead_xyz", "excluded": true },
    { "leadId": "lead_abc", "tag": "Interested" }
  ]
}
FieldNotes
updatesYes — non-empty array, length 1…100 (hard max)
updates[].leadIdRequired; lead_ prefix normalized
updates[].tagOptional; allowlisted labels or null to clear
updates[].excludedOptional boolean

At least one of tag / excluded per item (otherwise whole-request 400). Unknown top-level keys → 400. Soft per-item: bad id, duplicate leadId (first wins), auto-exclude tag + excluded: false.

Idempotency: array order matters (fingerprint). Persist 200 only when summary.updated > 0.


Response 200

{
  "results": [
    {
      "index": 0,
      "leadId": "lead_xyz",
      "status": "updated",
      "tag": null,
      "excluded": true
    }
  ],
  "summary": {
    "total": 1,
    "updated": 1,
    "not_found": 0,
    "validation_error": 0,
    "failed": 0
  },
  "creditsCharged": 0
}

Statuses: updated · not_found · validation_error · failed.

If the request fails mid-batch after durable writes, response is still 200 with completed rows as updated (only fields that actually landed — e.g. a tagged auto-exclude row does not claim excluded: true until the bulk/local exclude step succeeds) and remaining as failed. Idempotency-Key is persisted when summary.updated > 0.

Per-item soft failures may include an error object (code, message).


Errors

Whole-request failures (not partial 200):

error.codeWhen
unauthorizedMissing/invalid API key
validation_errorBad envelope / empty updates / item missing both tag and excluded / unknown keys / over-length
not_foundCampaign missing before any update
conflictIdempotency conflict
rate_limitedBatch-update RPM (6/min) or global RPM
upstream_unavailableIdempotency reserve fail — no updates

vs single PATCH

BehaviorPATCHBatch update
Auto-exclude deferralPossibleNo — immediate
Global exclude (with LinkedIn URL)Yes (per lead)Yes (one bulk)
No LinkedIn URL + excludeLead flag onlySame (local mark)
excluded: falseLead flag onlySame
lead.tagged webhook1Up to 100

MCP

Tool: update_leads_batch. Outbound REST timeout 300s (large exclude scans).

See also