Purple DEX API Documentation

Machine-readable OpenAPI 3.0 specification: https://marketplace.moveworks.com/api/purple-suite/dex/openapi.json

The consolidated all-apps document at https://marketplace.moveworks.com/api/purple-suite/openapi.json can be narrowed to this app with ?apps=dex, or combined with other apps comma-separated (e.g. ?apps=dex,itsm).

Overview

Digital Employee Experience (DEX) API — monitor device health, software inventory, experience scores, alerts, remediations, and IT campaigns. Resembles tools like Nexthink, Lakeside, and ServiceNow DEX. --- **Acting as a user (`X-PS-Impersonate-User`).** Every endpoint accepts an optional `X-PS-Impersonate-User` request header whose value is the email of the instance user to act as. The effective user resolves in this order: the header if present, else the instance's configured default MCP user, else none. User-scoped paths additionally accept the literal `me` in place of an email, and Graph-style apps also serve `/me/…` twins of their `/users/{email}/…` paths that resolve the same way. This header is honored by all operations but is intentionally omitted from each operation's parameter list so it is not surfaced as a per-tool argument by MCP clients; see the `ImpersonateUser` entry under `components.parameters`.

Endpoints

GET /api/purple-suite/dex/devices

List DEX-monitored endpoint devices with health telemetry

Managed endpoints (laptop, desktop, mobile, virtual_machine) and their live telemetry: health_score, CPU/memory/disk usage, battery health, uptime, last_seen, compliance_status, encryption and antivirus state, plus assigned_to, department and location. This is device-health monitoring (Nexthink/Lakeside style) — the finance-owned asset register lives in the erp app's assets collection, and user-reported device tickets live in itsm. Supports server-side OData querying — _filter, _orderby, _select, _search, _top, _skip, _count (the spec names these $filter etc.; MCP clients see the _ form because $ is not a legal tool-input key).

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
limitqueryintegernoLegacy page size (default 50). Prefer $top. Ignored when $top/$skip are used.
cursorquerystringnoLegacy keyset cursor — pass the previous response's nextCursor. Prefer $skip/$top.
$filterquerystringnoOData filter expression. Comparison operators: eq, ne, gt, ge, lt, le. Logical: and, or, not, with parentheses for grouping. String functions: contains(field,'x'), startswith(field,'x'), endswith(field,'x'). Membership: field in ('a','b'). Case-insensitive matching via tolower(field) / toupper(field). Nested fields use a slash, e.g. pto_balance/vacation_days. String literals use single quotes; dates are ISO-8601. Examples: "status eq 'active'"; "salary gt 50000 and department eq 'Engineering'"; "contains(tolower(name),'acme')"; "closeDate gt 2026-01-01".
$selectquerystringnoComma-separated list of fields to return, e.g. "id,firstName,email". Nested fields via slash ("pto_balance/vacation_days"). The id field is always included.
$orderbyquerystringnoSort clause(s), comma-separated, each "field [asc|desc]" (asc is the default). Example: "createdAt desc, lastName asc". Null values sort last.
$searchquerystringnoFree-text, case-insensitive substring match across the resource's searchable fields.
$topqueryintegernoMaximum number of items to return (page size).
$skipqueryintegernoNumber of matching items to skip before returning results (offset paging). Combine with $top.
$countquerybooleannoWhen true, include @odata.count (total matches after $filter/$search, before paging) in the response.

Responses

200
Paginated list

application/json

  • data array

    array of:

    Device

    • id string
    • hostname string
    • device_type string
    • os string
    • os_version string
    • manufacturer string
    • model string
    • serial_number string
    • assigned_to stringEmail of the assigned user
    • department string
    • location string
    • ip_address string
    • last_seen string
    • health_score number
    • cpu_usage_pct number
    • memory_usage_pct number
    • disk_usage_pct number
    • battery_health_pct number
    • uptime_hours number
    • compliance_status string
    • encryption_enabled boolean
    • antivirus_status string
    • createdAt string
    • updatedAt string
  • nextCursor stringCursor for the next page, or null on the last page. With $top/$skip this is the next $skip value; otherwise a keyset cursor.
  • total integerTotal documents in the collection.
  • @odata.count integerPresent only when $count=true: total matches after $filter/$search.
  • @odata.truncated booleanPresent and true only when the collection exceeded the in-memory query cap and results may be incomplete.
400
Invalid OData query (e.g. malformed $filter)

POST /api/purple-suite/dex/devices

Create device

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes

Request body

application/json — required

