BrightshoalDocsOpen console
MenuConversations

API reference

Conversations

Web chat conversations with their messages, costs and lead. Your team can take one over, reply as a person and hand it back to the assistant.

List conversations

GET/api/conversations

Web chat and WhatsApp conversations, newest first by default, one cursor page at a time. Each row is the conversation without its messages; fetch one by id for the transcript. Test conversations are left out unless include_test=true.

Secret API key. How it works

Query parameters

  • project_idstring

    Only this project's conversations (an org-wide key sees every project by default).

  • assistant_idarray of string

    Only these assistants' conversations. Repeat the parameter or comma-separate the values; a row matching any of them is kept.

  • statusstring

    Only open or only ended conversations.

    One of open ended

  • qstring

    Case-insensitive literal substring across conversation id and lead name/email.

  • fromstringISO 8601 timestamp

    Created at or after this time (ISO 8601 with an offset).

  • tostringISO 8601 timestamp

    Created at or before this time (ISO 8601 with an offset).

  • engagementstring

    engaged: the visitor replied at least once. no_reply: they never did.

    One of engaged no_reply all

    Default "all"

  • handoffstring

    requested: a handoff was asked for. pending: asked for, nobody has taken over, chat open. answered: a human took over at or after the request. missed: the chat ended before anyone took over (never an abandoned chat). missed_in_hours: missed, asked while advisors were said to be available. out_of_hours: asked while advisors were said to be unavailable (outside working hours). active: someone holds the seat now. taken_over: a human took over at least once, asked for or not. abandoned: a human took over and then left the visitor waiting (human_outcome abandoned).

    One of requested pending answered missed missed_in_hours out_of_hours active taken_over abandoned

  • include_testboolean

    Test chats (metadata.test, e.g. the console's test chat) are left out unless this is true. Ignored when mode is given.

    Default false

  • modestring

    Which chats to include, by the mode the server gave each. Absent: test and preview chats are left out, and so are live chats a page marked as a test, as before. live: every live-mode chat, including those a page marked as a test. test: test-mode chats. preview: preview chats. all: every chat.

    One of live test preview all

  • needs_reviewboolean

    When true, only conversations whose analysis flagged the human advisor's replies with severity 2 or more (see ConversationAnalysis.human_review).

  • taken_over_bystring

    Only conversations this operator id (the takeover agent.id) holds or held.

  • sortstring

    Sort by creation time or by number of messages.

    One of created_at message_count

    Default "created_at"

  • dirstring

    Sort direction.

    One of asc desc

    Default "desc"

  • cursorstring

    next_cursor from the previous page. Keep the same filters and sort while paging.

  • limitinteger1 to 200

    Page size.

    Default 50

  • include_totalboolean

    When true, the response carries total: the number of conversations matching every filter, ignoring the cursor.

    Default false

Returns

200 OK

Response attributes
  • dataarray of Conversationrequired

    41 attributes
    • idstring

    • conversation_idstring

      Alias used by the public resume surface.

    • org_idstring

    • project_idstring

    • assistant_idstring

    • widget_key_idstring | null

    • channelstring

      One of web_chat whatsapp

    • modestring

      Set by the server from the key the chat came in on: test chats run the draft, preview chats send nothing out.

      One of live test preview

    • statusstringrequired

      One of open ended

    • ended_reasonstring | null

      One of visitor_ended idle_timeout max_messages error

    • resumableboolean

      Public resume surface: ended only because the visitor went quiet, so the next message reopens it.

    • handoff_requested_atstring | nullISO 8601 timestamp

    • taken_over_atstring | nullISO 8601 timestamp

    • taken_over_heartbeat_atstring | nullISO 8601 timestamp

    • taken_over_bystring | null

    • taken_over_by_namestring | null

    • taken_overboolean

    • first_taken_over_atstring | nullISO 8601 timestamp

      First time a human took over; unlike taken_over_at, never cleared.

    • handoff_answered_atstring | nullISO 8601 timestamp

      First takeover at or after handoff_requested_at.

    • handoff_in_hoursboolean | null

      Whether the bot told the visitor advisors were available when they first asked for a person, by the assistant's working hours (none configured counts as available). Null when unknown, as on requests from before 7 October 2026 without a stored answer.

    • handoff_statusstring

      missed: the chat ended before anyone took over. abandoned: a human took over and then left the visitor waiting; it takes precedence over the others.

      One of none pending answered missed abandoned

    • handoff_answer_secondsinteger | null

    • human_outcomestring | null

      Null when no human took part. handled: every visitor message to the human got a human reply. abandoned: at least one did not, before the bot replied, the chat ended, or (chat still open) 5 minutes passed. Recomputed when a seat is released, when the chat ends, and on each analysis run.

      One of handled abandoned

    • human_metricsHumanMetrics | null

      One of 2 shapes

      HumanMetrics

      • first_response_secondsinteger | nullrequired

        From the first takeover to the first human message.

      • longest_wait_secondsinteger | nullrequired

        The longest a visitor waited on the human, answered or not.

      • unanswered_countintegerrequired

        Visitor messages to the human that no human answered.

      • agent_message_countintegerrequired

      Option 2

    • needs_reviewboolean

      Operator list only: the analysis flagged the human advisor's replies with severity 2 or more.

    • visitor_idstring | null

    • parent_originstring | null

    • last_message_atstring | nullISO 8601 timestamp

    • message_countinteger

    • lead_idstring | null

    • metadataobject | null

    • callbackobject | null

      One of 2 shapes

      Option 1

      • phonestringrequired

      • slot_startstringISO 8601 timestamp

      • notestring

      • requested_atstringrequiredISO 8601 timestamp

      Option 2

    • ended_atstring | nullISO 8601 timestamp

    • created_atstringISO 8601 timestamp

    • updated_atstringISO 8601 timestamp

    • messagesarray of ConversationMessage

      12 attributes
      • idstringrequired

      • conversation_idstring

      • org_idstring

      • project_idstring

      • rolestringrequired

        One of user assistant agent tool system

      • contentstringrequired

      • richRichContent | null

        4 attributes
        • quick_repliesarray of object

          2 attributes
          • labelstringrequired

          • valuestringrequired

        • buttonsarray of object

          3 attributes
          • typestringrequired

            One of link

          • labelstringrequired

          • urlstringrequireduri

        • metadataobject

          3 attributes
          • pageobject

            Visitor messages from the web widget: the page they sent the message from.

            2 attributes
            • pathstringrequired

            • titlestringrequired

          • channelstring

            A turn spoken in a voice session of this conversation rather than typed.

            One of voice

          • voice_session_idstring

            The voice session the turn was spoken in.

        • attachmentsarray of ConversationAttachment

          Files sent with the message. Each url is a signed link that works without credentials.

          5 attributes
          • idstringrequired

          • namestringrequired

          • content_typestringrequired

            One of image/jpeg image/png image/webp image/gif application/pdf application/vnd.openxmlformats-officedocument.wordprocessingml.document

          • sizeintegerrequired

            Bytes.

          • urlstringrequireduri

            Signed download link (GET /public/chat/attachments/{id}), valid for 24 hours (7 days in webhooks).

      • tool_callsarray of object | null

      • tool_call_idstring | null

      • seqinteger

      • created_atstringrequiredISO 8601 timestamp

      • updated_atstringISO 8601 timestamp

    • costsarray of object

    • leadLead | null

      One of 2 shapes

      Lead

      • idstringrequired

      • org_idstringrequired

      • project_idstringrequired

      • assistant_idstringrequired

      • conversation_idstring | null

      • namestring | null

      • emailstring | nullemail

      • phonestring | null

      • fieldsobject | null

      • sourcestringrequired

        One of web_chat whatsapp

      • modestring

        The mode of the chat that captured it: test and preview leads are left out of lists unless asked for.

        One of live test preview

      • outcomestring | null

        What became of the lead, as your CRM reports it (PUT /leads/{id}/outcome).

        One of open booked lost

      • outcome_valuestring | null

        Booking value as a decimal string.

      • outcome_currencystring | null

      • outcome_atstring | nullISO 8601 timestamp

      • outcome_refstring | null

        The CRM's own id for the booking.

      • customer_idstring | null

        The customer's own id for this person, set with PUT /v1/leads/{id}/outcome.

      • attributionChatAttribution | null

        Where the lead's chat came from. Returned by the list and detail reads; null when none was recorded.

        One of 2 shapes

        ChatAttribution

        • chat_pagestring

          The path the visitor started chatting on.

        • visitChatAttributionTouch

          This visit's landing.

          12 attributes
          • landing_pagestring

            A path starting with /, without query or fragment.

          • referrer_hoststring

          • utm_sourcestring

          • utm_mediumstring

          • utm_campaignstring

          • utm_termstring

          • utm_contentstring

          • gclidstring

          • gbraidstring

          • wbraidstring

          • fbclidstring

          • msclkidstring

        • firstobject

          The visitor's first-ever landing.

          13 attributes
          • landing_pagestring

            A path starting with /, without query or fragment.

          • referrer_hoststring

          • utm_sourcestring

          • utm_mediumstring

          • utm_campaignstring

          • utm_termstring

          • utm_contentstring

          • gclidstring

          • gbraidstring

          • wbraidstring

          • fbclidstring

          • msclkidstring

          • atstringISO 8601 timestamp

            When the visitor first landed.

        Option 2

      • created_atstringISO 8601 timestamp

      • updated_atstringISO 8601 timestamp

      Option 2

    • summarystring | null

      Operator list only: the latest background summary, when analysis is on.

    • analysisConversationAnalysis | null

      Operator detail only: the latest background summary and extracted facts.

      One of 2 shapes

      ConversationAnalysis

      • summarystring | nullrequired

      • structuredobjectrequired

        The configured channels.web_chat.analysis.fields the chat stated, keyed by field key.

      • through_seqintegerrequired

        The last message seq the run read.

      • human_reviewHumanReview | null

        Null when no human took part.

        One of 2 shapes

        HumanReview

        • flagsarray of objectrequired

          3 attributes
          • codestringrequired

            One of unanswered_question spelling_grammar unprofessional_tone broken_promise wrong_fact other left_mid_chat slow_reply

          • severityintegerrequired1 to 3

          • evidencestringrequiredup to 200 characters

            A paraphrase; never contact details.

        • reviewed_through_seqintegerrequired

          The last message seq the model review read.

        Option 2

      • needs_reviewboolean

        human_review has a flag of severity 2 or more.

      • updated_atstringrequiredISO 8601 timestamp

      Option 2

    • live_handoffboolean

      Operator detail only: whether the org takes web chats over live. When false, takeover is refused with 409 live_handoff_disabled.

  • next_cursorstring | nullrequired

    Opaque pagination cursor.

  • has_morebooleanrequired

  • totalintegermin 0

    Conversations matching the filters across all pages. Present only when include_total=true.

  • live_handoffbooleanrequired

    Whether the org takes web chats over live. When false, takeover is refused and handoff requests are callback requests.

  • 400 Validation error: usually invalid_request, with the failing fields in issues when there are any
  • 401 Missing, malformed, unknown or revoked API key (unauthorized)
  • 429 Rate limit exceeded (rate_limited). Wait Retry-After seconds. Budgets are per 60-second window: developer API 120 per key and 600 per organization; public chat 30 per IP address, except polling for updates (60 per conversation and IP address) and analytics events (120 per IP address).
GET /api/conversations
curl "https://api.myleadsfactory.tech/api/conversations" \
  -H "Authorization: Bearer $MLF_API_KEY"
Response 200
{
  "data": [
    {
      "id": "conv_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
      "conversation_id": "conv_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
      "org_id": "org_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
      "project_id": "proj_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
      "assistant_id": "asst_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
      "widget_key_id": "id_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
      "channel": "web_chat",
      "mode": "live",
      "status": "open",
      "ended_reason": "visitor_ended",
      "resumable": true,
      "handoff_requested_at": "2026-10-28T09:30:00.000Z",
      "taken_over_at": "2026-10-28T09:30:00.000Z",
      "taken_over_heartbeat_at": "2026-10-28T09:30:00.000Z",
      "taken_over_by": "string",
      "taken_over_by_name": "string",
      "taken_over": true,
      "first_taken_over_at": "2026-10-28T09:30:00.000Z",
      "handoff_answered_at": "2026-10-28T09:30:00.000Z",
      "handoff_in_hours": true,
      "handoff_status": "none",
      "handoff_answer_seconds": 1,
      "human_outcome": "handled",
      "human_metrics": {
        "first_response_seconds": 1,
        "longest_wait_seconds": 1,
        "unanswered_count": 1,
        "agent_message_count": 1
      },
      "needs_review": true,
      "visitor_id": "id_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
      "parent_origin": "https://www.example.com",
      "last_message_at": "2026-10-28T09:30:00.000Z",
      "message_count": 1,
      "lead_id": "lead_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
      "metadata": {},
      "callback": {
        "phone": "+14155550123",
        "slot_start": "2026-10-28T09:30:00.000Z",
        "note": "string",
        "requested_at": "2026-10-28T09:30:00.000Z"
      },
      "ended_at": "2026-10-28T09:30:00.000Z",
      "created_at": "2026-10-28T09:30:00.000Z",
      "updated_at": "2026-10-28T09:30:00.000Z",
      "messages": [
        {
          "id": "conv_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
          "conversation_id": "conv_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
          "org_id": "org_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
          "project_id": "proj_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
          "role": "user",
          "content": "Hi, can I book a trip to Lisbon in May?",
          "rich": {
            "quick_replies": {},
            "buttons": {},
            "metadata": {},
            "attachments": {}
          },
          "tool_calls": [
            {}
          ],
          "tool_call_id": "call_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
          "seq": 1,
          "created_at": "2026-10-28T09:30:00.000Z",
          "updated_at": "2026-10-28T09:30:00.000Z"
        }
      ],
      "costs": [
        {}
      ],
      "lead": {
        "id": "lead_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
        "org_id": "org_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
        "project_id": "proj_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
        "assistant_id": "asst_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
        "conversation_id": "conv_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
        "name": "Front desk",
        "email": "ana@example.com",
        "phone": "+14155550123",
        "fields": {
          "key": {}
        },
        "source": "web_chat",
        "mode": "live",
        "outcome": "open",
        "outcome_value": "string",
        "outcome_currency": "string",
        "outcome_at": "2026-10-28T09:30:00.000Z",
        "outcome_ref": "string",
        "customer_id": "id_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
        "attribution": {},
        "created_at": "2026-10-28T09:30:00.000Z",
        "updated_at": "2026-10-28T09:30:00.000Z"
      },
      "summary": "string",
      "analysis": {
        "summary": "string",
        "structured": {},
        "through_seq": 1,
        "human_review": {},
        "needs_review": true,
        "updated_at": "2026-10-28T09:30:00.000Z"
      },
      "live_handoff": true
    }
  ],
  "next_cursor": "eyJ0IjoiMjAyNi0xMC0yOCJ9",
  "has_more": true,
  "total": 1,
  "live_handoff": true
}

Get a conversation

GET/api/conversations/{id}

The conversation with its messages, usage lines, lead and latest analysis. Tool and system rows, and assistant tool-call steps, are returned only to instance staff, org admins and owners, and API keys. Members and viewers get the transcript the visitor saw.

Secret API key. How it works

Path parameters

  • idstringrequired

    Conversation id, conv_....

Returns

200 OK

Response attributes
  • dataConversationrequired

    41 attributes
    • idstring

    • conversation_idstring

      Alias used by the public resume surface.

    • org_idstring

    • project_idstring

    • assistant_idstring

    • widget_key_idstring | null

    • channelstring

      One of web_chat whatsapp

    • modestring

      Set by the server from the key the chat came in on: test chats run the draft, preview chats send nothing out.

      One of live test preview

    • statusstringrequired

      One of open ended

    • ended_reasonstring | null

      One of visitor_ended idle_timeout max_messages error

    • resumableboolean

      Public resume surface: ended only because the visitor went quiet, so the next message reopens it.

    • handoff_requested_atstring | nullISO 8601 timestamp

    • taken_over_atstring | nullISO 8601 timestamp

    • taken_over_heartbeat_atstring | nullISO 8601 timestamp

    • taken_over_bystring | null

    • taken_over_by_namestring | null

    • taken_overboolean

    • first_taken_over_atstring | nullISO 8601 timestamp

      First time a human took over; unlike taken_over_at, never cleared.

    • handoff_answered_atstring | nullISO 8601 timestamp

      First takeover at or after handoff_requested_at.

    • handoff_in_hoursboolean | null

      Whether the bot told the visitor advisors were available when they first asked for a person, by the assistant's working hours (none configured counts as available). Null when unknown, as on requests from before 7 October 2026 without a stored answer.

    • handoff_statusstring

      missed: the chat ended before anyone took over. abandoned: a human took over and then left the visitor waiting; it takes precedence over the others.

      One of none pending answered missed abandoned

    • handoff_answer_secondsinteger | null

    • human_outcomestring | null

      Null when no human took part. handled: every visitor message to the human got a human reply. abandoned: at least one did not, before the bot replied, the chat ended, or (chat still open) 5 minutes passed. Recomputed when a seat is released, when the chat ends, and on each analysis run.

      One of handled abandoned

    • human_metricsHumanMetrics | null

      One of 2 shapes

      HumanMetrics

      • first_response_secondsinteger | nullrequired

        From the first takeover to the first human message.

      • longest_wait_secondsinteger | nullrequired

        The longest a visitor waited on the human, answered or not.

      • unanswered_countintegerrequired

        Visitor messages to the human that no human answered.

      • agent_message_countintegerrequired

      Option 2

    • needs_reviewboolean

      Operator list only: the analysis flagged the human advisor's replies with severity 2 or more.

    • visitor_idstring | null

    • parent_originstring | null

    • last_message_atstring | nullISO 8601 timestamp

    • message_countinteger

    • lead_idstring | null

    • metadataobject | null

    • callbackobject | null

      One of 2 shapes

      Option 1

      • phonestringrequired

      • slot_startstringISO 8601 timestamp

      • notestring

      • requested_atstringrequiredISO 8601 timestamp

      Option 2

    • ended_atstring | nullISO 8601 timestamp

    • created_atstringISO 8601 timestamp

    • updated_atstringISO 8601 timestamp

    • messagesarray of ConversationMessage

      12 attributes
      • idstringrequired

      • conversation_idstring

      • org_idstring

      • project_idstring

      • rolestringrequired

        One of user assistant agent tool system

      • contentstringrequired

      • richRichContent | null

        4 attributes
        • quick_repliesarray of object

          2 attributes
          • labelstringrequired

          • valuestringrequired

        • buttonsarray of object

          3 attributes
          • typestringrequired

            One of link

          • labelstringrequired

          • urlstringrequireduri

        • metadataobject

          3 attributes
          • pageobject

            Visitor messages from the web widget: the page they sent the message from.

            2 attributes
            • pathstringrequired

            • titlestringrequired

          • channelstring

            A turn spoken in a voice session of this conversation rather than typed.

            One of voice

          • voice_session_idstring

            The voice session the turn was spoken in.

        • attachmentsarray of ConversationAttachment

          Files sent with the message. Each url is a signed link that works without credentials.

          5 attributes
          • idstringrequired

          • namestringrequired

          • content_typestringrequired

            One of image/jpeg image/png image/webp image/gif application/pdf application/vnd.openxmlformats-officedocument.wordprocessingml.document

          • sizeintegerrequired

            Bytes.

          • urlstringrequireduri

            Signed download link (GET /public/chat/attachments/{id}), valid for 24 hours (7 days in webhooks).

      • tool_callsarray of object | null

      • tool_call_idstring | null

      • seqinteger

      • created_atstringrequiredISO 8601 timestamp

      • updated_atstringISO 8601 timestamp

    • costsarray of object

    • leadLead | null

      One of 2 shapes

      Lead

      • idstringrequired

      • org_idstringrequired

      • project_idstringrequired

      • assistant_idstringrequired

      • conversation_idstring | null

      • namestring | null

      • emailstring | nullemail

      • phonestring | null

      • fieldsobject | null

      • sourcestringrequired

        One of web_chat whatsapp

      • modestring

        The mode of the chat that captured it: test and preview leads are left out of lists unless asked for.

        One of live test preview

      • outcomestring | null

        What became of the lead, as your CRM reports it (PUT /leads/{id}/outcome).

        One of open booked lost

      • outcome_valuestring | null

        Booking value as a decimal string.

      • outcome_currencystring | null

      • outcome_atstring | nullISO 8601 timestamp

      • outcome_refstring | null

        The CRM's own id for the booking.

      • customer_idstring | null

        The customer's own id for this person, set with PUT /v1/leads/{id}/outcome.

      • attributionChatAttribution | null

        Where the lead's chat came from. Returned by the list and detail reads; null when none was recorded.

        One of 2 shapes

        ChatAttribution

        • chat_pagestring

          The path the visitor started chatting on.

        • visitChatAttributionTouch

          This visit's landing.

          12 attributes
          • landing_pagestring

            A path starting with /, without query or fragment.

          • referrer_hoststring

          • utm_sourcestring

          • utm_mediumstring

          • utm_campaignstring

          • utm_termstring

          • utm_contentstring

          • gclidstring

          • gbraidstring

          • wbraidstring

          • fbclidstring

          • msclkidstring

        • firstobject

          The visitor's first-ever landing.

          13 attributes
          • landing_pagestring

            A path starting with /, without query or fragment.

          • referrer_hoststring

          • utm_sourcestring

          • utm_mediumstring

          • utm_campaignstring

          • utm_termstring

          • utm_contentstring

          • gclidstring

          • gbraidstring

          • wbraidstring

          • fbclidstring

          • msclkidstring

          • atstringISO 8601 timestamp

            When the visitor first landed.

        Option 2

      • created_atstringISO 8601 timestamp

      • updated_atstringISO 8601 timestamp

      Option 2

    • summarystring | null

      Operator list only: the latest background summary, when analysis is on.

    • analysisConversationAnalysis | null

      Operator detail only: the latest background summary and extracted facts.

      One of 2 shapes

      ConversationAnalysis

      • summarystring | nullrequired

      • structuredobjectrequired

        The configured channels.web_chat.analysis.fields the chat stated, keyed by field key.

      • through_seqintegerrequired

        The last message seq the run read.

      • human_reviewHumanReview | null

        Null when no human took part.

        One of 2 shapes

        HumanReview

        • flagsarray of objectrequired

          3 attributes
          • codestringrequired

            One of unanswered_question spelling_grammar unprofessional_tone broken_promise wrong_fact other left_mid_chat slow_reply

          • severityintegerrequired1 to 3

          • evidencestringrequiredup to 200 characters

            A paraphrase; never contact details.

        • reviewed_through_seqintegerrequired

          The last message seq the model review read.

        Option 2

      • needs_reviewboolean

        human_review has a flag of severity 2 or more.

      • updated_atstringrequiredISO 8601 timestamp

      Option 2

    • live_handoffboolean

      Operator detail only: whether the org takes web chats over live. When false, takeover is refused with 409 live_handoff_disabled.

  • 401 Missing, malformed, unknown or revoked API key (unauthorized)
  • 404 Not found, or outside what the key can see
  • 429 Rate limit exceeded (rate_limited). Wait Retry-After seconds. Budgets are per 60-second window: developer API 120 per key and 600 per organization; public chat 30 per IP address, except polling for updates (60 per conversation and IP address) and analytics events (120 per IP address).
GET /api/conversations/{id}
curl "https://api.myleadsfactory.tech/api/conversations/CONVERSATION_ID" \
  -H "Authorization: Bearer $MLF_API_KEY"
Response 200
{
  "data": {
    "id": "conv_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "conversation_id": "conv_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "org_id": "org_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "project_id": "proj_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "assistant_id": "asst_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "widget_key_id": "id_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "channel": "web_chat",
    "mode": "live",
    "status": "open",
    "ended_reason": "visitor_ended",
    "resumable": true,
    "handoff_requested_at": "2026-10-28T09:30:00.000Z",
    "taken_over_at": "2026-10-28T09:30:00.000Z",
    "taken_over_heartbeat_at": "2026-10-28T09:30:00.000Z",
    "taken_over_by": "string",
    "taken_over_by_name": "string",
    "taken_over": true,
    "first_taken_over_at": "2026-10-28T09:30:00.000Z",
    "handoff_answered_at": "2026-10-28T09:30:00.000Z",
    "handoff_in_hours": true,
    "handoff_status": "none",
    "handoff_answer_seconds": 1,
    "human_outcome": "handled",
    "human_metrics": {
      "first_response_seconds": 1,
      "longest_wait_seconds": 1,
      "unanswered_count": 1,
      "agent_message_count": 1
    },
    "needs_review": true,
    "visitor_id": "id_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "parent_origin": "https://www.example.com",
    "last_message_at": "2026-10-28T09:30:00.000Z",
    "message_count": 1,
    "lead_id": "lead_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "metadata": {},
    "callback": {
      "phone": "+14155550123",
      "slot_start": "2026-10-28T09:30:00.000Z",
      "note": "string",
      "requested_at": "2026-10-28T09:30:00.000Z"
    },
    "ended_at": "2026-10-28T09:30:00.000Z",
    "created_at": "2026-10-28T09:30:00.000Z",
    "updated_at": "2026-10-28T09:30:00.000Z",
    "messages": [
      {
        "id": "conv_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
        "conversation_id": "conv_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
        "org_id": "org_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
        "project_id": "proj_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
        "role": "user",
        "content": "Hi, can I book a trip to Lisbon in May?",
        "rich": {
          "quick_replies": [
            {}
          ],
          "buttons": [
            {}
          ],
          "metadata": {
            "page": {},
            "channel": "voice",
            "voice_session_id": {}
          },
          "attachments": [
            {}
          ]
        },
        "tool_calls": [
          {}
        ],
        "tool_call_id": "call_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
        "seq": 1,
        "created_at": "2026-10-28T09:30:00.000Z",
        "updated_at": "2026-10-28T09:30:00.000Z"
      }
    ],
    "costs": [
      {}
    ],
    "lead": {
      "id": "lead_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
      "org_id": "org_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
      "project_id": "proj_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
      "assistant_id": "asst_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
      "conversation_id": "conv_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
      "name": "Front desk",
      "email": "ana@example.com",
      "phone": "+14155550123",
      "fields": {
        "key": "string"
      },
      "source": "web_chat",
      "mode": "live",
      "outcome": "open",
      "outcome_value": "string",
      "outcome_currency": "string",
      "outcome_at": "2026-10-28T09:30:00.000Z",
      "outcome_ref": "string",
      "customer_id": "id_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
      "attribution": {
        "chat_page": {},
        "visit": {},
        "first": {}
      },
      "created_at": "2026-10-28T09:30:00.000Z",
      "updated_at": "2026-10-28T09:30:00.000Z"
    },
    "summary": "string",
    "analysis": {
      "summary": "string",
      "structured": {},
      "through_seq": 1,
      "human_review": {
        "flags": {},
        "reviewed_through_seq": {}
      },
      "needs_review": true,
      "updated_at": "2026-10-28T09:30:00.000Z"
    },
    "live_handoff": true
  }
}

The visits this conversation's visitor made to the site

GET/api/conversations/{id}/journey

Up to 20 recent visits, newest first, across the organization's projects, by the conversation's visitor id and by the visitor ids of other conversations in the same organization whose lead shares its email, phone number (digits only, at least 7) or customer id (at most 10 visitors, listed in visitors); test traffic excluded. A conversation without a visitor id (no analytics consent, or an older widget) and without linked chats returns visitors and visits empty.

Secret API key. How it works

Path parameters

  • idstringrequired

Returns

200 OK

Response attributes
  • dataVisitorJourneyrequired

    4 attributes
    • visitor_idstring | nullrequired

    • visitorsarray of objectrequired

      The visitor ids whose visits are listed: this conversation's own, plus those of conversations in the same organization whose lead shares an email, phone number or customer id. At most 10.

      3 attributes
      • visitor_idstringrequired

      • linked_bystringrequired

        One of this_chat email phone customer_id

      • conversation_idsarray of stringrequired

    • visitsarray of objectrequired

      14 attributes
      • visit_idstringrequired

      • visitor_idstringrequired

      • sitestring | nullrequired

        The site of the visit's earliest event.

      • visit_numberinteger | nullrequired

      • started_atstringrequiredISO 8601 timestamp

      • last_atstringrequiredISO 8601 timestamp

      • landing_pagestring | nullrequired

      • sourcestringrequired

        utm_source, else the referrer host, else direct.

      • page_viewsintegerrequired

      • pagesarray of stringrequired

        The first 10 distinct pages, in the order visited.

      • opened_reasonstring | nullrequired

        One of proactive visitor api

      • sentbooleanrequired

      • conversation_idsarray of stringrequired

      • is_this_conversationbooleanrequired

    • truncatedbooleanrequired

      True when the visitor has more than 20 visits.

  • 401 Missing, malformed, unknown or revoked API key (unauthorized)
  • 404 Not found, or outside what the key can see
  • 429 Rate limit exceeded (rate_limited). Wait Retry-After seconds. Budgets are per 60-second window: developer API 120 per key and 600 per organization; public chat 30 per IP address, except polling for updates (60 per conversation and IP address) and analytics events (120 per IP address).
GET /api/conversations/{id}/journey
curl "https://api.myleadsfactory.tech/api/conversations/CONVERSATION_ID/journey" \
  -H "Authorization: Bearer $MLF_API_KEY"
Response 200
{
  "data": {
    "visitor_id": "id_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "visitors": [
      {
        "visitor_id": "id_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
        "linked_by": "this_chat",
        "conversation_ids": [
          "conv_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f"
        ]
      }
    ],
    "visits": [
      {
        "visit_id": "id_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
        "visitor_id": "id_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
        "site": "string",
        "visit_number": 1,
        "started_at": "2026-10-28T09:30:00.000Z",
        "last_at": "2026-10-28T09:30:00.000Z",
        "landing_page": "string",
        "source": "string",
        "page_views": 1,
        "pages": [
          "string"
        ],
        "opened_reason": "proactive",
        "sent": true,
        "conversation_ids": [
          "conv_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f"
        ],
        "is_this_conversation": true
      }
    ],
    "truncated": true
  }
}

