Every API here is available over the APIs.io API and to AI agents over MCP.
openapi: 3.2.0
info:
title: Lusha API Documentation Webhooks API
version: ''
x-logo:
url: https://www.lusha.com/logo.png
license:
name: Proprietary
url: https://lusha.com/legal/terms
description: "<blockquote class=\"callout\">\n\n **This is the Lusha API V3 documentation.** \n \n 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/`.\n\n For more information on V3, refer to the [Migration Guide](/tutorials/v3-migration-guide).\n\n</blockquote>\n\n --- \n\nLusha 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.\n\nUse the Lusha API to **search for new prospects**, **enrich existing records**, **react to real-world changes**, and **expand coverage** with AI-powered lookalike recommendations.\n\n> All API requests must be made over **HTTPS**. All responses are returned in **JSON** format.\n\n--- \n## Available Endpoints\n\n| Category | Description |\n|---|---|\n| [**Search**](#tag/Search) | Find contacts or companies using known identifiers |\n| [**Enrich**](#tag/Enrich) | Retrieve full profile data for contacts or companies by ID |\n| [**Search & Enrich**](#tag/Search-and-Enrich) | Find and retrieve full contact or company data in a single call |\n| [**Prospecting**](#tag/Prospecting) | Filter-based search across contacts and companies |\n| [**Lookalikes**](#tag/Lookalikes) | AI-powered recommendations for similar contacts and companies |\n| [**Buying Group**](#tag/Buying-Group) | Identify decision makers, champions, and end users within target accounts |\n| [**Contacts Tables**](#tag/Contacts-Tables) | Persist, organize, and enrich contacts in reusable tables |\n| [**Companies Tables**](#tag/Companies-Tables) | Persist, organize, and enrich companies in reusable tables |\n| [**Signals**](#tag/Signals) | Real-world activity data for contacts and companies |\n| [**Website Visitors**](#tag/Website-Visits) | Companies ranked by website-visit signals for your tracked domains |\n| [**Filters**](#tag/Filters) | Discover valid filter values for prospecting |\n| [**Webhooks**](#tag/Webhooks) | Real-time signal notifications via HTTP callbacks |\n| [**Account**](#tag/Account) | Usage, credits, rate limits, and pricing |\n\n<blockquote class=\"callout\">\n\n **Waterfall Reveal for Contact Enrichment.**\n\n Enrich Contacts now supports `waterfallEnabled`. Fall through to your enabled third-party providers when Lusha's own data has no match, for extra reach on hard-to-match contacts. On by default once your account has it turned on - pass `waterfallEnabled: false` to opt a specific call out. [See Enrich Contacts](#operation/enrichContacts).\n\n</blockquote>\n\n---\n\n## Data Source and Privacy\n\n**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.\n\nFor more details on how we collect and handle data, see our [Privacy Policy](https://lusha.com/legal/privacy-notice/).\n\n---\n\n## Authentication\n\nAll 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.\n\n> Generate and manage your API key in the [Lusha dashboard](https://dashboard.lusha.com/enrich/api).\n\nStore your API key securely and use it only in **server-side environments**.\n\n---\n\n## Rate Limiting\n\nLusha enforces rate limits on a per-plan basis to ensure fair usage and platform stability. Limits are applied across multiple time windows (per minute, per hour, and per day), and vary depending on your account plan.\n\nRate limits for the **Credit Usage API** differ from standard endpoint limits.\n\n> **Note:** To check your current plan's limits, visit the [Lusha Help Center](https://info.lusha.com/en/articles/163856-all-there-is-to-know-about-lusha-s-api) or contact your account manager.\n\n**Rate Limit Response Headers**\n\n| Header | Description |\n|--------|-------------|\n| `x-rate-limit-daily` | Total requests allowed per day |\n| `x-daily-requests-left` | Requests remaining in your daily quota |\n| `x-daily-usage` | Requests made in the current daily period |\n| `x-rate-limit-hourly` | Total requests allowed per hour |\n| `x-hourly-requests-left` | Requests remaining in your hourly quota |\n| `x-hourly-usage` | Requests made in the current hourly period |\n| `x-rate-limit-minute` | Total requests allowed per minute |\n| `x-minute-requests-left` | Requests remaining in the current minute window |\n| `x-minute-usage` | Requests made in the current minute window |\n\n---\n## Error Codes\n\nLusha uses standard HTTP status codes to indicate the result of each request.\n\n| Code | Name | Description |\n|------|------|-------------|\n| `200` | OK | Request was successful |\n| `400` | Bad Request | Request is malformed or missing required fields |\n| `401` | Unauthorized | API key is missing or invalid |\n| `402` | Payment Required | Insufficient credits or payment needed |\n| `403` | Forbidden | Account is inactive. Contact support@lusha.com |\n| `404` | Not Found | Endpoint or resource does not exist |\n| `429` | Too Many Requests | Rate limit or daily quota exceeded |\n| `451` | Unavailable For Legal Reasons | Request blocked due to GDPR regulations |\n| `499` | Client Closed Request | Request timed out before completing |\n| `5XX` | Server Error | Issue on Lusha's end. Retry with exponential backoff |\n\n**Error Response Format**\n\n```json\n{\n \"statusCode\": 400,\n \"message\": \"Invalid request parameters\"\n}\n```\n\n**Tables-specific error codes**\n\n| Code | Status | Meaning |\n|---|---|---|\n| `TABLE_NOT_FOUND` | 404 | The `table_id` does not exist or is not accessible to this account |\n| `COLUMN_NOT_FOUND` | 404 | The `column_id` does not exist on the given table |\n| `TABLE_NAME_CONFLICT` | 409 | A table with this name already exists |\n\nTables error bodies use the shape `{ \"message\": \"...\", \"code\": <status>, ... }` rather than the `statusCode`/`errors` shape used elsewhere in this doc.\n\n**Limits:** up to 500 entity IDs per add/remove call · max 50,000 entities per table · max 500 tables per account · `page` 0–100 · `size` default 100.\n\n**Tips for Handling Errors**\n\n- Verify your API key is correct and active\n- Read the `message` field for specific troubleshooting details\n- For `429` errors, wait before retrying\n- For `5XX` errors, use exponential backoff before retrying\n"
contact:
name: Lusha Support
url: https://api.lusha.com
email: support@lusha.com
termsOfService: https://lusha.com/legal/terms
x-privacy-policy:
name: Privacy Policy
url: https://lusha.com/legal/privacy-notice/
servers:
- url: https://api.lusha.com
description: Production server
security:
- ApiKeyAuth: []
tags:
- name: Webhooks
description: "Subscribe to real-time notifications when contacts change jobs or companies experience key business events.\n\nWebhooks deliver HTTP POST requests to your endpoints when signals occur - from promotions and job changes to company growth.\n\n> For a full list of available signals, refer to [**Signal Options**](https://docs.lusha.com/apis/openapi/signals/getsignaloptions).\n---\n**Key Features:**\n- Real-time contact & company signal notifications\n- Bulk subscription management (up to 25 items per request)\n- Secure delivery with HMAC-SHA256 signatures\n- Delivery monitoring with audit logs\n\n **Available Endpoints:**\n\n| Method | Endpoint | Purpose |\n|--------|----------|---------|\n| POST | `/api/subscriptions` | Create subscriptions (bulk supported) |\n| GET | `/api/subscriptions` | List all subscriptions |\n| GET | `/api/subscriptions/{id}` | Get subscription by ID |\n| PATCH | `/api/subscriptions/{id}` | Update subscription |\n| POST | `/api/subscriptions/delete` | Delete subscriptions (bulk supported) |\n| POST | `/api/subscriptions/{id}/test` | Test subscription delivery |\n| GET | `/api/audit-logs` | Get webhook delivery logs |\n| GET | `/api/audit-logs/stats` | Get delivery statistics |\n| GET | `/api/account/secret` | Get account webhook secret |\n| POST | `/api/account/secret/regenerate` | Regenerate account secret |\n| POST | `/api/subscriptions/opt-out` | Subscribe to contact opt-out notifications |\n\n> **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.\n ---\n\n<details>\n<summary><strong>Rate Limits</strong></summary>\n\n| Operation | Limit |\n|-----------|-------|\n| API Requests | 100 requests/minute per account |\n| Create Subscriptions | 25 items per request |\n| Delete Subscriptions | 25 items per request |\n\n</details>\n\n---\n\n<details>\n<summary><strong>Security & Verification</strong></summary>\n\n**HTTPS Requirement:**\n- Production webhook URLs **must** use HTTPS\n- HTTP URLs are not accepted\n\n**Signature Verification:**\n\nAll webhook deliveries include an `X-Lusha-Signature` header containing an HMAC-SHA256 signature. Verify this signature to ensure the request is from Lusha:\n\n1. Extract the `X-Lusha-Signature` and `X-Lusha-Timestamp` headers\n2. Concatenate: `timestamp + \".\" + JSON.stringify(payload)`\n3. Compute HMAC-SHA256 using your webhook secret\n4. Compare the computed signature with the received signature\n\n**Example (Node.js):**\n```javascript\nconst crypto = require('crypto');\n\nfunction verifySignature(payload, signature, timestamp, secret) {\n const signedPayload = `${timestamp}.${JSON.stringify(payload)}`;\n const expectedSignature = crypto\n .createHmac('sha256', secret)\n .update(signedPayload)\n .digest('hex');\n \n return crypto.timingSafeEqual(\n Buffer.from(signature),\n Buffer.from(expectedSignature)\n );\n}\n```\n\n> **Security Best Practice:** Always verify webhook signatures to prevent spoofed requests.\n\n</details>\n\n---\n\n<details>\n<summary><strong>Credits & Billing</strong></summary>\n\n**Credit Charges:**\n- Credits are charged when signals are detected and delivered to your webhook\n- The `creditsCharged` field in the webhook payload indicates how many credits were used\n- Credits are deducted from your account balance per signal type\n\n**No Duplicate Charges:**\n- Each signal is delivered once and charged once\n- Webhook delivery retries do not incur additional charges\n\n</details>\n\n---\n\n<details>\n<summary><strong>Error Response Format</strong></summary>\n\nAll error responses follow this format:\n```json\n{\n \"statusCode\": 400,\n \"message\": \"Validation failed\",\n \"errors\": [\"entityType must be one of: contact, company\"]\n}\n```\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `statusCode` | number | HTTP status code |\n| `message` | string | Error message |\n| `errors` | string[] | Detailed error messages (optional) |\n\n</details>\n \n---\n"
x-tag-expanded: true
paths:
/api/subscriptions:
post:
tags:
- Webhooks
summary: Create Subscription
description: "Creates one or more webhook subscriptions for real-time signal notifications.\n\n**Delivery & Reliability:**\n- Webhooks are delivered with automatic retry on failures\n- Maximum 3 retry attempts with exponential backoff\n- Subscriptions auto-disable after max retries exceeded\n- All deliveries are logged in audit logs\n\n> **Note:** Your webhook endpoint must respond with a proper acknowledgment. \n See Client Response Format below for details.\n\n> **Limit:** Maximum 25 subscriptions per request\n\n*Endpoint*: **(POST) https://api.lusha.com/api/subscriptions**\n\n---\n\n### Webhook Payload You'll Receive\n When a signal is triggered, this payload is sent to your webhook URL:\n```json\n {\n \"id\": \"f3b87e05-0402-4f3e-8e26-6a38fd0ad62c\",\n \"type\": \"promotion\",\n \"entityType\": \"contact\",\n \"entityId\": \"4158887495\",\n \"subscriptionId\": \"507f1f77bcf86cd799439011\",\n \"data\": {\n \"personId\": 4158887495,\n \"currentCompanyId\": 40823133,\n \"currentCompanyName\": \"OMG Hospitality Group LLC\",\n \"currentDomain\": \"omghospitalitygroup.com\",\n \"currentTitle\": \"Bartender\",\n \"currentDepartments\": [\n { \"id\": 7, \"value\": \"Other\" }\n ],\n \"previousCompanyName\": \"First Watch Restaurants\",\n \"previousDomain\": \"firstwatch.com\",\n \"signalDate\": \"2025-07-01\"\n },\n \"timestamp\": \"2026-01-14T16:16:35.841Z\",\n \"billing\": {\n \"creditsCharged\": 1\n }\n }\n ```\n **Example — Company News Signal:**\n ```json\n {\n \"id\": \"a7c92f14-1234-4b3e-9d22-8b4fe1d0bc45\",\n \"type\": \"commercialActivityNews\",\n \"entityType\": \"company\",\n \"entityId\": \"33222678\",\n \"subscriptionId\": \"507f1f77bcf86cd799439011\",\n \"data\": {\n \"companyId\": \"33222678\",\n \"companyName\": \"Lusha\",\n \"domain\": \"lusha.com\",\n \"signalId\": \"1503910\",\n \"eventType\": \"partnership\",\n \"eventSummary\": \"Lusha announced a strategic partnership with Salesforce.\",\n \"articlePublishedDate\": \"2025-06-15\",\n \"articleTitle\": \"Lusha Partners with Salesforce\",\n \"articleHighlight\": \"The partnership enables Salesforce users to access Lusha data directly within their CRM.\",\n \"eventEffectiveDate\": \"2025-06-10\",\n \"articleUrl\": \"https://example.com/lusha-salesforce-partnership\"\n },\n \"timestamp\": \"2026-01-14T16:16:35.841Z\",\n \"billing\": {\n \"creditsCharged\": 1\n }\n }\n ```\n\n **Headers Included:**\n\n | Header | Description |\n |--------|-------------|\n | `X-Lusha-Signature` | HMAC-SHA256 signature for verification |\n | `X-Lusha-Timestamp` | Unix timestamp of the request |\n | `Content-Type` | application/json |\n | `User-Agent` | Lusha-Webhooks/1.0 |\n\n\n---\n⚠️ **Important:** Ensure your account has a webhook secret before creating subscriptions.\nCreate one via the [Regenerate Account Secret](#operation/regenerateAccountSecret) endpoint.\n\n---\n\n### Client Response Format (Required)\n\nWhen your webhook endpoint receives a delivery, it **must** acknowledge receipt with this response:\n\n **Required Response:**\n ````json\n {\n \"received\": true,\n \"timestamp\": \"2026-02-05T10:30:45.123Z\",\n \"webhookId\": \"f3b87e05-0402-4f3e-8e26-6a38fd0ad62c\"\n }\n ````\n\n<details>\n<summary><strong>Response Requirements</strong></summary>\n\n | Requirement | Value |\n |-------------|-------|\n | **HTTP Status** | `201 Created` (recommended) or any `2xx` status |\n | **Content-Type** | `application/json` |\n | **Response Time** | Within 10 seconds |\n</details>\n\n\n<details>\n<summary><strong>Field Descriptions & Implementation Guide</strong></summary>\n\n **Field Descriptions:**\n * `received` (boolean, required): Confirmation flag - must be `true`\n * `timestamp` (string, required): ISO 8601 timestamp of receipt\n * `webhookId` (string, required): Echo the `id` from webhook payload\n\n **Implementation Example:**\n ```javascript\n app.post('/webhook', async (req, res) => {\n // 1. Verify signature\n if (!verifyWebhookSignature(req)) {\n return res.status(401).json({ error: 'Invalid signature' });\n }\n \n // 2. Queue for async processing\n await queueWebhook(req.body);\n \n // 3. Acknowledge immediately\n res.status(201).json({\n received: true,\n timestamp: new Date().toISOString(),\n webhookId: req.body.id\n });\n ```\n\n **Important Notes:**\n * Return acknowledgment **before** heavy processing\n * Non-2xx responses trigger retry mechanism\n * After 3 failed retries, subscription is disabled\n\n </details>\n\n----\n"
operationId: createSubscription
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateSubscriptionRequest'
examples:
singleSubscription:
summary: Create a single subscription
value:
defaults:
entityType: contact
signalTypes:
- promotion
- companyChange
url: https://example.com/webhooks/lusha
subscriptions:
- entityId: '123456'
name: My Test Webhook
multipleSubscriptions:
summary: Create multiple subscriptions with shared URL
value:
defaults:
entityType: contact
signalTypes:
- promotion
- companyChange
url: https://example.com/webhooks/lusha
subscriptions:
- entityId: '123'
name: Contact 123
- entityId: '456'
name: Contact 456
- entityId: '789'
name: Contact 789
mixedEntityTypes:
summary: Mixed entity types with shared URL
value:
defaults:
signalTypes:
- promotion
- itSpendIncrease
url: https://example.com/webhooks/lusha
subscriptions:
- entityType: contact
entityId: '123'
- entityType: company
entityId: '456'
responses:
'201':
description: Subscriptions created (full or partial success)
content:
application/json:
schema:
$ref: '#/components/schemas/CreateSubscriptionResponse'
examples:
allSuccessful:
summary: All subscriptions created successfully
value:
total: 3
successful: 3
failed: 0
results:
- index: 0
success: true
subscription:
id: 507f1f77bcf86cd799439011
entityType: contact
entityId: '123'
signalTypes:
- promotion
- companyChange
url: https://example.com/webhooks/lusha
name: Contact 123
isActive: true
createdAt: '2026-02-02T10:00:00.000Z'
updatedAt: '2026-02-02T10:00:00.000Z'
partialSuccess:
summary: Some subscriptions failed (partial success)
value:
total: 3
successful: 2
failed: 1
results:
- index: 0
success: true
subscription:
id: 507f1f77bcf86cd799439011
entityType: contact
entityId: '123'
signalTypes:
- promotion
- companyChange
url: https://example.com/webhooks/lusha
name: Contact 123
isActive: true
createdAt: '2026-02-02T10:00:00.000Z'
updatedAt: '2026-02-02T10:00:00.000Z'
- index: 1
success: false
error:
code: DUPLICATE_SUBSCRIPTION
message: Subscription already exists for entity type 'contact' with entity ID '456'
'400':
description: Bad request - URL validation failed or invalid input
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
example:
statusCode: 400
message: Validation failed
errors:
- 'entityType must be one of: contact, company'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
description: Forbidden - feature not available or limit reached
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
example:
statusCode: 403
message: Maximum subscriptions limit reached for your account
'500':
$ref: '#/components/responses/InternalServerError'
get:
tags:
- Webhooks
summary: List Subscriptions
description: '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.
'
operationId: listSubscriptions
parameters:
- name: limit
in: query
required: false
description: Maximum number of results (1-100)
schema:
type: integer
minimum: 1
maximum: 100
default: 10
example: 10
- name: offset
in: query
required: false
description: Number of results to skip
schema:
type: integer
minimum: 0
default: 0
example: 0
responses:
'200':
description: List of subscriptions retrieved successfully
content:
application/json:
schema:
$ref: '#/components/schemas/SubscriptionListResponse'
example:
data:
- id: 507f1f77bcf86cd799439011
entityType: contact
entityId: '123456'
signalTypes:
- promotion
- companyChange
url: https://example.com/webhook
name: My Contact Webhook
isActive: true
createdAt: '2024-01-01T00:00:00.000Z'
updatedAt: '2024-01-01T00:00:00.000Z'
pagination:
total: 25
limit: 10
offset: 0
hasMore: true
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'500':
$ref: '#/components/responses/InternalServerError'
/api/subscriptions/{id}:
get:
tags:
- Webhooks
summary: Get Subscription by ID
description: 'Returns a single webhook subscription by ID.
*Endpoint*: **(GET) https://api.lusha.com/api/subscriptions/{id}**
'
operationId: getSubscriptionById
parameters:
- name: id
in: path
required: true
description: Subscription ID
schema:
type: string
example: 507f1f77bcf86cd799439011
responses:
'200':
description: Subscription retrieved successfully
content:
application/json:
schema:
$ref: '#/components/schemas/SubscriptionWithoutSecret'
'400':
$ref: '#/components/responses/BadRequest'
'404':
$ref: '#/components/responses/NotFound'
'500':
$ref: '#/components/responses/InternalServerError'
patch:
tags:
- Webhooks
summary: Update Subscription
description: '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
---
'
operationId: updateSubscription
parameters:
- name: id
in: path
required: true
description: Subscription ID
schema:
type: string
example: 507f1f77bcf86cd799439011
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateSubscriptionRequest'
examples:
disableSubscription:
summary: Disable a subscription
value:
isActive: false
updateSignals:
summary: Change subscribed signals
value:
signalTypes:
- promotion
- companyChange
regenerateSecret:
summary: Regenerate webhook secret
value:
regenerateSecret: true
updateUrl:
summary: Update webhook URL
value:
url: https://new-domain.com/webhooks/lusha
responses:
'200':
description: Subscription updated successfully
content:
application/json:
schema:
$ref: '#/components/schemas/SubscriptionResponse'
'400':
$ref: '#/components/responses/BadRequest'
'404':
$ref: '#/components/responses/NotFound'
'500':
$ref: '#/components/responses/InternalServerError'
/api/subscriptions/{id}/test:
post:
tags:
- Webhooks
summary: Test Subscription
description: '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)
**Important Notes:**
- Test deliveries do NOT consume credits
- Test payloads use mock data
- Useful for verifying webhook configuration before going live
'
operationId: testSubscription
parameters:
- name: id
in: path
required: true
description: Subscription ID
schema:
type: string
example: 507f1f77bcf86cd799439011
- name: mode
in: query
required: false
description: Test mode
schema:
type: string
enum:
- direct
- kafka
- full
default: full
example: full
responses:
'200':
description: Test executed successfully
content:
application/json:
schema:
$ref: '#/components/schemas/TestSubscriptionResponse'
example:
subscriptionId: 507f1f77bcf86cd799439011
subscriptionName: My Test Webhook
url: https://example.com/webhook
mode: full
flowCheck:
success: true
statusCode: 200
durationMs: 150
testPayload:
entityType: contact
signalType: promotion
data: {}
isSuccess: true
timestamp: '2024-01-01T00:00:00.000Z'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
description: Subscription does not belong to your account
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
example:
statusCode: 403
message: Subscription does not belong to your account
'404':
$ref: '#/components/responses/NotFound'
'500':
$ref: '#/components/responses/InternalServerError'
/api/subscriptions/delete:
post:
tags:
- Webhooks
summary: Delete Subscriptions
description: '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
'
operationId: deleteSubscriptions
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- ids
properties:
ids:
type: array
minItems: 1
maxItems: 25
items:
type: string
description: Array of subscription IDs to delete
example:
- 507f1f77bcf86cd799439011
- 507f1f77bcf86cd799439012
examples:
singleDelete:
summary: Delete a single subscription
value:
ids:
- sub-123
multipleDelete:
summary: Delete multiple subscriptions
value:
ids:
- sub-123
- sub-456
- sub-789
responses:
'200':
description: Delete operation completed (full or partial success)
content:
application/json:
schema:
$ref: '#/components/schemas/DeleteSubscriptionResponse'
examples:
allSuccessful:
summary: All subscriptions deleted successfully
value:
total: 3
successful: 3
failed: 0
results:
- index: 0
success: true
subscription:
id: sub-123
entityType: contact
entityId: '123'
name: Contact Webhook
partialSuccess:
summary: Some deletions failed
value:
total: 3
successful: 2
failed: 1
results:
- index: 0
success: true
subscription:
id: sub-123
entityType: contact
entityId: '123'
name: Contact Webhook
- index: 1
success: false
error:
code: NOT_FOUND
message: Subscription with id 'sub-456' not found
'400':
# --- truncated at 32 KB (57 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/lusha/refs/heads/main/openapi/lusha-webhooks-api-openapi.yml