Monitoring inbox
Inbox monitoring lets you track every incoming conversation on an account, instead of syncing people one by one. It involves 2 key steps:
- Enabling. Enable inbox sync once per account. From that point on, Linked API watches your whole inbox in the background and captures new messages across all threads.
- Polling. After inbox sync is enabled, poll a single endpoint to retrieve captured messages and receive new ones — without syncing each conversation.
💡 This is the default way to read messages. The inbox captures every new message on the account, and the same endpoint returns the whole conversation with one person when you pass
personUrl. See the Messaging overview for which tool fits which task.
Enabling
Execute a workflow with the st.syncInbox action (or nv.syncInbox for Sales Navigator). You only need to do this once per account. Standard and Sales Navigator inboxes can both be enabled on the same account; polled messages are tagged with a type so you can tell them apart.
Workflow:
{
"actionType": "st.syncInbox"
}Completion:
{
"actionType": "st.syncInbox",
"success": true
}Enabling only switches monitoring on: the action records the setting and returns. The messages themselves are picked up afterwards by a sync that runs periodically, so the first ones appear on the next sync rather than the moment the action completes.
Note: When that sync finds new messages in a thread – including messages you send yourself – it opens the profile page of the other participant in that thread to resolve their public URL – but only when Linked API does not already know it, so a person is visited once rather than on every message. Those visits are made from your own account, and such a visit is visible to the person whose profile is opened.
Polling
Unlike enabling, you don't execute workflows to poll the inbox. Instead, send a POST request to the following endpoint:
POST https://api.linkedapi.io/inbox/pollThe request body is a single object. All fields are optional:
{
"since": "2023-01-01T00:00:00Z",
"type": "st",
"threadId": "2-abc123..."
}since(optional) – timestamp indicating the starting point for retrieving messages. If not provided, all captured messages are returned.type(optional) – enum to filter by inbox type. If omitted, both standard and Sales Navigator messages are returned:st– standard inbox messages only.nv– Sales Navigator inbox messages only.
threadId(optional) – restrict the result to a single conversation thread.personUrl(optional) – return the conversation with one person instead of the whole inbox. See Polling one person for how this changes the response.
If your request is correct, you will receive the following response:
{
"success": true,
"result": {
"messages": [
{
"id": "f4d92946-8821-6da6-ff4c-c36f0671292a",
"type": "nv",
"threadId": "2-abb123...",
"personUrn": "urn:li:member:987654321",
"personHashedUrl": "https://www.linkedin.com/in/ACwAA9FmKpQ4T1r7XbNz",
"personPublicUrl": null,
"sender": "them",
"text": "Saw your post on pipeline automation. Can you share more?",
"time": "2023-01-02T10:42:00Z"
},
{
"id": "2a1b7f25-daba-5e20-70e9-c6427bb4f660",
"type": "st",
"threadId": "2-abc123...",
"personUrn": "urn:li:member:123456789",
"personHashedUrl": "https://www.linkedin.com/in/ACoAA2DdsSV83B48UDvgO5jPo3Gho0o",
"personPublicUrl": "https://www.linkedin.com/in/person1",
"sender": "us",
"text": "Sure, let's talk this afternoon.",
"time": "2023-01-02T10:38:00Z"
},
{
"id": "f4d92946-8821-6da6-ff4c-c36f0671292a",
"type": "st",
"threadId": "2-abc123...",
"personUrn": "urn:li:member:123456789",
"personHashedUrl": "https://www.linkedin.com/in/ACoAA2DdsSV83B48UDvgO5jPo3Gho0o",
"personPublicUrl": "https://www.linkedin.com/in/person1",
"sender": "them",
"text": "Hi! Are you available for a quick chat?",
"time": "2023-01-02T10:35:00Z"
}
]
}
}messages– flat array of messages across all threads, ordered newest first.id– unique identifier for the message.type– inbox type the message belongs to (stornv).threadId– identifier of the conversation thread. Pass it tost.sendMessage/nv.sendMessageto reply directly into the thread.personUrn– URN of the other participant, ornullif LinkedIn does not expose it.personHashedUrl– hashed LinkedIn URL of the other participant. This is the form the inbox exposes; every action that takes a person URL accepts it. The standard and Sales Navigator inboxes return different hashed values for the same person, so match people onpersonUrnrather than on thepersonUrlstring when you need identity across both surfaces.personPublicUrl– public LinkedIn URL of the other participant, ornullif it has not been resolved. It can benullon any message, including the first one in a thread.personUrl– deprecated, replaced bypersonHashedUrl, which carries the same value. Still returned so existing integrations keep working; do not use it in new code.sender– enum indicating who sent the message. Possible values:us– message was sent by you (through the LinkedIn UI or the Linked API).them– message was sent by the other person.
text– message text.time– timestamp when the message was sent or received.
💡 Handling
personPublicUrl. A person is resolved by the periodic sync, and only when their thread produces a message after monitoring was enabled. The field is thereforenullfor everyone you have not heard from yet, and some people are never resolvable at all – so always handlenullrather than assuming a message carries a public URL. Messages captured before this field existed, and people whose resolution did not succeed, staynulluntil that person sends another message or Linked API learns their public URL another way, for example throughst.openPersonPage.personHashedUrlis always present and is the safe input for follow-up actions.
The inbox only captures messages that arrive after monitoring is enabled – unless you ask for one person with personUrl, which also returns history loaded for that person. If inbox monitoring is not enabled on the account, the request still succeeds with an empty messages array.
Recommended flow for integrations:
- Leave
sinceempty on the first request to retrieve everything captured so far. - For subsequent requests, pass the timestamp of the most recent message you received as
sinceto fetch only newer messages. - Continue polling with an advancing
since. Whenever new messages arrive, updatesinceto the latest message time.
since is inclusive and message times are whole minutes, so the messages at the latest time come back on the next request. Remember their ids and skip them, so you never process – or reply to – the same message twice.
💡 For push-based delivery instead of polling, subscribe to the inbox Webhook Events. They fire for accounts with inbox monitoring enabled and carry the same message fields.
Polling one person
Pass personUrl to read the whole known conversation with one person. Besides the messages the inbox captured, the result includes that person's earlier history if it was loaded with st.syncConversation or nv.syncConversation – a message present in both appears once. Loaded history is returned even if inbox monitoring is not enabled on the account.
{
"personUrl": "https://www.linkedin.com/in/person1"
}personUrl– public or hashed LinkedIn URL of the person. A hashed URL, standard or Sales Navigator, always matches. A public URL matches only once Linked API knows this person's public URL; if inbox messages from this person carrypersonPublicUrl: null, pass theirpersonHashedUrlinstead.since,typeandthreadId(optional) – work as described above and narrow the messages further. Leavesinceempty to get the full conversation.
If your request is correct, you will receive the following response:
{
"success": true,
"result": {
"messages": [
{
"id": "8c0a1f3e-5b7d-4e21-9a6c-2f4d8e1b7c90",
"inboxMessageId": "8c0a1f3e-5b7d-4e21-9a6c-2f4d8e1b7c90",
"type": "st",
"threadId": "2-abc123...",
"personUrn": "urn:li:member:123456789",
"personHashedUrl": "https://www.linkedin.com/in/ACoAA2DdsSV83B48UDvgO5jPo3Gho0o",
"personPublicUrl": "https://www.linkedin.com/in/person1",
"sender": "them",
"text": "Thanks, the deck looks great. Let's talk next week.",
"time": "2023-03-14T16:05:00Z"
},
{
"id": "2a1b7f25-daba-5e20-70e9-c6427bb4f660",
"inboxMessageId": "e61c94d2-0b3a-4f8e-b5d7-91a2c3e4f5a6",
"type": "st",
"threadId": "2-abc123...",
"personUrn": "urn:li:member:123456789",
"personHashedUrl": "https://www.linkedin.com/in/ACoAA2DdsSV83B48UDvgO5jPo3Gho0o",
"personPublicUrl": "https://www.linkedin.com/in/person1",
"sender": "us",
"text": "Here is the deck we discussed.",
"time": "2023-03-14T10:20:00Z"
},
{
"id": "f4d92946-8821-6da6-ff4c-c36f0671292a",
"inboxMessageId": null,
"type": "st",
"threadId": "2-abc123...",
"personUrn": "urn:li:member:123456789",
"personHashedUrl": "https://www.linkedin.com/in/ACoAA2DdsSV83B48UDvgO5jPo3Gho0o",
"personPublicUrl": "https://www.linkedin.com/in/person1",
"sender": "them",
"text": "Hi! Are you available for a quick chat?",
"time": "2022-11-02T10:35:00Z"
}
],
"threads": [
{
"threadId": "2-abc123...",
"type": "st",
"personUrn": "urn:li:member:123456789",
"historyFrom": "2022-11-02T10:35:00Z",
"historyComplete": true
}
]
}
}messages– messages exchanged with this person across all their threads, ordered newest first. Each message carries the same fields as in the response above, plusinboxMessageId:id– identifier of the message in this view. It stays the same between requests, including after new messages arrive, but it can differ from theidthe same message has in the response withoutpersonUrl.inboxMessageId–idof the same message in the response withoutpersonUrl, which is alsomessageIdin inbox webhook events, ornullif the inbox did not capture this message – for example, history from before monitoring was enabled. Use it to match this view against the messages you have already received from the inbox.threadId– may benullin this view: a thread whose history was loaded through the person's profile keepsthreadId: nulluntil Linked API discovers the thread during the syncing period. AftersyncUntil, the same conversation can appear twice inthreads– once withthreadId: null(the loaded history, which tells you how far back it goes) and once with the inbox'sthreadId. To reply to such a person, passpersonUrltost.sendMessage.
threads– every thread with this person that Linked API knows about, listed regardless ofsince.threadId– identifier of the thread, ornullas described above.type– inbox type of the thread (stornv).personUrn– URN of the person, ornullif LinkedIn does not expose it.historyFrom– time of the earliest message Linked API has in this thread, ornullif it has none.historyComplete–trueonly when Linked API has read this thread back to its very first message, sohistoryFromis where the conversation starts.falsemeans earlier messages may exist that Linked API has not read.
If Linked API has no messages with this person, messages is empty; threads can still list a known thread with historyFrom: null.
💡 If
historyCompleteisfalseand you need earlier messages, see Loading conversation history.
Messages from the inbox and from the loaded history are matched by sender, minute and text within the same thread, so two identical messages sent in the same minute stay two messages. In rare cases the two copies of one message are recorded with a different minute, and then the message appears twice.
💡 To check whether a person answered your message, see Did this lead reply? in the Messaging overview.
This page provides examples of workflows and their completions. For detailed documentation on constraints, parameters, and possible results of specific actions, always refer to the corresponding action documentation pages.