Send a message as a person

POST/api/conversations/{id}/messages

Only the operator holding the seat may send (403 otherwise). With client_message_id, a retry by the same operator returns the original message instead of sending it again; reusing the id for different content is 409 client_message_id_reused.

Secret API key, not read-only. How it works

Path parameters

  • idstringrequired

    Conversation id, conv_....

Request body

  • contentstringrequiredup to 4000 characters

  • agentAgentIdentityInput

    3 attributes
    • idstring

    • emailstringemail

    • namestring

  • client_message_idstringup to 200 characters

    Unique per message from this operator; makes a retried send safe.

Returns

201 OK

Response attributes
  • dataConversationMessagerequired

    12 attributes
    • idstringrequired

    • conversation_idstring

    • org_idstring

    • project_idstring

    • rolestringrequired

      One of user assistant agent tool system

    • contentstringrequired

    • richRichContent | null

      4 attributes
      • quick_repliesarray of object

        2 attributes
        • labelstringrequired

        • valuestringrequired

      • buttonsarray of object

        3 attributes
        • typestringrequired

          One of link

        • labelstringrequired

        • urlstringrequireduri

      • metadataobject

        3 attributes
        • pageobject

          Visitor messages from the web widget: the page they sent the message from.

          2 attributes
          • pathstringrequired

          • titlestringrequired

        • channelstring

          A turn spoken in a voice session of this conversation rather than typed.

          One of voice

        • voice_session_idstring

          The voice session the turn was spoken in.

      • attachmentsarray of ConversationAttachment

        Files sent with the message. Each url is a signed link that works without credentials.

        5 attributes
        • idstringrequired

        • namestringrequired

        • content_typestringrequired

          One of image/jpeg image/png image/webp image/gif application/pdf application/vnd.openxmlformats-officedocument.wordprocessingml.document

        • sizeintegerrequired

          Bytes.

        • urlstringrequireduri

          Signed download link (GET /public/chat/attachments/{id}), valid for 24 hours (7 days in webhooks).

    • tool_callsarray of object | null

    • tool_call_idstring | null

    • seqinteger

    • created_atstringrequiredISO 8601 timestamp

    • updated_atstringISO 8601 timestamp

  • 400 Validation error: usually invalid_request, with the failing fields in issues when there are any
  • 401 Missing, malformed, unknown or revoked API key (unauthorized)
  • 403 Refused, for example a read-only key on a write (read_only_key), a role too low for the route (insufficient_role), or a route that needs a console session
  • 404 Not found, or outside what the key can see
  • 409 Conflict
  • 429 Rate limit exceeded (rate_limited). Wait Retry-After seconds. Budgets are per 60-second window: developer API 120 per key and 600 per organization; public chat 30 per IP address, except polling for updates (60 per conversation and IP address) and analytics events (120 per IP address).
