Webhooks

Webhooks allow you to receive real-time HTTP notifications for subscribed events. This functionality is only available for applications with an approved use case for webhooks.

Webhook Registration and Validation

Notifications will only be sent to webhooks that are registered and validated.

To begin, register your webhook in the "Webhooks" tab of your application in the developer portal.

Note

The Webhooks tab is only enabled for applications with a use case for webhooks. For Lead Syncing use cases, webhook subscriptions must be created via the Lead Notification Subscriptions API and cannot be created via the UI.

Fields

Field Name Description Required
applicationId ID of the Developer Application being validated. Only sent for integrations with parent-child applications such as Apply Connect. Indicates which application's clientSecret to use for generating the challenge response. False
challengeCode Randomly generated type-4 UUID string created by LinkedIn. True
challengeResponse Hex-encoded HMACSHA256 signature for the challengeCode using its clientSecret as the secret key. challengeResponse = Hex-encoded(HMACSHA256(challengeCode, clientSecret)) True

Validating the Webhook Endpoint

LinkedIn validates the ownership of a webhook URL before it can be registered by an application. The validation flow leverages the application's clientSecret as the secret key along with the universally-known HMACSHA256 algorithm to generate and validate the application's response to a challenge code.

  1. Before initiating the validation flow, LinkedIn will generate a string that will act as the challengeCode.
  2. LinkedIn will use the challengeCode as a query parameter to make an HTTP GET to your webhook endpoint. Integrations using parent-child applications will also receive an applicationId query parameter.
GET https://webhooks.example.com/linkedin?challengeCode=890e4665-4dfe-4ab1-b689-ed553bceeed0
  1. Your application must compute the challengeResponse (hex-encoded HMACSHA256 signature for the challengeCode) using its clientSecret as the secret key. If you received an applicationId query parameter in the previous step, use the clientSecret associated with the challenged application. Return both the challengeCode and challengeResponse in a JSON payload with a 200 OK status within 3 seconds. Refer to the example below. Set the Content-Type header to application/json.
challengeResponse = Hex-encoded(HMACSHA256(challengeCode, clientSecret))

In HMACSHA256(challengeCode, clientSecret), clientSecret is the secret key and challengeCode is the message. Encode the resulting digest as a lowercase hex string.

{
 "challengeCode" : "890e4665-4dfe-4ab1-b689-ed553bceeed0",
 "challengeResponse" : "27b1d19678542072a7f1d0ce845d0c78cec22567f413697e25648f44fa3d1514"
}
  1. On receiving the validation response, LinkedIn will verify by computing the challenge response and comparing it with the challengeResponse returned by the app.
  2. If the challengeResponse is successfully verified, then the webhook is ready to be used in subscriptions. If the verification fails, an error will be thrown with the message: This URL did not pass the security challenge check.

Re-validation and Blocked Endpoints

Webhook endpoints will be periodically re-validated after the initial validation every 2 hours. If the re-validation check fails 3 times in a row, the endpoint will move to a blocked state where events will no longer be sent.

Developers associated with that developer application will receive warning emails for any failed validation attempts. After re-validation checks fail 3 times in a row, an email will be sent notifying developers that the webhook has been blocked. The endpoint will also show as "Blocked" in the developer portal.

After resolving the issue, developers can manually kick off another validation check from the developer portal.

Requirements for Processing Notifications

Upon receiving notifications from LinkedIn, your webhook must fulfill the following requirements:

Verify the push event signature

LinkedIn includes an X-LI-Signature header with each POST request. Verify this signature to confirm the event is from LinkedIn and is not tampered with.

To compute and verify the expected signature:

  1. Combine the literal string hmacsha256= with the raw JSON POST body to build the string-to-sign.

  2. Compute the HMACSHA256 of that string using your app's clientSecret as the key. Encode the result as a lowercase hex string.

    stringToSign   = "hmacsha256=" + <raw JSON POST body>
    X-LI-Signature = Hex-encoded(HMACSHA256(stringToSign, clientSecret))
    

    In HMACSHA256(stringToSign, clientSecret), clientSecret is the secret key and stringToSign is the message.

  3. Compare your computed value against the X-LI-Signature header value using a constant-time comparison. Discard the event if the values do not match.

Important

The X-LI-Signature header contains only the hex digest. The hmacsha256= string is used only when building the string-to-sign.

Note

Use the request body exactly as received. Do not re-serialize, pretty-print, or reformat the JSON before hashing, or the computed signature will not match.

Deduplicate notifications

A notification can occasionally be delivered multiple times to your webhook. Your webhook must be able to deduplicate notifications using the Notification ID included in the payload.

Respond with an HTTP response

For each notification delivered to your webhook, it must return a 2xx HTTP status code to indicate successful delivery of the notification to your webhook. Any other response code returned will be treated by LinkedIn as a failure.

Test with lambda/serverless functions on a cloud provider

We recommend testing webhooks processing using lambda/serverless functions on a cloud provider.

Note

  • ngrok URIs are not supported.
  • All webhook URLs must use the HTTPS protocol. Non-HTTPS URLs are not supported.