LinkedIn · AsyncAPI Specification
Linkedin Webhooks
Version
View Spec
View on GitHub
BusinessCareersMarketingProfessional NetworkingRecruitingSocial-MediaFortune 1000AsyncAPIWebhooksEvents
AsyncAPI Specification
generated: '2026-08-13'
method: searched
source:
- https://learn.microsoft.com/en-us/linkedin/shared/api-guide/webhook-validation
- https://learn.microsoft.com/en-us/linkedin/marketing/community-management/organizations/organization-social-action-notifications
- https://learn.microsoft.com/en-us/linkedin/marketing/lead-sync/leadsync
spec_type: null
asyncapi_published: false
note: >-
LinkedIn publishes NO AsyncAPI document for its event surface. It does document a real,
first-party webhook surface: a shared webhook registration + HMAC validation contract in the
API guide, and two event families (organization social action notifications, and Lead Sync lead
notifications). This artifact captures that webhook catalog verbatim from the provider docs.
Nothing here is inferred — every header, event type, field and endpoint below is quoted from the
three source pages. Webhook access is gated: the Webhooks tab in the developer portal is only
enabled for applications with an approved use case for webhooks.
registration:
portal: https://www.linkedin.com/developers/apps
docs: https://learn.microsoft.com/en-us/linkedin/shared/api-guide/webhook-validation
transport: HTTPS only
constraints:
- All webhook URLs must use HTTPS. Non-HTTPS URLs are not supported.
- ngrok URIs are not supported.
- LinkedIn recommends testing with lambda/serverless functions on a cloud provider.
- Lead Sync webhook subscriptions must be created via the Lead Notification Subscriptions API, not the portal UI.
validation:
style: challenge-response (HMAC-SHA256 over a challenge code)
challenge_request: GET {webhook_url}?challengeCode={type-4 UUID}
challenge_extra_param: applicationId (only for parent-child application integrations such as Apply Connect)
expected_response_status: 200
expected_response_deadline_seconds: 3
expected_response_content_type: application/json
computation: 'challengeResponse = Hex-encoded(HMACSHA256(challengeCode, clientSecret))'
encoding: lowercase hex
response_body_fields: [challengeCode, challengeResponse]
failure_message: This URL did not pass the security challenge check
revalidation_interval_hours: 2
block_threshold_consecutive_failures: 3
blocked_state_recovery: Developers are emailed on failures and can manually restart validation from the developer portal.
signature:
header: X-LI-Signature
algorithm: HMAC-SHA256
key: the application clientSecret
string_to_sign: '"hmacsha256=" + <raw JSON POST body>'
computation: 'X-LI-Signature = Hex-encoded(HMACSHA256(stringToSign, clientSecret))'
encoding: lowercase hex (header carries the digest only; the "hmacsha256=" literal is part of the string-to-sign, not the header value)
comparison: constant-time; discard the event on mismatch
body_handling: Use the request body exactly as received — do not re-serialize, pretty-print or reformat before hashing.
delivery:
ack_required: any 2xx HTTP status
deduplication: required — dedupe on the notification identifier in the payload
retry_policy:
organization_social_actions: every 5 minutes for 8 hours, then aborted
backfill:
organization_social_actions:
api: GET https://api.linkedin.com/rest/organizationalEntityNotifications?q=criteria
retention_days: 60
event_families:
- name: Organization Social Action Notifications
event_type: ORGANIZATION_SOCIAL_ACTION_NOTIFICATIONS
docs: https://learn.microsoft.com/en-us/linkedin/marketing/community-management/organizations/organization-social-action-notifications
permission: rw_organization_admin
subscription:
resource: /rest/eventSubscriptions
create: >-
PUT https://api.linkedin.com/rest/eventSubscriptions/(developerApplication:urn:li:developerApplication:{id},user:urn:li:person:{id},entity:urn:li:organization:{id},eventType:ORGANIZATION_SOCIAL_ACTION_NOTIFICATIONS)
body_fields: [webhook]
read_by_key: GET https://api.linkedin.com/rest/eventSubscriptions/(developerApplication:...,user:...,entity:...,eventType:ORGANIZATION_SOCIAL_ACTION_NOTIFICATIONS)
read_for_member: GET https://api.linkedin.com/rest/eventSubscriptions?q=subscriberAndEventType&eventType=ORGANIZATION_SOCIAL_ACTION_NOTIFICATIONS
delete: DELETE https://api.linkedin.com/rest/eventSubscriptions/(developerApplication:...,user:...,entity:...,eventType:ORGANIZATION_SOCIAL_ACTION_NOTIFICATIONS)
lifetime: >-
A subscription lives only as long as the member's authorization grant to the application and the
member's ADMINISTRATOR role on the organization. Revoked grant (401) or lost admin role (403)
silently removes the subscription.
expires_at_field: expiresAt
batching:
batched_by: event type
batch_size: 10
payload_envelope:
schema: OrganizationSocialActionNotificationEventsPayload
fields:
- {name: type, type: string, description: 'Always ORGANIZATION_SOCIAL_ACTION_NOTIFICATIONS'}
- {name: notifications, type: 'OrganizationSocialActionNotification[]', description: List of notifications}
notification_schema:
name: OrganizationSocialActionNotification
dedupe_field: notificationId
fields:
- {name: notificationId, type: long}
- {name: organizationalEntity, type: URN}
- {name: action, type: string}
- {name: sourcePost, type: URN}
- {name: decoratedSourcePost, type: Share}
- {name: lastModifiedAt, type: long}
- {name: generatedActivity, type: URN}
- {name: decoratedGeneratedActivity, type: '[Share, Comment]'}
- {name: subscriber, type: URN}
actions:
- LIKE
- COMMENT
- SHARE
- SHARE_MENTION
- ADMIN_COMMENT
- COMMENT_EDIT
- COMMENT_DELETE
constraints:
- Webhook events for LIKE, COMMENT and SHARE are only triggered for posts with visibility set to PUBLIC.
- LinkedIn re-checks the subscriber's admin access and authorization before each send; the notification is skipped if either fails.
captured_in_openapi:
- openapi/linkedin-use-cases-social-actions-notifications-organization-social-actions-notifications-push-workflow-api-openapi.yml
- openapi/linkedin-use-cases-social-actions-notifications-organization-social-actions-notifications-pull-workflow-api-openapi.yml
operations: [putCreateASubscriptionRequest, getRetrieveSubscriptionByKey, deleteRemoveASubscription, getRetrieveNotificationsForThe]
- name: Lead Sync Lead Notifications
event_type: LEAD_ACTION
docs: https://learn.microsoft.com/en-us/linkedin/marketing/lead-sync/leadsync
permission: r_marketing_leadgen_automation
subscription:
resource: /rest/leadNotifications
create_owner_level: 'POST https://api.linkedin.com/rest/leadNotifications body: {webhook, owner, leadType}'
create_associated_entity_level: 'POST https://api.linkedin.com/rest/leadNotifications body: {webhook, owner, associatedEntity, leadType}'
create_form_level: 'POST https://api.linkedin.com/rest/leadNotifications body: {webhook, owner, versionedForm, leadType}'
read_finder: GET https://api.linkedin.com/rest/leadNotifications?q=criteria&owner=(value:(sponsoredAccount:...))&leadType=(leadType:SPONSORED)
read_by_id: GET https://api.linkedin.com/rest/leadNotifications/{id}
delete: DELETE https://api.linkedin.com/rest/leadNotifications/{id}
schema_docs: https://learn.microsoft.com/en-us/linkedin/marketing/lead-sync/lead-sync-schema
recommendation: LinkedIn recommends subscribing at the owner level so one subscription covers an owner.
enforcement:
validated_webhooks_only_since: '2026-03-16'
note: Only HTTPS URLs are supported; from 16 March 2026 new lead notifications are only pushed to validated webhooks.
payload_envelope:
fields:
- {name: type, type: string, description: Always set to LEAD_ACTION}
- {name: leadGenFormResponse, type: URN, description: URN of the lead}
- {name: owner, type: object, description: 'sponsoredAccount URN for SPONSORED leads, organization URN otherwise'}
- {name: associatedEntity, type: object, description: Entity the lead is associated with (e.g. event)}
- {name: leadGenForm, type: URN, description: URN of the versioned Lead Gen Form}
- {name: leadType, type: string, description: 'Type of lead, e.g. SPONSORED or EVENT'}
- {name: leadAction, type: string, description: CREATED or DELETED}
- {name: occurredAt, type: long, description: Unix timestamp of the action}
actions: [CREATED, DELETED]
deduplication: >-
LinkedIn states notifications can be delivered multiple times and the application MUST implement
deduplication logic to avoid processing the same lead twice.
captured_in_openapi:
- openapi/linkedin-use-cases-sponsored-api-openapi.yml
operations: [postSubscribeForLeadNotification, getFetchFullLeadData, deletePushDeleteARegistered, getGetFormsForThe]
related_non_webhook_event_surfaces:
- name: Compliance Events API
style: pull / polling
docs: https://learn.microsoft.com/en-us/linkedin/compliance/
note: Archives up to the last 30 days of a regulated member's LinkedIn activity; polled, not pushed.
operations: [getComplianceEvents, optInMemberForCompliance, optOutMemberFromCompliance, checkMemberRegulationStatus]
- name: Conversions API (streaming)
style: client-to-LinkedIn event streaming (outbound from the integrator)
note: >-
postStreamMultipleConversionEvents streams conversion events INTO LinkedIn; it is an event
ingestion endpoint, not a webhook LinkedIn calls.
operations: [postStreamMultipleConversionEvents]
- name: Audience streaming
style: client-to-LinkedIn batch streaming
operations: [streamUsersToSegment, streamCompaniesToSegment]
gaps:
- No AsyncAPI document is published for any LinkedIn event family.
- No public event catalog page enumerates every eventType across product lines; the two families above are the ones LinkedIn documents.
- Talent (Apply Connect) uses the same parent-child webhook validation flow but does not publish a standalone event-type table.