List inbox conversations
Returns the most recent ~20 conversations on the connected account.
Response shape — read this before parsing
The response returns two parallel views of the people in each thread:
- participants[] — preferred. Already enriched with name, slug, and headline extracted from the LinkedIn payload server- side, with zero extra API calls. Use these for rendering.
- participantUrns[] — back-compat, URN strings only.
There is no participant.name at the top level, no peer, no otherPerson, no lastMessage.snippet, no last_message field. If you normalise against those, every contact renders as "(unnamed)".
Field map (exact names, camelCase):
- conversationUrn — urn:li:msg_conversation:(...). Pass this to GET /linkedin/conversations/{conversationUrn}/messages. Always URL-encode when used as a path parameter.
- participants[] — Enriched: { urn, name, slug, headline }. Any of name/slug/headline may be null (deleted accounts, restricted profiles), but urn is always present.
- participantUrns[] — Mirror of participants[].urn. Kept for back-compat with clients written before the enrichment landed.
- title — Group chat title only. Null on 1-on-1 conversations. Don't fall back to this for the contact name; use participants instead.
- lastMessage.text — Plain text body. Not snippet, not preview, not bodyText.
- lastMessage.senderName — Display name of the sender of the latest message. Already resolved server-side; null only when LinkedIn omits the inline profile.
- lastMessage.senderUrn — URN of the same sender.
- lastActivityAt, lastReadAt, lastMessage.deliveredAt — Unix ms, not seconds. Nullable for system-initiated threads.
Worked example response
{
"ok": true,
"conversations": [
{
"conversationUrn": "urn:li:msg_conversation:(urn:li:fsd_profile:ACoAAA…,2-MWE…)",
"backendUrn": "urn:li:fs_conversation:2-MWE…",
"isGroup": false,
"title": null,
"lastActivityAt": 1715990400000,
"lastReadAt": 1715990405000,
"unreadCount": 1,
"read": false,
"participants": [
{
"urn": "urn:li:fsd_profile:ACoAAA…aaaa",
"name": "Jane Doe",
"slug": "jane-doe-1a2b3c",
"headline": "Head of Sales at Acme"
},
{
"urn": "urn:li:fsd_profile:ACoAAA…me",
"name": "Me",
"slug": "me-1a2b3c",
"headline": null
}
],
"participantUrns": [
"urn:li:fsd_profile:ACoAAA…aaaa",
"urn:li:fsd_profile:ACoAAA…me"
],
"lastMessage": {
"messageUrn": "urn:li:msg_message:(urn:li:fsd_profile:ACoAAA…,2-MWE…)",
"text": "Sure, happy to chat — Tuesday at 2pm work?",
"senderUrn": "urn:li:fsd_profile:ACoAAA…aaaa",
"senderName": "Jane Doe",
"deliveredAt": 1715990400000
}
}
]
}
Rendering the contact name (1-on-1 thread)
Filter your own viewer URN out of participants, then read name directly. No profile-lookup round-trip needed:
const { conversations } = await client.linkedinListConversations({ sessionId });
const viewerUrn = (await client.linkedinGetSession({ id: sessionId })).viewerProfileUrn;
for (const c of conversations) {
const other = c.participants.find(p => p.urn !== viewerUrn);
const displayName = other?.name
?? (c.isGroup && c.title)
?? "(unknown)";
// …render
}
For group chats, prefer title; if absent (rare), join the other participants' names with commas. For the rare case where participants[i].name is null (deleted / restricted), fall back to POST /linkedin/profile/lookup with the URN — but you'll only need that on a handful of edge cases, not every conversation.
Request
- Base URL: https://anjal.app
- URL: https://anjal.app/linkedin/conversations
- Auth: API key in header X-API-Key
Query parameters
Response
Array of conversations.
Changes
No recorded changes to this operation across all 1 revision of this API.