Messaging & Activity API

Overview

The Dux-Soup Messaging & Activity API lets you retrieve LinkedIn conversation history and recent automation activity from outside Dux-Soup. Use it to pull the latest messages for a profile into your CRM, sync conversation threads across multiple profiles in bulk, or audit which actions Dux-Soup has recently executed (and whether they succeeded).

All Messaging & Activity API calls are made against your Remote Control endpoint:

https://app.dux-soup.com/xapi/remote/control/{{USERID}}/...      


Required fields

All Dux-Soup API requests must include a signed X-Dux-Signature header. For POST   and PUT requests, include a JSON body containing targeturl, timestamp, and userid. For comprehensive guidance on obtaining the Authentication Key and calculating the signature, please refer to Connecting to, and Authenticating API calls.

Field Description

X-Dux-Signature  

(header)

HMAC signature calculated from your Authentication Key
targeturl    The target URL of the command (should start with https://app.dux-soup.com   )
userid    The userid the command is sent to; should match the userid in the target URL
timestamp    Current Unix time in milliseconds; must be within 5 minutes of the current time

You can generate curl  commands or execute calls directly at https://app.dux-soup.com/web/rc/test - the easiest way to try any endpoint on this page.


Get Recent Messages

Returns the recent conversation history for a single profile.

URL: https://app.dux-soup.com/xapi/remote/control/{{USERID}}/conversations/{{PROFILEID}}/recent   

HTTP method: GET

Query parameters:

Field Description
direction    all , incoming , or outgoing    (mandatory, String)
limit    Maximum number of message objects to return (optional, Number)

{{PROFILEID}}    is mandatory. If it's omitted from the URL, the call fails with a 404 - Dux-Soup does not treat it as an optional path segment despite the URL structure suggesting otherwise.


Example request

curl -v -XGET -H 'X-Dux-Signature: {{SIGNATURE}}' -H 'Content-type: application/json' 'https://app.dux-soup.com/xapi/remote/control/{{USERID}}/conversations/{{PROFILEID}}/recent?direction=all'

Other variations:

curl -v -XGET -H 'X-Dux-Signature: {{SIGNATURE}}' -H 'Content-type: application/json' 'https://app.dux-soup.com/xapi/remote/control/{{USERID}}/conversations/{{PROFILEID}}/recent?direction=incoming'

curl -v -XGET -H 'X-Dux-Signature: {{SIGNATURE}}' -H 'Content-type: application/json' 'https://app.dux-soup.com/xapi/remote/control/{{USERID}}/conversations/{{PROFILEID}}/recent?direction=outgoing&limit=10'

Example response

{
  "success": true,
  "data": [
    {
      "timestamp": "2026-06-19T17:03:50.886Z",
      "direction": "incoming",
      "type": "MEMBER_TO_MEMBER",
      "text": "Thanks for the connection",
      "name": "Cathy Kitterman"
    },
    {
      "timestamp": "2026-06-18T23:00:00.000Z",
      "direction": "incoming",
      "type": "INVITATION_ACCEPT",
      "text": "",
      "name": "Cathy Kitterman"
    }
  ]
}

Behavior notes

  • If {{PROFILEID}}    is missing from the URL, Dux-Soup returns a plain 404 HTML error page rather than a JSON error body, since the request never reaches the API route.
  • Message type  reflects the underlying LinkedIn event (e.g. MEMBER_TO_MEMBER    for a direct message, INVITATION_ACCEPT    for a connection acceptance). Find more about Message events here.

Get Recent Messages (bulk)

Returns recent conversation history for multiple profiles in a single call.

URL: https://app.dux-soup.com/xapi/remote/control/{{USERID}}/conversations/recent/batch   

HTTP method: POST

HTTP body: a JSON object with the following attributes, in addition to the required fields.

Query parameters:

Field Description
profileid   Array of Dux-Soup internal profile IDs (optional, Array of String). An empty array returns an empty result set rather than an error.
direction    all   , incoming   , or outgoing    (mandatory, String)
limit    Maximum number of message objects to return per profile (optional, Number)

Unlike the single-profile endpoint, profileid is  optional here - omitting it (or passing an empty array) does not raise an error; it simply returns "data": [] .


Example request

curl -v -XPOST -H 'X-Dux-Signature: {{SIGNATURE}}' -H 'Content-type: application/json' -d '{
  "targeturl": "https://app.dux-soup.com/xapi/remote/control/{{USERID}}/conversations/recent/batch",
  "userid": "{{USERID}}",
  "timestamp": 1783502534497,
  "profileids": ["id.548182024"],
  "direction": "all",
  "limit": 100
}' 'https://app.dux-soup.com/xapi/remote/control/{{USERID}}/conversations/recent/batch'