Device

  • id string
  • hostname string
  • device_type string
  • os string
  • os_version string
  • manufacturer string
  • model string
  • serial_number string
  • assigned_to stringEmail of the assigned user
  • department string
  • location string
  • ip_address string
  • last_seen string
  • health_score number
  • cpu_usage_pct number
  • memory_usage_pct number
  • disk_usage_pct number
  • battery_health_pct number
  • uptime_hours number
  • compliance_status string
  • encryption_enabled boolean
  • antivirus_status string
  • createdAt string
  • updatedAt string

Responses

201
Created

application/json

Device

  • id string
  • hostname string
  • device_type string
  • os string
  • os_version string
  • manufacturer string
  • model string
  • serial_number string
  • assigned_to stringEmail of the assigned user
  • department string
  • location string
  • ip_address string
  • last_seen string
  • health_score number
  • cpu_usage_pct number
  • memory_usage_pct number
  • disk_usage_pct number
  • battery_health_pct number
  • uptime_hours number
  • compliance_status string
  • encryption_enabled boolean
  • antivirus_status string
  • createdAt string
  • updatedAt string

GET /api/purple-suite/dex/devices/{id}

Get device

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Responses

200
Found

application/json

Device

  • id string
  • hostname string
  • device_type string
  • os string
  • os_version string
  • manufacturer string
  • model string
  • serial_number string
  • assigned_to stringEmail of the assigned user
  • department string
  • location string
  • ip_address string
  • last_seen string
  • health_score number
  • cpu_usage_pct number
  • memory_usage_pct number
  • disk_usage_pct number
  • battery_health_pct number
  • uptime_hours number
  • compliance_status string
  • encryption_enabled boolean
  • antivirus_status string
  • createdAt string
  • updatedAt string
404
Not found

DELETE /api/purple-suite/dex/devices/{id}

Delete device

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Responses

200
Deleted

application/json

  • success boolean
404
Not found

PATCH /api/purple-suite/dex/devices/{id}

Update device

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Request body

Fields to update (partial)

application/json

Device

  • id string
  • hostname string
  • device_type string
  • os string
  • os_version string
  • manufacturer string
  • model string
  • serial_number string
  • assigned_to stringEmail of the assigned user
  • department string
  • location string
  • ip_address string
  • last_seen string
  • health_score number
  • cpu_usage_pct number
  • memory_usage_pct number
  • disk_usage_pct number
  • battery_health_pct number
  • uptime_hours number
  • compliance_status string
  • encryption_enabled boolean
  • antivirus_status string
  • createdAt string
  • updatedAt string

Responses

200
Updated

application/json

Device

  • id string
  • hostname string
  • device_type string
  • os string
  • os_version string
  • manufacturer string
  • model string
  • serial_number string
  • assigned_to stringEmail of the assigned user
  • department string
  • location string
  • ip_address string
  • last_seen string
  • health_score number
  • cpu_usage_pct number
  • memory_usage_pct number
  • disk_usage_pct number
  • battery_health_pct number
  • uptime_hours number
  • compliance_status string
  • encryption_enabled boolean
  • antivirus_status string
  • createdAt string
  • updatedAt string
404
Not found

GET /api/purple-suite/dex/software_inventory

List software installed on DEX-monitored devices

One row per software title installed on a device (device_id plus software_name, version, publisher) with install_date, last_used, license_type and the is_managed / is_approved flags. Use it for licence-usage, shadow-IT (is_approved false) and version-spread questions — software purchasing and licence assets live in the erp app. Supports server-side OData querying — _filter, _orderby, _select, _search, _top, _skip, _count (the spec names these $filter etc.; MCP clients see the _ form because $ is not a legal tool-input key).

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
limitqueryintegernoLegacy page size (default 50). Prefer $top. Ignored when $top/$skip are used.
cursorquerystringnoLegacy keyset cursor — pass the previous response's nextCursor. Prefer $skip/$top.
$filterquerystringnoOData filter expression. Comparison operators: eq, ne, gt, ge, lt, le. Logical: and, or, not, with parentheses for grouping. String functions: contains(field,'x'), startswith(field,'x'), endswith(field,'x'). Membership: field in ('a','b'). Case-insensitive matching via tolower(field) / toupper(field). Nested fields use a slash, e.g. pto_balance/vacation_days. String literals use single quotes; dates are ISO-8601. Examples: "status eq 'active'"; "salary gt 50000 and department eq 'Engineering'"; "contains(tolower(name),'acme')"; "closeDate gt 2026-01-01".
$selectquerystringnoComma-separated list of fields to return, e.g. "id,firstName,email". Nested fields via slash ("pto_balance/vacation_days"). The id field is always included.
$orderbyquerystringnoSort clause(s), comma-separated, each "field [asc|desc]" (asc is the default). Example: "createdAt desc, lastName asc". Null values sort last.
$searchquerystringnoFree-text, case-insensitive substring match across the resource's searchable fields.
$topqueryintegernoMaximum number of items to return (page size).
$skipqueryintegernoNumber of matching items to skip before returning results (offset paging). Combine with $top.
$countquerybooleannoWhen true, include @odata.count (total matches after $filter/$search, before paging) in the response.

