> ## Documentation Index
> Fetch the complete documentation index at: https://docs.oneshotagent.com/llms.txt
> Use this file to discover all available pages before exploring further.

# List Messages

> Synced LinkedIn messages for a connected account, newest first.

Returns the account's synced messages, newest first, filterable by conversation, direction, and time. Free, proof-signed, keyset-paginated on `(sent_at, id)` so a growing inbox never shifts a page.

## Query

<ParamField query="conversation_id" type="string" optional>Restrict to one conversation.</ParamField>
<ParamField query="direction" type="string" optional>`inbound` (the human received it) or `outbound` (the human, or an agent through this account, sent it).</ParamField>
<ParamField query="since" type="string" optional>ISO time. Returns only messages **sent** after it. `direction=inbound` + `since` is the reply watermark for a cadence engine.</ParamField>
<ParamField query="changed_since" type="string" optional>ISO time. Returns only messages edited, read or deleted after it.</ParamField>
<ParamField query="cursor" type="string" optional>`next_cursor` from the previous page.</ParamField>
<ParamField query="limit" type="number" default="50">1–100.</ParamField>
<ParamField query="include_deleted" type="boolean" default="false">Include messages deleted upstream (kept with `deleted: true`).</ParamField>

## Response

```json theme={null}
{
  "messages": [
    {
      "id": "…",
      "conversation_id": "…",
      "provider_message_id": "…",
      "direction": "inbound",
      "sender_provider_id": "…",
      "sender_name": "Sam Rivera",
      "text": "Happy to chat next week — Tuesday?",
      "sent_at": "2026-09-15T11:58:00.000Z",
      "seen": false,
      "edited": false,
      "deleted": false,
      "attachments": [ { "id": "…", "type": "img", "mimetype": "image/png", "size": 48211, "file_name": null } ],
      "source": "webhook",
      "ingested_at": "2026-09-15T11:58:04.000Z",
      "updated_at": "2026-09-15T11:58:04.000Z"
    }
  ],
  "next_cursor": null,
  "has_more": false,
  "coverage": { "…": "…" },
  "sync_state": "complete"
}
```

* `source` says who first stored the row: `sync` (a history run), `webhook` (real-time), or `send` (a reply through this account).
* Attachments are **metadata only**. Download URLs are never stored, so they cannot leak. Downloading is not available in v1.
* Edits keep only the latest text plus an `edited` flag. There is no edit history upstream.

## Stop-on-reply pattern

Walk the whole window before you move the watermark.

```typescript theme={null}
// Walk every page before moving the watermark: results are newest-first,
// so advancing it after page one would skip anything on later pages.
let cursor: string | undefined;
let newest: string | undefined;
do {
  const page = await agent.linkedinMessages({ accountId, direction: 'inbound', since: watermark, limit: 100, cursor });
  for (const m of page.messages) {
    // m.conversation_id → your prospect; stop the cadence, record the reply
    if (!newest || m.sent_at > newest) newest = m.sent_at;
  }
  cursor = page.has_more ? page.next_cursor! : undefined;
} while (cursor);
if (newest) watermark = newest; // only after the whole window was processed
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.