Skip to main content
Webhooks allow you to receive real-time notifications when events happen on your connected accounts — new messages, connection acceptances, and more.

Delivery Modes

Webhooks support two delivery modes depending on your setup:

Hosted Mode

No server needed. Events are delivered via SSE stream or polling. Perfect for bots, scripts, and local apps.Create a webhook without a url to use hosted mode.

Custom Mode

Events are sent as POST requests to your server. Requires a publicly accessible HTTPS endpoint.Create a webhook with a url to use custom mode.
HostedCustom
SetupNo server requiredHTTPS endpoint required
Real-time deliverySSE stream (GET /stream)HTTP POST to your URL
Event history24h stored events (GET /events)Fire-and-forget
Best forBots, scripts, local devProduction servers

How It Works

1

Connect your account

Use POST /v2/login to connect an account and get an account_id.
2

Create a hosted webhook

Call POST /v2/webhooks without a url. You’ll receive a webhook_id, stream_url, and events_url.
3

Start monitoring

Call POST /v2/webhooks/{webhook_id}/start to begin real-time monitoring.
4

Receive events

Connect to the SSE stream or poll the events endpoint.

Event Types

Subscription filterEmitted event.typeDescription
message_received"message"A new LinkedIn message was received
accepted_invitation"accepted_invitation"One or more connection requests you sent were accepted
allSubscribe to all event types
By default, webhooks listen to all event types. You can filter specific events when creating the webhook by passing an events array.
The subscription filter message_received is intentionally different from the actual event.type field, which is "message". Filter against message_received when creating the webhook, but check event.type === "message" when parsing the payload.
In addition to subscribed events, every webhook also receives disconnection events — this is not filterable. They fire whenever the underlying LinkedIn session expires so you can react (re-auth, alert, etc.).

Event Payload Format

All events share the same wrapper structure. Note that the outer timestamp is when the API emitted the event, while event.timestamp is when the underlying LinkedIn activity happened — they differ slightly (latency).
{
  "account_id": "69ee261e41fc4cbecf9f34c9",
  "account_name": "[email protected]",
  "event": {
    "type": "...",
    "timestamp": "2026-04-28T08:07:45.525693"
    // event-specific fields below
  },
  "timestamp": "2026-04-28T08:07:45.525853"
}

Message Received

Triggered in real-time when a new LinkedIn message is received via the LinkedIn realtime stream (sub-second latency). The inner event type is "message".
{
  "account_id": "69ee261e41fc4cbecf9f34c9",
  "account_name": "[email protected]",
  "event": {
    "type": "message",
    "timestamp": "2026-04-28T10:07:45.525693",
    "message_text": "Hello! I'd love to connect.",
    "sender": {
      "name": "John Doe",
      "profile_url": "https://www.linkedin.com/in/ACoAAEMT_nsB5U1uon01_EjK9Yf4En52jDd2hGE"
    },
    "conversation": {
      "participants": [
        {
          "name": "Your Name",
          "profile_url": "https://www.linkedin.com/in/ACoAADxnv0oB_dN-NfpvEBlsVPU_W1omM-Xu24o"
        },
        {
          "name": "John Doe",
          "profile_url": "https://www.linkedin.com/in/ACoAAEMT_nsB5U1uon01_EjK9Yf4En52jDd2hGE"
        }
      ],
      "is_group_chat": false,
      "unread_count": 1
    },
    "metadata": {
      "entity_urn": "urn:li:msg_message:(urn:li:fsd_profile:ACoAADxnv0oB_dN-NfpvEBlsVPU_W1omM-Xu24o,2-MTc3NzM2MzY2NDkyMGI4MzE3Mi0xMDAmMDZiY2ExOTgtM2NjNy00OTU4LTgyNjUtZWFlMmIwZjM1NTlmXzEwMA==)",
      "conversation_urn": "urn:li:msg_conversation:(urn:li:fsd_profile:ACoAADxnv0oB_dN-NfpvEBlsVPU_W1omM-Xu24o,2-MDZiY2ExOTgtM2NjNy00OTU4LTgyNjUtZWFlMmIwZjM1NTlmXzEwMA==)",
      "delivered_at": 1777363664920,
      "read_status": false
    }
  },
  "timestamp": "2026-04-28T08:07:45.525853"
}
Field reference
FieldTypeDescription
event.message_textstringPlain text content of the message
event.sender.namestringDisplay name of the sender
event.sender.profile_urlstringLinkedIn URL of the sender (URN-style, not vanity)
event.conversation.participantsarrayAll participants of the thread, sender included
event.conversation.is_group_chatbooleantrue if 3+ participants
event.conversation.unread_countintegerNumber of unread messages in the thread
event.reply_toobject?Only present when the message is a reply. Contains message_text, sender_name, sender_profile_url, timestamp of the original message. Omitted (not null) for non-reply messages.
event.metadata.entity_urnstringLinkedIn URN of the message
event.metadata.conversation_urnstringLinkedIn URN of the conversation thread
event.metadata.delivered_atintegerUnix milliseconds delivery time
event.metadata.read_statusbooleanWhether the conversation is marked read
When the message is a reply, an additional event.reply_to object is included with the original message details. For non-reply messages, the field is omitted entirely from the payload — don’t expect a null.

