JavaScript / Node.js Examples
These examples use the built-infetch API (Node.js 18+). No additional dependencies required.
Setup
const API_KEY = process.env.NATURALEAD_API_KEY;
const BASE_URL = "https://api.naturalead.ai/api";
async function apiRequest(method, path, body) {
const response = await fetch(`${BASE_URL}${path}`, {
method,
headers: {
"X-API-Key": API_KEY,
"Content-Type": "application/json",
},
body: body ? JSON.stringify(body) : undefined,
});
if (response.status === 429) {
const retryAfter = response.headers.get("Retry-After") || "5";
throw new Error(`Rate limited. Retry after ${retryAfter}s`);
}
if (!response.ok) {
const { error } = await response.json();
throw new Error(`${response.status}: ${error}`);
}
if (response.status === 204) return null;
return response.json();
}
Lead Management
List all leads
const leads = await apiRequest("GET", "/leads");
for (const lead of leads) {
console.log(`#${lead.id} ${lead.name} (${lead.status})`);
}
Create a lead
try {
const lead = await apiRequest("POST", "/leads", {
name: "Jane Smith",
phone: "+14155551234",
email: "[email protected]",
tags: ["inbound", "demo"],
});
console.log(`Created lead #${lead.id}`);
} catch (error) {
if (error.message.includes("409")) {
console.log("Lead with this phone already exists");
} else {
throw error;
}
}
Search leads
const results = await apiRequest("GET", "/leads/search?q=john&limit=10");
console.log(`Found ${results.leads.length} leads`);
Bulk sync from CRM
const result = await apiRequest("POST", "/leads/sync", {
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",
},
],
});
console.log(`Created: ${result.created}, Updated: ${result.updated}`);
for (const error of result.errors) {
console.error(`Error for ${error.lead_id}: ${error.error}`);
}
Conversations
Start a conversation
try {
const conversation = await apiRequest("POST", "/conversations/start", {
leadId: 1,
channel: "whatsapp",
});
console.log(`Conversation started: ${conversation._id}`);
} catch (error) {
if (error.message.includes("503")) {
console.log("Messaging not configured. Set up integration first.");
}
}
List active conversations
const conversations = await apiRequest("GET", "/conversations?status=active");
for (const conv of conversations) {
console.log(`${conv._id}: ${conv.status} (${conv.messages?.length || 0} messages)`);
}
Campaigns
Create and launch a campaign
// Create
const campaign = await apiRequest("POST", "/campaigns", {
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
},
});
// Launch
const launched = await apiRequest("POST", `/campaigns/${campaign._id}/launch`);
console.log(`Campaign status: ${launched.status}`);
CSV Import
Two-step CSV import
const csvContent = `Name,Phone,Email,Company
Jane Smith,+14155551234,[email protected],Acme Corp
Bob Jones,+14155555678,[email protected],Widget Inc`;
// Step 1: Preview
const preview = await apiRequest("POST", "/leads/upload/preview", {
content: csvContent,
});
console.log(`Headers: ${preview.headers.join(", ")}`);
console.log(`Total rows: ${preview.totalRows}`);
// Step 2: Confirm with mapping
const result = await apiRequest("POST", "/leads/upload/confirm", {
content: csvContent,
mapping: {
Name: "name",
Phone: "phone",
Email: "email",
Company: "companyName", // becomes custom field
},
tags: ["csv-import", "q1-2026"],
});
console.log(`Imported: ${result.imported}, Duplicates: ${result.duplicatesSkipped}`);
Rate Limit Handling
async function apiRequestWithRetry(method, path, body, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
const response = await fetch(`${BASE_URL}${path}`, {
method,
headers: {
"X-API-Key": API_KEY,
"Content-Type": "application/json",
},
body: body ? JSON.stringify(body) : undefined,
});
if (response.status !== 429) {
if (!response.ok) {
const { error } = await response.json();
throw new Error(`${response.status}: ${error}`);
}
return response.status === 204 ? null : response.json();
}
const retryAfter = parseInt(response.headers.get("Retry-After") || String(2 ** attempt));
console.log(`Rate limited. Waiting ${retryAfter}s...`);
await new Promise((resolve) => setTimeout(resolve, retryAfter * 1000));
}
throw new Error("Max retries exceeded");
}