Purple HRIS API Documentation

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

Overview

--- **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

POST /api/purple-suite/hris/employees/search

Search HRIS employees by name, email or attributes

Fuzzy person lookup over the HRIS employee master (the record of employment: manager, department, title, salary band, status) - not the identity directory or a chat user roster. Pass `query` for scored free-text search OR framed fields (name, email, department, role, manager_name, employment_status) for structured search; the two are mutually exclusive. Returns RecordResult envelopes with a nested person_entity. Reach for this when you have a partial or misspelled name; use the employees list when you can express the criteria as an exact $filter.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes

Request body

application/json — required

  • query stringFree-text search query (tokenized, scored by term overlap). Mutually exclusive with framed fields.
  • name stringFull or partial person name — firstName + lastName substring match (framed search)
  • email stringEmail address partial match (framed search)
  • department stringExact department name match (framed search)
  • role stringRole/title substring match (framed search)
  • manager_name stringManager full name substring — applied as post-filter after framed scoring (framed search)
  • manager_email stringManager email substring — applied as post-filter after framed scoring (framed search)
  • employment_status stringEmployment status exact match (framed search)

Responses

200
Search results in RecordResult format (top 5 matches by score)

application/json

  • results array

    array of:

    • record objectNested RecordResult envelope
      Nested RecordResult envelope
      • meta_info object
        • structured_entity object
          • person_entity object
            • person_info object

            • contact_info object

            • occupation_info object

            • workplace_info object

    • score numberMatch score between 0 and 1
    • confidence stringEXACT_MATCH ≥ 0.9, VALID ≥ 0.5, INVALID < 0.5
  • total_retrieved integer
500
Internal server error

POST /api/purple-suite/hris/users/search

Search HRIS employees, projected as flat User records

Identical search semantics to the employee search (free-text `query` OR framed fields) but each match comes back as a flat User-shaped object (email_addr, full_name, record_id, ...) instead of the nested RecordResult envelope. Choose this only when the caller expects native-User field names; otherwise prefer the employee search. It still reads the HRIS employee master, not an identity or chat directory.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes

Request body

application/json — required

  • query stringFree-text search query (tokenized, scored by term overlap). Mutually exclusive with framed fields.
  • name stringFull or partial person name — firstName + lastName substring match (framed search)
  • email stringEmail address partial match (framed search)
  • department stringExact department name match (framed search)
  • role stringRole/title substring match (framed search)
  • manager_name stringManager full name substring — applied as post-filter after framed scoring (framed search)
  • manager_email stringManager email substring — applied as post-filter after framed scoring (framed search)
  • employment_status stringEmployment status exact match (framed search)

Responses

200
Search results as flat User records (top 5 matches by score)

application/json

  • results array

    array of:

    • record_id stringEmployee id
    • email_addr string
    • full_name string
    • first_name string
    • last_name string
    • department string
    • role string
    • manager_email string
    • timezone string
    • location string
  • total_retrieved integer
500
Internal server error

GET /api/purple-suite/hris/employees

List HRIS employee records

An HRIS employee is the system-of-record employment file for a person: employee id, name/email, manager, department, title, hire date, salary and compensation, employment status (active / on_leave / terminated / suspended), PTO balance, skills, reviews and goals. This is the HR master data - richer and more sensitive than the identity directory (a people/account lookup) or a chat user roster. Use it for org, headcount, compensation and status questions; use the employee search for fuzzy name matching. Server-side query: $filter/$select/$orderby/$search/$top/$skip/$count (MCP clients pass these as _filter, _top, ... because $ is not a legal tool-input key).

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
limitqueryintegernoMax items per page (default 50)
cursorquerystringnoPass the previous response's nextCursor to fetch the next page
$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.
statusquerystringnoFilter by employment status (exact match). Legacy — prefer $filter.
departmentquerystringnoFilter by department name (exact match). Legacy — prefer $filter.
firstNamequerystringnoFilter by first name (exact match). Legacy — prefer $filter.
lastNamequerystringnoFilter by last name (exact match). Legacy — prefer $filter.
emailquerystringnoFilter by email address (exact match). Legacy — prefer $filter.
managerIdquerystringnoFilter by manager employee ID (exact match). Legacy — prefer $filter.
searchquerystringnoFree-text search across firstName, lastName, and email (substring match). Legacy — equivalent to $search.

Responses

200
Paginated list

application/json

  • data array

    array of:

    Employee

    • id string
    • firstName string requiredEmployee first name. Alias accepted on create/update: first_name
    • lastName string requiredEmployee last name. Alias accepted on create/update: last_name
    • email string required
    • department stringDepartment name. Must match an existing department. Alias accepted on create: department_id
    • title string
    • status stringEmployment status. On PATCH also accepts 'suspended'. Use the /transition endpoint for lifecycle transitions.
    • startDate stringEmployment start date. Alias accepted on create: hire_date
    • salary number
    • managerId stringID of the manager employee. Alias accepted on create: manager_id
    • phone string
    • location stringCity (leaf of the location hierarchy city ∈ country ∈ region).
    • country stringCountry (derived from city). Middle level of the location hierarchy; drives HRBP country-level scope.
    • timezone string
    • costCenter string
    • region stringGeographic region (derived from location/city). Top level of the location hierarchy; used by HRBP analytics group-by + region scope.
    • job_level stringJob level code (IC1–IC6 / M1–M7). Alias accepted on create: level.
    • management_level stringIndividual Contributor or Managerial.
    • employment_type stringWorker classification. Drives contingent-headcount analytics.
    • probation_end_date stringEnd of probation period; null once past probation. Drives probation-headcount analytics.
    • termination_type stringSet when status→terminated via /transition.
    • termination_reason stringCategorized exit reason (e.g. compensation, career_growth, relocation, performance, retirement).
    • termination_date stringEffective termination date (mirrors the latest 'terminated' status_history entry).
    • pto_balance objectCurrent PTO balance. Use PATCH /employees/{id}/pto-balance to update directly.
      Current PTO balance. Use PATCH /employees/{id}/pto-balance to update directly.
      • vacation_days number
      • sick_days number
    • status_history arrayImmutable audit log of status transitions (appended by /transition endpoint).
      Immutable audit log of status transitions (appended by /transition endpoint).

      array of:

      • status string
      • reason string
      • effective_date string
      • recorded_at string
    • skills arrayEmployee skills with proficiency. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/skills.
      Employee skills with proficiency. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/skills.

      array of:

      • skill string
      • proficiency string
      • last_updated string
    • reviews arrayRecent performance reviews. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/reviews.
      Recent performance reviews. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/reviews.

      array of:

      • id string
      • period string
      • rating string
      • strengths array

        array of:

        string

      • gaps array

        array of:

        string

      • reviewer_id string
      • reviewed_at string
    • goals arrayCurrent development goals. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/goals.
      Current development goals. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/goals.

      array of:

      • id string
      • description string
      • target_role string
      • target_timeline string
      • status string
      • progress_pct integer
    • generate_related_records booleanCREATE only. When true (or camelCase generateRelatedRecords), seeds 3 timesheets and 2 benefits for the new employee. Not stored.
    • createdAt string
    • updatedAt string
  • nextCursor stringCursor for the next page, or null on the last page
  • total integerTotal documents in the collection

POST /api/purple-suite/hris/employees

Create an HRIS employee record

Onboards a person into the HR system of record with their employment details. Email must be unique in the instance (409 otherwise). This creates the employment file only - it does not provision identity, chat or any downstream account.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes

Request body

application/json — required

Employee

  • id string
  • firstName string requiredEmployee first name. Alias accepted on create/update: first_name
  • lastName string requiredEmployee last name. Alias accepted on create/update: last_name
  • email string required
  • department stringDepartment name. Must match an existing department. Alias accepted on create: department_id
  • title string
  • status stringEmployment status. On PATCH also accepts 'suspended'. Use the /transition endpoint for lifecycle transitions.
  • startDate stringEmployment start date. Alias accepted on create: hire_date
  • salary number
  • managerId stringID of the manager employee. Alias accepted on create: manager_id
  • phone string
  • location stringCity (leaf of the location hierarchy city ∈ country ∈ region).
  • country stringCountry (derived from city). Middle level of the location hierarchy; drives HRBP country-level scope.
  • timezone string
  • costCenter string
  • region stringGeographic region (derived from location/city). Top level of the location hierarchy; used by HRBP analytics group-by + region scope.
  • job_level stringJob level code (IC1–IC6 / M1–M7). Alias accepted on create: level.
  • management_level stringIndividual Contributor or Managerial.
  • employment_type stringWorker classification. Drives contingent-headcount analytics.
  • probation_end_date stringEnd of probation period; null once past probation. Drives probation-headcount analytics.
  • termination_type stringSet when status→terminated via /transition.
  • termination_reason stringCategorized exit reason (e.g. compensation, career_growth, relocation, performance, retirement).
  • termination_date stringEffective termination date (mirrors the latest 'terminated' status_history entry).
  • pto_balance objectCurrent PTO balance. Use PATCH /employees/{id}/pto-balance to update directly.
    Current PTO balance. Use PATCH /employees/{id}/pto-balance to update directly.
    • vacation_days number
    • sick_days number
  • status_history arrayImmutable audit log of status transitions (appended by /transition endpoint).
    Immutable audit log of status transitions (appended by /transition endpoint).

    array of:

    • status string
    • reason string
    • effective_date string
    • recorded_at string
  • skills arrayEmployee skills with proficiency. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/skills.
    Employee skills with proficiency. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/skills.

    array of:

    • skill string
    • proficiency string
    • last_updated string
  • reviews arrayRecent performance reviews. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/reviews.
    Recent performance reviews. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/reviews.

    array of:

    • id string
    • period string
    • rating string
    • strengths array

      array of:

      string

    • gaps array

      array of:

      string

    • reviewer_id string
    • reviewed_at string
  • goals arrayCurrent development goals. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/goals.
    Current development goals. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/goals.

    array of:

    • id string
    • description string
    • target_role string
    • target_timeline string
    • status string
    • progress_pct integer
  • generate_related_records booleanCREATE only. When true (or camelCase generateRelatedRecords), seeds 3 timesheets and 2 benefits for the new employee. Not stored.
  • createdAt string
  • updatedAt string

