Skip to main content

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

ParameterTypeRequiredDefaultDescription
enrichment_typestringNoFIND_EMAILType: FIND_EMAIL, FIND_EMAIL_WATERFALL, or FIND_PHONE
prospect_limitintegerNo100Maximum number of prospects to enrich
modestringNoasyncEither sync (return results immediately) or async (background processing)
webhook_urlstringNonullURL to send results to when enrichment completes (async mode only)
filtersobjectNo{}Additional filters to apply
sort_fieldstringNoidField to sort by
sort_directionstringNoascSort direction (asc or desc)

Enrichment Types

TypeDescriptionCost per LeadWhen to Use
FIND_EMAILBasic email finding3 creditsFast, cost-effective email discovery
FIND_EMAIL_WATERFALLMulti-provider email finding6 creditsHigher success rate, more comprehensive
FIND_PHONEPhone number finding30 creditsMobile 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

FieldTypeDescription
successbooleanWhether the enrichment was initiated successfully
modestringsync or async
enrichment_typestringThe enrichment type used
enriched_count / total_countintegerNumber of prospects enriched
success_countinteger(Sync only) Number of successfully enriched prospects
credits_deductedintegerTotal credits deducted
remaining_creditsintegerYour remaining credit balance
webhook_urlstring(Async only) Webhook URL if provided
resultsarray(Sync only) Enrichment results for each prospect

How It Works

  1. Validation: Checks if you have enough credits
  2. Credit Deduction: Deducts credits upfront from your account
  3. Status Update: Sets prospects to “Loading…” status
  4. Background Processing: Enrichment happens asynchronously
  5. 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"
  }'

Sync Mode (Immediate Results)

# 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

Python Example: Sync Mode (Immediate Results)

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

  1. Check Cost First: Always use the count endpoint before enriching
  2. Start Small: Test with a small batch before enriching thousands
  3. Monitor Credits: Keep track of your credit balance
  4. Batch Processing: Enrich in batches rather than all at once
  5. Waterfall for Higher Success: Use FIND_EMAIL_WATERFALL for better results (costs more)
  6. Phone Last: Phone enrichment is expensive (30 credits) - use sparingly
  7. Check Results: Poll the lead list to verify enrichment completed successfully