Responses

200
Paginated list

application/json

  • data array

    array of:

    SoftwareInventory

    • id string
    • device_id string
    • software_name string
    • version string
    • publisher string
    • install_date string
    • last_used string
    • license_type string
    • is_managed boolean
    • is_approved boolean
    • createdAt string
    • updatedAt string
  • nextCursor stringCursor for the next page, or null on the last page. With $top/$skip this is the next $skip value; otherwise a keyset cursor.
  • total integerTotal documents in the collection.
  • @odata.count integerPresent only when $count=true: total matches after $filter/$search.
  • @odata.truncated booleanPresent and true only when the collection exceeded the in-memory query cap and results may be incomplete.
400
Invalid OData query (e.g. malformed $filter)

POST /api/purple-suite/dex/software_inventory

Create software inventory entry

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes

Request body

application/json — required

SoftwareInventory

  • id string
  • device_id string
  • software_name string
  • version string
  • publisher string
  • install_date string
  • last_used string
  • license_type string
  • is_managed boolean
  • is_approved boolean
  • createdAt string
  • updatedAt string

Responses

201
Created

application/json

SoftwareInventory

  • id string
  • device_id string
  • software_name string
  • version string
  • publisher string
  • install_date string
  • last_used string
  • license_type string
  • is_managed boolean
  • is_approved boolean
  • createdAt string
  • updatedAt string

GET /api/purple-suite/dex/software_inventory/{id}

Get software inventory entry

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Responses

200
Found

application/json

SoftwareInventory

  • id string
  • device_id string
  • software_name string
  • version string
  • publisher string
  • install_date string
  • last_used string
  • license_type string
  • is_managed boolean
  • is_approved boolean
  • createdAt string
  • updatedAt string
404
Not found

DELETE /api/purple-suite/dex/software_inventory/{id}

Delete software inventory entry

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Responses

200
Deleted

application/json

  • success boolean
404
Not found

PATCH /api/purple-suite/dex/software_inventory/{id}

Update software inventory entry

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Request body

Fields to update (partial)

application/json

SoftwareInventory

  • id string
  • device_id string
  • software_name string
  • version string
  • publisher string
  • install_date string
  • last_used string
  • license_type string
  • is_managed boolean
  • is_approved boolean
  • createdAt string
  • updatedAt string

Responses

200
Updated

application/json

SoftwareInventory

  • id string
  • device_id string
  • software_name string
  • version string
  • publisher string
  • install_date string
  • last_used string
  • license_type string
  • is_managed boolean
  • is_approved boolean
  • createdAt string
  • updatedAt string
404
Not found

GET /api/purple-suite/dex/dex_alerts

List DEX device-health alerts (machine-generated telemetry alerts)

Automated endpoint alerts — high_cpu, low_disk, low_memory, crash, network_issue, battery_critical, security_threat, compliance_violation, software_error, hardware_failure — with severity, open/acknowledged/resolved status, and the metric_value that breached its threshold. These are generated from device telemetry, not raised by users (user-reported tickets live in the itsm app); the remediations collection records what was done about them. Supports server-side OData querying — _filter, _orderby, _select, _search, _top, _skip, _count (the spec names these $filter etc.; MCP clients see the _ form because $ is not a legal tool-input key).

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
limitqueryintegernoLegacy page size (default 50). Prefer $top. Ignored when $top/$skip are used.
cursorquerystringnoLegacy keyset cursor — pass the previous response's nextCursor. Prefer $skip/$top.
$filterquerystringnoOData filter expression. Comparison operators: eq, ne, gt, ge, lt, le. Logical: and, or, not, with parentheses for grouping. String functions: contains(field,'x'), startswith(field,'x'), endswith(field,'x'). Membership: field in ('a','b'). Case-insensitive matching via tolower(field) / toupper(field). Nested fields use a slash, e.g. pto_balance/vacation_days. String literals use single quotes; dates are ISO-8601. Examples: "status eq 'active'"; "salary gt 50000 and department eq 'Engineering'"; "contains(tolower(name),'acme')"; "closeDate gt 2026-01-01".
$selectquerystringnoComma-separated list of fields to return, e.g. "id,firstName,email". Nested fields via slash ("pto_balance/vacation_days"). The id field is always included.
$orderbyquerystringnoSort clause(s), comma-separated, each "field [asc|desc]" (asc is the default). Example: "createdAt desc, lastName asc". Null values sort last.
$searchquerystringnoFree-text, case-insensitive substring match across the resource's searchable fields.
$topqueryintegernoMaximum number of items to return (page size).
$skipqueryintegernoNumber of matching items to skip before returning results (offset paging). Combine with $top.
$countquerybooleannoWhen true, include @odata.count (total matches after $filter/$search, before paging) in the response.