Responses

201
Created

application/json

Employee

  • id string
  • firstName string requiredEmployee first name. Alias accepted on create/update: first_name
  • lastName string requiredEmployee last name. Alias accepted on create/update: last_name
  • email string required
  • department stringDepartment name. Must match an existing department. Alias accepted on create: department_id
  • title string
  • status stringEmployment status. On PATCH also accepts 'suspended'. Use the /transition endpoint for lifecycle transitions.
  • startDate stringEmployment start date. Alias accepted on create: hire_date
  • salary number
  • managerId stringID of the manager employee. Alias accepted on create: manager_id
  • phone string
  • location stringCity (leaf of the location hierarchy city ∈ country ∈ region).
  • country stringCountry (derived from city). Middle level of the location hierarchy; drives HRBP country-level scope.
  • timezone string
  • costCenter string
  • region stringGeographic region (derived from location/city). Top level of the location hierarchy; used by HRBP analytics group-by + region scope.
  • job_level stringJob level code (IC1–IC6 / M1–M7). Alias accepted on create: level.
  • management_level stringIndividual Contributor or Managerial.
  • employment_type stringWorker classification. Drives contingent-headcount analytics.
  • probation_end_date stringEnd of probation period; null once past probation. Drives probation-headcount analytics.
  • termination_type stringSet when status→terminated via /transition.
  • termination_reason stringCategorized exit reason (e.g. compensation, career_growth, relocation, performance, retirement).
  • termination_date stringEffective termination date (mirrors the latest 'terminated' status_history entry).
  • pto_balance objectCurrent PTO balance. Use PATCH /employees/{id}/pto-balance to update directly.
    Current PTO balance. Use PATCH /employees/{id}/pto-balance to update directly.
    • vacation_days number
    • sick_days number
  • status_history arrayImmutable audit log of status transitions (appended by /transition endpoint).
    Immutable audit log of status transitions (appended by /transition endpoint).

    array of:

    • status string
    • reason string
    • effective_date string
    • recorded_at string
  • skills arrayEmployee skills with proficiency. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/skills.
    Employee skills with proficiency. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/skills.

    array of:

    • skill string
    • proficiency string
    • last_updated string
  • reviews arrayRecent performance reviews. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/reviews.
    Recent performance reviews. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/reviews.

    array of:

    • id string
    • period string
    • rating string
    • strengths array

      array of:

      string

    • gaps array

      array of:

      string

    • reviewer_id string
    • reviewed_at string
  • goals arrayCurrent development goals. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/goals.
    Current development goals. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/goals.

    array of:

    • id string
    • description string
    • target_role string
    • target_timeline string
    • status string
    • progress_pct integer
  • generate_related_records booleanCREATE only. When true (or camelCase generateRelatedRecords), seeds 3 timesheets and 2 benefits for the new employee. Not stored.
  • createdAt string
  • updatedAt string
400
Missing required field or invalid status
409
Employee with this email already exists

GET /api/purple-suite/hris/employees/{id}

Get an HRIS employee record by id

Returns one employment file in full - manager, department, title, compensation, status history, PTO balance, skills, reviews and goals. Use the employee search when you have a name rather than an id.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Responses

200
Found

application/json

Employee

  • id string
  • firstName string requiredEmployee first name. Alias accepted on create/update: first_name
  • lastName string requiredEmployee last name. Alias accepted on create/update: last_name
  • email string required
  • department stringDepartment name. Must match an existing department. Alias accepted on create: department_id
  • title string
  • status stringEmployment status. On PATCH also accepts 'suspended'. Use the /transition endpoint for lifecycle transitions.
  • startDate stringEmployment start date. Alias accepted on create: hire_date
  • salary number
  • managerId stringID of the manager employee. Alias accepted on create: manager_id
  • phone string
  • location stringCity (leaf of the location hierarchy city ∈ country ∈ region).
  • country stringCountry (derived from city). Middle level of the location hierarchy; drives HRBP country-level scope.
  • timezone string
  • costCenter string
  • region stringGeographic region (derived from location/city). Top level of the location hierarchy; used by HRBP analytics group-by + region scope.
  • job_level stringJob level code (IC1–IC6 / M1–M7). Alias accepted on create: level.
  • management_level stringIndividual Contributor or Managerial.
  • employment_type stringWorker classification. Drives contingent-headcount analytics.
  • probation_end_date stringEnd of probation period; null once past probation. Drives probation-headcount analytics.
  • termination_type stringSet when status→terminated via /transition.
  • termination_reason stringCategorized exit reason (e.g. compensation, career_growth, relocation, performance, retirement).
  • termination_date stringEffective termination date (mirrors the latest 'terminated' status_history entry).
  • pto_balance objectCurrent PTO balance. Use PATCH /employees/{id}/pto-balance to update directly.
    Current PTO balance. Use PATCH /employees/{id}/pto-balance to update directly.
    • vacation_days number
    • sick_days number
  • status_history arrayImmutable audit log of status transitions (appended by /transition endpoint).
    Immutable audit log of status transitions (appended by /transition endpoint).

    array of:

    • status string
    • reason string
    • effective_date string
    • recorded_at string
  • skills arrayEmployee skills with proficiency. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/skills.
    Employee skills with proficiency. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/skills.

    array of:

    • skill string
    • proficiency string
    • last_updated string
  • reviews arrayRecent performance reviews. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/reviews.
    Recent performance reviews. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/reviews.

    array of:

    • id string
    • period string
    • rating string
    • strengths array

      array of:

      string

    • gaps array

      array of:

      string

    • reviewer_id string
    • reviewed_at string
  • goals arrayCurrent development goals. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/goals.
    Current development goals. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/goals.

    array of:

    • id string
    • description string
    • target_role string
    • target_timeline string
    • status string
    • progress_pct integer
  • generate_related_records booleanCREATE only. When true (or camelCase generateRelatedRecords), seeds 3 timesheets and 2 benefits for the new employee. Not stored.
  • createdAt string
  • updatedAt string
404
Not found

DELETE /api/purple-suite/hris/employees/{id}

Delete an HRIS employee record

DESTRUCTIVE and irreversible: erases the entire employment file including status history, reviews and PTO. This is NOT how you offboard someone - use the transition action to set status to `terminated`, which preserves the record. Confirm with the user before calling.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Responses

200
Deleted

application/json

  • success boolean
  • id string
404
Not found

PATCH /api/purple-suite/hris/employees/{id}

Update an HRIS employee record

Partial update of the employment file - also the way to write the `skills`, `reviews` and `goals` arrays that the dedicated GET sub-resources read back. Status accepts 'suspended' on top of the standard statuses, but terminated employees cannot be reactivated and their employment fields (salary, department_id, title) are frozen; for lifecycle moves prefer the transition action, and for PTO use the pto-balance action.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Request body

Fields to update (partial)

application/json

Employee

  • id string
  • firstName string requiredEmployee first name. Alias accepted on create/update: first_name
  • lastName string requiredEmployee last name. Alias accepted on create/update: last_name
  • email string required
  • department stringDepartment name. Must match an existing department. Alias accepted on create: department_id
  • title string
  • status stringEmployment status. On PATCH also accepts 'suspended'. Use the /transition endpoint for lifecycle transitions.
  • startDate stringEmployment start date. Alias accepted on create: hire_date
  • salary number
  • managerId stringID of the manager employee. Alias accepted on create: manager_id
  • phone string
  • location stringCity (leaf of the location hierarchy city ∈ country ∈ region).
  • country stringCountry (derived from city). Middle level of the location hierarchy; drives HRBP country-level scope.
  • timezone string
  • costCenter string
  • region stringGeographic region (derived from location/city). Top level of the location hierarchy; used by HRBP analytics group-by + region scope.
  • job_level stringJob level code (IC1–IC6 / M1–M7). Alias accepted on create: level.
  • management_level stringIndividual Contributor or Managerial.
  • employment_type stringWorker classification. Drives contingent-headcount analytics.
  • probation_end_date stringEnd of probation period; null once past probation. Drives probation-headcount analytics.
  • termination_type stringSet when status→terminated via /transition.
  • termination_reason stringCategorized exit reason (e.g. compensation, career_growth, relocation, performance, retirement).
  • termination_date stringEffective termination date (mirrors the latest 'terminated' status_history entry).
  • pto_balance objectCurrent PTO balance. Use PATCH /employees/{id}/pto-balance to update directly.
    Current PTO balance. Use PATCH /employees/{id}/pto-balance to update directly.
    • vacation_days number
    • sick_days number
  • status_history arrayImmutable audit log of status transitions (appended by /transition endpoint).
    Immutable audit log of status transitions (appended by /transition endpoint).

    array of:

    • status string
    • reason string
    • effective_date string
    • recorded_at string
  • skills arrayEmployee skills with proficiency. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/skills.
    Employee skills with proficiency. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/skills.

    array of:

    • skill string
    • proficiency string
    • last_updated string
  • reviews arrayRecent performance reviews. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/reviews.
    Recent performance reviews. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/reviews.

    array of:

    • id string
    • period string
    • rating string
    • strengths array

      array of:

      string

    • gaps array

      array of:

      string

    • reviewer_id string
    • reviewed_at string
  • goals arrayCurrent development goals. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/goals.
    Current development goals. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/goals.

    array of:

    • id string
    • description string
    • target_role string
    • target_timeline string
    • status string
    • progress_pct integer
  • generate_related_records booleanCREATE only. When true (or camelCase generateRelatedRecords), seeds 3 timesheets and 2 benefits for the new employee. Not stored.
  • createdAt string
  • updatedAt string