POST /api/conversations/{id}/messages
curl -X POST "https://api.myleadsfactory.tech/api/conversations/CONVERSATION_ID/messages" \
  -H "Authorization: Bearer $MLF_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "content": "Hi Ana, this is Alex from Acme Travel. Happy to help with Lisbon.",
  "agent": {
    "id": "operator_1"
  }
}'
Response 201
{
  "data": {
    "id": "conv_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "conversation_id": "conv_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "org_id": "org_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "project_id": "proj_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "role": "user",
    "content": "Hi, can I book a trip to Lisbon in May?",
    "rich": {
      "quick_replies": [
        {
          "label": "string",
          "value": "string"
        }
      ],
      "buttons": [
        {
          "type": "link",
          "label": "string",
          "url": "https://example.com/hook"
        }
      ],
      "metadata": {
        "page": {
          "path": "string",
          "title": "Front desk"
        },
        "channel": "voice",
        "voice_session_id": "id_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f"
      },
      "attachments": [
        {
          "id": "conv_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
          "name": "Front desk",
          "content_type": "image/jpeg",
          "size": 1,
          "url": "https://example.com/hook"
        }
      ]
    },
    "tool_calls": [
      {}
    ],
    "tool_call_id": "call_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "seq": 1,
    "created_at": "2026-10-28T09:30:00.000Z",
    "updated_at": "2026-10-28T09:30:00.000Z"
  }
}