Responses

200
Paginated list

application/json

  • data array

    array of:

    DexAlert

    • id string
    • device_id string
    • alert_type string
    • severity string
    • status string
    • title string
    • description string
    • metric_value numberThe metric reading that triggered the alert
    • threshold numberThe threshold that was exceeded
    • acknowledged boolean
    • acknowledged_by string
    • acknowledged_at string
    • resolved_at string
    • resolved_by string
    • resolution_notes stringNotes recorded when the alert was resolved
    • createdAt string
    • updatedAt string
  • nextCursor stringCursor for the next page, or null on the last page. With $top/$skip this is the next $skip value; otherwise a keyset cursor.
  • total integerTotal documents in the collection.
  • @odata.count integerPresent only when $count=true: total matches after $filter/$search.
  • @odata.truncated booleanPresent and true only when the collection exceeded the in-memory query cap and results may be incomplete.
400
Invalid OData query (e.g. malformed $filter)

POST /api/purple-suite/dex/dex_alerts

Create DEX alert

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes

Request body

application/json — required

DexAlert

  • id string
  • device_id string
  • alert_type string
  • severity string
  • status string
  • title string
  • description string
  • metric_value numberThe metric reading that triggered the alert
  • threshold numberThe threshold that was exceeded
  • acknowledged boolean
  • acknowledged_by string
  • acknowledged_at string
  • resolved_at string
  • resolved_by string
  • resolution_notes stringNotes recorded when the alert was resolved
  • createdAt string
  • updatedAt string

Responses

201
Created

application/json

DexAlert

  • id string
  • device_id string
  • alert_type string
  • severity string
  • status string
  • title string
  • description string
  • metric_value numberThe metric reading that triggered the alert
  • threshold numberThe threshold that was exceeded
  • acknowledged boolean
  • acknowledged_by string
  • acknowledged_at string
  • resolved_at string
  • resolved_by string
  • resolution_notes stringNotes recorded when the alert was resolved
  • createdAt string
  • updatedAt string

GET /api/purple-suite/dex/dex_alerts/{id}

Get DEX alert

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Responses

200
Found

application/json

DexAlert

  • id string
  • device_id string
  • alert_type string
  • severity string
  • status string
  • title string
  • description string
  • metric_value numberThe metric reading that triggered the alert
  • threshold numberThe threshold that was exceeded
  • acknowledged boolean
  • acknowledged_by string
  • acknowledged_at string
  • resolved_at string
  • resolved_by string
  • resolution_notes stringNotes recorded when the alert was resolved
  • createdAt string
  • updatedAt string
404
Not found

DELETE /api/purple-suite/dex/dex_alerts/{id}

Delete DEX alert

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Responses

200
Deleted

application/json

  • success boolean
404
Not found

PATCH /api/purple-suite/dex/dex_alerts/{id}

Update DEX alert

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Request body

Fields to update (partial)

application/json

DexAlert

  • id string
  • device_id string
  • alert_type string
  • severity string
  • status string
  • title string
  • description string
  • metric_value numberThe metric reading that triggered the alert
  • threshold numberThe threshold that was exceeded
  • acknowledged boolean
  • acknowledged_by string
  • acknowledged_at string
  • resolved_at string
  • resolved_by string
  • resolution_notes stringNotes recorded when the alert was resolved
  • createdAt string
  • updatedAt string

Responses

200
Updated

application/json

DexAlert

  • id string
  • device_id string
  • alert_type string
  • severity string
  • status string
  • title string
  • description string
  • metric_value numberThe metric reading that triggered the alert
  • threshold numberThe threshold that was exceeded
  • acknowledged boolean
  • acknowledged_by string
  • acknowledged_at string
  • resolved_at string
  • resolved_by string
  • resolution_notes stringNotes recorded when the alert was resolved
  • createdAt string
  • updatedAt string
404
Not found

POST /api/purple-suite/dex/dex_alerts/{id}/acknowledge

Acknowledge a DEX alert

Marks the alert as acknowledged. Fails if the alert is already resolved or already acknowledged.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Request body

application/json — required

  • acknowledged_by string requiredEmail of the person acknowledging the alert

Responses

200
Alert acknowledged