Responses

200
Updated

application/json

Employee

  • id string
  • firstName string requiredEmployee first name. Alias accepted on create/update: first_name
  • lastName string requiredEmployee last name. Alias accepted on create/update: last_name
  • email string required
  • department stringDepartment name. Must match an existing department. Alias accepted on create: department_id
  • title string
  • status stringEmployment status. On PATCH also accepts 'suspended'. Use the /transition endpoint for lifecycle transitions.
  • startDate stringEmployment start date. Alias accepted on create: hire_date
  • salary number
  • managerId stringID of the manager employee. Alias accepted on create: manager_id
  • phone string
  • location stringCity (leaf of the location hierarchy city ∈ country ∈ region).
  • country stringCountry (derived from city). Middle level of the location hierarchy; drives HRBP country-level scope.
  • timezone string
  • costCenter string
  • region stringGeographic region (derived from location/city). Top level of the location hierarchy; used by HRBP analytics group-by + region scope.
  • job_level stringJob level code (IC1–IC6 / M1–M7). Alias accepted on create: level.
  • management_level stringIndividual Contributor or Managerial.
  • employment_type stringWorker classification. Drives contingent-headcount analytics.
  • probation_end_date stringEnd of probation period; null once past probation. Drives probation-headcount analytics.
  • termination_type stringSet when status→terminated via /transition.
  • termination_reason stringCategorized exit reason (e.g. compensation, career_growth, relocation, performance, retirement).
  • termination_date stringEffective termination date (mirrors the latest 'terminated' status_history entry).
  • pto_balance objectCurrent PTO balance. Use PATCH /employees/{id}/pto-balance to update directly.
    Current PTO balance. Use PATCH /employees/{id}/pto-balance to update directly.
    • vacation_days number
    • sick_days number
  • status_history arrayImmutable audit log of status transitions (appended by /transition endpoint).
    Immutable audit log of status transitions (appended by /transition endpoint).

    array of:

    • status string
    • reason string
    • effective_date string
    • recorded_at string
  • skills arrayEmployee skills with proficiency. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/skills.
    Employee skills with proficiency. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/skills.

    array of:

    • skill string
    • proficiency string
    • last_updated string
  • reviews arrayRecent performance reviews. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/reviews.
    Recent performance reviews. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/reviews.

    array of:

    • id string
    • period string
    • rating string
    • strengths array

      array of:

      string

    • gaps array

      array of:

      string

    • reviewer_id string
    • reviewed_at string
  • goals arrayCurrent development goals. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/goals.
    Current development goals. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/goals.

    array of:

    • id string
    • description string
    • target_role string
    • target_timeline string
    • status string
    • progress_pct integer
  • generate_related_records booleanCREATE only. When true (or camelCase generateRelatedRecords), seeds 3 timesheets and 2 benefits for the new employee. Not stored.
  • createdAt string
  • updatedAt string
404
Not found
422
State machine violation (e.g. reactivating a terminated employee)

POST /api/purple-suite/hris/employees/{id}/transition

Move an employee through their lifecycle (leave / return / terminate)

The correct way to change employment status: applies the state machine and appends to status_history with a reason and effective date. Terminated employees cannot be reactivated or put on leave, and an on_leave employee must return to active before termination. Optionally deducts `days` of PTO when going on_leave. Terminating is effectively irreversible - confirm with the user first. Use this rather than PATCHing `status` on the employee.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Request body

application/json — required

  • status string requiredTarget status for the transition
  • reason stringHuman-readable reason for the transition (appended to status_history)
  • effective_date stringWhen the transition takes effect (defaults to now)
  • days numberPTO vacation days to deduct from pto_balance.vacation_days. Only applied when transitioning to on_leave.

Responses

200
Updated employee record

application/json

Employee

  • id string
  • firstName string requiredEmployee first name. Alias accepted on create/update: first_name
  • lastName string requiredEmployee last name. Alias accepted on create/update: last_name
  • email string required
  • department stringDepartment name. Must match an existing department. Alias accepted on create: department_id
  • title string
  • status stringEmployment status. On PATCH also accepts 'suspended'. Use the /transition endpoint for lifecycle transitions.
  • startDate stringEmployment start date. Alias accepted on create: hire_date
  • salary number
  • managerId stringID of the manager employee. Alias accepted on create: manager_id
  • phone string
  • location stringCity (leaf of the location hierarchy city ∈ country ∈ region).
  • country stringCountry (derived from city). Middle level of the location hierarchy; drives HRBP country-level scope.
  • timezone string
  • costCenter string
  • region stringGeographic region (derived from location/city). Top level of the location hierarchy; used by HRBP analytics group-by + region scope.
  • job_level stringJob level code (IC1–IC6 / M1–M7). Alias accepted on create: level.
  • management_level stringIndividual Contributor or Managerial.
  • employment_type stringWorker classification. Drives contingent-headcount analytics.
  • probation_end_date stringEnd of probation period; null once past probation. Drives probation-headcount analytics.
  • termination_type stringSet when status→terminated via /transition.
  • termination_reason stringCategorized exit reason (e.g. compensation, career_growth, relocation, performance, retirement).
  • termination_date stringEffective termination date (mirrors the latest 'terminated' status_history entry).
  • pto_balance objectCurrent PTO balance. Use PATCH /employees/{id}/pto-balance to update directly.
    Current PTO balance. Use PATCH /employees/{id}/pto-balance to update directly.
    • vacation_days number
    • sick_days number
  • status_history arrayImmutable audit log of status transitions (appended by /transition endpoint).
    Immutable audit log of status transitions (appended by /transition endpoint).

    array of:

    • status string
    • reason string
    • effective_date string
    • recorded_at string
  • skills arrayEmployee skills with proficiency. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/skills.
    Employee skills with proficiency. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/skills.

    array of:

    • skill string
    • proficiency string
    • last_updated string
  • reviews arrayRecent performance reviews. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/reviews.
    Recent performance reviews. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/reviews.

    array of:

    • id string
    • period string
    • rating string
    • strengths array

      array of:

      string

    • gaps array

      array of:

      string

    • reviewer_id string
    • reviewed_at string
  • goals arrayCurrent development goals. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/goals.
    Current development goals. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/goals.

    array of:

    • id string
    • description string
    • target_role string
    • target_timeline string
    • status string
    • progress_pct integer
  • generate_related_records booleanCREATE only. When true (or camelCase generateRelatedRecords), seeds 3 timesheets and 2 benefits for the new employee. Not stored.
  • createdAt string
  • updatedAt string
400
Invalid status value
404
Employee not found
422
Transition not allowed by state machine rules

PATCH /api/purple-suite/hris/employees/{id}/pto-balance

Set an employee's PTO day balances

Directly SETS (does not add to) vacation_days and/or sick_days on the employee's pto_balance; omitted fields keep their current value. Use this for balance corrections and accrual grants - booking actual time off goes through time-off requests, and going on leave can deduct days via the transition action.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Request body

application/json — required

  • vacation_days numberNew vacation day balance. Omit to keep current value.
  • sick_days numberNew sick day balance. Omit to keep current value.

Responses

200
Updated employee record with new pto_balance

application/json

Employee

  • id string
  • firstName string requiredEmployee first name. Alias accepted on create/update: first_name
  • lastName string requiredEmployee last name. Alias accepted on create/update: last_name
  • email string required
  • department stringDepartment name. Must match an existing department. Alias accepted on create: department_id
  • title string
  • status stringEmployment status. On PATCH also accepts 'suspended'. Use the /transition endpoint for lifecycle transitions.
  • startDate stringEmployment start date. Alias accepted on create: hire_date
  • salary number
  • managerId stringID of the manager employee. Alias accepted on create: manager_id
  • phone string
  • location stringCity (leaf of the location hierarchy city ∈ country ∈ region).
  • country stringCountry (derived from city). Middle level of the location hierarchy; drives HRBP country-level scope.
  • timezone string
  • costCenter string
  • region stringGeographic region (derived from location/city). Top level of the location hierarchy; used by HRBP analytics group-by + region scope.
  • job_level stringJob level code (IC1–IC6 / M1–M7). Alias accepted on create: level.
  • management_level stringIndividual Contributor or Managerial.
  • employment_type stringWorker classification. Drives contingent-headcount analytics.
  • probation_end_date stringEnd of probation period; null once past probation. Drives probation-headcount analytics.
  • termination_type stringSet when status→terminated via /transition.
  • termination_reason stringCategorized exit reason (e.g. compensation, career_growth, relocation, performance, retirement).
  • termination_date stringEffective termination date (mirrors the latest 'terminated' status_history entry).
  • pto_balance objectCurrent PTO balance. Use PATCH /employees/{id}/pto-balance to update directly.
    Current PTO balance. Use PATCH /employees/{id}/pto-balance to update directly.
    • vacation_days number
    • sick_days number
  • status_history arrayImmutable audit log of status transitions (appended by /transition endpoint).
    Immutable audit log of status transitions (appended by /transition endpoint).

    array of:

    • status string
    • reason string
    • effective_date string
    • recorded_at string
  • skills arrayEmployee skills with proficiency. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/skills.
    Employee skills with proficiency. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/skills.

    array of:

    • skill string
    • proficiency string
    • last_updated string
  • reviews arrayRecent performance reviews. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/reviews.
    Recent performance reviews. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/reviews.

    array of:

    • id string
    • period string
    • rating string
    • strengths array

      array of:

      string

    • gaps array

      array of:

      string

    • reviewer_id string
    • reviewed_at string
  • goals arrayCurrent development goals. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/goals.
    Current development goals. Settable via PATCH /employees/{id}. Also available at GET /employees/{id}/goals.

    array of:

    • id string
    • description string
    • target_role string
    • target_timeline string
    • status string
    • progress_pct integer
  • generate_related_records booleanCREATE only. When true (or camelCase generateRelatedRecords), seeds 3 timesheets and 2 benefits for the new employee. Not stored.
  • createdAt string
  • updatedAt string
