Purple WorkIQ API Documentation

Machine-readable OpenAPI 3.0 specification: https://marketplace.moveworks.com/api/purple-suite/workiq/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=workiq, or combined with other apps comma-separated (e.g. ?apps=workiq,itsm).

Overview

Conversational workplace-assistant API. Resembles Microsoft 365 Copilot / WorkIQ-style chat: start a session, then submit natural-language queries and receive synthesized answers with citations over the tenant's mail, calendar and collaboration data. This demo instance answers from a fixed set of canned responses rather than reasoning over live data. --- **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/workiq/conversations

List WorkIQ conversations

Lists conversational sessions started in this instance. OData-enabled ($filter/$select/$orderby/$search/$top/$skip/$count) for the Live Data browser and MCP discovery; there is no underlying queryable workplace dataset behind the answers themselves.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
$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:

    Conversation

    • id string
    • createdDateTime string
    • displayName string
    • agentId null
    • state string
    • turnCount integer
    • messages array

      array of:

      ResponseMessage

      • @odata.type string
      • id string
      • text string
      • createdDateTime string
      • adaptiveCards array

        array of:

      • attributions array

        array of:

      • references object
      • sensitivityLabel object
        • sensitivityLabelId string,null
        • displayName string,null
        • tooltip string,null
        • priority integer,null
        • color null
  • 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.

POST /api/purple-suite/workiq/conversations

Create a WorkIQ conversation

Starts a new conversational session. Call once per conversation, before the first /chat turn.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes

Responses

201
Conversation created

application/json

Conversation

  • id string
  • createdDateTime string
  • displayName string
  • agentId null
  • state string
  • turnCount integer
  • messages array

    array of:

    ResponseMessage

    • @odata.type string
    • id string
    • text string
    • createdDateTime string
    • adaptiveCards array

      array of:

    • attributions array

      array of:

    • references object
    • sensitivityLabel object
      • sensitivityLabelId string,null
      • displayName string,null
      • tooltip string,null
      • priority integer,null
      • color null

GET /api/purple-suite/workiq/conversations/{id}

Get a WorkIQ conversation

Fetches a conversation and its message history so far.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Responses

200
Conversation

application/json

Conversation

  • id string
  • createdDateTime string
  • displayName string
  • agentId null
  • state string
  • turnCount integer
  • messages array

    array of:

    ResponseMessage

    • @odata.type string
    • id string
    • text string
    • createdDateTime string
    • adaptiveCards array

      array of:

    • attributions array

      array of:

    • references object
    • sensitivityLabel object
      • sensitivityLabelId string,null
      • displayName string,null
      • tooltip string,null
      • priority integer,null
      • color null
404
Conversation not found

POST /api/purple-suite/workiq/conversations/{id}/chat

Submit a query to a WorkIQ conversation

Submits a natural-language query to an existing conversation and returns a synthesized answer with citations, appended to the conversation's message history. This demo instance matches queries against a fixed set of canned answers rather than reasoning over data.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Request body

application/json

ChatRequest

  • message object required
    • text string required
  • locationHint object
    • timeZone string

Responses

200
Updated conversation, including the new turn's messages

application/json

Conversation

  • id string
  • createdDateTime string
  • displayName string
  • agentId null
  • state string
  • turnCount integer
  • messages array

    array of:

    ResponseMessage

    • @odata.type string
    • id string
    • text string
    • createdDateTime string
    • adaptiveCards array

      array of:

    • attributions array

      array of:

    • references object
    • sensitivityLabel object
      • sensitivityLabelId string,null
      • displayName string,null
      • tooltip string,null
      • priority integer,null
      • color null
400
message.text is required
404
Conversation not found