Team Monitoring API (admin)

Overview

The Dux-Soup Team Monitoring API lets team/agency admins retrieve data across the accounts they manage, from outside Dux-Soup. Use it to list which accounts and Campaigns are under your management, check whether each managed account's automation is currently running, pull aggregate or per-member Campaign KPIs, and page through funnel data across the team.

This is an admin-level API - it's only usable by accounts that manage other accounts (team/agency plans). It also uses a different base path from the other Dux-Soup APIs: remote/team rather than remote/control.

All Team Monitoring API calls are made against your Remote Team endpoint:

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

{{USERID}}  here is the admin/managing account's userid, not the userid of the individual managed account you're asking about.

Required fields

All Dux-Soup API calls require a signed X-Dux-Signature header; POST requests require a JSON body containing targeturl, timestamp, and userid. For full details on generating the Authentication Key and calculating the signature, see 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.


List Managed Accounts

Returns every account the admin manages, including each account's userid, name, email, license key, and configured Campaigns.

URL: https://app.dux-soup.com/xapi/remote/team/{{USERID}}/accounts

HTTP method: POST

HTTP body: the required fields only - no additional attributes.

Example request

curl -v -XPOST -H 'X-Dux-Signature: {{SIGNATURE}}' -H 'Content-type: application/json' -d '{
  "targeturl": "https://app.dux-soup.com/xapi/remote/team/{{USERID}}/accounts",
  "userid": "{{USERID}}",
  "timestamp": 1785497592200
}' 'https://app.dux-soup.com/xapi/remote/team/{{USERID}}/accounts'

Example response

{
  "success": true,
  "data": [
    {
      "userid": "{{MANAGED_USERID_1}}",
      "name": "somenouns maybe",
      "email": "somenouns@gmail.com",
      "licensekey": "CMZ8-I9FB-JTSF-OIYA",
      "campaigns": [
        { "id": "default", "name": "Default" },
        { "id": "gin-visit-connect-marketing-women", "name": "Gin visit&connect Marketing Women" },
        { "id": "test", "name": "Test" }
      ],
      "isSelf": false
    },
    {
      "userid": "{{USERID}}",
      "name": "Vlada Dux",
      "email": "vlada@dux-soup.com",
      "licensekey": null,
      "campaigns": [
        { "id": "default", "name": "Default" },
        { "id": "new-july", "name": "July" },
        { "id": "visit", "name": "Visit" },
        { "id": "1st-degree-july", "name": "1st-degree-july" },
        { "id": "sent-invites", "name": "Sent invites" }
      ],
      "isSelf": true
    }
  ]
}

Behavior notes

  • isSelf indicates whether that entry is the admin account making the API call, as opposed to one of the other accounts it manages. The calling account is always included in the returned list alongside the accounts it manages.
  • licensekey can be null  - observed on the calling admin's own entry (isSelf: true ) in the example above.
  • Use the userid and campaigns.id values returned here as inputs to the other Team Monitoring endpoints below (members and campaignid ).

Team Run State

Returns the live automation status for one or more managed accounts - whether each account's Dux-Soup extension is currently running, stopped, or ready, along with the LinkedIn profile and connection details it's currently running under.

URL: https://app.dux-soup.com/xapi/remote/team/{{USERID}}/status

HTTP method: POST

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

Field Description
members Array of managed account user IDs to check (optional, Array of String). Omit or leave blank to check all managed accounts.

Example request - specific member

curl -v -XPOST -H 'X-Dux-Signature: {{SIGNATURE}}' -H 'Content-type: application/json' -d '{
  "targeturl": "https://app.dux-soup.com/xapi/remote/team/{{USERID}}/status",
  "userid": "{{USERID}}",
  "timestamp": 1785497500152,
  "members": ["{{USERID}}"]
}' 'https://app.dux-soup.com/xapi/remote/team/{{USERID}}/status'

Example response - specific member

{
  "success": true,
  "data": {
    "members": 1,
    "statuses": [
      {
        "userid": "{{USERID}}",
        "name": "Vlada Dux",
        "profileName": "-",
        "profileURL": "-",
        "clientTimezone": "-",
        "clientIp": "-",
        "statusCode": 1,
        "statusText": "stopped"
      }
    ]
  }
}

Example request - all managed accounts

curl -v -XPOST -H 'X-Dux-Signature: {{SIGNATURE}}' -H 'Content-type: application/json' -d '{
  "targeturl": "https://app.dux-soup.com/xapi/remote/team/{{USERID}}/status",
  "userid": "{{USERID}}",
  "timestamp": 1785497434002
}' 'https://app.dux-soup.com/xapi/remote/team/{{USERID}}/status'

