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
| Param | Type | Description |
|---|---|---|
page | integer | Page number (default: 1) |
limit | integer | Results per page (default: 20, max: 100) |
status | string | Filter by status - see the list below |
department | string | Filter 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"
}| Field | Required | Type | Description |
|---|---|---|---|
employee_name | ✅ | string | Full name (max 200 characters) |
exit_date | ✅ | date (YYYY-MM-DD) | Last working day |
employee_email | - | string | Work email (max 254 characters) |
employee_role | - | string | Job title (max 100 characters) |
employee_department | - | string | Department (max 100 characters) |
separation_type | - | enum | See separation types below (default: resignation) |
timezone | - | string | The 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 | - | string | Where 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 | - | string | The 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_revocationevery selected app must be revoked (or confirmed removed by hand), andcompletedneeds every assigned asset returned or lost, the asset return confirmed, and every checklist task done or marked not needed. A blocked move returns409withcode: "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
completedoffboarding 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(oroffboarding.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.