Replies Needing An Answer
li_replies_to_answerContacts who REPLIED and are awaiting a human/Claude answer (auto follow-ups already stopped). DB-backed and instant.
WORK THE WHOLE QUEUE IN THREE CALLS: ask for it with includeThread=true and each row arrives with the end of its stored conversation already attached, so there is no per-person read at all; draft every answer; send them together with li_send_reply's replies array. Without includeThread this is the queue alone and each person costs a second call to li_conversation_history.
THE QUEUE IS DERIVED FROM THE CONVERSATION, so a person leaves it by being answered — not by being marked. It drops anyone whose newest message from us is newer than their last word, which means a reply sent with li_send_reply clears the row BY ITSELF, but only once the send actually lands (it is queued, so that is minutes, not seconds) and only when it went out from the account on the row's own accountId — which li_send_reply now routes to for you, so you can hand this queue straight to it without grouping. Until then they are still here: read li_job_result, never re-send.
⚠️ THE ROW LEAVING THIS QUEUE IS NOT THE SAME AS THE CONVERSATION BEING CLOSED. Answering writes no status anywhere, so the contact still reads "needs reply" on their dossier and on the campaign, and the reply rate still counts them. li_mark_reply_handled is what records that a person dealt with it — call it after you answer, and call it for a conversation you are simply not going to answer.
⚠️ DO NOT use it to put somebody down for a while — it closes the conversation with no date to come back on. li_snooze_reply is that. Either way, a NEW message from them after the close or the snooze reopens it: the row comes back here carrying reopened (with what it had been marked, which is kept).
An answer somebody typed BY HAND in LinkedIn needs none of that: the inbox sweep (about hourly) notices a thread we already owed that now ends on our own message, stores it, and the row leaves this queue by itself. It runs only about hourly, so it can lag — force it with li_sweep_inbox (no selector sweeps every account) rather than reading threads one by one to check.
Each row carries WHO THEY ARE — name, headline, role, company and location, filled from research already bought for that person, so drafting needs no li_contact_dossier call. Plus campaignName (which sequence they are in, so you answer in the right offer's voice) and the two ends of the stored thread, theirLastAt and ourLastAt — their last word four days ago with nothing from us since is somebody genuinely waiting. Both null means this thread has never been read; theirLastAt alone can be the moment their reply was DETECTED when the thread itself was never stored. A row never shows our last message newer than theirs.
⚠️ An attached thread is the STORED one, so it can lag and it can be empty — empty means nobody has read that thread yet, NEVER that they did not write. For those, li_read_conversation fetches it live (a browser session, minutes) and stores it for next time. Record how it went afterwards with li_mark_outcome.
A row flagged bookingPending: true is somebody the booking link went to or who agreed to a call, and who has WRITTEN BACK since — answer what they said; they are deliberately NOT in li_booking_due, and a booking nudge on top of their message is refused. 🚨 Rows with bookingCheckRequired: true (our link is out, or a call is booked) need a CALENDAR SEARCH for that person before you write anything: people book within minutes of saying yes, and this server reads no calendar. Booked → send nothing, li_mark_booked. Not booked → answer, and li_send_reply with calendarChecked: true (refused without it). bookingHint says which. booking carries the state when one is tracked, and companyDomain their employer's web domain.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Most rows to return (default 100); `truncated` says when there are more | |
| sessionId | No | Limit to one account by id (li_list_accounts). Needed (or sessionLabel) when you have more than one account. | |
| sessionLabel | No | Limit to one account by label, LinkedIn name, profile slug or member id. Needed (or sessionId) when you have more than one account. | |
| includeThread | No | Attach the end of each stored conversation to its row, so drafting needs no second call per person. Off by default because it is the difference between a queue and a queue plus every thread in it; threads are attached to at most the first 25 rows and the reply says when it stopped. | |
| sessionLabels | No | Several accounts in ONE call, by label. Leaving every selector off already spans all your accounts, which is usually what you want; this is for "these three of my six". Each label must match exactly one of your accounts — a name shared by two is refused rather than guessed. | |
| threadMessages | No | How many of the most recent messages to attach per thread (default 6). Still returned oldest-first. Message text is never cut — a truncated question is the one thing that would make the answer wrong. |