404
Employee not found

GET /api/purple-suite/hris/employees/{id}/skills

Get an employee's skills profile

Read-only convenience view of the `skills` array on one employee record (skill, proficiency, last_updated) - useful for staffing and development questions. To change skills, PATCH the `skills` field on the employee; there is no write endpoint here.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Responses

200
Employee skills

application/json

  • employee_id string
  • skills array

    array of:

    #/components/schemas/Employee/properties/skills/items

404
Employee not found

GET /api/purple-suite/hris/employees/{id}/reviews

Get an employee's performance review history

Read-only convenience view of the `reviews` array on one employee record (period, rating, strengths, gaps). This is the narrative review history on the employment file - distinct from review-cycles, which track the review PROCESS. To change reviews, PATCH the `reviews` field on the employee.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Responses

200
Employee reviews

application/json

  • employee_id string
  • reviews array

    array of:

    #/components/schemas/Employee/properties/reviews/items

404
Employee not found

GET /api/purple-suite/hris/employees/{id}/goals

Get an employee's development goals

Read-only convenience view of the `goals` array on one employee record (description, target_role, target_timeline, status, progress_pct) - career-development plans, not company OKRs. To change goals, PATCH the `goals` field on the employee.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Responses

200
Employee goals

application/json

  • employee_id string
  • goals array

    array of:

    #/components/schemas/Employee/properties/goals/items

404
Employee not found

GET /api/purple-suite/hris/departments

List HRIS departments

A department is an org unit in the HR system of record - name, its manager and its headcount. Employees reference it by department_id / department name. Use it to enumerate the org structure or resolve a department before filtering employees. Server-side query: $filter/$select/$orderby/$search/$top/$skip/$count (MCP clients pass these as _filter, _top, ... because $ is not a legal tool-input key).

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
limitqueryintegernoMax items per page (default 50)
cursorquerystringnoPass the previous response's nextCursor to fetch the next page
$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.
namequerystringnoFilter by department name (exact match)

Responses

200
Paginated list

application/json

  • data array

    array of:

    Department

    • id string
    • name string required
    • manager stringEmail of the department manager. Aliases accepted on create: managerId, head_employee_id
    • budget number
    • headCount integerNumber of employees in the department. Alias accepted on create: headcount (lowercase)
    • createdAt string
    • updatedAt string
  • nextCursor stringCursor for the next page, or null on the last page
  • total integerTotal documents in the collection

POST /api/purple-suite/hris/departments

Create an HRIS department

Adds an org unit that employees can be assigned to. Creating a department does not move any employee into it - PATCH the employees for that.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes

Request body

application/json — required

Department

  • id string
  • name string required
  • manager stringEmail of the department manager. Aliases accepted on create: managerId, head_employee_id
  • budget number
  • headCount integerNumber of employees in the department. Alias accepted on create: headcount (lowercase)
  • createdAt string
  • updatedAt string

Responses

201
Created

application/json

Department

  • id string
  • name string required
  • manager stringEmail of the department manager. Aliases accepted on create: managerId, head_employee_id
  • budget number
  • headCount integerNumber of employees in the department. Alias accepted on create: headcount (lowercase)
  • createdAt string
  • updatedAt string

GET /api/purple-suite/hris/departments/{id}

Get an HRIS department by id

Returns one org unit with its manager and headcount. The employees in it are found by filtering the employees list on that department.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Responses

200
Found

application/json

Department

  • id string
  • name string required
  • manager stringEmail of the department manager. Aliases accepted on create: managerId, head_employee_id
  • budget number
  • headCount integerNumber of employees in the department. Alias accepted on create: headcount (lowercase)
  • createdAt string
  • updatedAt string
404
Not found

DELETE /api/purple-suite/hris/departments/{id}

Delete an HRIS department

DESTRUCTIVE and irreversible: removes the org unit. Employees that referenced it keep a department that no longer resolves. Confirm with the user before calling.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Responses

200
Deleted

application/json

  • success boolean
  • id string
404
Not found

PATCH /api/purple-suite/hris/departments/{id}

Edit an HRIS department

Partial update of an org unit (rename, change its manager). Renaming does not automatically re-point employees that store the department by name.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Request body

Fields to update (partial)

application/json

Department

  • id string
  • name string required
  • manager stringEmail of the department manager. Aliases accepted on create: managerId, head_employee_id
  • budget number
  • headCount integerNumber of employees in the department. Alias accepted on create: headcount (lowercase)
  • createdAt string
  • updatedAt string

Responses

200
Updated

application/json

Department

  • id string
  • name string required
  • manager stringEmail of the department manager. Aliases accepted on create: managerId, head_employee_id
  • budget number
  • headCount integerNumber of employees in the department. Alias accepted on create: headcount (lowercase)
  • createdAt string
  • updatedAt string
404
Not found

GET /api/purple-suite/hris/pay-runs

List payroll runs

A pay run is one payroll cycle for the company - its pay period, pay date, employee count, gross/net totals and a status of draft -> processing -> completed (or cancelled). Company-level payroll, not an individual payslip; per-person hours live on timesheets. Server-side query: $filter/$select/$orderby/$search/$top/$skip/$count (MCP clients pass these as _filter, _top, ... because $ is not a legal tool-input key).

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
limitqueryintegernoMax items per page (default 50)
cursorquerystringnoPass the previous response's nextCursor to fetch the next page
$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.
statusquerystringnoFilter by pay run status (exact match)

Responses

200
Paginated list

application/json

  • data array

    array of:

    PayRun

    • id string
    • periodStart stringPay period start date. Alias accepted on create: period_start
    • periodEnd stringPay period end date. Alias accepted on create: period_end
    • status stringPay run status. State machine: draft → processing → completed. Completed runs are locked. Cancelled runs cannot be reactivated.
    • totalAmount numberTotal gross payroll amount. Alias accepted on create: total_amount
    • employeeCount integerNumber of employees included in this run. Alias accepted on create: employee_count
    • runDate string
    • entries arrayPer-employee pay breakdown. Set on create or PATCH.
      Per-employee pay breakdown. Set on create or PATCH.

      array of:

      • employeeId string
      • grossPay number
      • netPay number
    • createdAt string
    • updatedAt string
  • nextCursor stringCursor for the next page, or null on the last page
  • total integerTotal documents in the collection

POST /api/purple-suite/hris/pay-runs

Open a payroll run

Creates a payroll cycle, normally in `draft`, for a pay period. Advance it with the update operation - it must pass through `processing` before it can be completed.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes

Request body

application/json — required

PayRun

  • id string
  • periodStart stringPay period start date. Alias accepted on create: period_start
  • periodEnd stringPay period end date. Alias accepted on create: period_end
  • status stringPay run status. State machine: draft → processing → completed. Completed runs are locked. Cancelled runs cannot be reactivated.
  • totalAmount numberTotal gross payroll amount. Alias accepted on create: total_amount
  • employeeCount integerNumber of employees included in this run. Alias accepted on create: employee_count
  • runDate string
  • entries arrayPer-employee pay breakdown. Set on create or PATCH.
    Per-employee pay breakdown. Set on create or PATCH.

    array of:

    • employeeId string
    • grossPay number
    • netPay number
  • createdAt string
  • updatedAt string

Responses

201
Created

application/json

PayRun

  • id string
  • periodStart stringPay period start date. Alias accepted on create: period_start
  • periodEnd stringPay period end date. Alias accepted on create: period_end
  • status stringPay run status. State machine: draft → processing → completed. Completed runs are locked. Cancelled runs cannot be reactivated.
  • totalAmount numberTotal gross payroll amount. Alias accepted on create: total_amount
  • employeeCount integerNumber of employees included in this run. Alias accepted on create: employee_count
  • runDate string
  • entries arrayPer-employee pay breakdown. Set on create or PATCH.
    Per-employee pay breakdown. Set on create or PATCH.

    array of:

    • employeeId string
    • grossPay number
    • netPay number
  • createdAt string
  • updatedAt string

GET /api/purple-suite/hris/pay-runs/{id}

Get a payroll run by id

Returns one payroll cycle: period, pay date, employee count, gross and net totals and current status.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Responses

200
Found

application/json

PayRun

  • id string
  • periodStart stringPay period start date. Alias accepted on create: period_start
  • periodEnd stringPay period end date. Alias accepted on create: period_end
  • status stringPay run status. State machine: draft → processing → completed. Completed runs are locked. Cancelled runs cannot be reactivated.
  • totalAmount numberTotal gross payroll amount. Alias accepted on create: total_amount
  • employeeCount integerNumber of employees included in this run. Alias accepted on create: employee_count
  • runDate string
  • entries arrayPer-employee pay breakdown. Set on create or PATCH.
    Per-employee pay breakdown. Set on create or PATCH.

    array of:

    • employeeId string
    • grossPay number
    • netPay number
  • createdAt string
  • updatedAt string