Hand a conversation back to the assistant

POST/api/conversations/{id}/release

The holder releases their own seat; org admins and API keys may release anyone's, which is recorded as a forced release naming the previous holder. Send the same agent you took over with, so the release is recorded as yours rather than forced. Release still works when the org has turned live handoff off.

Secret API key, not read-only. How it works

Path parameters

  • idstringrequired

    Conversation id, conv_....

Request body

  • agentAgentIdentityInput

    3 attributes
    • idstring

    • emailstringemail

    • namestring

Returns

200 OK

Response attributes
  • dataConversationTakeoverrequired

    5 attributes
    • idstringrequired

    • statusstringrequired

      One of open ended

    • taken_over_atstring | nullrequiredISO 8601 timestamp

    • taken_over_heartbeat_atstring | nullrequiredISO 8601 timestamp

    • taken_over_bystring | nullrequired

  • 401 Missing, malformed, unknown or revoked API key (unauthorized)
  • 403 Refused, for example a read-only key on a write (read_only_key), a role too low for the route (insufficient_role), or a route that needs a console session
  • 404 Not found, or outside what the key can see
  • 409 Conflict
  • 429 Rate limit exceeded (rate_limited). Wait Retry-After seconds. Budgets are per 60-second window: developer API 120 per key and 600 per organization; public chat 30 per IP address, except polling for updates (60 per conversation and IP address) and analytics events (120 per IP address).