application/json

DexAlert

  • id string
  • device_id string
  • alert_type string
  • severity string
  • status string
  • title string
  • description string
  • metric_value numberThe metric reading that triggered the alert
  • threshold numberThe threshold that was exceeded
  • acknowledged boolean
  • acknowledged_by string
  • acknowledged_at string
  • resolved_at string
  • resolved_by string
  • resolution_notes stringNotes recorded when the alert was resolved
  • createdAt string
  • updatedAt string
404
Alert not found
422
Alert already resolved or already acknowledged

POST /api/purple-suite/dex/dex_alerts/{id}/resolve

Resolve a DEX alert

Marks the alert as resolved. Fails if the alert is already resolved.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Request body

application/json — required

  • resolved_by string requiredEmail of the person resolving the alert
  • resolution_notes stringOptional notes about the resolution

Responses

200
Alert resolved

application/json

DexAlert

  • id string
  • device_id string
  • alert_type string
  • severity string
  • status string
  • title string
  • description string
  • metric_value numberThe metric reading that triggered the alert
  • threshold numberThe threshold that was exceeded
  • acknowledged boolean
  • acknowledged_by string
  • acknowledged_at string
  • resolved_at string
  • resolved_by string
  • resolution_notes stringNotes recorded when the alert was resolved
  • createdAt string
  • updatedAt string
404
Alert not found
422
Alert already resolved

GET /api/purple-suite/dex/remediations

List DEX remediation actions run against devices

Automated fix-it actions targeting a device (restart_service, clear_cache, force_update, restart_device, run_diagnostics, reset_network, update_drivers, scan_malware, enforce_compliance…) with status pending/in_progress/completed/failed, executor, timings and result. Use it to see what has already been attempted for a device or alert; the execute and complete tools are what drive the status. Supports server-side OData querying — _filter, _orderby, _select, _search, _top, _skip, _count (the spec names these $filter etc.; MCP clients see the _ form because $ is not a legal tool-input key).

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
limitqueryintegernoLegacy page size (default 50). Prefer $top. Ignored when $top/$skip are used.
cursorquerystringnoLegacy keyset cursor — pass the previous response's nextCursor. Prefer $skip/$top.
$filterquerystringnoOData filter expression. Comparison operators: eq, ne, gt, ge, lt, le. Logical: and, or, not, with parentheses for grouping. String functions: contains(field,'x'), startswith(field,'x'), endswith(field,'x'). Membership: field in ('a','b'). Case-insensitive matching via tolower(field) / toupper(field). Nested fields use a slash, e.g. pto_balance/vacation_days. String literals use single quotes; dates are ISO-8601. Examples: "status eq 'active'"; "salary gt 50000 and department eq 'Engineering'"; "contains(tolower(name),'acme')"; "closeDate gt 2026-01-01".
$selectquerystringnoComma-separated list of fields to return, e.g. "id,firstName,email". Nested fields via slash ("pto_balance/vacation_days"). The id field is always included.
$orderbyquerystringnoSort clause(s), comma-separated, each "field [asc|desc]" (asc is the default). Example: "createdAt desc, lastName asc". Null values sort last.
$searchquerystringnoFree-text, case-insensitive substring match across the resource's searchable fields.
$topqueryintegernoMaximum number of items to return (page size).
$skipqueryintegernoNumber of matching items to skip before returning results (offset paging). Combine with $top.
$countquerybooleannoWhen true, include @odata.count (total matches after $filter/$search, before paging) in the response.

Responses

200
Paginated list

application/json

  • data array

    array of:

    Remediation

    • id string
    • device_id string
    • action_type string
    • status string
    • target_software stringOptional: specific software targeted
    • executed_by string
    • executed_at string
    • completed_at string
    • result string
    • notes string
    • createdAt string
    • updatedAt string
  • nextCursor stringCursor for the next page, or null on the last page. With $top/$skip this is the next $skip value; otherwise a keyset cursor.
  • total integerTotal documents in the collection.
  • @odata.count integerPresent only when $count=true: total matches after $filter/$search.
  • @odata.truncated booleanPresent and true only when the collection exceeded the in-memory query cap and results may be incomplete.
400
Invalid OData query (e.g. malformed $filter)

POST /api/purple-suite/dex/remediations

Create remediation

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes

Request body

application/json — required

Remediation

  • id string
  • device_id string
  • action_type string
  • status string
  • target_software stringOptional: specific software targeted
  • executed_by string
  • executed_at string
  • completed_at string
  • result string
  • notes string
  • createdAt string
  • updatedAt string

Responses

201
Created

application/json

