Python Examples
These examples use therequests 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")