Example response - all managed accounts

{
  "success": true,
  "data": {
    "members": 2,
    "statuses": [
      {
        "userid": "{{MANAGED_USERID_1}}",
        "name": "somenouns maybe",
        "profileName": "Sam Summers",
        "profileURL": "https://www.linkedin.com/in/sam-summers-a00620305",
        "clientTimezone": "Pacific/Auckland",
        "clientIp": "217.61.246.239",
        "statusCode": 5,
        "statusText": "ready",
        "linkedinpage": null
      },
      {
        "userid": "{{USERID}}",
        "name": "Vlada Dux",
        "profileName": "-",
        "profileURL": "-",
        "clientTimezone": "-",
        "clientIp": "-",
        "statusCode": 1,
        "statusText": "stopped"
      }
    ]
  }
}

Behavior notes

  • Omitting members  (or leaving it blank) returns statuses for every managed account, not just the admin's own account.
  • When an account's extension isn't currently active, fields like profileName, profileURL, clientTimezone, and clientIp are returned as "-"  placeholders rather than null or being omitted.
  • linkedinpage appears only in some responses (seen on an active/"ready" account but not on a "stopped" one) - treat it as optional in the response shape.

Team Campaign KPIs

Returns aggregate and (optionally) per-member KPI counts for a Campaign across managed accounts - invites sent, connections added, messages sent, response rates, and action success rates.

URL: https://app.dux-soup.com/xapi/remote/team/{{USERID}}/kpis

HTTP method: POST

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

Field Description
members Array of managed account user IDs to include (optional, Array of String)
campaignid Campaign ID to report on (mandatory, String)
rangetype Date range type, e.g. "custom"  (mandatory, String)
fromdate ISO 8601 start date for the reporting range (mandatory when rangetype  is "custom", String)
breakdown Whether to include a perMember  breakdown in addition to the aggregate (optional, Boolean)

Example request

curl -v -XPOST -H 'X-Dux-Signature: {{SIGNATURE}}' -H 'Content-type: application/json' -d '{
  "targeturl": "https://app.dux-soup.com/xapi/remote/team/{{USERID}}/kpis",
  "userid": "{{USERID}}",
  "timestamp": 1785497545685,
  "members": ["{{USERID}}"],
  "campaignid": "default",
  "rangetype": "custom",
  "fromdate": "2025-10-04T11:32:25.685Z",
  "breakdown": true
}' 'https://app.dux-soup.com/xapi/remote/team/{{USERID}}/kpis'

Example response

{
  "success": true,
  "data": {
    "scope": {
      "members": ["{{USERID}}"],
      "campaignid": "default",
      "range": "custom"
    },
    "aggregate": {
      "success": true,
      "timestamp": "2026-07-31T11:32:53.460Z",
      "data": {
        "inmailsentcount": 0,
        "profileinvitedcount": 48,
        "messagesentcount": 0,
        "responsereceivedcount": 0,
        "connectionaddedcount": 22,
        "qualifiedincount": 0,
        "qualifiedoutcount": 1,
        "messagedprofilescount": 0,
        "respondedprofilescount": 0,
        "invitedvsacceptedpercent": 45.83,
        "messagedvsrespondedpercent": 0,
        "successfulactionscount": 887,
        "failedactionscount": 0,
        "successfulactionpercent": 100
      },
      "fromdate": "2025-10-04T11:32:52.684Z",
      "todate": "2026-07-31T11:32:53.460Z",
      "userid": "{{USERID}}"
    },
    "perMember": [
      {
        "userid": "{{USERID}}",
        "name": "Vlada Dux",
        "kpis": {
          "success": true,
          "timestamp": "2026-07-31T11:32:55.170Z",
          "data": {
            "inmailsentcount": 0,
            "profileinvitedcount": 48,
            "messagesentcount": 0,
            "responsereceivedcount": 0,
            "connectionaddedcount": 22,
            "qualifiedincount": 0,
            "qualifiedoutcount": 1,
            "messagedprofilescount": 0,
            "respondedprofilescount": 0,
            "invitedvsacceptedpercent": 45.83,
            "messagedvsrespondedpercent": 0,
            "successfulactionscount": 887,
            "failedactionscount": 0,
            "successfulactionpercent": 100
          },
          "fromdate": "2025-10-04T11:32:52.684Z",
          "todate": "2026-07-31T11:32:53.460Z",
          "userid": "{{USERID}}"
        }
      }
    ]
  }
}