POST /api/conversations/{id}/release
curl -X POST "https://api.myleadsfactory.tech/api/conversations/CONVERSATION_ID/release" \
  -H "Authorization: Bearer $MLF_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "agent": {
    "id": "id_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "email": "ana@example.com"
  }
}'
Response 200
{
  "data": {
    "id": "conv_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "status": "open",
    "taken_over_at": "2026-10-28T09:30:00.000Z",
    "taken_over_heartbeat_at": "2026-10-28T09:30:00.000Z",
    "taken_over_by": "string"
  }
}

Take over a conversation

POST/api/conversations/{id}/takeover

Only one operator holds a seat: when another already does, 409 already_taken_over names them in taken_over_by. Taking over a seat you hold refreshes it. 409 live_handoff_disabled when the org does not take web chats over live. Heartbeat and operator messages refuse the same way. With an API key, name the person in agent (otherwise the holder is api_key) and send the same agent on every message, heartbeat and release. A seat with no heartbeat for three minutes is released.

Secret API key, not read-only. How it works

Path parameters

  • idstringrequired

    Conversation id, conv_....

Request body

  • agentAgentIdentityInput

    3 attributes
    • idstring

    • emailstringemail

    • namestring

Returns

200 OK

Response attributes
  • dataConversationTakeoverrequired

    5 attributes
    • idstringrequired

    • statusstringrequired

      One of open ended

    • taken_over_atstring | nullrequiredISO 8601 timestamp

    • taken_over_heartbeat_atstring | nullrequiredISO 8601 timestamp

    • taken_over_bystring | nullrequired

  • 401 Missing, malformed, unknown or revoked API key (unauthorized)
  • 403 Refused, for example a read-only key on a write (read_only_key), a role too low for the route (insufficient_role), or a route that needs a console session
  • 404 Not found, or outside what the key can see
  • 409 Conflict
  • 429 Rate limit exceeded (rate_limited). Wait Retry-After seconds. Budgets are per 60-second window: developer API 120 per key and 600 per organization; public chat 30 per IP address, except polling for updates (60 per conversation and IP address) and analytics events (120 per IP address).
