On this page
POST/campaigns/:campaignId/leads/batch
Insert up to 100 LinkedIn profiles into an existing campaign in one HTTP call. Same credit, dedupe, exclude, and occupancy rules as POST …/leads.
For CRM / n8n bulk push: chunk lists larger than 100 (e.g. 185 → 100 + 85). Clients must call this route — parallel single-lead POSTs still hit per-key RPM. Raising RPM alone does not fix bulk dumps.
Credits: 1 per successfully inserted lead (summed in creditsCharged).
Rate class: 10 / minute (still subject to the global 120 / minute per key).
Request
POST /campaigns/search_abc/leads/batch
X-API-Key: sk_live_...
Content-Type: application/json
Idempotency-Key: optional-uuid
{
"leads": [
{
"linkedinUrl": "https://www.linkedin.com/in/jane-doe/",
"fullName": "Jane Doe",
"jobTitle": "VP Sales",
"companyName": "Acme"
}
]
}
| Field | Required | Notes |
|---|---|---|
leads | Yes | Non-empty array, length 1…100 (hard max) |
leads[] | Same allowlist as single add-lead (linkedinUrl required; optional profile fields with the same length caps) |
- Top-level allowlist: only
leads. Unknown keys → whole-request 400. - Per-item unknown keys / bad types / over-length → whole-request 400 (no inserts).
- Invalid LinkedIn URL on one item → that index is
validation_errorinresults; siblings still process. - Body subject to global 128 KiB cap — sparse CRM rows are fine; heavy
personalizationmay need smaller chunks.
Response 200
Always 200 when the envelope is valid and the campaign exists:
{
"results": [
{
"index": 0,
"linkedinUrl": "https://www.linkedin.com/in/jane-doe/",
"leadId": "lead_12",
"status": "created",
"creditsCharged": 1
}
],
"summary": {
"total": 1,
"created": 1,
"duplicate": 0,
"excluded": 0,
"validation_error": 0,
"insufficient_credits": 0,
"failed": 0
},
"creditsCharged": 1
}
Per-item status | Credit |
|---|---|
created | 1 |
duplicate / excluded / validation_error / insufficient_credits / failed | 0 |
On first credit exhaustion, that item and all remaining items are marked insufficient_credits without further inserts. Still HTTP 200.
Idempotency
Idempotency-Key is only stored when at least one item is created, duplicate, or excluded. All-insufficient / all-validation / all-failed batches release the key so top-up / fix-and-retry works. Fingerprint includes the full body (order matters).
Whole-request errors (not partial 200)
error.code | When |
|---|---|
validation_error | Bad envelope / types / unknown keys / over-length |
not_found | Campaign missing before any insert |
conflict | Idempotency conflict |
rate_limited | Per-key batch RPM or global RPM |
upstream_unavailable | Idempotency reserve fail — no inserts |
MCP
Tool: add_leads_batch → same REST route. Optional idempotencyKey.
See also
- Single lead: POST …/leads
- Batch update / Batch delete
- Credits & rate limits