Skip to content

API quickstart

This walks the path most integrations take: count → browse → reveal → export. Steps 1 and 2 are free. Set your key once:

Terminal window
export LS_KEY="ls_live_your_key_here"
  1. Count — free. Check how many people match before you spend anything.

    Terminal window
    curl https://app.leadsonar.io/api/v1/leads/search \
    -H "X-API-Key: $LS_KEY" -H "Content-Type: application/json" \
    -d '{
    "jobTitles": ["Head of Sales"],
    "exactMatch": true,
    "industryNames": ["Software Development"],
    "companySizes": ["51-200"],
    "countryCodes": ["US"]
    }'
    {
    "firmographic_total": 179984,
    "firmographic_is_exact": true,
    "estimated_total": 382,
    "basis": "sampled",
    "note": "estimated_total is sampled: keyword/role/department filters are applied per row and cannot be counted upstream. Plan exports around estimated_total.",
    "narrowed_by": null,
    "keywords": null,
    "filters": { "jobTitles": ["Head of Sales"], "exactMatch": true, "industryNames": ["Software Development"], "companySizes": ["51-200"], "countryCodes": ["US"], "matchAny": false }
    }

    firmographic_total counts the companies-side filters exactly. estimated_total is the number to plan with — it applies job titles too, from a sample. filters echoes what the server understood; check it whenever a count looks wrong.

  2. Browse — free. Page through matching people with contact details masked.

    Terminal window
    curl https://app.leadsonar.io/api/v1/leads/browse \
    -H "X-API-Key: $LS_KEY" -H "Content-Type: application/json" \
    -d '{ "jobTitles": ["Head of Sales"], "exactMatch": true, "countryCodes": ["US"], "companySizes": ["51-200"], "limit": 25 }'
    {
    "page": 1, "limit": 25, "returned": 25, "next_page": 2,
    "leads": [
    {
    "id": "3f1c2a90-0000-4000-8000-000000000001",
    "firstName": "Jordan", "jobTitle": "Head of Sales",
    "companyName": "Example Software Inc.", "companySize": "101 to 250",
    "industryName": "Software Development", "seniority": "Director",
    "city": "Austin", "state": "TX", "countryCode": "US",
    "email": "•••@•••.com", "phone": "+151****10"
    }
    ]
    }

    Keep the id of each lead you want. People you’ve already revealed don’t appear here.

  3. Reveal — 1 credit per new lead. Unlock the leads you picked (send their ids).

    Terminal window
    curl https://app.leadsonar.io/api/v1/leads/reveal \
    -H "X-API-Key: $LS_KEY" -H "Content-Type: application/json" \
    -d '{ "leadIds": ["3f1c2a90-0000-4000-8000-000000000001"] }'
    { "revealed": [ { "id": "3f1c2a90-…", "email": "jordan@example-software.com", "…": "…" } ],
    "credits_charged": 1, "new_reveals": 1, "already_revealed": 0 }

    Revealing the same lead again returns "credits_charged": 0, "already_revealed": 1.

  4. Export — for bulk. Instead of revealing page by page, export everyone matching your filters as a CSV (up to 50,000 per export).

    Terminal window
    curl https://app.leadsonar.io/api/v1/leads/exports \
    -H "X-API-Key: $LS_KEY" -H "Content-Type: application/json" \
    -d '{ "jobTitles": ["Head of Sales"], "exactMatch": true, "countryCodes": ["US"], "companySizes": ["51-200"], "limit": 500 }'
    { "job_id": "4fad85cd-3e37-4797-ab77-07ed02d8f408", "status": "queued", "requested_limit": 500, "capped_to_max": null,
    "poll": "/api/v1/leads/exports/4fad85cd-3e37-4797-ab77-07ed02d8f408",
    "download": "/api/v1/leads/exports/4fad85cd-3e37-4797-ab77-07ed02d8f408/csv" }

    Poll until status is completed, then download:

    Terminal window
    curl https://app.leadsonar.io/api/v1/leads/exports/4fad85cd-3e37-4797-ab77-07ed02d8f408 -H "X-API-Key: $LS_KEY"
    # {"id":"4fad85cd-…","status":"completed","progress":100,"deliveredRows":500,"creditsCharged":500,"downloadable":true,…}
    curl -o leads.csv https://app.leadsonar.io/api/v1/leads/exports/4fad85cd-3e37-4797-ab77-07ed02d8f408/csv -H "X-API-Key: $LS_KEY"

    The CSV columns: First Name, Last Name, Email, Phone, Company, Domain, Job Title, Seniority, Department, Industry, Country, State, City, Company Size, LinkedIn.

Unknown filter values don’t raise an error — they just match nothing. Ask the API for the real values:

Terminal window
curl "https://app.leadsonar.io/api/v1/leads/filters" -H "X-API-Key: $LS_KEY"
# {"filters":["industry","seniority","country","department","company_size","revenue","companyType"], ...}
curl "https://app.leadsonar.io/api/v1/leads/filters?field=seniority" -H "X-API-Key: $LS_KEY"
# {"field":"seniority","values":[{"value":"Staff","count":"46030856"},{"value":"Manager",...},{"value":"Cxo",...},{"value":"Director",...},{"value":"Vp",...}]}

jobTitles, excludeTitles, includeKeywords and excludeKeywords are free text and have no fixed list. For company size you can send either the app’s bands ("51-200") or the raw buckets the filters endpoint lists ("51 to 100", "101 to 250").