LeadSonar API
Enrich contacts with 20+ data providers through one simple API. Waterfall enrichment that maximizes hit rates at minimum cost.
Quick Start
Go from zero to enriched contacts in three steps.
ls_live_.curl -X POST https://api.leadsonar.com/api/v1/find-email \
-H "Content-Type: application/json" \
-H "X-API-Key: ls_live_sk_7f3a9b2c..." \
-d '{
"first_name": "Sarah",
"last_name": "Chen",
"domain": "stripe.com"
}'
{
"email": "sarah.chen@stripe.com",
"confidence": 0.95,
"provider": "leadmagic",
"verified": true,
"cost_credits": 1
}
curl -X POST https://api.leadsonar.com/api/v1/enrich \
-H "Content-Type: application/json" \
-H "X-API-Key: ls_live_sk_7f3a9b2c..." \
-d '{
"contacts": [
{ "first_name": "Sarah", "last_name": "Chen", "domain": "stripe.com" },
{ "first_name": "Marcus", "last_name": "Rivera", "domain": "notion.so", "linkedin_url": "https://linkedin.com/in/marcusrivera" }
],
"fields": ["email", "phone"]
}'
{
"id": "b47e2a1f-8c3d-4e5a-9f6b-1d2e3f4a5b6c",
"status": "processing",
"total_contacts": 2,
"estimated_seconds": 15
}
Authentication
All API requests require authentication via an API key passed in the request header.
X-API-Key header. Keys are prefixed with ls_live_ for production.curl https://api.leadsonar.com/api/v1/credits \
-H "X-API-Key: ls_live_sk_7f3a9b2c4d5e6f7a8b9c0d1e2f3a4b5c"
{
"error": "Invalid or missing API key"
}
Endpoints
All endpoints live under the base URL. Authentication is required unless noted otherwise.
Find an email for a single contact (synchronous). Runs the full waterfall cascade and returns the best email found. Blocks until complete, typically 2-10 seconds.
| Parameter | Type | Description |
|---|---|---|
| first_namerequired | string | Contact's first name |
| last_namerequired | string | Contact's last name |
| domainrequired | string | Company domain (e.g. stripe.com) |
| linkedin_urloptional | string | LinkedIn profile URL, improves accuracy |
{
"first_name": "Sarah",
"last_name": "Chen",
"domain": "stripe.com",
"linkedin_url": "https://linkedin.com/in/sarahchen"
}
{
"email": "sarah.chen@stripe.com",
"confidence": 0.95,
"provider": "leadmagic",
"verified": true,
"cost_credits": 1
}
| Field | Type | Description |
|---|---|---|
| string | null | Found email address, or null if no providers returned a result | |
| confidence | number | Confidence score between 0 and 1 |
| provider | string | null | Which provider found the email |
| verified | boolean | Whether the email was verified deliverable |
| cost_credits | number | Credits charged for this lookup |
Find a phone number for a single contact (synchronous). Cascades through phone providers and returns the best match. Typically 2-10 seconds.
| Parameter | Type | Description |
|---|---|---|
| first_namerequired | string | Contact's first name |
| last_namerequired | string | Contact's last name |
| domainrequired | string | Company domain |
| linkedin_urloptional | string | LinkedIn profile URL |
{
"first_name": "Marcus",
"last_name": "Rivera",
"domain": "notion.so"
}
{
"phone": "+14155551234",
"phone_type": "mobile",
"provider": "contactout",
"validated": true,
"cost_credits": 2
}
| Field | Type | Description |
|---|---|---|
| phone | string | null | Phone number in E.164 format, or null |
| phone_type | string | null | Type: "mobile", "landline", etc. |
| provider | string | null | Which provider found the phone |
| validated | boolean | Whether the number was validated |
| cost_credits | number | Credits charged |
Submit up to 100 contacts for enrichment (asynchronous). Returns a job ID immediately. Poll GET /api/v1/enrich/{id} for results.
| Parameter | Type | Description |
|---|---|---|
| contactsrequired | array | Array of contact objects (max 100). Each requires first_name, last_name, domain. |
| fieldsoptional | string[] | What to find: "email", "phone", or both. Default: ["email"] |
| webhook_urloptional | string | URL to POST results to when complete (coming soon) |
| Field | Type | Description |
|---|---|---|
| first_namerequired | string | Contact's first name |
| last_namerequired | string | Contact's last name |
| domainrequired | string | Company domain |
| linkedin_urloptional | string | LinkedIn profile URL |
| company_nameoptional | string | Company name for better matching |
{
"contacts": [
{
"first_name": "Sarah",
"last_name": "Chen",
"domain": "stripe.com"
},
{
"first_name": "Marcus",
"last_name": "Rivera",
"domain": "notion.so",
"linkedin_url": "https://linkedin.com/in/marcusrivera"
},
{
"first_name": "Emily",
"last_name": "Nakamura",
"domain": "figma.com",
"company_name": "Figma"
}
],
"fields": ["email", "phone"]
}
{
"id": "b47e2a1f-8c3d-4e5a-9f6b-1d2e3f4a5b6c",
"status": "processing",
"total_contacts": 3,
"estimated_seconds": 15
}
Get enrichment job status and results. Poll this endpoint to check progress. When status is "completed", the contacts array and meta object are included.
| Parameter | Type | Description |
|---|---|---|
| idrequired | uuid | Job ID returned from POST /api/v1/enrich |
{
"id": "b47e2a1f-8c3d-4e5a-9f6b-1d2e3f4a5b6c",
"status": "processing",
"progress": {
"total": 3,
"completed": 1,
"emails_found": 1,
"phones_found": 0
}
}
{
"id": "b47e2a1f-8c3d-4e5a-9f6b-1d2e3f4a5b6c",
"status": "completed",
"progress": {
"total": 3,
"completed": 3,
"emails_found": 3,
"phones_found": 2
},
"contacts": [
{
"first_name": "Sarah",
"last_name": "Chen",
"domain": "stripe.com",
"email": "sarah.chen@stripe.com",
"email_confidence": 0.95,
"phone": "+14155559012",
"phone_type": "mobile",
"providers_used": ["leadmagic", "contactout"]
},
{
"first_name": "Marcus",
"last_name": "Rivera",
"domain": "notion.so",
"email": "marcus@notion.so",
"email_confidence": 0.92,
"phone": "+12125553847",
"phone_type": "mobile",
"providers_used": ["prospeo", "lusha"]
},
{
"first_name": "Emily",
"last_name": "Nakamura",
"domain": "figma.com",
"email": "emily.nakamura@figma.com",
"email_confidence": 0.88,
"phone": null,
"phone_type": null,
"providers_used": ["findymail"]
}
],
"meta": {
"total_cost_usd": 0.42,
"duration_ms": 8340
}
}
Check your current credit balance, total earned, and total spent.
{
"balance": 450,
"total_earned": 500,
"total_spent": 50
}
| Field | Type | Description |
|---|---|---|
| balance | integer | Current available credits |
| total_earned | integer | All-time credits earned (purchased + bonuses) |
| total_spent | integer | All-time credits consumed |
List all enrichment providers with their type, tier, and enabled status.
{
"providers": [
{
"name": "leadmagic",
"type": "both",
"tier": "T1",
"enabled": true
},
{
"name": "prospeo",
"type": "both",
"tier": "T1",
"enabled": true
},
{
"name": "findymail",
"type": "email",
"tier": "T2",
"enabled": true
}
],
"total_enabled": 18
}
Provider List
LeadSonar cascades through 20+ providers in a waterfall pattern. Providers are grouped into tiers by cost and reliability.
Pricing
Simple credit-based pricing. One credit, one lookup attempt.
| Lookup Type | Cost | Details |
|---|---|---|
| Email Lookup | 1 credit | Per contact, regardless of how many providers are tried |
| Phone Lookup | 5 credits | Per contact, phone data costs more from upstream providers |
| Email + Phone | 6 credits | Both lookups for one contact |
SDKs & Integration
Official SDKs are coming soon. In the meantime, use cURL or any HTTP client.
https://api.leadsonar.com/api/v1/openapi.json