POST /api/conversations/{id}/takeover
curl -X POST "https://api.myleadsfactory.tech/api/conversations/CONVERSATION_ID/takeover" \
  -H "Authorization: Bearer $MLF_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "agent": {
    "id": "operator_1",
    "name": "Alex"
  }
}'
Response 200
{
  "data": {
    "id": "conv_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "status": "open",
    "taken_over_at": "2026-10-28T09:30:00.000Z",
    "taken_over_heartbeat_at": "2026-10-28T09:30:00.000Z",
    "taken_over_by": "string"
  }
}

Keep a takeover alive

POST/api/conversations/{id}/takeover/heartbeat

Call at least once a minute while a person is working the chat. A seat with no heartbeat for three minutes is released and the assistant answers again. Send the same agent you took over with.

Secret API key, not read-only. How it works

Path parameters

  • idstringrequired

    Conversation id, conv_....

Request body

  • agentAgentIdentityInput

    3 attributes
    • idstring

    • emailstringemail

    • namestring

Returns

200 OK

Response attributes
  • dataConversationTakeoverHeartbeatrequired

    1 attribute
    • taken_over_heartbeat_atstringrequiredISO 8601 timestamp

  • 401 Missing, malformed, unknown or revoked API key (unauthorized)
  • 403 Refused, for example a read-only key on a write (read_only_key), a role too low for the route (insufficient_role), or a route that needs a console session
  • 404 Not found, or outside what the key can see
  • 409 Conflict
  • 429 Rate limit exceeded (rate_limited). Wait Retry-After seconds. Budgets are per 60-second window: developer API 120 per key and 600 per organization; public chat 30 per IP address, except polling for updates (60 per conversation and IP address) and analytics events (120 per IP address).
