Record How A Conversation Went
li_mark_outcomeRecord the human verdict on a conversation: won, meeting_booked (a call is on the calendar — NOT won), interested (they want to talk, nothing booked yet), not_interested, or no_outcome (it ran its course and nothing came of it). A demo request or a booked call is never won. This is orthogonal to the message status, which only ever says where the AUTOMATION stopped — a deal and a dead end are both handed_off, and nothing in the pipeline can tell them apart, so a person marks it.
Mark up to the batch limit at once with profileUrls — after working a queue the verdict is usually the same for several people, and it was the one mark that still cost a call each.
Marking an outcome CLOSES the conversation: every SCHEDULED step is cancelled and an open sequence moves to handed_off, so no further automated message goes out. A newer message from them REOPENS it (verdict kept), so an interested person who writes back is owed a reply again and leaves li_marked_conversations(dueOnly) until marked again.
For someone who AGREED to a call, use li_track_booking instead of marking interested by hand: it marks interested AND schedules the booking check that li_booking_due works from. A booked call is li_mark_booked (outcome meeting_booked plus the calendar event). Marking not_interested/no_outcome closes an open booking; meeting_booked marks it booked.
⚠️ It does NOT reach a message already handed to the queue. A reply you queued with li_send_reply moments ago is a job on its way to a browser, and nothing consults the outcome before it types — so marking somebody not_interested does not stop the answer you just sent them. Check li_job_result before marking if that matters. Pass outcome=null to clear a mis-mark — that only unsets the verdict and revives nothing; use li_reset_contact to put a contact back into the sequence.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| note | No | Why — stored with the verdict and in the timeline | |
| outcome | Yes | won | meeting_booked | interested | not_interested | no_outcome, or null to clear a mis-mark. Applies to every contact in this call. | |
| contactId | No | One contact by id (from li_contact_dossier or li_campaign_contacts), instead of profileUrl | |
| messageId | No | The exact message row, when you already have it from a dossier or a queue read. | |
| sessionId | No | The account this conversation is on. Only used when the person is in NO campaign: then a light record is created on this account so the mark has something to act on. Needed only when you have more than one account. | |
| campaignId | No | Which campaign membership to act on. A contact can be in more than one campaign, and without this the row is whichever was touched last — so stopping them in one campaign while leaving the other running was not possible. Pass it whenever the contact might be in two. | |
| profileUrl | No | One contact, by profile URL | |
| profileUrls | No | Several contacts in ONE call, max 200. Each is resolved and marked independently: one refusal does not stop the rest, and the reply reports every one by URL. | |
| sessionLabel | No | Same, by account label | |
| conversationUrn | No | The thread, straight from li_list_conversations (single-person form). Recorded on the conversation so the live inbox recognises it as decided. On its own it finds the person only when their thread is already stored — pass profileUrl (the participantProfileId / ACoAA… URL) too. | |
| participantName | No | Their name from li_list_conversations — kept on a newly recorded contact. |