404
Not found

DELETE /api/purple-suite/hris/pay-runs/{id}

Delete a payroll run

DESTRUCTIVE and irreversible: erases the payroll cycle and its totals. Prefer setting status to `cancelled`, which keeps the audit trail.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Responses

200
Deleted

application/json

  • success boolean
  • id string
404
Not found

PATCH /api/purple-suite/hris/pay-runs/{id}

Advance or edit a payroll run

Partial update, and the way a run moves through its lifecycle. State machine: a completed run is LOCKED and cannot be edited, a cancelled run cannot be reactivated, and draft cannot jump straight to completed (it must pass through processing). Completing a run is effectively irreversible - confirm with the user.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Request body

Fields to update (partial)

application/json

PayRun

  • id string
  • periodStart stringPay period start date. Alias accepted on create: period_start
  • periodEnd stringPay period end date. Alias accepted on create: period_end
  • status stringPay run status. State machine: draft → processing → completed. Completed runs are locked. Cancelled runs cannot be reactivated.
  • totalAmount numberTotal gross payroll amount. Alias accepted on create: total_amount
  • employeeCount integerNumber of employees included in this run. Alias accepted on create: employee_count
  • runDate string
  • entries arrayPer-employee pay breakdown. Set on create or PATCH.
    Per-employee pay breakdown. Set on create or PATCH.

    array of:

    • employeeId string
    • grossPay number
    • netPay number
  • createdAt string
  • updatedAt string

Responses

200
Updated

application/json

PayRun

  • id string
  • periodStart stringPay period start date. Alias accepted on create: period_start
  • periodEnd stringPay period end date. Alias accepted on create: period_end
  • status stringPay run status. State machine: draft → processing → completed. Completed runs are locked. Cancelled runs cannot be reactivated.
  • totalAmount numberTotal gross payroll amount. Alias accepted on create: total_amount
  • employeeCount integerNumber of employees included in this run. Alias accepted on create: employee_count
  • runDate string
  • entries arrayPer-employee pay breakdown. Set on create or PATCH.
    Per-employee pay breakdown. Set on create or PATCH.

    array of:

    • employeeId string
    • grossPay number
    • netPay number
  • createdAt string
  • updatedAt string
404
Not found
422
State machine violation (e.g. modifying a completed run, or skipping processing status)

GET /api/purple-suite/hris/timesheets

List employee timesheets

A timesheet is one employee's hours for one week (week start, regular and overtime hours) with a status of submitted / approved / rejected. Per-person time capture that feeds payroll; the payroll cycle itself is a pay run, and paid absence is a time-off request. Server-side query: $filter/$select/$orderby/$search/$top/$skip/$count (MCP clients pass these as _filter, _top, ... because $ is not a legal tool-input key).

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
limitqueryintegernoMax items per page (default 50)
cursorquerystringnoPass the previous response's nextCursor to fetch the next page
$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.
employee_idquerystringnoFilter by employee ID (exact match)
statusquerystringnoFilter by timesheet status (exact match)

Responses

200
Paginated list

application/json

  • data array

    array of:

    Timesheet

    • id string
    • employee_id string
    • week_start string
    • hours_worked number
    • overtime_hours number
    • status string
    • created_at string
    • updated_at string
  • nextCursor stringCursor for the next page, or null on the last page
  • total integerTotal documents in the collection

POST /api/purple-suite/hris/timesheets

Submit a weekly timesheet

Records an employee's hours for one week. One timesheet per employee per week (409 on a duplicate), hours are range-checked, and terminated employees are rejected with 422.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes

Request body

application/json — required

Timesheet

  • id string
  • employee_id string
  • week_start string
  • hours_worked number
  • overtime_hours number
  • status string
  • created_at string
  • updated_at string

Responses

201
Created

application/json

Timesheet

  • id string
  • employee_id string
  • week_start string
  • hours_worked number
  • overtime_hours number
  • status string
  • created_at string
  • updated_at string
400
Missing required field or out-of-range hours
404
Employee not found
409
Timesheet already exists for this employee and week
422
Cannot submit timesheet for a terminated employee

GET /api/purple-suite/hris/timesheets/{id}

Get a timesheet by id

Returns one employee-week of hours with its regular/overtime split and approval status.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Responses

200
Found

application/json

Timesheet

  • id string
  • employee_id string
  • week_start string
  • hours_worked number
  • overtime_hours number
  • status string
  • created_at string
  • updated_at string
404
Not found

DELETE /api/purple-suite/hris/timesheets/{id}

Delete a timesheet

DESTRUCTIVE and irreversible: removes the week's recorded hours. Prefer rejecting the timesheet, which keeps the record.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Responses

200
Deleted

application/json

  • success boolean
  • id string
404
Not found

PATCH /api/purple-suite/hris/timesheets/{id}

Approve, reject or correct a timesheet

Partial update - the way a manager sets `status` to approved or rejected, and the way logged hours are corrected before payroll picks them up.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Request body

Fields to update (partial)

application/json

Timesheet

  • id string
  • employee_id string
  • week_start string
  • hours_worked number
  • overtime_hours number
  • status string
  • created_at string
  • updated_at string

Responses

200
Updated

application/json

Timesheet

  • id string
  • employee_id string
  • week_start string
  • hours_worked number
  • overtime_hours number
  • status string
  • created_at string
  • updated_at string
404
Not found

GET /api/purple-suite/hris/benefits

List employee benefit enrollments

A benefit record is one employee's ENROLLMENT in a plan - the benefit type (insurance / retirement / wellness / health), plan name, coverage level, employee and employer contributions and a status of active / pending / terminated. These are per-person enrollments, not a catalog of available plans. Server-side query: $filter/$select/$orderby/$search/$top/$skip/$count (MCP clients pass these as _filter, _top, ... because $ is not a legal tool-input key).

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
limitqueryintegernoMax items per page (default 50)
cursorquerystringnoPass the previous response's nextCursor to fetch the next page
$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.
employee_idquerystringnoFilter by employee ID (exact match)
typequerystringnoFilter by benefit type (exact match)
statusquerystringnoFilter by benefit status (exact match)

Responses

200
Paginated list

application/json

  • data array

    array of:

    Benefit

    • id string
    • employee_id string
    • type string
    • plan_name string
    • status string
    • enrollment_date string
    • created_at string
    • updated_at string
  • nextCursor stringCursor for the next page, or null on the last page
  • total integerTotal documents in the collection

POST /api/purple-suite/hris/benefits

Enroll an employee in a benefit plan

Creates an enrollment for one employee. An employee may hold only one ACTIVE benefit of a given type (422 otherwise), so terminate the existing enrollment before switching plans.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes

Request body

application/json — required

Benefit

  • id string
  • employee_id string
  • type string
  • plan_name string
  • status string
  • enrollment_date string
  • created_at string
  • updated_at string

Responses

201
Created

application/json

Benefit

  • id string
  • employee_id string
  • type string
  • plan_name string
  • status string
  • enrollment_date string
  • created_at string
  • updated_at string
400
Missing required field or invalid type
404
Employee not found
422
Employee already has an active benefit of this type

GET /api/purple-suite/hris/benefits/{id}

Get a benefit enrollment by id

Returns one employee's enrollment: plan, coverage level, contributions, effective dates and status.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Responses

200
Found

application/json

Benefit

  • id string
  • employee_id string
  • type string
  • plan_name string
  • status string
  • enrollment_date string
  • created_at string
  • updated_at string
404
Not found

DELETE /api/purple-suite/hris/benefits/{id}

Delete a benefit enrollment

DESTRUCTIVE and irreversible: erases the enrollment and its history. Prefer setting `status` to terminated.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Responses

200
Deleted

application/json

  • success boolean
  • id string
404
Not found

PATCH /api/purple-suite/hris/benefits/{id}

Change or terminate a benefit enrollment

Partial update of one enrollment - change coverage or contributions, or set `status` to terminated to end it while keeping the history.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Request body

Fields to update (partial)

application/json

Benefit

  • id string
  • employee_id string
  • type string
  • plan_name string
  • status string
  • enrollment_date string
  • created_at string
  • updated_at string

Responses

200
Updated

application/json

Benefit

  • id string
  • employee_id string
  • type string
  • plan_name string
  • status string
  • enrollment_date string
  • created_at string
  • updated_at string
404
Not found

GET /api/purple-suite/hris/review-cycles

List performance review cycles

A review cycle tracks the performance-review PROCESS for an employee in a period: reviewer, due date, overall rating and a status of planning / in_progress / completed / cancelled. Use it for 'is my review done / who is my reviewer'; the narrative outcomes live in the employee's reviews sub-resource. Server-side query: $filter/$select/$orderby/$search/$top/$skip/$count (MCP clients pass these as _filter, _top, ... because $ is not a legal tool-input key).

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
limitqueryintegernoMax items per page (default 50)
cursorquerystringnoPass the previous response's nextCursor to fetch the next page
$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.
employee_idquerystringnoFilter by employee ID (exact match)
statusquerystringnoFilter by review cycle status (exact match)

Responses

200
Paginated list

application/json

  • data array

    array of:

    ReviewCycle

    • id string
    • name string
    • period string
    • status string
    • employee_id string
    • manager_id string
    • rating string
    • notes string
    • created_at string
    • updated_at string
  • nextCursor stringCursor for the next page, or null on the last page
  • total integerTotal documents in the collection