Remediation

  • id string
  • device_id string
  • action_type string
  • status string
  • target_software stringOptional: specific software targeted
  • executed_by string
  • executed_at string
  • completed_at string
  • result string
  • notes string
  • createdAt string
  • updatedAt string

GET /api/purple-suite/dex/remediations/{id}

Get remediation

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Responses

200
Found

application/json

Remediation

  • id string
  • device_id string
  • action_type string
  • status string
  • target_software stringOptional: specific software targeted
  • executed_by string
  • executed_at string
  • completed_at string
  • result string
  • notes string
  • createdAt string
  • updatedAt string
404
Not found

DELETE /api/purple-suite/dex/remediations/{id}

Delete remediation

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Responses

200
Deleted

application/json

  • success boolean
404
Not found

PATCH /api/purple-suite/dex/remediations/{id}

Update remediation

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Request body

Fields to update (partial)

application/json

Remediation

  • id string
  • device_id string
  • action_type string
  • status string
  • target_software stringOptional: specific software targeted
  • executed_by string
  • executed_at string
  • completed_at string
  • result string
  • notes string
  • createdAt string
  • updatedAt string

Responses

200
Updated

application/json

Remediation

  • id string
  • device_id string
  • action_type string
  • status string
  • target_software stringOptional: specific software targeted
  • executed_by string
  • executed_at string
  • completed_at string
  • result string
  • notes string
  • createdAt string
  • updatedAt string
404
Not found

POST /api/purple-suite/dex/remediations/{id}/execute

Execute a remediation

Transitions the remediation to in_progress and records the executor. Fails if already completed or in_progress. Failed remediations may be re-executed.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Request body

application/json — required

  • executed_by stringEmail or identifier of the executor (defaults to 'system')

Responses

200
Remediation started (status = in_progress)

application/json

Remediation

  • id string
  • device_id string
  • action_type string
  • status string
  • target_software stringOptional: specific software targeted
  • executed_by string
  • executed_at string
  • completed_at string
  • result string
  • notes string
  • createdAt string
  • updatedAt string
404
Remediation not found
422
Remediation already completed or already in_progress

POST /api/purple-suite/dex/remediations/{id}/complete

Mark a remediation as complete

Transitions the remediation to completed. Remediation must be in_progress.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Request body

application/json — required

  • result stringOutcome description (defaults to 'success')

Responses

200
Remediation completed

application/json

Remediation

  • id string
  • device_id string
  • action_type string
  • status string
  • target_software stringOptional: specific software targeted
  • executed_by string
  • executed_at string
  • completed_at string
  • result string
  • notes string
  • createdAt string
  • updatedAt string
404
Remediation not found
422
Remediation is not in_progress (must execute first)

GET /api/purple-suite/dex/experience_scores

List DEX digital-experience scores (0–10) per device and user

Periodic scorecards that roll boot time, responsiveness, network, stability and battery into an overall_score for a device_id / user_email at a measured_at timestamp, alongside the raw boot_time_seconds, crash count and response-time inputs. Use it for experience trends and worst-experience rankings; point-in-time device telemetry lives on devices instead. Supports server-side OData querying — _filter, _orderby, _select, _search, _top, _skip, _count (the spec names these $filter etc.; MCP clients see the _ form because $ is not a legal tool-input key).

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
limitqueryintegernoLegacy page size (default 50). Prefer $top. Ignored when $top/$skip are used.
cursorquerystringnoLegacy keyset cursor — pass the previous response's nextCursor. Prefer $skip/$top.
$filterquerystringnoOData filter expression. Comparison operators: eq, ne, gt, ge, lt, le. Logical: and, or, not, with parentheses for grouping. String functions: contains(field,'x'), startswith(field,'x'), endswith(field,'x'). Membership: field in ('a','b'). Case-insensitive matching via tolower(field) / toupper(field). Nested fields use a slash, e.g. pto_balance/vacation_days. String literals use single quotes; dates are ISO-8601. Examples: "status eq 'active'"; "salary gt 50000 and department eq 'Engineering'"; "contains(tolower(name),'acme')"; "closeDate gt 2026-01-01".
$selectquerystringnoComma-separated list of fields to return, e.g. "id,firstName,email". Nested fields via slash ("pto_balance/vacation_days"). The id field is always included.
$orderbyquerystringnoSort clause(s), comma-separated, each "field [asc|desc]" (asc is the default). Example: "createdAt desc, lastName asc". Null values sort last.
$searchquerystringnoFree-text, case-insensitive substring match across the resource's searchable fields.
$topqueryintegernoMaximum number of items to return (page size).
$skipqueryintegernoNumber of matching items to skip before returning results (offset paging). Combine with $top.
$countquerybooleannoWhen true, include @odata.count (total matches after $filter/$search, before paging) in the response.