POST /api/conversations/{id}/takeover/heartbeat
curl -X POST "https://api.myleadsfactory.tech/api/conversations/CONVERSATION_ID/takeover/heartbeat" \
  -H "Authorization: Bearer $MLF_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "agent": {
    "id": "id_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "email": "ana@example.com"
  }
}'
Response 200
{
  "data": {
    "taken_over_heartbeat_at": "2026-10-28T09:30:00.000Z"
  }
}

Summarize human handoffs

GET/api/conversations/handoff-summary

Conversations created in the range (inclusive), test conversations excluded unless mode says otherwise. answer_seconds runs from the handoff request to the first takeover. first_response_seconds and longest_wait_seconds are taken over the conversations with human_metrics.

Secret API key. How it works

Query parameters

  • project_idstring

    Only this project's conversations.

  • assistant_idarray of string

    Only these assistants' conversations. Repeat the parameter or comma-separate the values; a row matching any of them is kept.

  • fromstringISO 8601 timestamp

    Created at or after this time.

  • tostringISO 8601 timestamp

    Created at or before this time.

  • modestring

    Which chats to include, by the mode the server gave each. Absent: test and preview chats are left out, and so are live chats a page marked as a test, as before. live: every live-mode chat, including those a page marked as a test. test: test-mode chats. preview: preview chats. all: every chat.

    One of live test preview all

Returns

200 OK

