Skip to main content
Leads are the recipients of your cold email campaigns. ColdSend supports uploading leads via CSV, adding them individually, and tracking their engagement.

Lead Status

StatusDescription
PENDINGLead not yet contacted — eligible for sending
QUEUEDEmail task created, waiting to be sent
SENTInitial email successfully sent
OPENEDEmail was opened (tracking enabled)
REPLIEDLead replied to email
FAILEDEmail send failed
BOUNCEDEmail bounced after sending
UNSUBSCRIBEDLead unsubscribed
EXTERNALExternal/unsolicited incoming lead

Lead Upload via CSV

POST /api/public/v1/campaigns/{campaign_id}/leads Upload leads asynchronously via CSV file. The file must include an email column.
import requests
import json

campaign_id = "550e8400-e29b-41d4-a716-446655440000"

mapping = {
    "email": "Email",
    "first_name": "First Name",
    "last_name": "Last Name",
    "company": "Company"
}

with open("leads.csv", "rb") as f:
    response = requests.post(
        f"https://api.coldsend.pro/api/public/v1/campaigns/{campaign_id}/leads",
        headers={"X-API-Key": api_key},
        files={"file": f},
        data={"mapping": json.dumps(mapping)}
    )

print(response.json())

CSV Requirements

  • Must include an email column (required)
  • Additional supported columns: first_name, last_name, company
  • Custom columns are mapped automatically and available as {{custom_column_name}} in your email templates
  • Max CSV size: 50MB
  • Max leads per upload: 10,000

Upload Progress

The upload runs asynchronously. Check progress with:
response = requests.get(
    f"https://api.coldsend.pro/api/public/v1/campaigns/{campaign_id}/leads/upload/{job_id}",
    headers={"X-API-Key": api_key}
)

Manual Lead Addition

POST /api/public/v1/campaigns/{campaign_id}/leads/manual Add a single lead:
response = requests.post(
    f"{base_url}/api/public/v1/campaigns/{campaign_id}/leads/manual",
    headers={"X-API-Key": api_key},
    json={
        "email": "john.doe@example.com",
        "first_name": "John",
        "last_name": "Doe",
        "company": "Acme Inc"
    }
)

Listing Leads

GET /api/public/v1/campaigns/{campaign_id}/leads List leads with pagination and filtering:
response = requests.get(
    f"{base_url}/api/public/v1/campaigns/{campaign_id}/leads?status=PENDING&page=1&limit=20",
    headers={"X-API-Key": api_key}
)

Query Parameters

ParameterDescription
pagePage number (1-based, default: 1)
limitItems per page (1-100, default: 20)
statusFilter by status: PENDING, SENT, OPENED, REPLIED, BOUNCED, etc.
searchSearch by email or name

Deleting Leads

DELETE /api/public/v1/campaigns/{campaign_id}/leads Only PENDING leads (not yet sent) can be deleted:
response = requests.delete(
    f"{base_url}/api/public/v1/campaigns/{campaign_id}/leads",
    headers={"X-API-Key": api_key},
    json={
        "lead_ids": [
            "650e8400-e29b-41d4-a716-446655440000",
            "750e8400-e29b-41d4-a716-446655440001"
        ]
    }
)
Leads that have already received emails cannot be deleted. This ensures compliance and prevents data gaps in campaign analytics.

Next Steps

Create Campaign

Set up your campaign with lead mapping configuration.

Personalization

Use lead data in personalized email content.