API Reference
Offboarding Initiations

Offboarding Initiations

An initiation is a request to start offboarding an employee, submitted by a manager (or HR/admin) and optionally routed through an approval chain before the real offboarding record gets created. This is a separate, earlier step from the Offboarding API - an initiation only becomes an offboarding once it's approved (or auto-approved).

Base path: /api/offboarding-initiations

⚠️

This feature is gated behind the managerInitiation plan feature and is session-authenticated, like the rest of the app API - it is not part of the API-key-based /api/v1 surface.


Approval behavior

Whether an initiation needs approval at all depends on your org's settings and who's submitting it:

  • If HR or an admin submits the request, it's auto-approved immediately and the offboarding is created on the spot.
  • If your org has require_initiation_approval turned off, everything auto-approves the same way.
  • Otherwise, the initiation is routed through an approval chain: either the chain_id you pass explicitly, or the org's default_chain_id. If neither resolves to a real chain, there's no formal chain - the request just sits pending and PurpletGo posts an interactive notification to Slack/Teams instead of routing through named steps.

Chains are made of ordered steps, each targeting either a specific approver_id or an approver_role. Approving a step advances current_step; approving the last step creates the offboarding. Steps can also be delegated to someone else. Chain configuration itself (creating/editing chains and their steps) lives under /api/approval-chains, not documented here.


Initiation object

{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "org_id": "org_xyz",
  "initiated_by": "usr_mgr001",
  "initiated_by_name": "Alex Chen",
  "initiated_by_email": "alex@acme.com",
  "employee_name": "Jordan Lee",
  "employee_email": "jordan.lee@acme.com",
  "employee_role": "Senior Engineer",
  "employee_department": "Engineering",
  "exit_date": "2025-07-11",
  "separation_type": "resignation",
  "apps_to_revoke": ["github", "slack"],
  "notes": "Employee has signed their resignation letter.",
  "status": "pending",
  "chain_id": "9c1e...",
  "chain_name": "Standard Engineering Exit",
  "current_step": 2,
  "reviewed_by": null,
  "reviewed_by_name": null,
  "reviewed_at": null,
  "rejection_reason": null,
  "offboarding_id": null,
  "created_at": "2025-06-26T10:30:00.000Z",
  "updated_at": "2025-06-26T11:00:00.000Z"
}

Status values: pending · approved · rejected. There's no cancelled status - withdrawing a pending initiation deletes it outright (see Withdraw).


Endpoints

Submit an initiation

POST /api/offboarding-initiations

Restricted to managers, HR, and admins.

Request body

{
  "employee_name": "Jordan Lee",
  "employee_email": "jordan.lee@acme.com",
  "employee_role": "Senior Engineer",
  "employee_department": "Engineering",
  "exit_date": "2025-07-11",
  "separation_type": "resignation",
  "apps_to_revoke": ["github", "slack"],
  "notes": "Employee has signed their resignation letter.",
  "chain_id": null
}
FieldRequiredTypeDescription
employee_nameYesstringFree-text name - there's no employee lookup by ID
exit_dateYesdateISO 8601 date (YYYY-MM-DD)
employee_emailNostring
employee_roleNostring
employee_departmentNostring
separation_typeNoenumresignation · termination · layoff · retirement · contract_end · other. Defaults to resignation
apps_to_revokeNostring[]Defaults to []
notesNostringInternal notes, max 2000 characters
chain_idNouuidExplicit approval chain to use instead of the org default

Response 201 Created - the created initiation object. If it was auto-approved, status will already be "approved" and offboarding_id will be populated.


List initiations

GET /api/offboarding-initiations

Managers only see initiations they submitted; HR and admins see everything in the org.

Query parameters

ParameterTypeDescription
statusstringpending · approved · rejected
limitintegerDefault 50, max 200
offsetintegerRow offset

Response 200 OK

{
  "rows": [ /* initiation objects */ ],
  "total": 1,
  "limit": 50,
  "offset": 0
}

Get an initiation

GET /api/offboarding-initiations/:id

Returns the initiation with a step_history array attached - one entry per approval step that's been reached, including who acted, when, and any notes or delegation.

Managers can only fetch their own initiations; HR/admins can fetch any.


Edit an initiation

PATCH /api/offboarding-initiations/:id

Only while status is pending, and only by the original submitter or HR/admin. Accepts any subset of the submit-time fields (employee_name, employee_email, employee_role, employee_department, exit_date, separation_type, apps_to_revoke, notes).


Approve an initiation

POST /api/offboarding-initiations/:id/approve

Request body

{ "comment": "Confirmed with finance. All clear to proceed." }

The body key is notes, not comment - it's read straight off req.body.notes.

For chain-based initiations, only the designated approver (or role, or an active delegate) for the current step can call this - you'll get 403 otherwise, and 409 if that step was already acted on. Approving the final step creates the offboarding and sets status: "approved" with offboarding_id populated. For non-chain initiations, only HR/admins can approve.

Response 200 OK - the updated initiation. On the final approval, also includes offboarding_id.


Reject an initiation

POST /api/offboarding-initiations/:id/reject

Request body

{ "rejection_reason": "Incorrect employee record - please resubmit with corrected exit date." }

rejection_reason is required. No offboarding is created; status becomes "rejected".


Delegate the current step

POST /api/offboarding-initiations/:id/delegate

Only meaningful for chain-based initiations - returns 400 if the initiation has no chain. Only the current step's designated approver can delegate, and not to the original initiator or to themself.

Request body

{ "delegate_id": "usr_hr002", "notes": "Out this week, please cover." }

Response 200 OK

{ "delegated": true, "delegate_id": "usr_hr002", "step": 2 }

Withdraw an initiation

DELETE /api/offboarding-initiations/:id

Only while status is pending, by the original submitter or HR/admin. Deletes the row outright.

Response 200 OK

{ "deleted": true }

Approval settings

GET /api/offboarding-initiations/settings

{ "require_initiation_approval": true, "default_chain_id": "9c1e..." }

PATCH /api/offboarding-initiations/settings

HR/admin only. Body: require_initiation_approval (boolean) and/or default_chain_id (uuid or null - must belong to your org).


HRIS integration example

A typical pattern for wiring an HRIS termination webhook to PurpletGo:

app.post('/webhooks/bamboohr', async (req, res) => {
  const event = req.body;
  if (event.type !== 'employee.terminated') return res.sendStatus(200);
 
  await fetch('https://app.purpletgo.com/api/offboarding-initiations', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Cookie': sessionCookie, // this endpoint is session-authenticated, not API-key based
    },
    body: JSON.stringify({
      employee_name: event.employeeName,
      employee_email: event.employeeEmail,
      exit_date: event.lastDay,
      separation_type: 'termination',
      notes: `BambooHR event ID: ${event.id}`,
    }),
  });
 
  res.sendStatus(202);
});

Related

  • Offboarding API - the record that gets created once an initiation is approved
  • Checklists - tasks generated automatically when the offboarding is created