Skip to main content
Create and configure cold email campaigns programmatically. Campaign activation follows a component-based approach where you provide the fields you want, then set launch: true when ready.

Create a New Campaign

POST /api/public/v1/campaigns
import requests

api_key = "cs_live_your_api_key_here"
base_url = "https://api.coldsend.pro"

response = requests.post(
    f"{base_url}/api/public/v1/campaigns",
    headers={"X-API-Key": api_key},
    json={
        "name": "Q1 Product Launch Outreach",
        "timezone": "America/New_York",
        "sending_days": [1, 2, 3, 4, 5],
        "sending_window_start": 9,
        "sending_window_end": 17,
        "daily_limit_per_inbox": 30,
        "enable_tracking": True,
        "enable_unsubscribe": True
    }
)

campaign = response.json()
campaign_id = campaign["campaign_id"]
print(f"Campaign created: {campaign_id}")
{
  "success": true,
  "message": "Campaign created successfully",
  "campaign_id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "Q1 Product Launch Outreach",
  "status": "DRAFT",
  "created_at": "2024-01-15T10:30:00Z"
}

Request Parameters

Required Fields

ParameterTypeDescription
namestringCampaign name (8-255 characters)

Optional Fields

ParameterTypeDefaultDescription
timezonestringAmerica/New_YorkIANA timezone for scheduling
sending_daysint[][1,2,3,4,5]Days to send (1=Mon, 7=Sun)
sending_window_startint9Start hour (0-23)
sending_window_start_minuteint0Start minute (0-59)
sending_window_endint17End hour (1-24)
sending_window_end_minuteint0End minute (0-59)
daily_limit_per_inboxintnullMax emails per inbox/day (1-100)
start_datedatetimenullISO 8601 start date
enable_trackingboolfalseEnable email open tracking
enable_unsubscribebooltrueInclude unsubscribe link
The sending window supports minute-precision. For example, sending_window_start: 9 with sending_window_start_minute: 30 starts at 9:30 AM. When sending_window_end is 24, the minute must be 0.

Update Campaign

PUT /api/public/v1/campaigns/{campaign_id} Update any campaign field or activate it. Only include the fields you want to change.
response = requests.put(
    f"{base_url}/api/public/v1/campaigns/{campaign_id}",
    headers={"X-API-Key": api_key},
    json={
        "name": "Updated Campaign Name",
        "inbox_ids": ["inbox-uuid"],
        "variants": [
            {
                "variant_name": "A",
                "subject_template": "Quick question about {{company}}",
                "email_content": "Hi {{first_name}},\n\n...",
                "distribution_percent": 100
            }
        ],
        "sequences": [...],
        "launch": True
    }
)

Updatable Fields

Basic Settings: name, timezone, sending_days, sending_window_start, sending_window_start_minute, sending_window_end, sending_window_end_minute, daily_limit_per_inbox, enable_tracking, enable_unsubscribe, start_date Inboxes: inbox_ids — Array of inbox UUIDs to assign Email Content: variants — Array of email variant objects for A/B testing Follow-ups: sequences — Array of follow-up sequence objects Launch Control: launch — Set to true to activate the campaign

Launch Validation

When launch: true, the API checks:
  • At least one lead exists
  • At least one inbox is assigned
  • At least one email variant is configured
response = requests.put(
    f"{base_url}/api/public/v1/campaigns/{campaign_id}",
    headers={"X-API-Key": api_key},
    json={"launch": True}
)

result = response.json()
print(f"Launch ready: {result['is_launch_ready']}")
print(f"Missing: {result['missing_requirements']}")
Response
{
  "campaign_id": "550e8400-e29b-41d4-a716-446655440000",
  "status": "DRAFT",
  "is_launch_ready": false,
  "missing_requirements": ["leads", "variants"],
  ...
}
If requirements are missing, the campaign remains in DRAFT. The missing_requirements field tells you exactly what’s needed.

Validation Errors

ErrorCause
ensure this value has at least 8 charactersCampaign name too short
Invalid timezone: America/InvalidInvalid IANA timezone
sending_window_end must be after sending_window_startWindow configuration invalid
Variant distributions must sum to 100%Variant percentages don’t total 100

Best Practices

  1. Use descriptive names — Include goal, target audience, or time period
  2. Match timezone to audience — Prevents emails from sending at odd hours
  3. Start conservative with limits — 20-50 emails/inbox/day for new accounts
  4. Enable tracking — Essential for measuring campaign performance
  5. Test before launching — Try with a few test leads first

Next Steps

Email Variants

Configure A/B testing and distribution.

Follow-up Sequences

Set up automated follow-up emails.

Personalization

Use variables, spintax, and conditionals.