POST /api/purple-suite/hris/review-cycles

Open a performance review cycle

Starts a review for an employee in a period, with a reviewer and due date. It schedules the process; it does not itself record a rating narrative.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes

Request body

application/json — required

ReviewCycle

  • id string
  • name string
  • period string
  • status string
  • employee_id string
  • manager_id string
  • rating string
  • notes string
  • created_at string
  • updated_at string

Responses

201
Created

application/json

ReviewCycle

  • id string
  • name string
  • period string
  • status string
  • employee_id string
  • manager_id string
  • rating string
  • notes string
  • created_at string
  • updated_at string

GET /api/purple-suite/hris/review-cycles/{id}

Get a performance review cycle by id

Returns one review's period, reviewer, due date, status and overall rating if recorded.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Responses

200
Found

application/json

ReviewCycle

  • id string
  • name string
  • period string
  • status string
  • employee_id string
  • manager_id string
  • rating string
  • notes string
  • created_at string
  • updated_at string
404
Not found

DELETE /api/purple-suite/hris/review-cycles/{id}

Delete a performance review cycle

DESTRUCTIVE and irreversible: removes the review record and its rating. Prefer setting status to `cancelled`.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Responses

200
Deleted

application/json

  • success boolean
  • id string
404
Not found

PATCH /api/purple-suite/hris/review-cycles/{id}

Progress or complete a review cycle

Partial update - the way a review moves from planning to in_progress to completed and an overall rating is recorded.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Request body

Fields to update (partial)

application/json

ReviewCycle

  • id string
  • name string
  • period string
  • status string
  • employee_id string
  • manager_id string
  • rating string
  • notes string
  • created_at string
  • updated_at string

Responses

200
Updated

application/json

ReviewCycle

  • id string
  • name string
  • period string
  • status string
  • employee_id string
  • manager_id string
  • rating string
  • notes string
  • created_at string
  • updated_at string
404
Not found

GET /api/purple-suite/hris/time-off-requests

List time-off (PTO) requests

A time-off request is one employee's absence request - type (vacation / sick / personal / bereavement / jury_duty), date range, day count and a status of pending / approved / denied / cancelled. Use it for 'who is out' and approval queues; the remaining day balance lives on the employee's pto_balance. Server-side query: $filter/$select/$orderby/$search/$top/$skip/$count (MCP clients pass these as _filter, _top, ... because $ is not a legal tool-input key).

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
limitqueryintegernoMax items per page (default 50)
cursorquerystringnoPass the previous response's nextCursor to fetch the next page
$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.
employee_idquerystringnoFilter by employee ID (exact match)
statusquerystringnoFilter by request status (exact match)
typequerystringnoFilter by time-off type (exact match)

Responses

200
Paginated list

application/json

  • data array

    array of:

    TimeOffRequest

    • id string
    • employee_id string requiredID of the requesting employee. Alias accepted on create: employeeId
    • type stringKind of time off. Defaults to 'vacation'.
    • start_date string requiredFirst day off (inclusive). Alias accepted on create: startDate
    • end_date string requiredLast day off (inclusive). Alias accepted on create: endDate
    • hours numberTotal hours requested
    • note stringOptional reason / note for the request
    • status stringRequest status. Defaults to 'pending' on create; approve/deny via PATCH.
    • created_at string
    • updated_at string
  • nextCursor stringCursor for the next page, or null on the last page
  • total integerTotal documents in the collection

POST /api/purple-suite/hris/time-off-requests

Submit a time-off (PTO) request

The employee-facing way to ASK for time off: creates the request in `pending` for an approver to decide via the update operation. It does not deduct the PTO balance - use the pto-balance action for that. Fires the `hris.time_off_request.created` outbound webhook to any configured subscriber.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes

Request body

application/json — required

TimeOffRequest

  • id string
  • employee_id string requiredID of the requesting employee. Alias accepted on create: employeeId
  • type stringKind of time off. Defaults to 'vacation'.
  • start_date string requiredFirst day off (inclusive). Alias accepted on create: startDate
  • end_date string requiredLast day off (inclusive). Alias accepted on create: endDate
  • hours numberTotal hours requested
  • note stringOptional reason / note for the request
  • status stringRequest status. Defaults to 'pending' on create; approve/deny via PATCH.
  • created_at string
  • updated_at string

Responses

201
Created

application/json

TimeOffRequest

  • id string
  • employee_id string requiredID of the requesting employee. Alias accepted on create: employeeId
  • type stringKind of time off. Defaults to 'vacation'.
  • start_date string requiredFirst day off (inclusive). Alias accepted on create: startDate
  • end_date string requiredLast day off (inclusive). Alias accepted on create: endDate
  • hours numberTotal hours requested
  • note stringOptional reason / note for the request
  • status stringRequest status. Defaults to 'pending' on create; approve/deny via PATCH.
  • created_at string
  • updated_at string
400
Missing required field or invalid type/status
404
Employee not found

GET /api/purple-suite/hris/time-off-requests/{id}

Get a time-off (PTO) request by id

Returns one absence request: employee, type, date range, day count, status and reason.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Responses

200
Found

application/json

TimeOffRequest

  • id string
  • employee_id string requiredID of the requesting employee. Alias accepted on create: employeeId
  • type stringKind of time off. Defaults to 'vacation'.
  • start_date string requiredFirst day off (inclusive). Alias accepted on create: startDate
  • end_date string requiredLast day off (inclusive). Alias accepted on create: endDate
  • hours numberTotal hours requested
  • note stringOptional reason / note for the request
  • status stringRequest status. Defaults to 'pending' on create; approve/deny via PATCH.
  • created_at string
  • updated_at string
404
Not found

PATCH /api/purple-suite/hris/time-off-requests/{id}

Approve, deny or amend a time-off request

The approver-facing counterpart of submitting: partial update, typically setting `status` to approved, denied or cancelled, and also used to amend dates. Fires the `hris.time_off_request.updated` outbound webhook. Approving does not itself adjust the employee's pto_balance.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Request body

Fields to update (partial), e.g. { "status": "approved" }

application/json

TimeOffRequest

  • id string
  • employee_id string requiredID of the requesting employee. Alias accepted on create: employeeId
  • type stringKind of time off. Defaults to 'vacation'.
  • start_date string requiredFirst day off (inclusive). Alias accepted on create: startDate
  • end_date string requiredLast day off (inclusive). Alias accepted on create: endDate
  • hours numberTotal hours requested
  • note stringOptional reason / note for the request
  • status stringRequest status. Defaults to 'pending' on create; approve/deny via PATCH.
  • created_at string
  • updated_at string

Responses

200
Updated

application/json

TimeOffRequest

  • id string
  • employee_id string requiredID of the requesting employee. Alias accepted on create: employeeId
  • type stringKind of time off. Defaults to 'vacation'.
  • start_date string requiredFirst day off (inclusive). Alias accepted on create: startDate
  • end_date string requiredLast day off (inclusive). Alias accepted on create: endDate
  • hours numberTotal hours requested
  • note stringOptional reason / note for the request
  • status stringRequest status. Defaults to 'pending' on create; approve/deny via PATCH.
  • created_at string
  • updated_at string
404
Not found

GET /api/purple-suite/hris/work-authorizations

List work authorizations (visas / right to work)

A work authorization is one person's immigration status in a country - type (citizen, permanent_resident, h1b, skilled_worker, eu_blue_card, ...), country, expiry date, renewal state and any travel restrictions. Use it for right-to-work, visa-expiry and travel-eligibility questions (it pairs with an expense trip's destination_country). Convenience: pass employee=me (the impersonated/default user) or employee=<email> to scope to one person. Server-side query: $filter/$select/$orderby/$search/$top/$skip/$count (MCP clients pass these as _filter, _top, ... because $ is not a legal tool-input key).

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
limitqueryintegernoMax items per page (default 50)
cursorquerystringnoPass the previous response's nextCursor to fetch the next page
$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.
employeequerystringnoFilter to one employee — an email, or the literal 'me' (resolves to the impersonated/default user).
statusquerystringnoFilter by status (exact match)
countryquerystringnoFilter by country (exact match)

Responses

200
Paginated list

application/json

  • data array

    array of:

    WorkAuthorization

    An employee's right-to-work record for a country: visa/permit type, status, expiry, and renewal tracking. Citizens and permanent residents have no expiry. The agent stitches this with Purple Expense trips to answer travel-eligibility questions.
    • id string
    • employee_email stringThe employee this authorization belongs to (matches an Employee.email and the canonical Identity directory).
    • country stringCountry this authorization grants the right to work in.
    • authorization_type string
    • status string
    • issued_date string
    • expiry_date stringNull for citizen / permanent_resident.
    • sponsoring_entity stringEmployer/entity sponsoring the visa, if any.
    • renewal_status string
    • renewal_due_date string
    • travel_restrictions arrayAdvisories that affect international travel (e.g. advance_parole_required).
      Advisories that affect international travel (e.g. advance_parole_required).

      array of:

      string

    • notes string
    • createdAt string
    • updatedAt string
  • nextCursor stringCursor for the next page, or null on the last page
  • total integerTotal documents in the collection

POST /api/purple-suite/hris/work-authorizations

Record a work authorization for an employee

Registers a person's right-to-work status in a country (type, expiry, sponsorship). Types citizen and permanent_resident have no expiry and cannot be renewed.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes

Request body

application/json — required

WorkAuthorization