Accepted Invitation

Triggered when one or more connection requests you sent are accepted. Detected by a background worker that polls the connections list every ~6 hours and diffs against the previously stored snapshot. The payload batches all new connections detected in the same check.
{
  "account_id": "69ee261e41fc4cbecf9f34c9",
  "account_name": "[email protected]",
  "event": {
    "type": "accepted_invitation",
    "new_connections": [
      {
        "profile_url": "https://www.linkedin.com/in/maruthigudi/",
        "name": "Maruthi Gudi",
        "job_title": "Building High-Performance Tech & FinTech Teams | Headhunter @ HackerTrail",
        "profile_picture": "https://media.licdn.com/dms/image/v2/D4E03AQEEUE9iAq2LXA/profile-displayphoto-shrink_100_100/B4EZYY8bulGYAU-/0/1744175218426"
      },
      {
        "profile_url": "https://www.linkedin.com/in/musokeshaibu/",
        "name": "Musoke Shaibu",
        "job_title": "Building the definitive operating system for sales, marketing, and research.",
        "profile_picture": "https://media.licdn.com/dms/image/v2/D4D03AQGCOZ3SrVT5Tg/profile-displayphoto-shrink_200_200/B4DZZtP29UGcAY-/0/1745589597790"
      }
    ],
    "count": 2,
    "timestamp": "2026-04-27T14:52:59.970134"
  },
  "timestamp": "2026-04-27T14:52:59.970144"
}
Field reference
FieldTypeDescription
event.new_connectionsarrayProfiles that accepted your connection request since the last check
event.new_connections[].profile_urlstringLinkedIn vanity URL of the connection
event.new_connections[].namestringDisplay name
event.new_connections[].job_titlestring | nullHeadline / current role as shown on LinkedIn
event.new_connections[].profile_picturestring | nullCDN URL of the profile picture (may expire)
event.countintegerLength of new_connections
When you create a webhook subscribed to accepted_invitation (or all), the API performs an initial sync of your existing connections in the background. The first detection check then runs ~6 hours later and every 6 hours thereafter.

Disconnection

Triggered when the account’s LinkedIn session expires, the cookie is invalidated, or the user logs out. Sent to every webhook attached to the account regardless of subscription filters.
{
  "account_id": "69ee261e41fc4cbecf9f34c9",
  "account_name": "[email protected]",
  "event": {
    "type": "disconnection",
    "reason": "LinkedIn cookie invalid or expired",
    "timestamp": "2026-04-28T09:15:30.123456"
  },
  "timestamp": "2026-04-28T09:15:30.123456"
}
Field reference
FieldTypeDescription
event.reasonstringHuman-readable cause (e.g. "Token expired (detected after 10 reconnections)", "LinkedIn cookie invalid or expired")
When you receive a disconnection event, monitoring stops automatically and every webhook attached to the account is paused (with auto_paused: true). You need to re-authenticate the account via POST /v2/login (or POST /v2/checkpoint if a 2FA is required) — paused webhooks are auto-restarted on a successful re-login.

Architecture

Unlike the V1 webhook system which required creating a separate “webhook account”, the V2 system works with your existing accounts:
  • V2 accounts are created via POST /v2/login (profiles, messages, network, etc.)
  • Webhooks are configurations that attach to those accounts
  • One account can have multiple webhooks with different event filters
  • Starting/stopping monitoring is done per webhook