Leads - SMB Sales Boost API
Search, filter, and export leads from our database. Supports keyword filtering, location filtering, industry filtering, and pagination.
Lead Database
Every lead comes from the Main database (API value other), which covers small and medium businesses of all types. Contact info includes both phone numbers and email addresses. The database parameter is optional. Every value is accepted and resolves to the Main database, so existing integrations keep working unchanged.
How Search Works: Two-Phase Query Model
Phase 1 - Include (OR Logic)
All positive keywords and include terms are combined with OR logic. A lead matches if any positive keyword matches in any of the OR group search columns.
- Default OR group columns
- Registered URL, Crawled URL, Company Name, Categories (AI Enrichment)
Phase 2 - Exclude (AND Logic)
Negative keywords are checked against the same columns as positive keywords. A lead is excluded if any negative keyword matches in any of those columns.
URL Space-to-Wildcard
For URL columns, spaces in search terms are automatically replaced with % wildcards. For example, "dental clinic" becomes %dental%clinic% to match URLs like example.com/dental-clinic.
AI Category Estimation
Leads in the Main database are progressively enriched by AI with estimated business type categories. Each lead may include an aiCategoryEstimation field containing an array of 1-3 category names, or null if not yet classified.
Endpoints
GET /api/v1/leads- Search and filter leads. Requires at least one positive filter (positiveKeywords, nameIncludeTerms, etc.). While another export, search or push of your account is still recording its charge, the search waits up to 30 seconds, then answers 429
charge_in_progress(Retry-After: 30) with nothing charged. GET /api/v1/leads/preview- Preview leads with masked contact info (masked, not hashed: for example
(512) ***-**42andhel*@domain.com). Accepts the same filters as GET /api/v1/leads, including the contact term filters (emailPrimaryInclude, phonePrimaryInclude and the rest) and the company-column include, exclude and empty filters. Does not consume credits. Leads you already purchased come back unmasked (contactExported: true); pass excludePurchased=true to return only not-yet-purchased leads. POST /api/v1/leads/export- Export filtered leads to CSV, JSON, or XLSX. Subject to export rate limits. Supports credit-optimized ordering via maxCredits and maxResults parameters. Pass excludePurchased=true to export only not-yet-purchased leads. Each file's
datais plain UTF-8 text for csv and json files and base64 for xlsx files. Pass inline=false (body field or ?inline=false) to omit each file's body and receive a per-file exportId plus downloadUrl instead - the recommended shape for large exports. XLSX is capped at 20,000 rows per file; for larger runs use a csv export format, or an xlsx format with splitFiles true, splitMode max_rows, maxRowsPerFile of 20,000 or less and includeTotal false. Any xlsx export that would put more than 20,000 rows in one file (a single file, a split part, or the includeTotal file, which holds every lead) returns 400 export_too_large after the leads are charged and recorded as received. Do not simply repeat it: an export picks new leads first, so a repeat can charge for different leads. Re-run it with maxCredits 0 (and without excludePurchased) and a fixed format, which returns the leads you already have at no cost, or re-export them with POST /api/v1/lead-export-history/re-export. An export that is not finished within about 75 seconds answers 202 Accepted with a jobId and keeps running: the charge, your lead export history and the Export History files are written whether or not you collect the response. PollGET /api/v1/jobs/{jobId}for the full response, kept for up to 60 minutes after the export finishes (then 410job_result_expiredfor about a day, then 404job_not_found; the files stay in Export History for 90 days). Send anIdempotency-Keyheader with each export: repeating it with the same key returns the same job instead of exporting again. To get the result of a running export poll the job, never send the export again: a new export after this one finished (or with other arguments) picks new leads first and charges for them; an identical request while it runs returns the same job. If the answer is lost, check Export History first; a re-run with maxCredits 0 returns leads you already paid for at no charge. A 402insufficient_creditsdoes not use up the key: buy credits, then retry. A 429charge_in_progress(Retry-After: 30) means another export, lead search or push of your account was still recording its charge; nothing was charged. See Long-Running Requests. GET /api/v1/leads/other/schema-types- Returns a sorted list of all distinct website schema types found in the Main database. Use these values with the websiteSchemaFilter parameter on GET /api/v1/leads. The list is kept up to date in the background, so this normally answers at once; right after a server restart it waits up to 55 seconds (
Prefer: wait=N, counted from the request's arrival, sets a shorter wait) and can then answer 503schema_types_warmingwith Retry-After: 60 while the list is rebuilt.
Key Parameters
positiveKeywords (required), negativeKeywords, orColumns, stateInclude, stateExclude, cityInclude, cityExclude, zipInclude, zipExclude, streetInclude, streetExclude, minNumLocations, maxNumLocations, minRatingValue, maxRatingValue, minReviewCount, maxReviewCount (numeric ranges), buyingSignalTypeFilter, lastBuyingSignalFrom, lastBuyingSignalTo, sortBy, sortOrder, page, limit, database, and various column-specific include/exclude terms. Empty/non-empty filters per column are also supported via streetEmptyFilter, cityEmptyFilter, stateEmptyFilter, zipEmptyFilter plus phonePrimaryEmptyFilter, phoneTotalEmptyFilter, emailPrimaryEmptyFilter, emailTier1EmptyFilter through emailTier6EmptyFilter, descriptionEmptyFilter, and the new firmographic and technology columns such as employeeCountEmptyFilter, foundingDateEmptyFilter, isChainEmptyFilter, priceRangeEmptyFilter, legalNameEmptyFilter, industryNaicsEmptyFilter, dunsEmptyFilter, founderEmptyFilter, founderEmailEmptyFilter, founderPhoneEmptyFilter, openingHoursEmptyFilter, areaServedEmptyFilter, offersEmptyFilter, brandEmptyFilter, sloganEmptyFilter, logoUrlEmptyFilter, socialProfilesEmptyFilter, platformEmptyFilter, bookingOpsCrmSoftwareEmptyFilter, reputationChatSoftwareEmptyFilter, marketingEmailSoftwareEmptyFilter, adPixelsEmptyFilter, paymentFinancingSoftwareEmptyFilter, emailPrimaryMxEmptyFilter, emailDomainMxEmptyFilter, emailSecurityEmptyFilter, addressSourceEmptyFilter. The firmographic and technology columns from employeeCount through paymentFinancingSoftware also support include/exclude term filters (e.g. employeeCountInclude/employeeCountExclude, founderEmailInclude/founderEmailExclude); founder email and phone values stay masked until a lead is unlocked or exported. The Email Primary Provider, Website Email Provider, Website Email Security, and Address Source columns have no include/exclude terms; they use exact-value multi-choice matching via emailPrimaryMxValues, emailDomainMxValues, emailSecurityValues, and addressSourceValues - each a JSON array of exact values matched with IN semantics. Number of Job Postings uses minOpenPositions/maxOpenPositions, and the short description uses descriptionIncludeTerms/descriptionExcludeTerms. Each empty filter accepts 'any' | 'only_empty' | 'exclude_empty'.
Buying Signal Type Filtering
Every lead carries a Buying Signal Type list describing why its Last Buying Signal timestamp last changed. Filter on it with buyingSignalTypeFilter (comma-separated values). Values: Newly Added, Phone Primary, Total Phones, Email Primary, Tier 1 Emails, Tier 2 Emails, Address Full, plus per-source social profile signals - Instagram, LinkedIn, Facebook, YouTube, TikTok, X (Twitter), Google Maps, Yelp, Pinterest, and Other Social - recorded when a social profile for that source is added or changed for a business. Social profile changes also bump the lead's Last Buying Signal timestamp, so recently-active businesses surface under lastBuyingSignalFrom / lastBuyingSignalTo date filters. Last Buying Signal is also the default sort (sortBy=lastBuyingSignal).
The former names updateReasonFilter, lastUpdatedFrom, lastUpdatedTo and sortBy=lastUpdated are still accepted (ignored when the new name is also sent), and lead responses still include a deprecated Last Updated key with the same value as Last Buying Signal. Default-format export files (POST /api/v1/leads/export, Export History downloads, email schedule attachments) name these columns Last Buying Signal and Buying Signal Type in their CSV/XLSX headers and JSON keys; they no longer have Last Updated / Update Reason columns. To keep the old header names, export with a custom export format (formatId) that maps lastUpdated and lastUpdatedReason to the names you need.
Credit-Optimized Export Parameters
The export endpoint supports additional parameters for controlling credit usage:
maxLeads- Cap total leads exported. Leads over the cap, and new leads cut because credits ran short, are counted in the response's overflowCount and kept in the lead reservoir while it has room (one pool per account, shared with your email schedules, up to your plan's monthly credit allowance; leads that do not fit are not kept), then added to your next export that also sets maxLeads.
maxResults- Cap total results returned (both new and previously-exported leads). New leads are prioritized first, then previously-exported leads fill remaining slots.
maxCredits- Cap credits spent on this export. Only new (credit-consuming) leads count toward this cap. The export is also capped at your spendable balance, so the effective cap is the smaller of the two. Set to 0 to only receive previously-exported leads at no credit cost.
excludePurchased- When true, export only leads you have not purchased yet (already-exported leads, matched by lead id or shared contact point, are skipped). Credit and dedup math are unchanged. Default false.
On credit plans, GET /api/v1/leads and POST /api/v1/leads/export always return leads in credit-optimized order: new leads (credit-consuming) sorted first, then previously-exported leads, each group sorted by Last Buying Signal descending (or your custom sort). New leads are cut to the smaller of maxCredits and your spendable balance (credit balance plus any overage-budget headroom); when the balance was the limit the response has the X-Credits-Capped: true header, so omitting maxCredits caps the request at your balance instead of failing. 402 insufficient_credits only happens if a concurrent request spends the balance between the check and the charge.
What Costs a Credit
Each new lead returned by GET /api/v1/leads or POST /api/v1/leads/export costs 1 credit. Charging is sticky: a lead you have already received through any channel (dashboard, API, MCP or email schedule) is never charged again, even if its data changed later, and a new lead that shares a primary phone or primary email with a lead you already received is also free.
Purchased-Lead Reveal on Preview
The preview endpoint reveals leads you have already purchased: any preview lead that matches a prior export (by lead id or by a shared phone or email contact point) is returned unmasked with contactExported: true, the same as on the dashboard. Leads you have not bought stay masked. Pass excludePurchased=true on preview to return only not-yet-purchased leads. A shared contact point here includes the lead's Total Phones and Email Tier values, while charging compares primary phone and primary email only, so a lead revealed only through one of those lists can still cost a credit.
API Documentation Sections
Introduction | Programmatic Purchase | Authentication | Rate Limits | Long-Running Requests | User Profile | Enrichments | Leads | Filter Presets | Keyword Lists | Email Schedules | Export Formats | Export History | Lead Export History | Account Settings | AI Features | Export Blacklist | Error Handling | Credits & Subscription | MCP Server | Integrations
Ready to Find Your Next Customers? Get access to growing local business leads updated every 5 minutes. See plans starting at $49/mo →