An employee's right-to-work record for a country: visa/permit type, status, expiry, and renewal tracking. Citizens and permanent residents have no expiry. The agent stitches this with Purple Expense trips to answer travel-eligibility questions.
  • id string
  • employee_email stringThe employee this authorization belongs to (matches an Employee.email and the canonical Identity directory).
  • country stringCountry this authorization grants the right to work in.
  • authorization_type string
  • status string
  • issued_date string
  • expiry_date stringNull for citizen / permanent_resident.
  • sponsoring_entity stringEmployer/entity sponsoring the visa, if any.
  • renewal_status string
  • renewal_due_date string
  • travel_restrictions arrayAdvisories that affect international travel (e.g. advance_parole_required).
    Advisories that affect international travel (e.g. advance_parole_required).

    array of:

    string

  • notes string
  • createdAt string
  • updatedAt string

Responses

201
Created

application/json

WorkAuthorization

An employee's right-to-work record for a country: visa/permit type, status, expiry, and renewal tracking. Citizens and permanent residents have no expiry. The agent stitches this with Purple Expense trips to answer travel-eligibility questions.
  • id string
  • employee_email stringThe employee this authorization belongs to (matches an Employee.email and the canonical Identity directory).
  • country stringCountry this authorization grants the right to work in.
  • authorization_type string
  • status string
  • issued_date string
  • expiry_date stringNull for citizen / permanent_resident.
  • sponsoring_entity stringEmployer/entity sponsoring the visa, if any.
  • renewal_status string
  • renewal_due_date string
  • travel_restrictions arrayAdvisories that affect international travel (e.g. advance_parole_required).
    Advisories that affect international travel (e.g. advance_parole_required).

    array of:

    string

  • notes string
  • createdAt string
  • updatedAt string
400
Validation error

GET /api/purple-suite/hris/work-authorizations/{id}

Get a work authorization by id

Returns one immigration record: type, country, expiry date, status, renewal state and travel restrictions.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Responses

200
Found

application/json

WorkAuthorization

An employee's right-to-work record for a country: visa/permit type, status, expiry, and renewal tracking. Citizens and permanent residents have no expiry. The agent stitches this with Purple Expense trips to answer travel-eligibility questions.
  • id string
  • employee_email stringThe employee this authorization belongs to (matches an Employee.email and the canonical Identity directory).
  • country stringCountry this authorization grants the right to work in.
  • authorization_type string
  • status string
  • issued_date string
  • expiry_date stringNull for citizen / permanent_resident.
  • sponsoring_entity stringEmployer/entity sponsoring the visa, if any.
  • renewal_status string
  • renewal_due_date string
  • travel_restrictions arrayAdvisories that affect international travel (e.g. advance_parole_required).
    Advisories that affect international travel (e.g. advance_parole_required).

    array of:

    string

  • notes string
  • createdAt string
  • updatedAt string
404
Not found

DELETE /api/purple-suite/hris/work-authorizations/{id}

Delete a work authorization

DESTRUCTIVE and irreversible: removes the person's right-to-work record, which can make them appear unauthorized. Confirm with the user before calling.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Responses

200
Deleted

application/json

  • success boolean
  • id string
404
Not found

PATCH /api/purple-suite/hris/work-authorizations/{id}

Edit a work authorization

Partial update of an immigration record (correct the expiry, type or restrictions). To file an extension use the renew action, which applies the state machine and extends the expiry for you.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Request body

Fields to update (partial)

application/json

WorkAuthorization

An employee's right-to-work record for a country: visa/permit type, status, expiry, and renewal tracking. Citizens and permanent residents have no expiry. The agent stitches this with Purple Expense trips to answer travel-eligibility questions.
  • id string
  • employee_email stringThe employee this authorization belongs to (matches an Employee.email and the canonical Identity directory).
  • country stringCountry this authorization grants the right to work in.
  • authorization_type string
  • status string
  • issued_date string
  • expiry_date stringNull for citizen / permanent_resident.
  • sponsoring_entity stringEmployer/entity sponsoring the visa, if any.
  • renewal_status string
  • renewal_due_date string
  • travel_restrictions arrayAdvisories that affect international travel (e.g. advance_parole_required).
    Advisories that affect international travel (e.g. advance_parole_required).

    array of:

    string

  • notes string
  • createdAt string
  • updatedAt string

Responses

200
Updated

application/json

WorkAuthorization

An employee's right-to-work record for a country: visa/permit type, status, expiry, and renewal tracking. Citizens and permanent residents have no expiry. The agent stitches this with Purple Expense trips to answer travel-eligibility questions.
  • id string
  • employee_email stringThe employee this authorization belongs to (matches an Employee.email and the canonical Identity directory).
  • country stringCountry this authorization grants the right to work in.
  • authorization_type string
  • status string
  • issued_date string
  • expiry_date stringNull for citizen / permanent_resident.
  • sponsoring_entity stringEmployer/entity sponsoring the visa, if any.
  • renewal_status string
  • renewal_due_date string
  • travel_restrictions arrayAdvisories that affect international travel (e.g. advance_parole_required).
    Advisories that affect international travel (e.g. advance_parole_required).

    array of:

    string

  • notes string
  • createdAt string
  • updatedAt string
404
Not found

POST /api/purple-suite/hris/work-authorizations/{id}/renew

File a renewal / extension for a work authorization

The action to take when a visa is expiring: transitions an expiring_soon / expired / renewal_pending authorization to renewal_filed, pushes expiry_date out by `extend_months` (default 24) and clears travel restrictions that were tied to the pending renewal. Rejected with 422 for citizen / permanent_resident (no expiry) or when a renewal has already been filed. Use this rather than PATCHing the expiry by hand.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Request body

application/json

  • extend_months integerMonths to extend expiry_date by (default 24).
  • notes string

Responses

200
Renewal filed

application/json

WorkAuthorization

An employee's right-to-work record for a country: visa/permit type, status, expiry, and renewal tracking. Citizens and permanent residents have no expiry. The agent stitches this with Purple Expense trips to answer travel-eligibility questions.
  • id string
  • employee_email stringThe employee this authorization belongs to (matches an Employee.email and the canonical Identity directory).
  • country stringCountry this authorization grants the right to work in.
  • authorization_type string
  • status string
  • issued_date string
  • expiry_date stringNull for citizen / permanent_resident.
  • sponsoring_entity stringEmployer/entity sponsoring the visa, if any.
  • renewal_status string
  • renewal_due_date string
  • travel_restrictions arrayAdvisories that affect international travel (e.g. advance_parole_required).
    Advisories that affect international travel (e.g. advance_parole_required).

    array of:

    string

  • notes string
  • createdAt string
  • updatedAt string
404
Authorization not found
422
Authorization cannot be renewed (no expiry, or already filed)

GET /api/purple-suite/hris/job-families

List job families (career groupings)

A job family is the top of the HRIS job architecture - a career grouping such as Engineering or Finance that job profiles and job roles hang off. Reference catalog, not people: use employees for who holds a job. Server-side query: $filter/$select/$orderby/$search/$top/$skip/$count (MCP clients pass these as _filter, _top, ... because $ is not a legal tool-input key).

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
limitqueryintegernoMax items per page (default 50)
cursorquerystringnoPass the previous response's nextCursor to fetch the next page
$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:

    JobFamily

    Career family grouping related job profiles (reference catalog).
    • id string
    • name string required
    • description string
    • createdAt string
    • updatedAt string
  • nextCursor stringCursor for the next page, or null on the last page
  • total integerTotal documents in the collection

POST /api/purple-suite/hris/job-families

Create a job family

Adds a career grouping to the job architecture. The id is server-derived from the name; duplicates are rejected with 409.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes

Request body

application/json — required

JobFamily

Career family grouping related job profiles (reference catalog).
  • id string
  • name string required
  • description string
  • createdAt string
  • updatedAt string

Responses

201
Created

application/json

JobFamily

Career family grouping related job profiles (reference catalog).
  • id string
  • name string required
  • description string
  • createdAt string
  • updatedAt string
400
Validation / missing reference
409
Duplicate

GET /api/purple-suite/hris/job-families/{id}

Get a job family by id

Returns one career grouping's name and description.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Responses

200
Found

application/json

JobFamily

Career family grouping related job profiles (reference catalog).
  • id string
  • name string required
  • description string
  • createdAt string
  • updatedAt string
404
Not found

DELETE /api/purple-suite/hris/job-families/{id}

Delete a job family

DESTRUCTIVE: removes the career grouping. Blocked with 409 while job profiles or job roles still reference it, so clear dependents first.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Responses

200
Deleted

application/json

  • success boolean
  • id string
404
Not found
409
Blocked — still referenced by dependents

PATCH /api/purple-suite/hris/job-families/{id}

Rename or edit a job family

Partial update of a career grouping. Renaming CASCADES to the job profiles and job roles that reference it by name.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Request body

Fields to update (partial)

application/json

JobFamily

Career family grouping related job profiles (reference catalog).
  • id string
  • name string required
  • description string
  • createdAt string
  • updatedAt string

Responses

200
Updated

application/json

JobFamily

Career family grouping related job profiles (reference catalog).
  • id string
  • name string required
  • description string
  • createdAt string
  • updatedAt string
400
Validation / missing reference
404
Not found

GET /api/purple-suite/hris/job-levels

List job levels (leveling framework grades)

A job level is one grade in the leveling framework - a code such as IC3 or M2 with its track (IC or M), numeric tier and management level. Use it to compare seniority or to resolve the job_level on a job profile. Server-side query: $filter/$select/$orderby/$search/$top/$skip/$count (MCP clients pass these as _filter, _top, ... because $ is not a legal tool-input key).

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
limitqueryintegernoMax items per page (default 50)
cursorquerystringnoPass the previous response's nextCursor to fetch the next page
$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:

    JobLevel

    Job level / grade in the leveling framework (reference catalog).
    • id stringLevel code (IC1–IC6 / M1–M5).
    • name string required
    • track stringIndividual-contributor or management track.
    • tier integerNumeric rank within the track.
    • management_level string
    • createdAt string
    • updatedAt string
  • nextCursor stringCursor for the next page, or null on the last page
  • total integerTotal documents in the collection

