Lusha · AsyncAPI Specification
Lusha Webhooks
Version
View Spec
View on GitHub
Sales IntelligenceB2BEnrichmentContact DataProspectingIntentSignalsLookalikesWebhookMCPAsyncAPIWebhooksEvents
AsyncAPI Specification
generated: '2026-08-13'
method: searched
source: >-
https://docs.lusha.com/apis/openapi (Webhooks section),
https://docs.lusha.com/user-guide/webhooks/how-to-set-up-webhooks-in-lusha,
openapi/lusha-webhooks-api-openapi.yml
spec_type: none
asyncapi_published: false
asyncapi_note: >-
Lusha publishes NO AsyncAPI document — probed https://docs.lusha.com/asyncapi.yaml
(404) and searched the docs site and the lusha-oss GitHub org. The event surface
is real but is described only as REST subscription-management operations plus a
prose delivery contract, so it is captured here as a webhook catalogue rather
than fabricated into an AsyncAPI.
description: >-
Lusha delivers signal events as HTTP POST callbacks to subscriber-registered
HTTPS endpoints. Subscriptions are per entity (a specific contact or company id)
and per signal type; the same account-level secret signs every delivery. There
is no fan-out event bus, no topic namespace, and no replay endpoint — but there
IS a full audit log with delivery statistics.
transport: https-webhook
delivery:
method: POST
https_required: true
https_note: HTTP endpoint URLs are rejected in production.
acknowledgment_required: true
acknowledgment_note: >-
The receiving endpoint must reply in the acknowledgment shape documented on
the createSubscription operation.
retries: true
retry_note: >-
Retried deliveries are not re-charged. A subscription that exceeds max retries
is disabled and carries blockReason ("Max retries exceeded") and blockedAt.
ordering: not specified
security:
signature_header: X-Lusha-Signature
timestamp_header: X-Lusha-Timestamp
algorithm: HMAC-SHA256
signed_payload: '<X-Lusha-Timestamp> + "." + JSON.stringify(payload)'
comparison: constant-time (provider's Node.js example uses crypto.timingSafeEqual)
secret:
scope: account
read: GET /api/account/secret (getAccountSecret)
rotate: POST /api/account/secret/regenerate (regenerateAccountSecret)
note: >-
Shown once on creation. Regeneration invalidates the old secret for every
subscription on the account; a secret must exist before any webhook is
delivered.
subscriptions:
entity_types: [contact, company]
per_request_max: 25
identified_by: entityId (Lusha contact or company id)
management_operations:
- {operationId: createSubscription, method: POST, path: /api/subscriptions}
- {operationId: listSubscriptions, method: GET, path: /api/subscriptions}
- {operationId: getSubscriptionById, method: GET, path: '/api/subscriptions/{id}'}
- {operationId: updateSubscription, method: PATCH, path: '/api/subscriptions/{id}'}
- {operationId: deleteSubscriptions, method: POST, path: /api/subscriptions/delete}
- {operationId: testSubscription, method: POST, path: '/api/subscriptions/{id}/test'}
- {operationId: createOptOutSubscription, method: POST, path: /api/subscriptions/opt-out}
- {operationId: getAccountSecret, method: GET, path: /api/account/secret}
- {operationId: regenerateAccountSecret, method: POST, path: /api/account/secret/regenerate}
- {operationId: getAuditLogs, method: GET, path: /api/audit-logs}
- {operationId: getAuditLogStats, method: GET, path: /api/audit-logs/stats}
events:
- name: contact signal
entity_type: contact
signal_types: [promotion, companyChange, allSignals]
payload: signal event for the subscribed contact, including creditsCharged
billing: credits charged once per delivered signal
- name: company signal
entity_type: company
signal_types:
- headcountIncrease1m
- headcountIncrease3m
- headcountIncrease6m
- headcountIncrease12m
- headcountDecrease1m
- headcountDecrease3m
- headcountDecrease6m
- headcountDecrease12m
- surgeInHiring
- surgeInHiringByDepartment
- surgeInHiringByLocation
- websiteTrafficIncrease
- websiteTrafficDecrease
- itSpendIncrease
- itSpendDecrease
- riskNews
- commercialActivityNews
- corporateStrategyNews
- financialEventsNews
- peopleNews
- marketIntelligenceNews
- productActivityNews
- linkedinActivityIntent
- allSignals
payload: signal event for the subscribed company, including creditsCharged
billing: credits charged once per delivered signal
- name: contact opt-out
entity_type: contact
payload: OptOutWebhookPayload
description: >-
Fired when a contact requests removal from data processing, so the subscriber
can action the removal in their own CRM/outreach systems.
billing: not credit-charged
subscribe_via: createOptOutSubscription
observability:
audit_log: GET /api/audit-logs
audit_stats: GET /api/audit-logs/stats
retention_successful_days: 90
retention_failed_days: 180
rate_limit: 100 requests/minute per account (webhook management endpoints)
signal_discovery:
contact_types: GET /v3/contacts/signals/types
company_types: GET /v3/companies/signals/types
company_filters: GET /v3/companies/signals/filters