Behavior notes

  • aggregate totals all requested members' KPIs together; each entry in perMember repeats the same KPI field set (data, fromdate, todate, etc.) scoped to a single account, so both views share one consistent shape.
  • breakdown: true is what adds the perMember array - omitting it (or setting it false ) likely returns aggregate only, but this hasn't been confirmed against a live response yet.
  • todate in the response reflects when the KPI calculation actually ran, not a value you supply in the request.

Team Funnel

Returns paginated prospect-level funnel data - profile details and applied tags - across one or more managed accounts, optionally filtered by Campaign, date range, or a specific tag.

URL: https://app.dux-soup.com/xapi/remote/team/{{USERID}}/funnel

HTTP method: POST

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

Field Description
members Array of managed account userids to include (optional, Array of String). Every value supplied must match an account the admin actually manages.
campaignid Campaign ID to filter by (optional, String)
rangetype Date range type, e.g. "custom"  (optional, String)
fromdate ISO 8601 start date for the reporting range (optional, String)
filterTag Restrict results to prospects carrying this specific tag, e.g. a system qualified-out tag (optional, String)
pagesize Number of prospect entries to return per page (optional, Number)
page Page number to retrieve (optional, Number)

Example request - invalid member

curl -v -XPOST -H 'X-Dux-Signature: {{SIGNATURE}}' -H 'Content-type: application/json' -d '{
  "targeturl": "https://app.dux-soup.com/xapi/remote/team/{{USERID}}/funnel",
  "userid": "{{USERID}}",
  "timestamp": 1785497258036,
  "members": ["somenouns"],
  "campaignid": "default",
  "rangetype": "custom",
  "fromdate": "2025-10-04T11:27:38.036Z",
  "filterTag": "🦆-eu-first-campaign-olive-studio-qualified-out",
  "pagesize": 100,
  "page": 2
}' 'https://app.dux-soup.com/xapi/remote/team/{{USERID}}/funnel'

Example response - invalid member

{ "success": false, "message": "No managed accounts match the requested members." }

Example request - all managed accounts

curl -v -XPOST -H 'X-Dux-Signature: {{SIGNATURE}}' -H 'Content-type: application/json' -d '{
  "targeturl": "https://app.dux-soup.com/xapi/remote/team/{{USERID}}/funnel",
  "userid": "{{USERID}}",
  "timestamp": 1785497381203,
  "campaignid": "default",
  "rangetype": "custom",
  "fromdate": "2025-10-04T11:29:41.203Z",
  "pagesize": 100,
  "page": 2
}' 'https://app.dux-soup.com/xapi/remote/team/{{USERID}}/funnel'

Example response - all managed accounts

{
  "success": true,
  "data": [
    {
      "tags": ["🦆-default-enrolled"],
      "userid": "{{USERID}}",
      "id": "{{USERID}}-id.218197366",
      "First_Name": "Cordula",
      "Last_Name": "Ahrens",
      "Title": "Mindsetcoach für Business und Persönlichkeitsentwicklung",
      "Company": "Cordula.Coach",
      "Profile": "https://www.linkedin.com/in/cordulacoach/"
    },
    {
      "tags": ["🦆-default-enrolled", "🦆-default-invited", "🦆-default-accepted"],
      "userid": "{{USERID}}",
      "id": "{{USERID}}-id.217109867",
      "First_Name": "Guy",
      "Last_Name": "Bromwich",
      "Title": "Managing Director at Metrix Accountancy",
      "Company": "Metrix Accountancy",
      "Profile": "https://www.linkedin.com/in/guy-bromwich-34b86260/"
    }
  ]
}

Behavior notes

  • If members contains any userid the admin doesn't actually manage, the entire call fails with "No managed accounts match the requested members."  - this is an all-or-nothing validation on the whole array, not a per-member filter.
  • Omitting members entirely returns funnel data across all managed accounts, rather than requiring the admin's own userid to be listed explicitly.
  • Each returned prospect's id field is composed of {{USERID}}-{{PROFILEID}} , since the same funnel response can span multiple managed accounts and profile IDs are only unique per account.
  • Tags on each entry follow the same system-tag conventions (🦆-{{CAMPAIGNID}}-enrolled, -invited, -accepted, etc.) described in the Campaign Management and Prospect APIs.
  • pagesize and page control pagination through what can be a large prospect list; there's no total-count field in the response shown, so detecting the last page isn't obvious from this data alone.