POST /api/purple-suite/hris/job-levels

Create a job level

Adds a grade to the leveling framework (code, track, tier). Reference-catalog administration; it does not re-level any employee.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes

Request body

application/json — required

JobLevel

Job level / grade in the leveling framework (reference catalog).
  • id stringLevel code (IC1–IC6 / M1–M5).
  • name string required
  • track stringIndividual-contributor or management track.
  • tier integerNumeric rank within the track.
  • management_level string
  • createdAt string
  • updatedAt string

Responses

201
Created

application/json

JobLevel

Job level / grade in the leveling framework (reference catalog).
  • id stringLevel code (IC1–IC6 / M1–M5).
  • name string required
  • track stringIndividual-contributor or management track.
  • tier integerNumeric rank within the track.
  • management_level string
  • createdAt string
  • updatedAt string
400
Validation / missing reference
409
Duplicate

GET /api/purple-suite/hris/job-levels/{id}

Get a job level by id

Returns one grade: its code, display name, track, tier and management level.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Responses

200
Found

application/json

JobLevel

Job level / grade in the leveling framework (reference catalog).
  • id stringLevel code (IC1–IC6 / M1–M5).
  • name string required
  • track stringIndividual-contributor or management track.
  • tier integerNumeric rank within the track.
  • management_level string
  • createdAt string
  • updatedAt string
404
Not found

DELETE /api/purple-suite/hris/job-levels/{id}

Delete a job level

DESTRUCTIVE: removes the grade from the framework. Blocked with 409 while job profiles still reference it.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Responses

200
Deleted

application/json

  • success boolean
  • id string
404
Not found
409
Blocked — still referenced by dependents

PATCH /api/purple-suite/hris/job-levels/{id}

Rename or edit a job level

Partial update of a grade's name, track or tier. Renaming CASCADES to job profiles that reference the level code.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Request body

Fields to update (partial)

application/json

JobLevel

Job level / grade in the leveling framework (reference catalog).
  • id stringLevel code (IC1–IC6 / M1–M5).
  • name string required
  • track stringIndividual-contributor or management track.
  • tier integerNumeric rank within the track.
  • management_level string
  • createdAt string
  • updatedAt string

Responses

200
Updated

application/json

JobLevel

Job level / grade in the leveling framework (reference catalog).
  • id stringLevel code (IC1–IC6 / M1–M5).
  • name string required
  • track stringIndividual-contributor or management track.
  • tier integerNumeric rank within the track.
  • management_level string
  • createdAt string
  • updatedAt string
400
Validation / missing reference
404
Not found

GET /api/purple-suite/hris/job-profiles

List job profiles (role templates: title + family + level)

A job profile is the template that ties a TITLE to a job family and a job level (e.g. Software Engineer / Engineering / IC3). It is the canonical answer to 'what titles exist and where do they sit' - employees carry the title, this defines it. Server-side query: $filter/$select/$orderby/$search/$top/$skip/$count (MCP clients pass these as _filter, _top, ... because $ is not a legal tool-input key).

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
limitqueryintegernoMax items per page (default 50)
cursorquerystringnoPass the previous response's nextCursor to fetch the next page
$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:

    JobProfile

    Job profile (role template) tying a title to a family + level (reference catalog).
    • id string
    • title string required
    • job_family stringJobFamily name.
    • job_level stringJobLevel code.
    • management_level string
    • createdAt string
    • updatedAt string
  • nextCursor stringCursor for the next page, or null on the last page
  • total integerTotal documents in the collection

POST /api/purple-suite/hris/job-profiles

Create a job profile

Defines a new titled role template against an existing job family and job level. Missing references are rejected with 400.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes

Request body

application/json — required

JobProfile

Job profile (role template) tying a title to a family + level (reference catalog).
  • id string
  • title string required
  • job_family stringJobFamily name.
  • job_level stringJobLevel code.
  • management_level string
  • createdAt string
  • updatedAt string

Responses

201
Created

application/json

JobProfile

Job profile (role template) tying a title to a family + level (reference catalog).
  • id string
  • title string required
  • job_family stringJobFamily name.
  • job_level stringJobLevel code.
  • management_level string
  • createdAt string
  • updatedAt string
400
Validation / missing reference
409
Duplicate

GET /api/purple-suite/hris/job-profiles/{id}

Get a job profile by id

Returns one role template: its title, job family, job level and management level.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Responses

200
Found

application/json

JobProfile

Job profile (role template) tying a title to a family + level (reference catalog).
  • id string
  • title string required
  • job_family stringJobFamily name.
  • job_level stringJobLevel code.
  • management_level string
  • createdAt string
  • updatedAt string
404
Not found

DELETE /api/purple-suite/hris/job-profiles/{id}

Delete a job profile

DESTRUCTIVE: removes the role template. Blocked with 409 while job roles still reference it.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Responses

200
Deleted

application/json

  • success boolean
  • id string
404
Not found
409
Blocked — still referenced by dependents

PATCH /api/purple-suite/hris/job-profiles/{id}

Edit a job profile

Partial update of a role template's title, family or level. Renaming CASCADES to job roles that reference this profile.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Request body

Fields to update (partial)

application/json

JobProfile

Job profile (role template) tying a title to a family + level (reference catalog).
  • id string
  • title string required
  • job_family stringJobFamily name.
  • job_level stringJobLevel code.
  • management_level string
  • createdAt string
  • updatedAt string

Responses

200
Updated

application/json

JobProfile

Job profile (role template) tying a title to a family + level (reference catalog).
  • id string
  • title string required
  • job_family stringJobFamily name.
  • job_level stringJobLevel code.
  • management_level string
  • createdAt string
  • updatedAt string
400
Validation / missing reference
404
Not found

GET /api/purple-suite/hris/job-roles

List job roles (positions under a family)

A job role is a named position under a job family, optionally mapped to a job profile (modeled on ServiceNow sn_hr_core_position). It is the most concrete layer of the job architecture: family -> profile -> role. Server-side query: $filter/$select/$orderby/$search/$top/$skip/$count (MCP clients pass these as _filter, _top, ... because $ is not a legal tool-input key).

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
limitqueryintegernoMax items per page (default 50)
cursorquerystringnoPass the previous response's nextCursor to fetch the next page
$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:

    JobRole

    Job role under a family, optionally mapped to a job profile (reference catalog; modeled on sn_hr_core_position).
    • id string
    • name string required
    • description string
    • active boolean
    • job_family stringJobFamily name.
    • job_profile stringJobProfile id.
    • createdAt string
    • updatedAt string
  • nextCursor stringCursor for the next page, or null on the last page
  • total integerTotal documents in the collection

POST /api/purple-suite/hris/job-roles

Create a job role

Adds a position under an existing job family and, optionally, a job profile. Missing references are rejected with 400.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes

Request body

application/json — required

JobRole

Job role under a family, optionally mapped to a job profile (reference catalog; modeled on sn_hr_core_position).
  • id string
  • name string required
  • description string
  • active boolean
  • job_family stringJobFamily name.
  • job_profile stringJobProfile id.
  • createdAt string
  • updatedAt string

Responses

201
Created

application/json

JobRole

Job role under a family, optionally mapped to a job profile (reference catalog; modeled on sn_hr_core_position).
  • id string
  • name string required
  • description string
  • active boolean
  • job_family stringJobFamily name.
  • job_profile stringJobProfile id.
  • createdAt string
  • updatedAt string
400
Validation / missing reference
409
Duplicate

GET /api/purple-suite/hris/job-roles/{id}

Get a job role by id

Returns one position: its name, description, active flag, job family and mapped job profile.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Responses

200
Found

application/json

JobRole

Job role under a family, optionally mapped to a job profile (reference catalog; modeled on sn_hr_core_position).
  • id string
  • name string required
  • description string
  • active boolean
  • job_family stringJobFamily name.
  • job_profile stringJobProfile id.
  • createdAt string
  • updatedAt string
404
Not found

DELETE /api/purple-suite/hris/job-roles/{id}

Delete a job role

DESTRUCTIVE: removes the position from the catalog. Blocked with 409 while dependents still reference it; prefer setting `active` to false to retire a role.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Responses

200
Deleted

application/json

  • success boolean
  • id string
404
Not found
409
Blocked — still referenced by dependents

PATCH /api/purple-suite/hris/job-roles/{id}

Edit a job role

Partial update of a position's name, description, family/profile mapping or active flag.

Parameters

NameInTypeRequiredDescription
X-Instance-IDheaderstringyes
idpathstringyes

Request body

Fields to update (partial)

application/json

JobRole

Job role under a family, optionally mapped to a job profile (reference catalog; modeled on sn_hr_core_position).
  • id string
  • name string required
  • description string
  • active boolean
  • job_family stringJobFamily name.
  • job_profile stringJobProfile id.
  • createdAt string
  • updatedAt string

Responses

200
Updated

application/json

JobRole

Job role under a family, optionally mapped to a job profile (reference catalog; modeled on sn_hr_core_position).
  • id string
  • name string required
  • description string
  • active boolean
  • job_family stringJobFamily name.
  • job_profile stringJobProfile id.
  • createdAt string
  • updatedAt string
400
Validation / missing reference
404
Not found