---
title: "Add leads to a campaign (imports into its lead list; seeds them immediately when the campaign is active)"
method: POST
path: "/api/v1/campaigns/{id}/leads"
tags: ["Campaigns"]
---

# Add leads to a campaign (imports into its lead list; seeds them immediately when the campaign is active)

`POST /api/v1/campaigns/{id}/leads`

## Request

- Base URL: `https://app.reachium.io`
- URL: `https://app.reachium.io/api/v1/campaigns/{id}/leads`
- Auth: HTTP bearer

A campaign owned by another workspace and one that does not exist at all both return the same not_found - no cross-tenant existence leak. When the campaign is active, newly imported leads are seeded and excluded (same engine call the launch route uses) so they start right away instead of waiting on the next scheduler pass.

## Path parameters

- `id` string, required

## Request body

- object
  - `leads` object[], required
    - `linkedin_url` string, required
    - `first_name` string
    - `last_name` string
    - `email` string
    - `company` string
    - `position` string
    - `phone` string

## Response `201`

Imported.

- object
  - `data` object, required
    - `imported` integer, required
    - `skipped_invalid` integer, required
    - `seeded` integer, required: 0 unless the campaign is active.
    - `excluded` integer, required: 0 unless the campaign is active.
    - `campaign_status` string, required
  - `error` unknown, required

## Other responses

- `400`: leads is missing/empty/over 500 rows, a row is not an object, a row is missing linkedin_url, or every row failed validation (code invalid_request or no_valid_rows).
- `401`: Missing or invalid API key. Send `Authorization: Bearer rmcp_...` (code unauthorized).
- `402`: Workspace billing is blocked; mutating requests are refused (code billing_blocked).
- `403`: The key's granted scopes do not satisfy this endpoint's minimum required scope (code insufficient_scope).
- `404`: No such campaign in this workspace (code not_found), or its lead list vanished between checks (code list_not_found).
- `409`: This campaign has no lead list attached (code no_lead_list).
- `429`: Rate limited: shared `mcp:ip:{ip}` (600/60s) or `mcp:key:{keyId}` (120/60s) bucket, the SAME buckets the MCP endpoint uses (code rate_limited).
- `500`: The import itself failed (code lookup_failed or import_failed), or, for an active campaign, the seeding DB write failed (code seed_failed). Retryable.
- `502`: The campaign is active and the fail-closed exclusion-engine call failed (code exclusion_failed). Retryable.
- `503`: The billing-status check itself failed (DB error): fails closed rather than letting a blocked workspace through; safe to retry (code billing_check_failed).

---

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