Messaging & Activity API

Overview


The Messaging & Activity API lets you retrieve LinkedIn conversation history and recent automation activity. 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 have been 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 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 guidance on calculating the signature, please refer to 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 - the robot 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, the robot 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 out 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 or STACKED 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.