Responses

200
Paginated list

application/json

  • data array

    array of:

    ExperienceScore

    • id string
    • device_id string
    • user_email string
    • overall_score number
    • boot_time_score number
    • responsiveness_score number
    • network_score number
    • stability_score number
    • battery_score number
    • measured_at string
    • boot_time_seconds number
    • avg_app_crash_count number
    • avg_response_time_ms number
    • createdAt string
    • updatedAt string
  • nextCursor stringCursor for the next page, or null on the last page. With $top/$skip this is the next $skip value; otherwise a keyset cursor.
  • total integerTotal documents in the collection.
  • @odata.count integerPresent only when $count=true: total matches after $filter/$search.
  • @odata.truncated booleanPresent and true only when the collection exceeded the in-memory query cap and results may be incomplete.
400
Invalid OData query (e.g. malformed $filter)

POST /api/purple-suite/dex/experience_scores

Create experience score

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes

Request body

application/json — required

ExperienceScore

  • id string
  • device_id string
  • user_email string
  • overall_score number
  • boot_time_score number
  • responsiveness_score number
  • network_score number
  • stability_score number
  • battery_score number
  • measured_at string
  • boot_time_seconds number
  • avg_app_crash_count number
  • avg_response_time_ms number
  • createdAt string
  • updatedAt string

Responses

201
Created

application/json

ExperienceScore

  • id string
  • device_id string
  • user_email string
  • overall_score number
  • boot_time_score number
  • responsiveness_score number
  • network_score number
  • stability_score number
  • battery_score number
  • measured_at string
  • boot_time_seconds number
  • avg_app_crash_count number
  • avg_response_time_ms number
  • createdAt string
  • updatedAt string

GET /api/purple-suite/dex/experience_scores/{id}

Get experience score

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Responses

200
Found

application/json

ExperienceScore

  • id string
  • device_id string
  • user_email string
  • overall_score number
  • boot_time_score number
  • responsiveness_score number
  • network_score number
  • stability_score number
  • battery_score number
  • measured_at string
  • boot_time_seconds number
  • avg_app_crash_count number
  • avg_response_time_ms number
  • createdAt string
  • updatedAt string
404
Not found

DELETE /api/purple-suite/dex/experience_scores/{id}

Delete experience score

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Responses

200
Deleted

application/json

  • success boolean
404
Not found

PATCH /api/purple-suite/dex/experience_scores/{id}

Update experience score

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Request body

Fields to update (partial)

application/json

ExperienceScore

  • id string
  • device_id string
  • user_email string
  • overall_score number
  • boot_time_score number
  • responsiveness_score number
  • network_score number
  • stability_score number
  • battery_score number
  • measured_at string
  • boot_time_seconds number
  • avg_app_crash_count number
  • avg_response_time_ms number
  • createdAt string
  • updatedAt string

Responses

200
Updated

application/json

ExperienceScore

  • id string
  • device_id string
  • user_email string
  • overall_score number
  • boot_time_score number
  • responsiveness_score number
  • network_score number
  • stability_score number
  • battery_score number
  • measured_at string
  • boot_time_seconds number
  • avg_app_crash_count number
  • avg_response_time_ms number
  • createdAt string
  • updatedAt string
404
Not found

GET /api/purple-suite/dex/dex_campaigns

List DEX IT campaigns (fleet patch, rollout and compliance sweeps)

Fleet-wide IT operations targeting a device cohort — patch_deployment, software_rollout, compliance_check, security_scan, driver_update, os_upgrade — with target_criteria, status draft/active/completed and total/completed/failed device counts. These are IT rollout campaigns, not marketing campaigns (see the crm app). Supports server-side OData querying — _filter, _orderby, _select, _search, _top, _skip, _count (the spec names these $filter etc.; MCP clients see the _ form because $ is not a legal tool-input key).

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
limitqueryintegernoLegacy page size (default 50). Prefer $top. Ignored when $top/$skip are used.
cursorquerystringnoLegacy keyset cursor — pass the previous response's nextCursor. Prefer $skip/$top.
$filterquerystringnoOData filter expression. Comparison operators: eq, ne, gt, ge, lt, le. Logical: and, or, not, with parentheses for grouping. String functions: contains(field,'x'), startswith(field,'x'), endswith(field,'x'). Membership: field in ('a','b'). Case-insensitive matching via tolower(field) / toupper(field). Nested fields use a slash, e.g. pto_balance/vacation_days. String literals use single quotes; dates are ISO-8601. Examples: "status eq 'active'"; "salary gt 50000 and department eq 'Engineering'"; "contains(tolower(name),'acme')"; "closeDate gt 2026-01-01".
$selectquerystringnoComma-separated list of fields to return, e.g. "id,firstName,email". Nested fields via slash ("pto_balance/vacation_days"). The id field is always included.
$orderbyquerystringnoSort clause(s), comma-separated, each "field [asc|desc]" (asc is the default). Example: "createdAt desc, lastName asc". Null values sort last.
$searchquerystringnoFree-text, case-insensitive substring match across the resource's searchable fields.
$topqueryintegernoMaximum number of items to return (page size).
$skipqueryintegernoNumber of matching items to skip before returning results (offset paging). Combine with $top.
$countquerybooleannoWhen true, include @odata.count (total matches after $filter/$search, before paging) in the response.