Response attributes
  • dataConversationHandoffSummaryrequired

    18 attributes
    • conversationsintegerrequired

    • requestedintegerrequired

    • pendingintegerrequired

    • answeredintegerrequired

    • missedintegerrequired

    • requested_in_hoursintegerrequired

      Requests made while advisors were said to be available.

    • requested_out_of_hoursintegerrequired

      Requests made outside working hours, when the bot offers a callback instead.

    • missed_in_hoursintegerrequired

    • missed_out_of_hoursintegerrequired

    • taken_overintegerrequired

      Conversations a human took over, requested or not.

    • abandonedintegerrequired

      Conversations a human took over and then left the visitor waiting.

    • handledintegerrequired

      Conversations a human took part in where every visitor message to them got a human reply.

    • unanswered_messagesintegerrequired

      Visitor messages to a human that no human answered, summed.

    • callbacksintegerrequired

      Conversations where the visitor left a callback request.

    • live_handoffbooleanrequired

      Whether the org takes web chats over live. When false, requests for a person are callback requests only.

    • answer_secondsSecondsPercentilesrequired

      2 attributes
      • medianinteger | nullrequired

      • p90integer | nullrequired

    • first_response_secondsSecondsPercentilesrequired

      From the first takeover to the first human message.

      2 attributes
      • medianinteger | nullrequired

      • p90integer | nullrequired

    • longest_wait_secondsSecondsPercentilesrequired

      Each conversation's longest wait for the human, answered or not.

      2 attributes
      • medianinteger | nullrequired

      • p90integer | nullrequired

  • 400 Validation error: usually invalid_request, with the failing fields in issues when there are any
  • 401 Missing, malformed, unknown or revoked API key (unauthorized)
  • 429 Rate limit exceeded (rate_limited). Wait Retry-After seconds. Budgets are per 60-second window: developer API 120 per key and 600 per organization; public chat 30 per IP address, except polling for updates (60 per conversation and IP address) and analytics events (120 per IP address).
GET /api/conversations/handoff-summary
curl "https://api.myleadsfactory.tech/api/conversations/handoff-summary" \
  -H "Authorization: Bearer $MLF_API_KEY"
Response 200
{
  "data": {
    "conversations": 1,
    "requested": 1,
    "pending": 1,
    "answered": 1,
    "missed": 1,
    "requested_in_hours": 1,
    "requested_out_of_hours": 1,
    "missed_in_hours": 1,
    "missed_out_of_hours": 1,
    "taken_over": 1,
    "abandoned": 1,
    "handled": 1,
    "unanswered_messages": 1,
    "callbacks": 1,
    "live_handoff": true,
    "answer_seconds": {
      "median": 1,
      "p90": 1
    },
    "first_response_seconds": {
      "median": 1,
      "p90": 1
    },
    "longest_wait_seconds": {
      "median": 1,
      "p90": 1
    }
  }
}

Count a project's test data

GET/api/test-data

What POST /v1/test-data/clear would delete now: test-mode and preview chats, their files, the leads they captured, and test telemetry. An estimate, as tests may start meanwhile.

Secret API key. How it works

Query parameters

  • project_idstringrequired

Returns

200 OK

Response attributes
  • dataobjectrequired

    6 attributes
    • project_idstringrequired

    • conversationsintegerrequired

      Test and preview chats there are now.

    • leadsintegerrequired

      Test and preview leads.

    • eventsintegerrequired

      Chat events and request outcomes.

    • attachmentsintegerrequired

      Uploaded files.

    • callsinteger

      Finished test calls (with their costs, analysis and recording rows).

  • 400 Validation error: usually invalid_request, with the failing fields in issues when there are any
  • 401 Missing, malformed, unknown or revoked API key (unauthorized)
  • 403 Refused, for example a read-only key on a write (read_only_key), a role too low for the route (insufficient_role), or a route that needs a console session
  • 404 Not found, or outside what the key can see
  • 429 Rate limit exceeded (rate_limited). Wait Retry-After seconds. Budgets are per 60-second window: developer API 120 per key and 600 per organization; public chat 30 per IP address, except polling for updates (60 per conversation and IP address) and analytics events (120 per IP address).
GET /api/test-data
curl "https://api.myleadsfactory.tech/api/test-data?project_id=proj_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f" \
  -H "Authorization: Bearer $MLF_API_KEY"
Response 200
{
  "data": {
    "project_id": "proj_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "conversations": 1,
    "leads": 1,
    "events": 1,
    "attachments": 1,
    "calls": 1
  }
}

Clear a project's test and preview chats and leads

POST/api/test-data/clear

Deletes the project's test-mode and preview chats started before the request (with their messages, files, analysis, telemetry and webhook events) and the leads they captured. Live chats are never touched, nor are live chats whose page only claimed to be a test. Sends no webhooks. Returns what it deleted.

Secret API key, not read-only. How it works

Request body

  • project_idstringrequired

Returns

200 OK

Response attributes
  • dataobjectrequired

    7 attributes
    • project_idstringrequired

    • conversationsintegerrequired

      Test and preview chats deleted.

    • leadsintegerrequired

      Test and preview leads.

    • eventsintegerrequired

      Chat events and request outcomes.

    • attachmentsintegerrequired

      Uploaded files.

    • callsinteger

      Finished test calls (with their costs, analysis and recording rows).

    • attachment_failuresinteger

      Files whose delete failed (logged).

  • 400 Validation error: usually invalid_request, with the failing fields in issues when there are any
  • 401 Missing, malformed, unknown or revoked API key (unauthorized)
  • 403 Refused, for example a read-only key on a write (read_only_key), a role too low for the route (insufficient_role), or a route that needs a console session
  • 404 Not found, or outside what the key can see
  • 429 Rate limit exceeded (rate_limited). Wait Retry-After seconds. Budgets are per 60-second window: developer API 120 per key and 600 per organization; public chat 30 per IP address, except polling for updates (60 per conversation and IP address) and analytics events (120 per IP address).
POST /api/test-data/clear
curl -X POST "https://api.myleadsfactory.tech/api/test-data/clear" \
  -H "Authorization: Bearer $MLF_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "project_id": "proj_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f"
}'
Response 200
{
  "data": {
    "project_id": "proj_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "conversations": 1,
    "leads": 1,
    "events": 1,
    "attachments": 1,
    "calls": 1,
    "attachment_failures": 1
  }
}