API Reference
Offboarding

Offboarding

The offboarding endpoints let you create offboarding records and track their status from the outside - useful for HRIS integrations that kick off an offboarding the moment someone is marked as departing.

Base path: /api/v1/offboardings


List offboardings

GET /api/v1/offboardings

Required scope: offboardings:read

Query parameters

ParamTypeDescription
pageintegerPage number (default: 1)
limitintegerResults per page (default: 20, max: 100)
statusstringFilter by status - see the list below
departmentstringFilter by exact department match

Response 200 OK

{
  "data": [
    {
      "id": "3f9c8b1a-...",
      "employee_name": "Jordan Lee",
      "employee_email": "jordan@acme.com",
      "employee_role": "Senior Engineer",
      "employee_department": "Engineering",
      "exit_date": "2024-06-15",
      "status": "notice_period",
      "separation_type": "resignation",
      "manager_email": "sam@acme.com",
      "created_at": "2024-05-28T10:00:00Z"
    }
  ],
  "meta": {
    "page": 1,
    "limit": 20,
    "total": 12,
    "total_pages": 1,
    "has_next": false
  }
}

Get an offboarding

GET /api/v1/offboardings/:id

Required scope: offboardings:read

Returns the same fields as the list endpoint, plus updated_at. Returns 400 if the ID isn't a UUID, and 404 if no offboarding with that ID belongs to your organisation.


Create an offboarding

POST /api/v1/offboardings

Required scope: offboardings:write

Request body

{
  "employee_name": "Jordan Lee",
  "employee_email": "jordan@acme.com",
  "employee_role": "Senior Engineer",
  "employee_department": "Engineering",
  "exit_date": "2024-06-15",
  "separation_type": "resignation",
  "manager_email": "sam@acme.com"
}
FieldRequiredTypeDescription
employee_name✅stringFull name (max 200 characters)
exit_date✅date (YYYY-MM-DD)Last working day
employee_email-stringWork email (max 254 characters)
employee_role-stringJob title (max 100 characters)
employee_department-stringDepartment (max 100 characters)
separation_type-enumSee separation types below (default: resignation)
timezone-stringThe person's IANA time zone (for example America/New_York) when it isn't your organization's. The end of their last day, when access is revoked automatically, is in this zone. Omit it for your organization's time zone.
apps_to_revoke-string[]The connected integrations to revoke, by name, up to 50. A name that isn't a connected integration able to revoke access is refused with 400 and code: "unknown_apps" (the body lists them). Left out, the case starts with no apps and IT revocation waits for an admin to confirm there is nothing to revoke.
jurisdiction-stringWhere the person works, as ISO 3166 (DE, US-CA); it decides which legal documents the departure needs. Left out, your organisation's default applies.
manager_email-stringThe person's manager (max 254 characters). The Microsoft 365 out-of-office reply names it, and Google Drive files can be transferred to it (Integrations). Left out, PurpletGo fills it in from the employee directory when it knows the manager; null means none. An invalid address returns 400; the employee's own address returns 400 with code: "manager_email_is_employee".

Separation types

resignation · termination · layoff · redundancy · retirement · contract_end · other

New offboardings are always created with status: "pending" - there's no way to set the initial status via this call.

Response 201 Created - the created offboarding object: the list endpoint's fields without updated_at, plus apps_to_revoke (the names after resolution) and revoke_at (when access is revoked automatically, or null).

Other outcomes: 409 when an open offboarding already exists for the same employee_email (the body carries its id, so a retried request is safe), and 402 with code: "read_only" when the organisation's trial or subscription has ended.

Creating an offboarding this way also notifies your organisation's admin and HR users in-app, the same as if it had been created from the dashboard.


Update offboarding status or manager

PATCH /api/v1/offboardings/:id

Required scope: offboardings:write

This endpoint updates status, manager_email, or both - there's no way to change employee details or other fields after creation.

Request body

{ "status": "it_revocation" }

Valid status values: pending, notice_period, it_revocation, asset_recovery, completed, cancelled. Any other value returns 400.

cancelled is for a rescinded resignation: send { "status": "cancelled", "reason": "..." } (5 to 500 characters, required). It is allowed from any stage except completed, and is final: a canceled offboarding keeps its record but cannot be reopened (start a new one). Canceling cancels a scheduled access revocation that has not run, revokes the self-service portal link, and puts the person back to active in the directory. It is allowed under legal hold (nothing is deleted). The reason is stored on the record and audited, and the usual stage webhook and SIEM status_changed event carry the new status.

manager_email follows the same rules as on create, and also can't be the employee's personal email. null or "" clears it. A change is recorded in the audit log with the old and new values.

  • Moving forward passes the same stage gates as the app: past it_revocation every selected app must be revoked (or confirmed removed by hand), and completed needs every assigned asset returned or lost, the asset return confirmed, and every checklist task done or marked not needed. A blocked move returns 409 with code: "stage_gate" and a message naming what's missing. Completing with open tasks can only be overridden in the app, by a Super Admin or Admin.
  • Moving a completed offboarding back reopens it. No paid plan limits open offboardings.
  • Setting the status it already has changes nothing and sends nothing.
  • A change has the same effects as in the app: the person's directory record is deactivated on completion (reactivated when reopened), and your team gets the stage email and notification, Slack or Teams, your offboarding.stage_changed (or offboarding.completed) webhook and SIEM events.

Response 200 OK

{
  "id": "3f9c8b1a-...",
  "employee_name": "Jordan Lee",
  "status": "it_revocation",
  "manager_email": "sam@acme.com",
  "updated_at": "2024-06-02T14:30:00Z"
}

Note that the response only includes id, employee_name, status, manager_email, and updated_at - not the full offboarding record. Fetch GET /offboardings/:id afterward if you need the rest.

The public API can't delete an offboarding, revoke access or record asset returns: do those in the PurpletGo app. It can move the stage once they're done.