Skip to main content

Python Examples

These examples use the requests library. Install it with pip install requests.

Setup

import os
import requests

API_KEY = os.environ["NATURALEAD_API_KEY"]
BASE_URL = "https://api.naturalead.ai/api"

headers = {
    "X-API-Key": API_KEY,
    "Content-Type": "application/json",
}

Lead Management

List all leads

response = requests.get(f"{BASE_URL}/leads", headers=headers)
leads = response.json()

for lead in leads:
    print(f"#{lead['id']} {lead['name']} ({lead['status']})")

Create a lead

response = requests.post(
    f"{BASE_URL}/leads",
    headers=headers,
    json={
        "name": "Jane Smith",
        "phone": "+14155551234",
        "email": "[email protected]",
        "tags": ["inbound", "demo"],
    },
)

if response.status_code == 201:
    lead = response.json()
    print(f"Created lead #{lead['id']}")
elif response.status_code == 409:
    print("Lead with this phone already exists")
else:
    print(f"Error: {response.json()['error']}")

Search leads

response = requests.get(
    f"{BASE_URL}/leads/search",
    headers=headers,
    params={"q": "john", "limit": 10},
)

results = response.json()
print(f"Found {len(results['leads'])} leads")

Bulk sync from CRM

response = requests.post(
    f"{BASE_URL}/leads/sync",
    headers=headers,
    json={
        "leads": [
            {
                "lead_id": "crm-001",
                "name": "Alice Johnson",
                "phone": "+14155551111",
                "email": "[email protected]",
                "custom_fields": {"company": "Acme Corp", "deal_size": "50000"},
            },
            {
                "lead_id": "crm-002",
                "name": "Bob Wilson",
                "phone": "+14155552222",
            },
        ]
    },
)

result = response.json()
print(f"Created: {result['created']}, Updated: {result['updated']}, Failed: {result['failed']}")

if result["errors"]:
    for error in result["errors"]:
        print(f"  Error for {error['lead_id']}: {error['error']}")

Conversations

Start a conversation

response = requests.post(
    f"{BASE_URL}/conversations/start",
    headers=headers,
    json={"leadId": 1, "channel": "whatsapp"},
)

if response.status_code == 201:
    conversation = response.json()
    print(f"Conversation started: {conversation['_id']}")
elif response.status_code == 503:
    print("Messaging not configured. Set up integration first.")

List active conversations

response = requests.get(
    f"{BASE_URL}/conversations",
    headers=headers,
    params={"status": "active"},
)

conversations = response.json()
for conv in conversations:
    print(f"{conv['_id']}: {conv['status']} ({len(conv.get('messages', []))} messages)")

Campaigns

Create and launch a campaign

# Create
response = requests.post(
    f"{BASE_URL}/campaigns",
    headers=headers,
    json={
        "name": "Q1 Outreach",
        "agentConfigId": "AGENT_ID",
        "channel": "whatsapp",
        "leadFilter": {"statuses": ["new"], "tags": ["inbound"]},
        "schedule": {
            "rateLimit": 10,
            "activeHours": {"start": "09:00", "end": "17:00", "timezone": "America/New_York"},
            "activeDays": [1, 2, 3, 4, 5],  # Monday-Friday
        },
    },
)

campaign = response.json()
campaign_id = campaign["_id"]

# Launch
response = requests.post(f"{BASE_URL}/campaigns/{campaign_id}/launch", headers=headers)
print(f"Campaign launched: {response.json()['status']}")

CSV Import

Two-step CSV import

csv_content = """Name,Phone,Email,Company
Jane Smith,+14155551234,[email protected],Acme Corp
Bob Jones,+14155555678,[email protected],Widget Inc"""

# Step 1: Preview
response = requests.post(
    f"{BASE_URL}/leads/upload/preview",
    headers=headers,
    json={"content": csv_content},
)

preview = response.json()
print(f"Headers: {preview['headers']}")
print(f"Total rows: {preview['totalRows']}")

# Step 2: Confirm with mapping
response = requests.post(
    f"{BASE_URL}/leads/upload/confirm",
    headers=headers,
    json={
        "content": csv_content,
        "mapping": {
            "Name": "name",
            "Phone": "phone",
            "Email": "email",
            "Company": "companyName",  # becomes custom field
        },
        "tags": ["csv-import", "q1-2026"],
    },
)

result = response.json()
print(f"Imported: {result['imported']}, Duplicates skipped: {result['duplicatesSkipped']}")

Rate Limit Handling

import time

def safe_request(method, path, max_retries=3, **kwargs):
    for attempt in range(max_retries):
        response = requests.request(
            method,
            f"{BASE_URL}{path}",
            headers=headers,
            **kwargs,
        )

        if response.status_code != 429:
            return response

        retry_after = int(response.headers.get("Retry-After", 2 ** attempt))
        print(f"Rate limited. Waiting {retry_after}s...")
        time.sleep(retry_after)

    raise Exception("Max retries exceeded")