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 |
|---|---|
|
(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
curlcommands 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
typereflects the underlying LinkedIn event (e.g.MEMBER_TO_MEMBERfor a direct message,INVITATION_ACCEPTfor 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
messagesarray, so results don't need to be manually grouped by profile on your side. - Passing an empty
profileidarray 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: 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
typequery parameter accepts RC command type names (connect,likepost, etc.) - these describe the command as submitted, not yet an executed action. Thetypevalue returned in each action object indata, however, is the corresponding action name (connectProfile,likepostProfile, etc.) - this is the action that was actually attempted, and is what carries asuccess/resultoutcome.