Successful response
Lusha API Documentation
This is the Lusha API V3 documentation.
V3 introduces a new search-then-enrich pattern, bulk operations, AI-powered lookalikes, and richer filter capabilities. All endpoints are under
https://api.lusha.com/v3/.For more information on V3, refer to the Migration Guide.
Lusha provides a RESTful API for querying a comprehensive dataset of business profiles and company information. Built for teams running prospecting, enrichment, automation, and analytics workflows that need accurate, continuously updated business data. The API supports both real-time and bulk use cases.
Use the Lusha API to search for new prospects, enrich existing records, react to real-world changes, and expand coverage with AI-powered lookalike recommendations.
All API requests must be made over HTTPS. All responses are returned in JSON format.
| Category | Description |
|---|---|
| Search | Find contacts or companies using known identifiers |
| Enrich | Retrieve full profile data for contacts or companies by ID |
| Search & Enrich | Find and retrieve full contact or company data in a single call |
| Prospecting | Filter-based search across contacts and companies |
| Lookalikes | AI-powered recommendations for similar contacts and companies |
| Signals | Real-world activity data for contacts and companies |
| Filters | Discover valid filter values for prospecting |
| Webhooks | Real-time signal notifications via HTTP callbacks |
| Account | Usage, credits, rate limits, and pricing |
Lusha is a search platform. The data provided is not created or directly managed by Lusha. It is sourced from publicly available information and trusted business partners.
For more details on how we collect and handle data, see our Privacy Policy.
All API requests require an API key linked to your Lusha account and plan. Pass your key in the api_key request header on every call.
Generate and manage your API key in the Lusha dashboard.
Store your API key securely and use it only in server-side environments.
Lusha enforces rate limits to ensure fair usage and protect against excessive load.
| Scope | Limit |
|---|---|
| General endpoints | 25 requests per second |
| Credit Usage API | 5 requests per minute |
Rate limits may vary by account type and plan. Contact your account manager or Lusha support if you frequently hit limits.
Rate Limit Response Headers
| Header | Description |
|---|---|
x-rate-limit-daily | Total requests allowed per day |
x-daily-requests-left | Requests remaining in your daily quota |
x-daily-usage | Requests made in the current daily period |
x-rate-limit-hourly | Total requests allowed per hour |
x-hourly-requests-left | Requests remaining in your hourly quota |
x-hourly-usage | Requests made in the current hourly period |
x-rate-limit-minute | Total requests allowed per minute |
x-minute-requests-left | Requests remaining in the current minute window |
x-minute-usage | Requests made in the current minute window |
Lusha uses standard HTTP status codes to indicate the result of each request.
| Code | Name | Description |
|---|---|---|
200 | OK | Request was successful |
400 | Bad Request | Request is malformed or missing required fields |
401 | Unauthorized | API key is missing or invalid |
402 | Payment Required | Insufficient credits or payment needed |
403 | Forbidden | Account is inactive. Contact support@lusha.com |
404 | Not Found | Endpoint or resource does not exist |
429 | Too Many Requests | Rate limit or daily quota exceeded |
451 | Unavailable For Legal Reasons | Request blocked due to GDPR regulations |
499 | Client Closed Request | Request timed out before completing |
5XX | Server Error | Issue on Lusha's end. Retry with exponential backoff |
Error Response Format
{
"statusCode": 400,
"message": "Invalid request parameters"
}Tips for Handling Errors
- Verify your API key is correct and active
- Read the
messagefield for specific troubleshooting details - For
429errors, wait before retrying - For
5XXerrors, use exponential backoff before retrying
Search
Search APIs: Find contacts or companies using known identifiers.
Look up contacts by id, linkedinUrl, email, or firstName + lastName + companyName/companyDomain. Look up companies by id, name, or domain.
Returns a non-PII preview of each profile with a has field listing available data points and a canReveal field showing what can be unlocked via Enrich.
Billing: Charged per successful result via the
api_searchaction.
Request
Reveal full contact data for contacts you've already found via Search Contacts.
Pass up to 100 contact ids (from the search response). Use the reveal field to control what gets unlocked:
emails— work and personal email addressesphones— mobile and direct phone numbers- Omit
revealto get both by default
Tip: If
canReveal.creditsis0in the search response, that data has already been revealed for your account — re-enriching it is free.
Billing: Charged per revealed field (email or phone) via per-datapoint pricing.
- Mock serverhttps://docs.lusha.com/_mock/apis/openapi/v3/contacts/enrich
- Production serverhttps://api.lusha.com/v3/contacts/enrich
- curl
- JavaScript
- Node.js
- Python
- Java
- C#
- PHP
- Go
- Ruby
- R
- Payload
curl -i -X POST \
https://docs.lusha.com/_mock/apis/openapi/v3/contacts/enrich \
-H 'Content-Type: application/json' \
-H 'api_key: YOUR_API_KEY_HERE' \
-d '{
"ids": [
"4389064654",
"4389064624"
],
"reveal": [
"emails",
"phones"
]
}'{ "requestId": "71581363-f73d-46e1-9115-ecbd771b964b", "results": [ { … } ], "billing": { "creditsCharged": 2, "resultsReturned": 2 } }
Request
Reveal full company data for companies you've already found via Search Companies.
Pass up to 100 company ids (from the search response). Each enriched result includes:
- Firmographics: size, revenue range, year founded, company type
- Industry: primary industry, sub-industry, SIC/NAICS codes
- Locations: HQ and additional office sites
- Technologies, funding rounds, buyer intent topics
- LinkedIn followers, logo URL, social links
Billing: Charged per successful result via the
reveal_companyaction.
Company IDs from search results (strings)
Additional data fields to reveal. Each field is charged separately per result.
employeesByDepartment— breakdown of employees by departmentemployeesByLocation— breakdown of employees by country/stateemployeesBySeniority— breakdown of employees by seniority levelcompetitors— list of competitor company IDsintent— buyer intent topics
- Mock serverhttps://docs.lusha.com/_mock/apis/openapi/v3/companies/enrich
- Production serverhttps://api.lusha.com/v3/companies/enrich
- curl
- JavaScript
- Node.js
- Python
- Java
- C#
- PHP
- Go
- Ruby
- R
- Payload
curl -i -X POST \
https://docs.lusha.com/_mock/apis/openapi/v3/companies/enrich \
-H 'Content-Type: application/json' \
-H 'api_key: YOUR_API_KEY_HERE' \
-d '{
"ids": [
"16303253",
"12790225"
],
"reveal": [
"employeesByLocation",
"employeesByDepartment",
"employeesBySeniority",
"competitors",
"intent"
]
}'{ "requestId": "5e8f5993-a0a3-4510-bc90-7b4506272c68", "results": [ { … }, { … } ], "billing": { "creditsCharged": 10, "resultsReturned": 2 } }
Search & Enrich
Search & Enrich APIs: Find and retrieve full contact or company data in a single call.
Combines Search and Enrich into one request. Provide identifiers and control what gets revealed via the reveal field.
Billing: Two charges apply — one for the search (
api_search) and one per revealed field.
Prospecting
Prospecting APIs: Filter-based search for contacts and companies.
Use prospecting to find new records that match your Ideal Customer Profile (ICP). Apply rich filters across:
- Contact attributes: title, seniority, location, signals
- Company attributes: size, revenue, industry, technologies, intent
Results are paginated: up to 1,000 pages x 50 results = 50,000 results per query.
Billing: Uses the capture/charge model with
api_searchactions. Signal charges apply additionally.
Signals
Real-world activity data for contacts and companies.
Signals are available as standalone endpoints or as an optional signals filter on Search and Prospecting endpoints.
Contact signal types: promotion, companyChange, allSignals
Company signal types: headcountIncrease1m/3m/6m/12m, headcountDecrease1m/3m/6m/12m, surgeInHiring, surgeInHiringByDepartment, surgeInHiringByLocation, websiteTrafficIncrease, websiteTrafficDecrease, itSpendIncrease, itSpendDecrease, riskNews, commercialActivityNews, corporateStrategyNews, financialEventsNews, peopleNews, marketIntelligenceNews, productActivityNews, allSignals
Credits are charged per matched signal per result via showSignalsContact or showSignalsCompany.
Filters
Filter APIs: Retrieve available filter values for prospecting.
Use the discovery endpoints to list all available filter types, then fetch valid values for a specific filter type before building a prospecting request.
Contact filter types: departments, seniority, existingDataPoints, countries, locations
Company filter types: names, sizes, revenues, locations, sics, naics, industriesLabels, intentTopics, technologies
Webhooks
Subscribe to real-time notifications when contacts change jobs or companies experience key business events.
Webhooks deliver HTTP POST requests to your endpoints when signals occur - from promotions and job changes to company growth.
For a full list of available signals, refer to Signal Options.
Key Features:
- Real-time contact & company signal notifications
- Bulk subscription management (up to 25 items per request)
- Secure delivery with HMAC-SHA256 signatures
- Delivery monitoring with audit logs
Available Endpoints:
| Method | Endpoint | Purpose |
|---|---|---|
| POST | /api/subscriptions | Create subscriptions (bulk supported) |
| GET | /api/subscriptions | List all subscriptions |
| GET | /api/subscriptions/{id} | Get subscription by ID |
| PATCH | /api/subscriptions/{id} | Update subscription |
| POST | /api/subscriptions/delete | Delete subscriptions (bulk supported) |
| POST | /api/subscriptions/{id}/test | Test subscription delivery |
| GET | /api/audit-logs | Get webhook delivery logs |
| GET | /api/audit-logs/stats | Get delivery statistics |
| GET | /api/account/secret | Get account webhook secret |
| POST | /api/account/secret/regenerate | Regenerate account secret |
| POST | /api/subscriptions/opt-out | Subscribe to contact opt-out notifications |
Webhook Delivery Acknowledgment: When receiving webhook deliveries (POST requests), your endpoint must acknowledge with a specific response format. See the Create Subscription endpoint for the required acknowledgment structure.
Rate Limits
| Operation | Limit |
|---|---|
| API Requests | 100 requests/minute per account |
| Create Subscriptions | 25 items per request |
| Delete Subscriptions | 25 items per request |
Security & Verification
HTTPS Requirement:
- Production webhook URLs must use HTTPS
- HTTP URLs are not accepted
Signature Verification:
All webhook deliveries include an X-Lusha-Signature header containing an HMAC-SHA256 signature. Verify this signature to ensure the request is from Lusha:
- Extract the
X-Lusha-SignatureandX-Lusha-Timestampheaders - Concatenate:
timestamp + "." + JSON.stringify(payload) - Compute HMAC-SHA256 using your webhook secret
- Compare the computed signature with the received signature
Example (Node.js):
const crypto = require('crypto');
function verifySignature(payload, signature, timestamp, secret) {
const signedPayload = `${timestamp}.${JSON.stringify(payload)}`;
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(signedPayload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
);
}Security Best Practice: Always verify webhook signatures to prevent spoofed requests.
Credits & Billing
Credit Charges:
- Credits are charged when signals are detected and delivered to your webhook
- The
creditsChargedfield in the webhook payload indicates how many credits were used - Credits are deducted from your account balance per signal type
No Duplicate Charges:
- Each signal is delivered once and charged once
- Webhook delivery retries do not incur additional charges
Error Response Format
All error responses follow this format:
{
"statusCode": 400,
"message": "Validation failed",
"errors": ["entityType must be one of: contact, company"]
}| Field | Type | Description |
|---|---|---|
statusCode | number | HTTP status code |
message | string | Error message |
errors | string[] | Detailed error messages (optional) |