Read messages in a conversation
https://myagentmail.com/linkedin/conversations/{conversationUrn}/messagesRead messages in one thread, most-recent first.
URL-encode the path parameter
conversationUrn contains parens and colons — both are reserved
characters in URL paths. Always wrap in encodeURIComponent()
before constructing the URL:
const encoded = encodeURIComponent(conv.conversationUrn);
const r = await fetch(`/v1/linkedin/conversations/${encoded}/messages?sessionId=${sessionId}`);
Response shape
Unlike GET /linkedin/conversations, this endpoint does return
senderName and senderSlug for most messages — LinkedIn embeds
the sender's display data in the message payload. They're still
nullable for system-generated messages (e.g. "X joined the
conversation"), so guard before rendering.
Field map (exact names, camelCase):
messageUrn—urn:li:msg_message:(…). Stable identifier for reaction / attachment lookups.text— Plain text body. Empty string for attachment- only messages (checkattachmentCount > 0).senderUrn— Profile URN. Null only on system messages.senderName— Display name; usually"First Last". Nullable.senderSlug—linkedin.com/in/<slug>segment. Nullable. Useful when you want to build a profile URL without a separate lookup.isFromViewer—truewhen sent by the authenticated session holder. Use this for left/right bubble layout.deliveredAt— Unix ms (not seconds). Nullable.
Worked example response
{
"ok": true,
"conversationUrn": "urn:li:msg_conversation:(urn:li:fsd_profile:ACoAAA…,2-MWE…)",
"messages": [
{
"messageUrn": "urn:li:msg_message:(urn:li:fsd_profile:ACoAAA…,2-MWE…)",
"conversationUrn": "urn:li:msg_conversation:(urn:li:fsd_profile:ACoAAA…,2-MWE…)",
"text": "Sure, happy to chat — Tuesday at 2pm work?",
"deliveredAt": 1715990400000,
"senderUrn": "urn:li:fsd_profile:ACoAAA…aaaa",
"senderName": "Jane Doe",
"senderSlug": "jane-doe-1a2b3c",
"attachmentCount": 0,
"reactionCount": 0,
"isFromViewer": false
},
{
"messageUrn": "urn:li:msg_message:(urn:li:fsd_profile:ACoAAA…,2-XYZ…)",
"conversationUrn": "urn:li:msg_conversation:(urn:li:fsd_profile:ACoAAA…,2-MWE…)",
"text": "Hey Jane — quick one about your team's cold outbound setup. Got 5 minutes this week?",
"deliveredAt": 1715986800000,
"senderUrn": "urn:li:fsd_profile:ACoAAA…me",
"senderName": "Me",
"senderSlug": "me-1a2b3c",
"attachmentCount": 0,
"reactionCount": 0,
"isFromViewer": true
}
]
}
Path parameters
conversationUrnrequired string | URL-encoded `urn:li:msg_conversation:(…)` — pass through `encodeURIComponent()` before substituting. Source: the `conversationUrn` field on each conversation returned by `GET /linkedin/conversations`. |
Query parameters
sessionIdrequired string |
Responses
okboolean | |
conversationUrnstring | |
messagesobject[] | |
messageUrnstring | `urn:li:msg_message:(…)`. Stable identifier. |
conversationUrnstring | Echoes the path parameter; convenient for downstream filtering. |
textstring | Plain text body. Empty string for attachment-only messages — check `attachmentCount > 0`. |
deliveredAtinteger | Unix **ms** (not seconds). |
senderUrnstring | Profile URN. Null only on system messages. |
senderNamestring | Display name, typically `"First Last"`. Null on system messages. |
senderSlugstring | `linkedin.com/in/<slug>` segment. Build a profile URL with `https://www.linkedin.com/in/${senderSlug}/` instead of doing a separate lookup. |
attachmentCountinteger | Number of files/images in this message. Non-zero with empty `text` = attachment-only. |
reactionCountinteger | Total emoji reactions on this message. |
isFromViewerboolean | `true` when sent by the authenticated session holder. Use this for left/right bubble layout rather than comparing `senderUrn` against the viewer URN. |
Authentication
Send your API key in the X-API-Key header (or Authorization: Bearer <key>). Any prefix accepted by this endpoint — tk_, wk_, ak_, or sa_ — is documented in the key prefix table.