Responses

200
Paginated list

application/json

  • data array

    array of:

    Campaign

    • id string
    • name string
    • description string
    • campaign_type string
    • status string
    • target_criteria objectFilter criteria for targeted devices (e.g. OS, department)
    • total_devices integer
    • completed_devices integer
    • failed_devices integer
    • launched_at string
    • launched_by string
    • created_by string
    • createdAt string
    • updatedAt string
  • nextCursor stringCursor for the next page, or null on the last page. With $top/$skip this is the next $skip value; otherwise a keyset cursor.
  • total integerTotal documents in the collection.
  • @odata.count integerPresent only when $count=true: total matches after $filter/$search.
  • @odata.truncated booleanPresent and true only when the collection exceeded the in-memory query cap and results may be incomplete.
400
Invalid OData query (e.g. malformed $filter)

POST /api/purple-suite/dex/dex_campaigns

Create DEX campaign

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes

Request body

application/json — required

Campaign

  • id string
  • name string
  • description string
  • campaign_type string
  • status string
  • target_criteria objectFilter criteria for targeted devices (e.g. OS, department)
  • total_devices integer
  • completed_devices integer
  • failed_devices integer
  • launched_at string
  • launched_by string
  • created_by string
  • createdAt string
  • updatedAt string

Responses

201
Created

application/json

Campaign

  • id string
  • name string
  • description string
  • campaign_type string
  • status string
  • target_criteria objectFilter criteria for targeted devices (e.g. OS, department)
  • total_devices integer
  • completed_devices integer
  • failed_devices integer
  • launched_at string
  • launched_by string
  • created_by string
  • createdAt string
  • updatedAt string

GET /api/purple-suite/dex/dex_campaigns/{id}

Get DEX campaign

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Responses

200
Found

application/json

Campaign

  • id string
  • name string
  • description string
  • campaign_type string
  • status string
  • target_criteria objectFilter criteria for targeted devices (e.g. OS, department)
  • total_devices integer
  • completed_devices integer
  • failed_devices integer
  • launched_at string
  • launched_by string
  • created_by string
  • createdAt string
  • updatedAt string
404
Not found

DELETE /api/purple-suite/dex/dex_campaigns/{id}

Delete DEX campaign

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Responses

200
Deleted

application/json

  • success boolean
404
Not found

PATCH /api/purple-suite/dex/dex_campaigns/{id}

Update DEX campaign

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Request body

Fields to update (partial)

application/json

Campaign

  • id string
  • name string
  • description string
  • campaign_type string
  • status string
  • target_criteria objectFilter criteria for targeted devices (e.g. OS, department)
  • total_devices integer
  • completed_devices integer
  • failed_devices integer
  • launched_at string
  • launched_by string
  • created_by string
  • createdAt string
  • updatedAt string

Responses

200
Updated

application/json

Campaign

  • id string
  • name string
  • description string
  • campaign_type string
  • status string
  • target_criteria objectFilter criteria for targeted devices (e.g. OS, department)
  • total_devices integer
  • completed_devices integer
  • failed_devices integer
  • launched_at string
  • launched_by string
  • created_by string
  • createdAt string
  • updatedAt string
404
Not found

POST /api/purple-suite/dex/dex_campaigns/{id}/launch

Launch a DEX campaign

Transitions the campaign to active and records launch metadata. Fails if already active or completed.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Request body

application/json — required

  • launched_by stringEmail or identifier of the person launching the campaign (defaults to 'system')

Responses

200
Campaign launched (status = active)

application/json

Campaign

  • id string
  • name string
  • description string
  • campaign_type string
  • status string
  • target_criteria objectFilter criteria for targeted devices (e.g. OS, department)
  • total_devices integer
  • completed_devices integer
  • failed_devices integer
  • launched_at string
  • launched_by string
  • created_by string
  • createdAt string
  • updatedAt string
404
Campaign not found
422
Campaign already active or already completed