# Overview

How messaging works in Linked API: send messages and replies, receive new messages from every conversation through the inbox, and load a person's earlier history once when you need it.

Messaging in Linked API covers two things: **sending** messages and **reading** them. For reading, start with the inbox – it catches every new message on the account; load a person's earlier history only once, when you need it.

| Task | Tool |
|---|---|
| Send a message to a person | [`st.sendMessage`](/docs/action-st-send-message) with `personUrl` |
| Reply into an existing conversation | [`st.sendMessage`](/docs/action-st-send-message) with `threadId` |
| Archive, star, or mute a conversation | [`st.manageConversation`](/docs/action-st-manage-conversation) |
| Receive new messages from everyone | [`st.syncInbox`](/docs/action-st-sync-inbox) once per account, then [`/inbox/poll`](/docs/monitoring-inbox#polling) or [`inbox.*` webhook events](/docs/webhooks#inbox-events) |
| Read the whole conversation with one person | [`/inbox/poll` with `personUrl`](/docs/monitoring-inbox#polling-one-person) |
| Get a person's messages from before the inbox was enabled | [`st.syncConversation`](/docs/action-st-sync-conversation) once for that person |

> 💡 For **Sales Navigator**, use the same flow with the `nv.` actions: [`nv.sendMessage`](/docs/action-nv-send-message) sends InMail to people you are not connected to, and [`nv.syncInbox`](/docs/action-nv-sync-inbox), [`nv.syncConversation`](/docs/action-nv-sync-conversation) and [`nv.manageConversation`](/docs/action-nv-manage-conversation) work like their standard counterparts. The same `/inbox/poll` endpoint returns both inboxes, tagged with a `type`.

## Sending

[`st.sendMessage`](/docs/action-st-send-message) sends a message from your account, the same way you would in LinkedIn. Address it by the person's `personUrl` to message a 1st-degree connection, or by a `threadId` from inbox polling to reply into a conversation you already have – no profile URL needed. To archive, star, or mute the conversation right after sending, add [`st.manageConversation`](/docs/action-st-manage-conversation) as a child action; on its own, it manages any conversation by `threadId`.

See [Sending messages](/docs/sending-message) for examples.

## Reading

Everything you read comes from one endpoint, `/inbox/poll`. It draws on two sources:

- **Inbox.** Enable monitoring once per account with [`st.syncInbox`](/docs/action-st-sync-inbox). From that moment, a periodic sync captures every new message in every conversation, both incoming and the ones you send. Poll them with an advancing `since`, or receive them as [webhook events](/docs/webhooks#inbox-events). See [Monitoring inbox](/docs/monitoring-inbox).
- **History.** The inbox does not import anything from before it was enabled. When you need earlier messages with a specific person, run [`st.syncConversation`](/docs/action-st-sync-conversation) for them once. It is a one-time load, not a way to check for new messages – those keep arriving through the inbox. See [Loading conversation history](/docs/working-with-conversations).

Pass `personUrl` to `/inbox/poll` to get the whole known conversation with one person from both sources, each message once. Its `threads` tell you how far back the history goes: if `historyComplete` is `false` and you need more, that is when to load the history.

> 💡 `/conversations/poll`, the previous way to read loaded conversations, keeps working, but new code should use `/inbox/poll` with `personUrl`.

### Did this lead reply?

A common check after outreach: did the person answer your message? Enable inbox monitoring **before** you send – it captures only messages that arrive after it is turned on, so a reply that came earlier will not be there. Then poll [`/inbox/poll`](/docs/monitoring-inbox#polling-one-person) with their `personUrl` and `since` set a few minutes before you sent your message:

```json
{
  "personUrl": "https://www.linkedin.com/in/person1",
  "since": "2023-03-14T10:20:00Z"
}
```

Message times are whole minutes, so a reply sent in the same minute as your message can carry a time earlier than the exact moment you sent yours. Pass the `type` of your message (`st` or `nv`) and take the **earliest** message with `sender` `us` in the result – the one you sent; later messages of yours, such as follow-ups, must not move this point. Treat a message whose `sender` is `them` and whose `time` is not earlier than it as the reply. If your message is not in the result yet, the periodic sync has not captured it, and the answer is not known yet – not "no reply". A `them` message in the same minute as yours is ambiguous: with minute precision it may have been sent just before yours. If you store people by public URL, see [which URL to pass](/docs/monitoring-inbox#polling-one-person). A reply appears only after the periodic sync captures it, so an empty result means there is no reply **yet** – poll again later, or subscribe to the `inbox.messageReceived` [webhook event](/docs/webhooks#inbox-events) instead of polling.

For a walkthrough of the whole flow from the first message to the reply, see [How to automate LinkedIn messages](/guides/how-to-automate-linkedin-messages).
