# Lusha API Documentation
Lusha provides a RESTful API that allows you to query a comprehensive dataset of business profiles and company information.
It is designed for teams building prospecting, enrichment, automation, and analytics workflows that require accurate, continuously updated business data. The API supports both real-time and bulk use cases and is suitable for production environments.
Use the Lusha API to search for new prospects, enrich existing records, react to real-world changes, and expand coverage using lookalike recommendations.
*All API requests should be made over HTTPS (SSL), and the response bodies are delivered in JSON format.*
---
Person
https://api.lusha.com/v2/person
▶ Common Use Cases
- • Form enrichment
- • CRM completion
- • Outbound personalization
Company
https://api.lusha.com/v2/company
▶ Common Use Cases
- • Account enrichment
- • Routing, scoring, territory logic
- • Market analysis & segmentation
Signals
https://api.lusha.com/v2/signals
▶ Common Use Cases
- • Job change tracking
- • Company updates signals
- • News event alerts
Lookalikes
https://api.lusha.com/v2/recommendations
▶ Common Use Cases
- • Market expansion
- • Similar account discovery
- • Prospect recommendations
Webhooks API
NEW
Subscribe to real-time notifications when contacts change jobs or companies experience key business events.
View Documentation →
---
**Data Source and Privacy**
Please note that **Lusha is a search platform**, meaning the data provided is not created or directly managed by us. Instead, it is retrieved from publicly available sources and through contributions from trusted business partners.
For more information on how we collect, use, and handle business profiles, please refer to our [Privacy Policy](https://lusha.com/legal/privacy-notice/).
----
## Authentication
API keys are required for all API and MCP requests and are tied to your Lusha account and plan. To access the Lusha API, you must authenticate your requests using your API key. This key is unique to your account and is used to identify your usage of the API.
How to Authenticate:
When making an API call, include your API key in the `api_key` header of the
request.
> You can generate and retrieve your API key [here](https://dashboard.lusha.com/enrich/api).
API keys should be stored securely and used only in server-side environments.
---
### Rate Limiting
Lusha API enforces rate limiting to ensure fair usage and protect against excessive load.
- **General Rate Limit**: You can make up to 25 requests per second to each API endpoint
- **Credit Usage API**: Has a specific rate limit of 5 requests per minute
> **Note**: Rate limits may vary based on your account type and subscription plan.
If you're encountering rate limit issues frequently, please consult with your
account manager or Lusha support team to discuss your specific needs.
**Rate Limit Headers**
To monitor your current rate limit status, check the HTTP response headers in your API calls:
| Header | Description |
|--------|-------------|
| `x-rate-limit-daily` | The total number of requests allowed per day under your current plan |
| `x-daily-requests-left` | The number of requests remaining in your daily quota |
| `x-daily-usage` | The number of requests you have made in the current daily period |
| `x-rate-limit-hourly` | The total number of requests allowed per hour under your current plan |
| `x-hourly-requests-left` | The number of requests remaining in your hourly quota |
| `x-hourly-usage` | The number of requests you have made in the current hourly period |
| `x-rate-limit-minute` | The total number of requests allowed per minute under your current plan |
| `x-minute-requests-left` | The number of requests remaining in your current minute window |
| `x-minute-usage` | The number of requests you have made in the current minute window |
**Notes on API Rate Limiting**
- If you exceed the rate limit, the API will return a 429 (Too Many Requests) error.
- To ensure a smooth experience, respect the rate limits defined by your subscription tier.
- Daily limits vary based on your billing plan — higher tiers have higher quotas.
- You can programmatically track your usage through these response headers:
- `X-RateLimit-Remaining-Daily`
- `X-RateLimit-Reset-Daily`
- It is strongly recommended to implement logic that:
- Monitors these headers
- Pauses or retries requests accordingly
- Helps avoid hitting the limit and ensures reliable operation
---
## Error Codes
Lusha API uses standard HTTP response codes to indicate the status of your request. These codes help you understand whether the request was successful or if there was an issue.
| Status Code | Name | Description |
|-------------|------|-------------|
| **200** | OK | Successful request |
| **400** | Bad Request | Badly formatted request |
| **401** | Unauthorized | The API key is invalid |
| **402** | Payment Required | Your account requires payment |
| **403** | Forbidden | Your account is not active. Please reach out to support at *support@lusha.com* for assistance |
| **403** | Forbidden | Your pricing version does not support requesting individual datapoints [revealEmails, revealPhones] |
| **404** | Not Found | The requested endpoint was not found |
| **412** | Precondition Failed | The request failed due to invalid syntax that was provided. Please make sure to send a full name field that contains a valid first & last name |
| **429** | Too Many Requests | You've reached your trial limit, please contact support for upgrade |
| **429** | Too Many Requests | Daily API quota limit exceeded. Limit X calls per day |
| **429** | Too Many Requests | Hourly API rate limit exceeded. Limit: X calls per hour. Reset in X seconds |
| **451** | Unavailable For Legal Reasons | We are unable to process this contact request due to our GDPR regulations |
| **499** | Client Closed Request | Request failed due to request timeout |
| **5XX** | Server Error | There's a problem on Lusha's end |
**Error Response Format**
In case of an error, the response body will contain details about the error:
```json
{
"error": {
"code": 400,
"message": "Invalid request parameters"
}
}
```
Handling errors
- Always ensure your API key is correct and valid
- Pay attention to the specific error message and code to troubleshoot issues efficiently
- Implement proper error handling and retry logic in your application
- For 5XX errors, implement exponential backoff before retrying
---
License: Proprietary
## Servers
Production server
```
https://api.lusha.com
```
## Security
### ApiKeyAuth
Your Lusha API key. You can find this in your Lusha dashboard under API settings.
Include this key in the `api_key` header for all requests.
Type: apiKey
In: header
Name: api_key
## Download OpenAPI description
[Lusha API Documentation](https://docs.lusha.com/_bundle/apis/openapi.yaml)
## Enrichment
**What is enrichment?**:
Enrichment is the process of adding missing or updated data to existing contact or company records.
Use enrichment to:
- Complete CRM records
- Improve outbound accuracy and deliverability
- Keep records current as people and companies change
> Enrichment can be performed in real time or in bulk, depending on the endpoint and use case.
**Available enrichment APIs**
Person enrichment:
- [**Search single contact**](/apis/openapi/enrichment/searchsinglecontact) - Enrich one contact at a time
- [**Search multiple contacts**](/apis/openapi/enrichment/searchmultiplecontacts) - Bulk enrich contacts
Company enrichment:
- [**Search a single company**](/apis/openapi/enrichment/searchsinglecompanyv2) - Enrich one company at a time
- [**Search multiple companies**](/apis/openapi/enrichment/searchmultiplecompaniesv2) - Bulk enrich companies
### Search Single Contact
- [GET /v2/person](https://docs.lusha.com/apis/openapi/enrichment/searchsinglecontact.md): Find and enrich a single contact using various search criteria. You can search by name, email,
LinkedIn URL, or company information.
>##### Endpoint
GET https://api.lusha.com/v2/person
>##### Search Requirements
You must provide either:
- personId OR
- email OR
- linkedinUrl OR
- firstName AND lastName AND (companyName OR companyDomain)
>##### Notes:
- Provide as much information as possible for better results
- Using personId provides the most direct way to retrieve contact information, as it uniquely identifies a contact in Lusha's database.
- Use refreshJobInfo=true to get the latest employment data
- Use filterBy parameter to specify what contact details you need
- Include the signals parameter to retriever contact signals (If no signals data is found for the specified period, the signals object will be empty but still present in the response.)
- When requesting signals, you can optionally specify a start date using signalsStartDate.
- Signals data is optional. If you don't include the signals parameter, no signals data will be returned.
---
⚠️ Important Notice - Unified Credits Plan Required
| Parameter | Requirement |
|-----------|-------------|
| revealEmails and revealPhones | Only available to customers on the Unified Credits pricing plan |
| Plan Restriction | Attempting to use these parameters on other plans will result in a 403 Unauthorized error |
| Default Behavior | When neither parameter is used, the API returns both email addresses and phone numbers, if available |
---
### Search Multiple Contacts
- [POST /v2/person](https://docs.lusha.com/apis/openapi/enrichment/searchmultiplecontacts.md): Enrich multiple contacts in a single request. This endpoint allows you to submit a list of contacts
and receive enriched data for each one, including company information.
>##### Endpoint:
POST https://api.lusha.com/v2/person
>##### Notes
- You can process up to 100 contacts per request.
- Using personId provides the most direct way to retrieve contact information.
- At least one of email, linkedinUrl, or company/domain with fullName is required.
---
⚠️ Important Notice - Unified Credits Plan Required
| Parameter | Requirement |
|-----------|-------------|
| revealEmails and revealPhones | Only available to customers on the Unified Credits pricing plan |
| Plan Restriction | Attempting to use these parameters on other plans will result in a 403 Unauthorized error |
| Default Behavior | When neither parameter is used, the API returns both email addresses and phone numbers, if available |
---
### Search Single Company
- [GET /v2/company](https://docs.lusha.com/apis/openapi/enrichment/searchsinglecompanyv2.md): Find detailed information about a single company by using different paramaters.
>##### Endpoint:
GET https://api.lusha.com/v2/company
>##### Notes:
- At least one of domain, company, or companyId is required.
### Search Multiple Companies
- [POST /v2/company](https://docs.lusha.com/apis/openapi/enrichment/searchmultiplecompaniesv2.md): Search for multiple companies in a single request. Provide a list of companies with
identifiers like domain names or company IDs.
>##### Endpoint:
POST https://api.lusha.com/bulk/company/v2
>##### Notes:
- At least one of domain, company, or companyId is required.
- You can process up to 100 companies per request.
## Prospecting - Search & Enrich
With Lusha's Prospecting API, you can query Lusha's extensive database based on specific criteria (such as job title, seniority, location, and more) to retrieve detailed contact and company information.
The Prospecting API is designed to help you generate new records (contacts or companies) for your CRM system, using filters that align with your Ideal Customer Profile (ICP).
This process involves three main steps:
| Step | API | Description |
|------|-----|-------------|
| 1 | **Filters API** | Apply filters to refine your search *(Check available filters under [Contact](/apis/openapi/contact-filters) and [Company](/apis/openapi/company-filters) Filters)*|
| 2 | **Search API** | Query [Contacts](/apis/openapi/prospecting-search-and-enrich/searchprospectingcontacts) or [Companies](/apis/openapi/prospecting-search-and-enrich/searchprospectingcompanies) using the available filters |
| 3 | **Enrich API** | Get full details of [Contacts](/apis/openapi/prospecting-search-and-enrich/enrichprospectingcontacts) and [Companies](/apis/openapi/prospecting-search-and-enrich/enrichprospectingcompanies) from the search results |
### Search Contacts
- [POST /prospecting/contact/search](https://docs.lusha.com/apis/openapi/prospecting-search-and-enrich/searchprospectingcontacts.md): Search for contacts using various filters. This is step 2 of the prospecting process.
Endpoint: (POST) https://api.lusha.com/prospecting/contact/search
---
##### Signal Filtering (Premium Feature)
Filter contacts by signal types to find prospects at key career moments.
> Note: This is a premium feature. Credits are charged for each signal type that returns results.
### Search Companies
- [POST /prospecting/company/search](https://docs.lusha.com/apis/openapi/prospecting-search-and-enrich/searchprospectingcompanies.md): Search for companies using various filters. This is step 2 of the prospecting process.
Endpoint: (POST) https://api.lusha.com/prospecting/company/search
---
##### Signal Filtering (Premium Feature)
Filter companies by signal types to identify those with recent business events and changes.
> Note: This is a premium feature. Credits are charged for each signal type that returns results.
### Enrich Companies
- [POST /prospecting/company/enrich](https://docs.lusha.com/apis/openapi/prospecting-search-and-enrich/enrichprospectingcompanies.md): Enrich companies from search results. This is step 3 of the prospecting process.
Endpoint: (POST) https://api.lusha.com/prospecting/company/enrich
## Contact Filters
Available filters for contact searches
### Departments
- [GET /prospecting/filters/contacts/departments](https://docs.lusha.com/apis/openapi/contact-filters/getcontactdepartments.md): Get list of available departments for contact filtering
### Seniority
- [GET /prospecting/filters/contacts/seniority](https://docs.lusha.com/apis/openapi/contact-filters/getcontactseniority.md): Get list of available seniority levels for contact filtering
### Data Points
- [GET /prospecting/filters/contacts/existing_data_points](https://docs.lusha.com/apis/openapi/contact-filters/getcontactdatapoints.md): Get list of available data points for contact filtering
### Countries
- [GET /prospecting/filters/contacts/all_countries](https://docs.lusha.com/apis/openapi/contact-filters/getcontactcountries.md): Get list of all available countries for contact filtering
### Locations
- [POST /prospecting/filters/contacts/locations](https://docs.lusha.com/apis/openapi/contact-filters/searchcontactlocations.md): Search for locations by text for contact filtering
## Company Filters
Available filters for company searches
### Names
- [POST /prospecting/filters/companies/names](https://docs.lusha.com/apis/openapi/company-filters/searchcompanynames.md): Search for company names by text
### Industries
- [GET /prospecting/filters/companies/industries_labels](https://docs.lusha.com/apis/openapi/company-filters/getcompanyindustries.md): Get list of available industries for company filtering
### Sizes
- [GET /prospecting/filters/companies/sizes](https://docs.lusha.com/apis/openapi/company-filters/getcompanysizes.md): Get list of available company size ranges
### Revenues
- [GET /prospecting/filters/companies/revenues](https://docs.lusha.com/apis/openapi/company-filters/getcompanyrevenues.md): Get list of available revenue ranges
### Locations
- [POST /prospecting/filters/companies/locations](https://docs.lusha.com/apis/openapi/company-filters/searchcompanylocations.md): Search for company locations by text
### SIC Codes
- [GET /prospecting/filters/companies/sics](https://docs.lusha.com/apis/openapi/company-filters/getcompanysiccodes.md): Get list of available SIC codes
### NAICS Codes
- [GET /prospecting/filters/companies/naics](https://docs.lusha.com/apis/openapi/company-filters/getcompanynaicscodes.md): Get list of available NAICS codes
### Intent Topics
- [GET /prospecting/filters/companies/intent_topics](https://docs.lusha.com/apis/openapi/company-filters/getcompanyintenttopics.md): Get list of available intent topics
### Technologies
- [POST /prospecting/filters/companies/technologies](https://docs.lusha.com/apis/openapi/company-filters/searchcompanytechnologies.md): Search for technologies by text
## Signals
With Lusha’s Signals API, you can enrich your contacts and companies with timely insights that highlight key account and prospect changes. Signals help you identify moments of opportunity - from job moves and promotions to company growth and new initiatives - so you can engage prospects and customers at exactly the right time. Easily integrate signal data into enrichment flows, CRM systems, or automation workflows to keep pipelines and customer records always up to date.
### Get Signal Options
- [GET /api/signals/filters/{objectType}](https://docs.lusha.com/apis/openapi/signals/getsignaloptions.md): Retrieve available signal options for a specific entity type (contact or company).
This endpoint returns the list of signal types you can filter by when enriching contacts or companies.
Endpoints:
* Contacts: GET /api/signals/filters/contact
* Companies: GET /api/signals/filters/company
### Available Signal Types
#### For contacts:
* allSignals - All available contact signal types
* promotion - Job title promotions
* companyChange - Company changes
---
#### For companies:
* allSignals - All available company signal types
Hiring & Workforce:
* surgeInHiring - Overall hiring activity increase
* surgeInHiringByDepartment - Department-specific hiring surges
* surgeInHiringByLocation - Location-specific hiring surges
Headcount Trends:
| Signal | Description |
|--------|-------------|
| headcountIncrease1m / headcountDecrease1m | 1-month employee count changes |
| headcountIncrease3m / headcountDecrease3m | 3-month employee count changes |
| headcountIncrease6m / headcountDecrease6m | 6-month employee count changes |
| headcountIncrease12m / headcountDecrease12m | 12-month employee count changes |
Technology & Digital Presence:
* websiteTrafficIncrease - Website traffic growth
* websiteTrafficDecrease - Website traffic decline
* itSpendIncrease - IT spending increase
* itSpendDecrease - IT spending decrease
##### News Event Categories
Each category includes the following event types:
| Category | Event Types |
|----------|------------|
| businessMilestones | product launch, partnership, product development, product integration, signs new client, new client of |
| corporateExpansion | acquires, acquired, facilities expansion, new location, new offices |
| financialGrowth | funding, invests into assets, invests into, ipo, receives investment |
| peopleAndLeadership | executive appointment, executive departure, executive promotion, headcount increase |
| recognition | event attendance, recognition, award |
| risk | vulnerability issue, office closure, sells assets, sues, sued |
-->
### Get Contact Signals by IDs
- [POST /api/signals/contacts](https://docs.lusha.com/apis/openapi/signals/getcontactsignalsbyid.md): Retrieve signals data for a list of contact IDs.
This endpoint allows you to get recent activities and signals for up to 100 contacts per request.
Endpoint: (POST) https://api.lusha.com/api/signals/contacts
Default Behavior:
- Returns signals from the last 6 months by default
- Use startDate to customize the timeframe
- Each signal type requested counts towards credit usage
### Search Contact Signals
- [POST /api/signals/contacts/search](https://docs.lusha.com/apis/openapi/signals/searchcontactsignals.md): Search for contact signals using identifiers like LinkedIn URL, email, or name + company.
This endpoint combines search and signal enrichment in a single request.
Endpoint: (POST) https://api.lusha.com/api/signals/contacts/search
Search Requirements:
Each contact can be identified by:
- Contact ID
- LinkedIn URL
- Email address
- Full name + Company (name or domain)
Default Behavior:
- Returns signals from the last 6 months by default
- Contacts are matched based on provided identifiers
- Returns both contact data and associated signals
### Get Company Signals by IDs
- [POST /api/signals/companies](https://docs.lusha.com/apis/openapi/signals/getcompanysignalsbyid.md): Retrieve signals data for a list of company IDs.
This endpoint allows you to get recent activities and signals for up to 100 companies per request.
Endpoint: (POST) https://api.lusha.com/api/signals/companies
Default Behavior:
- Returns signals from the last 6 months by default
- Use startDate to customize the timeframe
### Search Company Signals
- [POST /api/signals/companies/search](https://docs.lusha.com/apis/openapi/signals/searchcompanysignals.md): Search for company signals using identifiers like domain, company name, or ID.
This endpoint combines search and signal enrichment in a single request.
Endpoint: (POST) https://api.lusha.com/api/signals/companies/search
Search Requirements:
Each company must have at least one identifier:
- Company ID (as string)
- Company name
- Company domain
Default Behavior:
- Returns signals from the last 6 months by default
- Companies are matched based on provided identifiers
## Lookalikes
Lusha's Lookalikes API helps you discover similar contacts and companies based on your existing data. Get AI-powered suggestions for new prospects that match your ideal customer profile.
[**Contact Lookalikes**](/apis/openapi/lookalikes/getcontactrecommendations) - Find similar contacts based on role, seniority, and industry patterns.
[**Company Lookalikes**](/apis/openapi/lookalikes/getcompanyrecommendations)- Discover companies with similar firmographics and characteristics.
### Contact Lookalikes
- [POST /api/recommendations/contacts](https://docs.lusha.com/apis/openapi/lookalikes/getcontactrecommendations.md): Fetch recommended contacts by supplying the contact’s IDs, enabling Lusha to return similar profiles aligned by job title, seniority, and company context Use requestId to get more results from a previous search.
Endpoint: (POST) https://api.lusha.com/api/recommendations/contacts
### Company Lookalikes
- [POST /v3/lookalike/companies](https://docs.lusha.com/apis/openapi/lookalikes/getcompanyrecommendations.md): Returns company lookalikes based on seed companies.
Endpoint: (POST) https://api.lusha.com/v3/lookalike/companies
#### How It Works
First Request (Start a New Run):
- Do not send dedupeSessionId
- Server generates one and returns it in the response
- Use returned dedupeSessionId for subsequent "get more" requests
Subsequent Requests ("Get More"):
- Send the returned dedupeSessionId to fetch more results without duplicates
- Server uses dedupeSessionId to deduplicate companies already returned
- Session history retained for 30 days from last activity (sliding window)
---
## 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**](https://docs.lusha.com/apis/openapi/signals/getsignaloptions).
---
**Key Features:**
- Real-time contact & company signal notifications
- Bulk subscription management (up to 25 items per request)
- Secure delivery with HMAC-SHA256 signatures
- Automatic URL verification during setup
- 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 |
> **Webhook Setup Verification:** When creating subscriptions, Lusha sends a GET request with a `challenge` parameter to verify your endpoint. Your endpoint must return `{"challenge": "value"}` with HTTP 200.
> **Webhook Delivery Acknowledgment:** When receiving webhook deliveries (POST requests), your endpoint must acknowledge with a specific response format. See the [Create Subscription](#operation/createSubscription) 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
**Webhook Verification:**
When creating or updating a subscription, Lusha verifies your webhook URL by sending a GET request with a `challenge` query parameter.
**Verification Request:**
```
GET https://your-webhook-url.com?challenge=abc123xyz
```
**Expected Response (200 OK):**
```json
{
"challenge": "abc123xyz"
}
```
**Requirements:**
- Return HTTP 200 status
- Return Content-Type: application/json
- Echo back the exact challenge value
**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:
1. Extract the `X-Lusha-Signature` and `X-Lusha-Timestamp` headers
2. Concatenate: `timestamp + "." + JSON.stringify(payload)`
3. Compute HMAC-SHA256 using your webhook secret
4. Compare the computed signature with the received signature
**Example (Node.js):**
```javascript
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 `creditsCharged` field 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:
```json
{
"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) |
---
### Create Subscription
- [POST /api/subscriptions](https://docs.lusha.com/apis/openapi/webhooks/createsubscription.md): Creates one or more webhook subscriptions for real-time signal notifications.
URL Validation:
- The URL is validated once before creating any subscriptions
- Includes format checking and challenge request verification
- If URL validation fails, no subscriptions are created
Delivery & Reliability:
- Webhooks are delivered with automatic retry on failures
- Maximum 3 retry attempts with exponential backoff
- Subscriptions auto-disable after max retries exceeded
- All deliveries are logged in audit logs
> Note: Your webhook endpoint must respond with a proper acknowledgment.
See Client Response Format below for details.
> Limit: Maximum 25 subscriptions per request
Endpoint: (POST) https://api.lusha.com/api/subscriptions
---
### Webhook Payload You'll Receive
When a signal is triggered, this payload is sent to your webhook URL:
json
{
"id": "f3b87e05-0402-4f3e-8e26-6a38fd0ad62c",
"type": "promotion",
"entityType": "contact",
"entityId": "4158887495",
"subscriptionId": "507f1f77bcf86cd799439011",
"data": {
"personId": 4158887495,
"currentCompanyId": 40823133,
"currentCompanyName": "OMG Hospitality Group LLC",
"currentDomain": "omghospitalitygroup.com",
"currentTitle": "Bartender",
"currentDepartments": [
{ "id": 7, "value": "Other" }
],
"previousCompanyName": "First Watch Restaurants",
"previousDomain": "firstwatch.com",
"signalDate": "2025-07-01"
},
"timestamp": "2026-01-14T16:16:35.841Z",
"billing": {
"creditsCharged": 1
}
}
Headers Included:
| Header | Description |
|--------|-------------|
| X-Lusha-Signature | HMAC-SHA256 signature for verification |
| X-Lusha-Timestamp | Unix timestamp of the request |
| Content-Type | application/json |
| User-Agent | Lusha-Webhooks/1.0 |
---
⚠️ Important: Ensure your account has a webhook secret before creating subscriptions.
Create one via the Regenerate Account Secret endpoint.
---
### Client Response Format (Required)
When your webhook endpoint receives a delivery, it must acknowledge receipt with this response:
Required Response:
json
{
"received": true,
"timestamp": "2026-02-05T10:30:45.123Z",
"webhookId": "f3b87e05-0402-4f3e-8e26-6a38fd0ad62c"
}
Response Requirements
| Requirement | Value |
|-------------|-------|
| HTTP Status | 201 Created (recommended) or any 2xx status |
| Content-Type | application/json |
| Response Time | Within 10 seconds |
Field Descriptions & Implementation Guide
Field Descriptions:
* received (boolean, required): Confirmation flag - must be true
* timestamp (string, required): ISO 8601 timestamp of receipt
* webhookId (string, required): Echo the id from webhook payload
Implementation Example:
javascript
app.post('/webhook', async (req, res) => {
// 1. Verify signature
if (!verifyWebhookSignature(req)) {
return res.status(401).json({ error: 'Invalid signature' });
}
// 2. Queue for async processing
await queueWebhook(req.body);
// 3. Acknowledge immediately
res.status(201).json({
received: true,
timestamp: new Date().toISOString(),
webhookId: req.body.id
});
Important Notes:
* Return acknowledgment before heavy processing
* Non-2xx responses trigger retry mechanism
* After 3 failed retries, subscription is disabled
----
### List Subscriptions
- [GET /api/subscriptions](https://docs.lusha.com/apis/openapi/webhooks/listsubscriptions.md): Returns all webhook subscriptions for your account with pagination support.
Endpoint: (GET) https://api.lusha.com/api/subscriptions
Pagination:
- Results are sorted by createdAt in descending order (newest first)
- Default limit: 10, max limit: 100
- Use offset for pagination through large result sets
> Note: The webhook secret is never returned in list responses for security.
### Get Subscription by ID
- [GET /api/subscriptions/{id}](https://docs.lusha.com/apis/openapi/webhooks/getsubscriptionbyid.md): Returns a single webhook subscription by ID.
Endpoint: (GET) https://api.lusha.com/api/subscriptions/{id}
### Update Subscription
- [PATCH /api/subscriptions/{id}](https://docs.lusha.com/apis/openapi/webhooks/updatesubscription.md): Updates an existing webhook subscription. All fields are optional.
Endpoint: (PATCH) https://api.lusha.com/api/subscriptions/{id}
---
Reactivating Disabled Subscriptions:
When setting isActive: true on a previously disabled subscription, the system automatically:
- Clears the blockReason field
- Clears the blockedAt timestamp
- Resets the retry counter
Regenerating Secrets:
Set regenerateSecret: true to generate a new webhook secret. The new secret:
- Affects all subscriptions for your account
- Is only shown once in the response
- Immediately invalidates the old secret
---
### Test Subscription
- [POST /api/subscriptions/{id}/test](https://docs.lusha.com/apis/openapi/webhooks/testsubscription.md): Test a webhook subscription by sending a test signal. Supports three test modes.
Endpoint: (POST) https://api.lusha.com/api/subscriptions/{id}/test
---
Test Modes:
- direct - Quick HTTP check only (validates URL responds correctly)
- kafka - Fanout handler only (tests Kafka message processing)
- full - Complete Kafka flow (default - end-to-end test)
What Gets Tested:
- URL accessibility and response time
- Challenge verification (for direct mode)
- Complete delivery pipeline (for full mode)
- Signature generation and headers
Important Notes:
- Test deliveries do NOT consume credits
- Test payloads use mock data
- Useful for verifying webhook configuration before going live
### Delete Subscriptions
- [POST /api/subscriptions/delete](https://docs.lusha.com/apis/openapi/webhooks/deletesubscriptions.md): Delete one or more webhook subscriptions. Returns detailed results for each deletion with partial success support.
Endpoint: (POST) https://api.lusha.com/api/subscriptions/delete
---
Behavior:
- Each subscription is processed independently
- Returns detailed results for each item including deleted subscription info
- Invalid ID formats are gracefully handled and reported as NOT_FOUND
- Duplicate IDs are automatically deduplicated
- Deletion is permanent and cannot be undone
### Get Audit Logs
- [GET /api/audit-logs](https://docs.lusha.com/apis/openapi/webhooks/getauditlogs.md): Retrieve webhook delivery logs for your account.
Endpoint: (GET) https://api.lusha.com/api/audit-logs
What's Logged:
- All webhook delivery attempts (success and failures)
- HTTP status codes and response times
- Error messages for failed deliveries
- Delivery timestamps and duration metrics
Filtering:
- Filter by subscription ID to see logs for specific subscriptions
- Filter by status to see only successes, failures, or permanent failures
Rate Limit: 100 requests/minute per account
> Note: Logs are retained for 90 days (successful) and 180 days (failed/DLQ)
### Get Audit Log Statistics
- [GET /api/audit-logs/stats](https://docs.lusha.com/apis/openapi/webhooks/getauditlogstats.md): Get delivery statistics for your account.
Endpoint: (GET) https://api.lusha.com/api/audit-logs/stats
### Get Account Secret
- [GET /api/account/secret](https://docs.lusha.com/apis/openapi/webhooks/getaccountsecret.md): Retrieve the current account webhook secret.
Endpoint: (GET) https://api.lusha.com/api/account/secret
### Regenerate Account Secret
- [POST /api/account/secret/regenerate](https://docs.lusha.com/apis/openapi/webhooks/regenerateaccountsecret.md): Regenerate the account webhook secret. Affects all subscriptions for the account.
Endpoint: (POST) https://api.lusha.com/api/account/secret/regenerate
Behavior:
- If a secret already exists: Replaces with new secret (old secret is invalidated)
- If no secret exists: Creates new secret automatically
Important Notes:
- The secret is only shown once in the response. Store it securely.
- This endpoint always succeeds (upsert operation)
- Regenerating invalidates the old secret for all subscriptions (if one existed)
- An account secret must exist before webhooks can be delivered
## Account Management
Manage your account and monitor usage.
Use this endpoint to:
- Monitor credit usage
- Understand consumption patterns
- Align API usage with plan limits
- Support governance and production operations
Account-level insights are especially important for teams running Lusha at scale or across multiple systems.
### Get Account Usage Statistics
- [GET /account/usage](https://docs.lusha.com/apis/openapi/account-management/getaccountusagestats.md): Retrieve your current API credit usage statistics including used, remaining, and total credits.
Endpoint: (GET) https://api.lusha.com/account/usage
Rate Limits: This endpoint has a specific rate limit of 5 requests per minute.