Purple Cloud Logs API Documentation
Machine-readable OpenAPI 3.0 specification: https://marketplace.moveworks.com/api/purple-suite/cloud-logs/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=cloud-logs, or combined with other apps comma-separated (e.g. ?apps=cloud-logs,itsm).
Overview
Read-only synthetic cloud inventory and application observations. Correlate project, stable resource identity, FQDN and observation time with your inventory source. Does not modify cloud infrastructure or CMDB relationships.
---
**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/cloud-logs/resources
Search cloud inventory
Find cloud resources by name, project, resource identity, address, kind, or hosting node. Returns runtime identity, hosting metadata and validity windows; names and IPs need not be unique. Supports OData $filter/$select/$orderby/$search/$top/$skip/$count (MCP uses _filter, _top, etc.). Use $orderby with an id tie-breaker and $top/$skip for stable paging. Nested fields use slash paths. This is a Purple Suite mock API, not a native cloud provider API contract.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
X-Instance-ID | header | string | yes | |
limit | query | integer | no | Legacy page size (default 50). Prefer $top. Ignored when $top/$skip are used. |
cursor | query | string | no | Legacy keyset cursor — pass the previous response's nextCursor. Prefer $skip/$top. |
$filter | query | string | no | OData 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". |
$select | query | string | no | Comma-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. |
$orderby | query | string | no | Sort clause(s), comma-separated, each "field [asc|desc]" (asc is the default). Example: "createdAt desc, lastName asc". Null values sort last. |
$search | query | string | no | Free-text, case-insensitive substring match across the resource's searchable fields. |
$top | query | integer | no | Maximum number of items to return (page size). |
$skip | query | integer | no | Number of matching items to skip before returning results (offset paging). Combine with $top. |
$count | query | boolean | no | When true, include @odata.count (total matches after $filter/$search, before paging) in the response. |
projectId | query | string | no | Exact-match projectId filter. Combine with $filter for other predicates. |
environment | query | string | no | Exact-match environment filter. Combine with $filter for other predicates. |
name | query | string | no | Exact-match name filter. Combine with $filter for other predicates. |
resourceKind | query | string | no | Exact-match resourceKind filter. Combine with $filter for other predicates. |
resourceUid | query | string | no | Exact-match resourceUid filter. Combine with $filter for other predicates. |
podUid | query | string | no | Exact-match podUid filter. Combine with $filter for other predicates. |
hostingNodeName | query | string | no | Exact-match hostingNodeName filter. Combine with $filter for other predicates. |
cloudInstanceId | query | string | no | Exact-match cloudInstanceId filter. Combine with $filter for other predicates. |
ipAddress | query | string | no | Exact-match ipAddress filter. Combine with $filter for other predicates. |
status | query | string | no | Exact-match status filter. Combine with $filter for other predicates. |
Responses
200- Paginated list
application/jsondataarrayarray of:
CloudResourceidstring requiredinstanceIdstring — Purple Suite tenant ID, not a cloud compute instance ID.syntheticbooleansnapshotAtstring — Fixed historical observation snapshot; these records are not live cloud data.namestring requiredfqdnstringipAddressstringprojectIdstring requiredresourceUidstring required — Stable cloud resource identity; not a CMDB sys_id.podUidstringcloudInstanceIdstring — Compute instance identifier as a string to preserve 64-bit precision. Not the Purple Suite tenant ID.resourceKindstring requiredenvironmentstringregionstringzonestringresourceUristring — Fictional inventory URI; not a callable cloud endpoint.statusstringvalidFromstring requiredvalidTostring requiredlastObservedAtstringclusterNamestringnamespacestringkubernetesUidstringhostingNodeNamestringhostingInstanceIdstringworkloadNamestringnodePoolNamestringmachineTypestringosVersionstringnodeVersionstringendpointPortintegerenginestringengineVersionstring
nextCursorstring — Cursor for the next page, or null on the last page. With $top/$skip this is the next $skip value; otherwise a keyset cursor.totalinteger — Total documents in the collection.@odata.countinteger — Present only when $count=true: total matches after $filter/$search.@odata.truncatedboolean — Present 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)
GET /api/purple-suite/cloud-logs/resources/{id}
Get cloud resource
Retrieve one inventory resource by its id returned by search, including identity and hosting metadata.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
X-Instance-ID | header | string | yes | |
id | path | string | yes |
Responses
200- Found
application/jsonCloudResourceidstring requiredinstanceIdstring — Purple Suite tenant ID, not a cloud compute instance ID.syntheticbooleansnapshotAtstring — Fixed historical observation snapshot; these records are not live cloud data.namestring requiredfqdnstringipAddressstringprojectIdstring requiredresourceUidstring required — Stable cloud resource identity; not a CMDB sys_id.podUidstringcloudInstanceIdstring — Compute instance identifier as a string to preserve 64-bit precision. Not the Purple Suite tenant ID.resourceKindstring requiredenvironmentstringregionstringzonestringresourceUristring — Fictional inventory URI; not a callable cloud endpoint.statusstringvalidFromstring requiredvalidTostring requiredlastObservedAtstringclusterNamestringnamespacestringkubernetesUidstringhostingNodeNamestringhostingInstanceIdstringworkloadNamestringnodePoolNamestringmachineTypestringosVersionstringnodeVersionstringendpointPortintegerenginestringengineVersionstring
404- Not found
GET /api/purple-suite/cloud-logs/log-entries
Search cloud logs
Search timestamped application observations by project, emitting pod or hosting server. Bound the timestamp field to the investigation window. Returns caller/callee identities, request outcome, protocol and operation; observations are evidence, not declared dependencies. Supports OData $filter/$select/$orderby/$search/$top/$skip/$count (MCP uses _filter, _top, etc.). Use $orderby with an id tie-breaker and $top/$skip for stable paging. Nested fields use slash paths. This is a Purple Suite mock API, not a native cloud provider API contract.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
X-Instance-ID | header | string | yes | |
limit | query | integer | no | Legacy page size (default 50). Prefer $top. Ignored when $top/$skip are used. |
cursor | query | string | no | Legacy keyset cursor — pass the previous response's nextCursor. Prefer $skip/$top. |
$filter | query | string | no | OData 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". |
$select | query | string | no | Comma-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. |
$orderby | query | string | no | Sort clause(s), comma-separated, each "field [asc|desc]" (asc is the default). Example: "createdAt desc, lastName asc". Null values sort last. |
$search | query | string | no | Free-text, case-insensitive substring match across the resource's searchable fields. |
$top | query | integer | no | Maximum number of items to return (page size). |
$skip | query | integer | no | Number of matching items to skip before returning results (offset paging). Combine with $top. |
$count | query | boolean | no | When true, include @odata.count (total matches after $filter/$search, before paging) in the response. |
projectId | query | string | no | Exact-match projectId filter. Combine with $filter for other predicates. |
environment | query | string | no | Exact-match environment filter. Combine with $filter for other predicates. |
serverName | query | string | no | Exact-match serverName filter. Combine with $filter for other predicates. |
podName | query | string | no | Exact-match podName filter. Combine with $filter for other predicates. |
podUid | query | string | no | Exact-match podUid filter. Combine with $filter for other predicates. |
severity | query | string | no | Exact-match severity filter. Combine with $filter for other predicates. |
Responses
200- Paginated list
application/jsondataarrayarray of:
CloudLogEntryidstring requiredinstanceIdstring — Purple Suite tenant ID, not a cloud compute instance ID.syntheticbooleansnapshotAtstring — Fixed historical observation snapshot; these records are not live cloud data.insertIdstring requiredtimestampstring requiredseveritystringlogNamestringprojectIdstring requiredenvironmentstringserverNamestring — Hosting node of the emitting pod, or the emitting service name for non-pod logs.podNamestringpodUidstringresourceobject requiredtypestringlabelsobject
jsonPayloadobject requiredeventTypestringdirectionstring — Direction relative to the emitting resource. Source is always the caller; destination is always the callee.sourceobjectPeerIdentitynamestringfqdnstringipAddressstringprojectIdstringresourceUidstring — Stable cloud resource identity; not a CMDB sys_id.podUidstringcloudInstanceIdstring — Compute instance identifier as a string to preserve 64-bit precision. Not the Purple Suite tenant ID.
destinationobjectPeerIdentitynamestringfqdnstringipAddressstringprojectIdstringresourceUidstring — Stable cloud resource identity; not a CMDB sys_id.podUidstringcloudInstanceIdstring — Compute instance identifier as a string to preserve 64-bit precision. Not the Purple Suite tenant ID.
protocolstringdestinationPortintegeroperationstringstatusstringlatencyMsinteger
nextCursorstring — Cursor for the next page, or null on the last page. With $top/$skip this is the next $skip value; otherwise a keyset cursor.totalinteger — Total documents in the collection.@odata.countinteger — Present only when $count=true: total matches after $filter/$search.@odata.truncatedboolean — Present 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)
GET /api/purple-suite/cloud-logs/log-entries/{id}
Get cloud log entry
Retrieve one observation by its id for evidence review or citation.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
X-Instance-ID | header | string | yes | |
id | path | string | yes |
Responses
200- Found
application/jsonCloudLogEntryidstring requiredinstanceIdstring — Purple Suite tenant ID, not a cloud compute instance ID.syntheticbooleansnapshotAtstring — Fixed historical observation snapshot; these records are not live cloud data.insertIdstring requiredtimestampstring requiredseveritystringlogNamestringprojectIdstring requiredenvironmentstringserverNamestring — Hosting node of the emitting pod, or the emitting service name for non-pod logs.podNamestringpodUidstringresourceobject requiredtypestringlabelsobject
jsonPayloadobject requiredeventTypestringdirectionstring — Direction relative to the emitting resource. Source is always the caller; destination is always the callee.sourceobjectPeerIdentitynamestringfqdnstringipAddressstringprojectIdstringresourceUidstring — Stable cloud resource identity; not a CMDB sys_id.podUidstringcloudInstanceIdstring — Compute instance identifier as a string to preserve 64-bit precision. Not the Purple Suite tenant ID.
destinationobjectPeerIdentitynamestringfqdnstringipAddressstringprojectIdstringresourceUidstring — Stable cloud resource identity; not a CMDB sys_id.podUidstringcloudInstanceIdstring — Compute instance identifier as a string to preserve 64-bit precision. Not the Purple Suite tenant ID.
protocolstringdestinationPortintegeroperationstringstatusstringlatencyMsinteger
404- Not found