Purple Identity API Documentation

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

Overview

Purple Identity — the canonical people directory for a Purple Suite instance. Every other app (HRIS, Calendar, Expense, ITSM, …) draws its internal people from this same roster, so an email means the same person everywhere. Exposes an OData-queryable /people collection AND an emulation of the Moveworks Identity Gateway (GET /users, GET /users/{userId}) so a deployment can sync its user directory directly from Purple Suite. --- **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/identity/people

List people in the Purple Identity directory

The canonical internal roster for this Purple Suite instance — every other app (HRIS, ITSM, Expense, Calendar, PM, …) draws its employees, owners and assignees from these same records, so an email means the same human everywhere. Returns flat Person records (email, first/last/full name, title, department, managerEmail, country, city, timezone, startDate, workStatus). Supports server-side OData querying — $filter, $search, $orderby, $select, $top, $skip, $count (MCP clients see these as _filter, _search, _orderby, _select, _top, _skip, _count because $ is not a legal tool-input key). Example: $filter=department eq 'Engineering' and country eq 'US'. Use this to resolve a person, look up a manager, or build an org view; use identity__list__users only when you need the same people in the Moveworks Identity Gateway wire shape.

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:

    Person

    A person in the canonical directory.
    • id string
    • email string
    • firstName string
    • lastName string
    • fullName string
    • title string
    • department string
    • managerEmail string
    • country string
    • locale string
    • city string
    • region string
    • location string
    • timezone string
    • phone string
    • avatarColor string
    • startDate string
    • workStatus 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/identity/people

Add a person to the Purple Identity directory

Creates a Person in the instance's canonical internal roster, making that email resolvable across every other Purple app. Use only for internal staff (employees, contingent workers, interns) — external parties such as CRM contacts, ATS candidates or bank customers live in their own app and must not be added here.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes

Request body

application/json — required

Person

A person in the canonical directory.
  • id string
  • email string
  • firstName string
  • lastName string
  • fullName string
  • title string
  • department string
  • managerEmail string
  • country string
  • locale string
  • city string
  • region string
  • location string
  • timezone string
  • phone string
  • avatarColor string
  • startDate string
  • workStatus string
  • createdAt string
  • updatedAt string

Responses

201
Created

application/json

Person

A person in the canonical directory.
  • id string
  • email string
  • firstName string
  • lastName string
  • fullName string
  • title string
  • department string
  • managerEmail string
  • country string
  • locale string
  • city string
  • region string
  • location string
  • timezone string
  • phone string
  • avatarColor string
  • startDate string
  • workStatus string
  • createdAt string
  • updatedAt string

GET /api/purple-suite/identity/people/{id}

Get one person from the Purple Identity directory

Fetches a single Person by directory id (e.g. PERSON-0001) from the canonical internal roster. If you only have an email, call identity__list__people with $filter=email eq 'someone@acme.com' instead. Returns the flat Person shape; identity__get__users returns the same human in the nested Identity Gateway shape.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Responses

200
Found

application/json

Person

A person in the canonical directory.
  • id string
  • email string
  • firstName string
  • lastName string
  • fullName string
  • title string
  • department string
  • managerEmail string
  • country string
  • locale string
  • city string
  • region string
  • location string
  • timezone string
  • phone string
  • avatarColor string
  • startDate string
  • workStatus string
  • createdAt string
  • updatedAt string
404
Not found

DELETE /api/purple-suite/identity/people/{id}

Delete a person from the Purple Identity directory

DESTRUCTIVE and irreversible: permanently removes the Person from the canonical roster, so their email no longer resolves in any Purple app and existing references to them (tickets, expenses, enrollments) are left dangling. For a departure, prefer identity__update__people to change their status rather than deleting the record.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Responses

200
Deleted

application/json

  • success boolean
404
Not found

PATCH /api/purple-suite/identity/people/{id}

Update a person's directory record

Partially updates a Person in the canonical roster (e.g. title, department, managerEmail, location, workStatus). Because every other Purple app reads people from here, the change is immediately visible suite-wide. Send only the fields you want to change.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Request body

Fields to update (partial)

application/json

Person

A person in the canonical directory.
  • id string
  • email string
  • firstName string
  • lastName string
  • fullName string
  • title string
  • department string
  • managerEmail string
  • country string
  • locale string
  • city string
  • region string
  • location string
  • timezone string
  • phone string
  • avatarColor string
  • startDate string
  • workStatus string
  • createdAt string
  • updatedAt string

Responses

200
Updated

application/json

Person

A person in the canonical directory.
  • id string
  • email string
  • firstName string
  • lastName string
  • fullName string
  • title string
  • department string
  • managerEmail string
  • country string
  • locale string
  • city string
  • region string
  • location string
  • timezone string
  • phone string
  • avatarColor string
  • startDate string
  • workStatus string
  • createdAt string
  • updatedAt string
404
Not found

GET /api/purple-suite/identity/users

List users in the Moveworks Identity Gateway shape

Emulates the Moveworks Identity Gateway 'List Users' contract for user-directory sync. These are the SAME humans as identity__list__people, projected into the gateway's nested envelope ({ results: [{ user, system_identity, last_updated_at }], next_page_token }) — reach for it when you are exercising or debugging a Moveworks identity sync, and for everything else use identity__list__people, which returns the flat, easier-to-read Person records. This endpoint is NOT OData: page with pageToken/pageSize and narrow results with the gateway's own `filter` expression (e.g. filter=department eq 'Engineering'), not $filter/$top.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
pageTokenquerystringnoOpaque paging token — pass the previous response's next_page_token.
pageSizequeryintegernoMaximum users to return in one page (default 1000).
filterquerystringnoFilter expression over person fields. Operators eq/ne/gt/lt, combined with and/or and parentheses. Example: "department eq 'Engineering'".

Responses

200
A page of users

application/json

  • results array

    array of:

    IdentityGatewayUser

    A single user record in the Moveworks Identity Gateway shape (projection of a Person).
    • user object
      • state string
      • universal_identifier string
      • email_addr string
      • first_name string
      • last_name string
      • full_name string
      • work_status string
      • employment_info object
        • employee_start_date_ts string
        • role string
        • manager_email string
        • cost_center_id string
        • cost_center_name string
        • department string
        • office_phone_number string
        • assistant_full_name string
        • employment_location object
          • location string
          • office string
          • country_code string
          • region string
          • timezone string
    • system_identity object
      • id string
      • username string
    • last_updated_at string
  • next_page_token stringToken for the next page, or empty on the last page.
400
Invalid filter expression

GET /api/purple-suite/identity/users/{userId}

Get one user in the Moveworks Identity Gateway shape

Emulates the Moveworks Identity Gateway 'Get User by ID' contract. userId is the user's system_identity.id, which is the same value as the directory's person id (e.g. PERSON-0001). Returns one nested gateway user record with no results envelope. Prefer identity__get__people unless you specifically need the gateway wire shape.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
userIdpathstringyesThe user's system_identity.id (e.g. PERSON-0001).

Responses

200
The user

application/json

IdentityGatewayUser

A single user record in the Moveworks Identity Gateway shape (projection of a Person).
  • user object
    • state string
    • universal_identifier string
    • email_addr string
    • first_name string
    • last_name string
    • full_name string
    • work_status string
    • employment_info object
      • employee_start_date_ts string
      • role string
      • manager_email string
      • cost_center_id string
      • cost_center_name string
      • department string
      • office_phone_number string
      • assistant_full_name string
      • employment_location object
        • location string
        • office string
        • country_code string
        • region string
        • timezone string
  • system_identity object
    • id string
    • username string
  • last_updated_at string
404
User not found