Documentation Index
Fetch the complete documentation index at: https://docs.seleqt.ai/llms.txt
Use this file to discover all available pages before exploring further.
POST /api/v1/public/lead-lists/:id/enrichment/
Enrich email addresses or phone numbers for prospects in a lead list. Credits are deducted upfront and enrichment happens asynchronously in the background.
Auth: X-API-Key
Path Parameters
id (integer, required): Lead list ID
Request Body
{
"enrichment_type": "FIND_EMAIL",
"prospect_limit": 100,
"mode": "async",
"webhook_url": "https://your-domain.com/webhook",
"filters": {},
"sort_field": "id",
"sort_direction": "asc"
}
Parameters
| Parameter | Type | Required | Default | Description |
|---|
enrichment_type | string | No | FIND_EMAIL | Type: FIND_EMAIL, FIND_EMAIL_WATERFALL, or FIND_PHONE |
prospect_limit | integer | No | 100 | Maximum number of prospects to enrich |
mode | string | No | async | Either sync (return results immediately) or async (background processing) |
webhook_url | string | No | null | URL to send results to when enrichment completes (async mode only) |
filters | object | No | {} | Additional filters to apply |
sort_field | string | No | id | Field to sort by |
sort_direction | string | No | asc | Sort direction (asc or desc) |
Enrichment Types
| Type | Description | Cost per Lead | When to Use |
|---|
FIND_EMAIL | Basic email finding | 3 credits | Fast, cost-effective email discovery |
FIND_EMAIL_WATERFALL | Multi-provider email finding | 6 credits | Higher success rate, more comprehensive |
FIND_PHONE | Phone number finding | 30 credits | Mobile and direct phone numbers |
Response (Async Mode)
{
"success": true,
"mode": "async",
"enrichment_type": "FIND_EMAIL",
"enriched_count": 100,
"credits_deducted": 300,
"remaining_credits": 700,
"webhook_url": "https://your-domain.com/webhook",
"message": "Enrichment started in background. Results will be sent to https://your-domain.com/webhook"
}
Response (Sync Mode)
{
"success": true,
"mode": "sync",
"enrichment_type": "FIND_EMAIL",
"total_count": 100,
"success_count": 87,
"credits_deducted": 300,
"remaining_credits": 700,
"results": [
{
"id": 12345,
"first_name": "John",
"last_name": "Doe",
"success": true,
"data": {
"email": "john.doe@company.com"
}
},
{
"id": 12346,
"first_name": "Jane",
"last_name": "Smith",
"success": false,
"data": {
"email": null
},
"message": "Email not found"
}
]
}
Response Fields
| Field | Type | Description |
|---|
success | boolean | Whether the enrichment was initiated successfully |
mode | string | sync or async |
enrichment_type | string | The enrichment type used |
enriched_count / total_count | integer | Number of prospects enriched |
success_count | integer | (Sync only) Number of successfully enriched prospects |
credits_deducted | integer | Total credits deducted |
remaining_credits | integer | Your remaining credit balance |
webhook_url | string | (Async only) Webhook URL if provided |
results | array | (Sync only) Enrichment results for each prospect |
How It Works
- Validation: Checks if you have enough credits
- Credit Deduction: Deducts credits upfront from your account
- Status Update: Sets prospects to “Loading…” status
- Background Processing: Enrichment happens asynchronously
- Auto-Update: Prospects are automatically updated when data is found
Important Notes
- Asynchronous: Enrichment happens in the background. Results appear gradually.
- Credit Deduction: Credits are deducted immediately, even if enrichment fails for some leads
- Automatic Filtering: Only prospects without valid emails/phones are enriched
- PEOPLE Lists Only: This endpoint only works for people lists, not company lists
- Refunds: If an email/phone is not found, credits may be refunded (varies by type)
Error Responses
400 Bad Request - Insufficient Credits
{
"success": false,
"error": "insufficient_credits",
"message": "Not enough credits. Need 300, have 250"
}
400 Bad Request - Wrong List Type
{
"error": "Email/phone enrichment is only available for people lists"
}
400 Bad Request - Invalid Enrichment Type
{
"error": "enrichment_type must be FIND_EMAIL, FIND_EMAIL_WATERFALL, or FIND_PHONE"
}
404 Not Found
{
"error": "Lead list not found"
}
Example Usage
Async Mode (Default)
# Enrich emails asynchronously (background processing)
curl -X POST "https://api.seleqt.ai/api/v1/public/lead-lists/123/enrichment/" \
-H "X-API-Key: <your-api-key>" \
-H "Content-Type: application/json" \
-d '{
"enrichment_type": "FIND_EMAIL",
"prospect_limit": 100,
"mode": "async"
}'
# With webhook notification
curl -X POST "https://api.seleqt.ai/api/v1/public/lead-lists/123/enrichment/" \
-H "X-API-Key: <your-api-key>" \
-H "Content-Type: application/json" \
-d '{
"enrichment_type": "FIND_EMAIL",
"prospect_limit": 100,
"mode": "async",
"webhook_url": "https://your-domain.com/webhook/enrichment"
}'
# Enrich and get results immediately
curl -X POST "https://api.seleqt.ai/api/v1/public/lead-lists/123/enrichment/" \
-H "X-API-Key: <your-api-key>" \
-H "Content-Type: application/json" \
-d '{
"enrichment_type": "FIND_EMAIL",
"prospect_limit": 50,
"mode": "sync"
}'
Python Example: Async Mode with Webhook
import requests
API_KEY = "<your-api-key>"
BASE_URL = "https://api.seleqt.ai/api/v1"
LEAD_LIST_ID = 123
WEBHOOK_URL = "https://your-domain.com/webhook/enrichment"
# Step 1: Check cost first
count_response = requests.get(
f"{BASE_URL}/public/lead-lists/{LEAD_LIST_ID}/enrichment/count/",
headers={"X-API-Key": API_KEY},
params={"enrichment_type": "FIND_EMAIL"}
)
count_data = count_response.json()
print(f"Will enrich {count_data['unenriched_count']} prospects")
print(f"Cost: {count_data['total_cost']} credits")
if not count_data['has_enough_credits']:
print("❌ Not enough credits!")
exit()
# Step 2: Start async enrichment with webhook
enrich_response = requests.post(
f"{BASE_URL}/public/lead-lists/{LEAD_LIST_ID}/enrichment/",
headers={"X-API-Key": API_KEY},
json={
"enrichment_type": "FIND_EMAIL",
"prospect_limit": count_data['unenriched_count'],
"mode": "async",
"webhook_url": WEBHOOK_URL
}
)
enrich_data = enrich_response.json()
if enrich_data['success']:
print(f"✓ Enrichment started for {enrich_data['enriched_count']} prospects")
print(f"✓ Results will be sent to {WEBHOOK_URL}")
print(f"Credits deducted: {enrich_data['credits_deducted']}")
else:
print(f"❌ Error: {enrich_data.get('message')}")
# Your webhook handler will receive results when complete
# See lead-lists-enrichment-webhook for webhook implementation
import requests
API_KEY = "<your-api-key>"
BASE_URL = "https://api.seleqt.ai/api/v1"
LEAD_LIST_ID = 123
# Check cost
count_response = requests.get(
f"{BASE_URL}/public/lead-lists/{LEAD_LIST_ID}/enrichment/count/",
headers={"X-API-Key": API_KEY},
params={"enrichment_type": "FIND_EMAIL"}
)
count_data = count_response.json()
if not count_data['has_enough_credits']:
print("❌ Not enough credits!")
exit()
# Enrich in sync mode - returns results immediately
enrich_response = requests.post(
f"{BASE_URL}/public/lead-lists/{LEAD_LIST_ID}/enrichment/",
headers={"X-API-Key": API_KEY},
json={
"enrichment_type": "FIND_EMAIL",
"prospect_limit": min(count_data['unenriched_count'], 50), # Limit for sync
"mode": "sync"
}
)
result = enrich_response.json()
if result['success']:
print(f"✓ Enriched {result['total_count']} prospects")
print(f"✓ Success: {result['success_count']}/{result['total_count']}")
print(f"✓ Credits used: {result['credits_deducted']}")
# Process results immediately
for prospect in result['results']:
if prospect['success']:
email = prospect['data'].get('email')
print(f" ✓ {prospect['first_name']} {prospect['last_name']}: {email}")
else:
print(f" ✗ {prospect['first_name']} {prospect['last_name']}: {prospect.get('message')}")
else:
print(f"❌ Error: {result.get('message')}")
Complete Workflow Example
def enrich_lead_list_emails(lead_list_id, max_prospects=100):
"""
Complete workflow: check cost, enrich, and verify results.
"""
# 1. Check how many prospects need enrichment
count_response = requests.get(
f"{BASE_URL}/public/lead-lists/{lead_list_id}/enrichment/count/",
headers={"X-API-Key": API_KEY},
params={"enrichment_type": "FIND_EMAIL"}
)
if not count_response.ok:
print(f"Error checking count: {count_response.text}")
return
count_data = count_response.json()
unenriched = count_data['unenriched_count']
if unenriched == 0:
print("✓ All prospects already have emails!")
return
print(f"Found {unenriched} prospects without emails")
# 2. Check if we have enough credits
if not count_data['has_enough_credits']:
print(f"❌ Need {count_data['total_cost']} credits, have {count_data['available_credits']}")
return
# 3. Limit to max_prospects if needed
to_enrich = min(unenriched, max_prospects)
# 4. Start enrichment
enrich_response = requests.post(
f"{BASE_URL}/public/lead-lists/{lead_list_id}/enrichment/",
headers={"X-API-Key": API_KEY},
json={
"enrichment_type": "FIND_EMAIL",
"prospect_limit": to_enrich
}
)
if not enrich_response.ok:
print(f"Error enriching: {enrich_response.text}")
return
enrich_data = enrich_response.json()
print(f"✓ Enriching {enrich_data['enriched_count']} prospects")
print(f"✓ {enrich_data['credits_deducted']} credits deducted")
print(f"✓ {enrich_data['remaining_credits']} credits remaining")
# 5. Wait a bit and check results
print("\nWaiting for enrichment to complete...")
time.sleep(30) # Wait 30 seconds
# 6. Get updated leads
leads_response = requests.get(
f"{BASE_URL}/public/lead-lists/{lead_list_id}/leads/",
headers={"X-API-Key": API_KEY},
params={"page": 1, "page_size": to_enrich}
)
leads = leads_response.json()['prospects']
enriched_count = sum(1 for lead in leads if lead.get('email') and '@' in lead['email'])
print(f"\n📊 Results:")
print(f" {enriched_count}/{to_enrich} prospects now have emails")
print(f" Success rate: {(enriched_count/to_enrich)*100:.1f}%")
# Use the function
enrich_lead_list_emails(123, max_prospects=100)
Monitoring Enrichment Progress
Since enrichment happens asynchronously, you can poll the lead list to check progress:
def wait_for_enrichment(lead_list_id, timeout=300):
"""
Poll the lead list until enrichment is complete or timeout.
"""
start_time = time.time()
while time.time() - start_time < timeout:
response = requests.get(
f"{BASE_URL}/public/lead-lists/{lead_list_id}/leads/",
headers={"X-API-Key": API_KEY},
params={"page": 1, "page_size": 100}
)
prospects = response.json()['prospects']
loading_count = sum(1 for p in prospects if p.get('email') == 'Loading...')
if loading_count == 0:
print("✓ Enrichment complete!")
return True
print(f"Still processing... ({loading_count} prospects remaining)")
time.sleep(10)
print("⚠ Timeout reached")
return False
Best Practices
- Check Cost First: Always use the count endpoint before enriching
- Start Small: Test with a small batch before enriching thousands
- Monitor Credits: Keep track of your credit balance
- Batch Processing: Enrich in batches rather than all at once
- Waterfall for Higher Success: Use
FIND_EMAIL_WATERFALL for better results (costs more)
- Phone Last: Phone enrichment is expensive (30 credits) - use sparingly
- Check Results: Poll the lead list to verify enrichment completed successfully