Example response

{
  "success": true,
  "data": [
    {
      "profileid": "id.66667975",
      "messages": [
        {
          "timestamp": "2026-06-19T17:03:50.886Z",
          "direction": "incoming",
          "type": "MEMBER_TO_MEMBER",
          "text": "Thanks for the connection",
          "name": "Cathy Kitterman"
        },
        {
          "timestamp": "2026-06-18T23:00:00.000Z",
          "direction": "incoming",
          "type": "INVITATION_ACCEPT",
          "text": "",
          "name": "Cathy Kitterman"
        }
      ]
    },
    {
      "profileid": "id.548182024",
      "messages": [
        {
          "timestamp": "2026-06-18T00:10:00.818Z",
          "direction": "incoming",
          "type": "MEMBER_TO_MEMBER",
          "text": "Thanks for connecting.",
          "name": "Gintarė Kuzminskaitė"
        }
      ]
    }
  ]
}

Empty-array example:

// Request profileids: []
{ "success": true, "data": [] }

Behavior notes

  • The response returns one entry per requested profile, each containing its own messages  array, so results don't need to be manually grouped by profile on your side.
  • Passing an empty profileid  array is a valid, no-op call - useful for health-checking the endpoint without pulling any real conversation data.

Get Recent Actions

Returns a log of recent automation actions Dux-Soup has executed, with success/failure status for each.

URL: https://app.dux-soup.com/xapi/remote/control/{{USERID}}/actions/recent   

HTTP method: GET

Query parameters:

Field Description
campaignid    Restrict results to a specific campaign (optional, string).
profileid    Restrict results to a specific profile (optional, string)
type   

Command type to filter on (optional, String). One of: visit   , enroll   , connect   , message   , inmail   , endorse   , follow   , likepost   , savetopdf   , tag   , untag   , disconnect   , saveaslead   

Please review the LinkedIn Activity API documentation for more information on commands.

successflag    Filter to successful (true   ) or failed (false   ) actions only (optional, Boolean)
days    How many days back Dux-Soup should look (optional, Number)
limit    Maximum number of action objects to return (optional, Number)

All query parameters are optional and can be combined freely to narrow the result set.


Example request

curl -v -XGET -H 'X-Dux-Signature: {{SIGNATURE}}' -H 'Content-type: application/json' 'https://app.dux-soup.com/xapi/remote/control/{{USERID}}/actions/recent?campaignid=default&profileid={{PROFILEID}}&type=connect&days=100&limit=100'

Filtering to only successful actions of a given type:

curl -v -XGET -H 'X-Dux-Signature: {{SIGNATURE}}' -H 'Content-type: application/json' 'https://app.dux-soup.com/xapi/remote/control/{{USERID}}/actions/recent?campaignid=default&profileid={{PROFILEID}}&type=connect&successflag=true&days=100&limit=100'

Filtering across all action types for a profile:

curl -v -XGET -H 'X-Dux-Signature: {{SIGNATURE}}' -H 'Content-type: application/json' 'https://app.dux-soup.com/xapi/remote/control/{{USERID}}/actions/recent?campaignid=default&profileid={{PROFILEID}}&successflag=true&days=100&limit=100'

Example response

{
  "success": true,
  "data": [
    {
      "when": "2026-06-16T06:09:48.547Z",
      "type": "connectProfile",
      "profileid": "id.1597569",
      "campaignid": "default",
      "success": true,
      "result": "[object Object]"
    },
    {
      "when": "2026-06-11T16:24:34.116Z",
      "type": "likepostProfile",
      "profileid": "id.872152742",
      "campaignid": "default",
      "success": true,
      "result": "Required field not found: '.react-button__trigger[aria-pressed=false],button:has(svg[id*=thumbs-up]'"
    }
  ]
}

The type  query parameter accepts RC command type names (connect , likepost , etc.)  - these describe the command as submitted, not yet an executed action. The type  value returned in each action object in data , however, is the corresponding action name (connectProfile , likepostProfile , etc.) -  this is the action that was actually attempted, and is what carries a success  /result  outcome.