# Business Made · Offboarding

Part of AppEngine API Documentation. Full index: https://appengine.appmint.io/documentation.md
## GET /business-made/offboarding/cases

**Offboarding records with progress**

`operationId: OffboardingController_cases`

Every offboarding as a finished row — person, last day, status, task progress (`tasks: { total, done, openRequired }`), the steps allowed now (`moves`) and whether it can be completed — newest last day first, with counts of open, completed and cancelled. `status=open` shows everything not closed; any other value filters by status.

#### Signature

```http
GET /business-made/offboarding/cases (status?: string) -> `{ counts:{open, completed, cancelled}, data:[row] }`
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /business-made/offboarding/cases/{id}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `status` | query | string | — | `open`, or a status such as `completed`. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | `{ counts:{open, completed, cancelled}, data:[row] }` |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /business-made/offboarding/cases/{id}

**One offboarding with its checklist**

`operationId: OffboardingController_caseDetail`

The row plus its checklist and the steps allowed (`moves`: `start`/`cancel` when initiated, `complete`/`cancel` while in progress, none once closed).

#### Signature

```http
GET /business-made/offboarding/cases/{id} (id: string) -> The offboarding detail
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | OFFBOARDING_NOT_FOUND | Offboarding not found | No offboarding record has that id. | The body carries `code: "OFFBOARDING_NOT_FOUND"` and the id. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `id` | path | string | yes | Record id. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The offboarding detail |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Offboarding not found — No offboarding record has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /business-made/offboarding/cases/{id}/action

**Take an offboarding step**

`operationId: OffboardingController_caseAction`

One endpoint for every step, with the checks the screen should not have to make: `start`, `complete` (refused while required tasks are open), `cancel` (with `reason`), `task-done` and `task-na` (with `taskId`, optional `reason`). Returns the detail after the step.

#### Signature

```http
POST /business-made/offboarding/cases/{id}/action (id: string, body) -> The offboarding detail after the step
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | OFFBOARDING_NOT_FOUND | Offboarding not found | No offboarding record has that id. | The body carries `code: "OFFBOARDING_NOT_FOUND"` and the id. |
| `400` | OFFBOARDING_ACTION | 2 required tasks are still open | The step is not allowed now — already started, not in progress, required tasks open, already closed, no `taskId`, or an unknown action. The message says which. | — |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `id` | path | string | yes | Record id. |

### Request body

```json
{
  "action": "task-done",
  "taskId": "return-laptop"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The offboarding detail after the step |
| `400` | 2 required tasks are still open — The step is not allowed now — already started, not in progress, required tasks open, already closed, no `taskId`, or an unknown action. The message says which. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Offboarding not found — No offboarding record has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /business-made/offboarding

**List offboarding records**

`operationId: OffboardingController_getOffboardings`

Offboarding across the org.

#### Signature

```http
GET /business-made/offboarding () -> Offboarding records
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /business-made/offboarding/status/active`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Offboarding records |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /business-made/offboarding

**Create an offboarding record**

`operationId: OffboardingController_createOffboarding`

Opens offboarding for a departing employee, generating the checklist. Terminating the employee record and offboarding them are separate steps — this is the operational one.

#### Signature

```http
POST /business-made/offboarding (body) -> The created record
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /business-made/employees/{id}/terminate`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The offboarding to create.

```json
{
  "employeeId": "EMP-4821",
  "lastWorkingDay": "2026-09-30",
  "reason": "Resignation"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The created record |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /business-made/offboarding/{id}

**Get an offboarding record**

`operationId: OffboardingController_getOffboarding`

Fetches one offboarding record with its checklist and progress.

#### Signature

```http
GET /business-made/offboarding/{id} (id: string) -> The offboarding record
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `400` | INVALID_ID | invalid id <id> | The id is not a valid record id. A well-formed id that matches nothing returns an empty 200, not a 404. | — |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /business-made/offboarding/{id}/start`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `id` | path | string | yes | Record id. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The offboarding record |
| `400` | invalid id <id> — The id is not a valid record id. A well-formed id that matches nothing returns an empty 200, not a 404. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## DELETE /business-made/offboarding/{id}

**Delete an offboarding record**

`operationId: OffboardingController_deleteOffboarding`

Deletes an offboarding record and its checklist history.

#### Signature

```http
DELETE /business-made/offboarding/{id} (id: string) -> Deletion result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /business-made/offboarding/{id}/cancel`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `id` | path | string | yes | Record id. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Deletion result |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /business-made/offboarding/update

**Update an offboarding record**

`operationId: OffboardingController_updateOffboarding`

Updates an offboarding record. **Replaces the stored record** — send the whole record as read (`sk` plus `data`), not just the changed fields.

#### Signature

```http
POST /business-made/offboarding/update (body) -> The updated record
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /business-made/offboarding/{id}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The record to update.

```json
{
  "sk": "OFF-4821",
  "data": {
    "lastWorkingDay": "2026-10-07"
  }
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The updated record |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /business-made/offboarding/{id}/start

**Start offboarding**

`operationId: OffboardingController_startOffboarding`

Begins the offboarding process, activating the checklist.

#### Signature

```http
POST /business-made/offboarding/{id}/start (id: string) -> The started record
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | OFFBOARDING_NOT_FOUND | Offboarding not found | No offboarding record has that id. | The body carries `code: "OFFBOARDING_NOT_FOUND"` and the id. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /business-made/offboarding/{id}/tasks/{taskId}/complete`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `id` | path | string | yes | Record id. |

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The started record |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Offboarding not found — No offboarding record has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /business-made/offboarding/{id}/tasks/{taskId}/complete

**Complete an offboarding task**

`operationId: OffboardingController_completeChecklistTask`

Marks one checklist task done.

#### Signature

```http
POST /business-made/offboarding/{id}/tasks/{taskId}/complete (id: string, taskId: string, body) -> The updated record
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | OFFBOARDING_NOT_FOUND | Offboarding not found | No offboarding record has that id. | The body carries `code: "OFFBOARDING_NOT_FOUND"` and the id. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /business-made/offboarding/{id}/tasks/{taskId}/not-applicable`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `id` | path | string | yes | Record id. |
| `taskId` | path | string | yes | Task id. |

### Request body

Optional completion note.

```json
{
  "note": "Laptop returned and wiped"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The updated record |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Offboarding not found — No offboarding record has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /business-made/offboarding/{id}/tasks/{taskId}/not-applicable

**Mark an offboarding task not applicable**

`operationId: OffboardingController_markTaskNotApplicable`

Marks a task as not relevant to this departure — no company car to return, no parking pass to surrender. Distinct from completing it, so the checklist stays truthful.

#### Signature

```http
POST /business-made/offboarding/{id}/tasks/{taskId}/not-applicable (id: string, taskId: string, body) -> The updated record
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | OFFBOARDING_NOT_FOUND | Offboarding not found | No offboarding record has that id. | The body carries `code: "OFFBOARDING_NOT_FOUND"` and the id. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /business-made/offboarding/{id}/tasks/{taskId}/complete`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `id` | path | string | yes | Record id. |
| `taskId` | path | string | yes | Task id. |

### Request body

Why it does not apply.

```json
{
  "reason": "Remote employee, no equipment issued"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The updated record |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Offboarding not found — No offboarding record has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /business-made/offboarding/{id}/equipment

**Record equipment return**

`operationId: OffboardingController_recordEquipmentReturn`

Records company equipment returned by the departing employee. Anything outstanding at completion is worth resolving first — recovering a laptop after someone has left is much harder.

#### Signature

```http
POST /business-made/offboarding/{id}/equipment (id: string, body) -> The updated record
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | OFFBOARDING_NOT_FOUND | Offboarding not found | No offboarding record has that id. | The body carries `code: "OFFBOARDING_NOT_FOUND"` and the id. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /business-made/offboarding/{id}/complete`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `id` | path | string | yes | Record id. |

### Request body

The equipment returned.

```json
{
  "items": [
    {
      "type": "laptop",
      "assetTag": "LT-9912",
      "condition": "good"
    }
  ]
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The updated record |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Offboarding not found — No offboarding record has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /business-made/offboarding/{id}/revoke-access

**Revoke system access**

`operationId: OffboardingController_revokeAccess`

Revokes the departing employee's system access.

Timing matters more than most steps here: access left active after someone leaves is the security failure offboarding exists to prevent, and it is routinely the thing that gets forgotten.

#### Signature

```http
POST /business-made/offboarding/{id}/revoke-access (id: string, body) -> The updated record
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Record what was revoked — a partial revocation that looks complete is worse than none.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | OFFBOARDING_NOT_FOUND | Offboarding not found | No offboarding record has that id. | The body carries `code: "OFFBOARDING_NOT_FOUND"` and the id. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /business-made/offboarding/{id}/complete`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `id` | path | string | yes | Record id. |

### Request body

Optional details.

```json
{
  "effectiveAt": "2026-09-30T17:00:00.000Z",
  "systems": [
    "email",
    "vpn",
    "git"
  ]
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The updated record |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Offboarding not found — No offboarding record has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /business-made/offboarding/{id}/final-pay

**Record final pay**

`operationId: OffboardingController_processFinalPay`

Records the final pay settlement — outstanding salary, accrued leave and any deductions. Many jurisdictions set a deadline for paying a leaver, so this is time-sensitive.

#### Signature

```http
POST /business-made/offboarding/{id}/final-pay (id: string, body) -> The updated record
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | OFFBOARDING_NOT_FOUND | Offboarding not found | No offboarding record has that id. | The body carries `code: "OFFBOARDING_NOT_FOUND"` and the id. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /business-made/leave/balances/employee/{employeeId}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `id` | path | string | yes | Record id. |

### Request body

Final pay details.

```json
{
  "finalPayDate": "2026-10-05",
  "accruedLeaveDays": 6.5,
  "deductions": []
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The updated record |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Offboarding not found — No offboarding record has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /business-made/offboarding/{id}/complete

**Complete offboarding**

`operationId: OffboardingController_completeOffboarding`

Closes the offboarding process. Check equipment, access revocation and final pay are all done first — completing with those outstanding leaves genuine loose ends.

#### Signature

```http
POST /business-made/offboarding/{id}/complete (id: string) -> The completed record
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | OFFBOARDING_NOT_FOUND | Offboarding not found | No offboarding record has that id. | The body carries `code: "OFFBOARDING_NOT_FOUND"` and the id. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /business-made/offboarding/{id}/revoke-access`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `id` | path | string | yes | Record id. |

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The completed record |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Offboarding not found — No offboarding record has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /business-made/offboarding/{id}/cancel

**Cancel offboarding**

`operationId: OffboardingController_cancelOffboarding`

Abandons offboarding — a resignation withdrawn, or a departure deferred. The record is kept.

#### Signature

```http
POST /business-made/offboarding/{id}/cancel (id: string, body) -> The cancelled record
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Restore any access already revoked — cancelling does not undo it.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | OFFBOARDING_NOT_FOUND | Offboarding not found | No offboarding record has that id. | The body carries `code: "OFFBOARDING_NOT_FOUND"` and the id. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /business-made/offboarding/{id}/revoke-access`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `id` | path | string | yes | Record id. |

### Request body

Why it was cancelled.

```json
{
  "reason": "Employee retracted resignation"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The cancelled record |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Offboarding not found — No offboarding record has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /business-made/offboarding/status/active

**List active offboarding**

`operationId: OffboardingController_getActiveOffboardings`

Departures currently in progress — who is leaving and what is outstanding.

#### Signature

```http
GET /business-made/offboarding/status/active () -> Active offboarding
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /business-made/offboarding/{id}/complete`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Active offboarding |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /business-made/offboarding/exit-interviews

**List exit interviews**

`operationId: OffboardingController_getExitInterviews`

Exit interviews across the org — the data behind understanding why people leave.

#### Signature

```http
GET /business-made/offboarding/exit-interviews () -> Exit interviews
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /business-made/offboarding/metrics`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Exit interviews |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /business-made/offboarding/exit-interviews/{id}

**Get an exit interview**

`operationId: OffboardingController_getExitInterview`

Fetches one exit interview and its responses. Departing employees say candid things — restrict access to those who need it.

#### Signature

```http
GET /business-made/offboarding/exit-interviews/{id} (id: string) -> The exit interview
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Candid feedback about named managers. Handle accordingly.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `400` | INVALID_ID | invalid id <id> | The id is not a valid record id. A well-formed id that matches nothing returns an empty 200, not a 404. | — |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /business-made/offboarding/exit-interviews/{id}/conduct`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `id` | path | string | yes | Record id. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The exit interview |
| `400` | invalid id <id> — The id is not a valid record id. A well-formed id that matches nothing returns an empty 200, not a 404. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /business-made/offboarding/{offboardingId}/exit-interview

**Schedule an exit interview**

`operationId: OffboardingController_scheduleExitInterview`

Creates an exit interview against an offboarding record.

#### Signature

```http
POST /business-made/offboarding/{offboardingId}/exit-interview (offboardingId: string, body) -> The created exit interview
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | OFFBOARDING_NOT_FOUND | Offboarding not found | No offboarding record has that id. | The body carries `code: "OFFBOARDING_NOT_FOUND"` and the id. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /business-made/offboarding/exit-interviews/{id}/conduct`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `offboardingId` | path | string | yes | Offboarding record id. |

### Request body

Interview details.

```json
{
  "scheduledDate": "2026-09-29",
  "interviewer": "hr@acme.com"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The created exit interview |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Offboarding not found — No offboarding record has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /business-made/offboarding/exit-interviews/{id}/conduct

**Record an exit interview**

`operationId: OffboardingController_conductExitInterview`

Records the responses from a conducted exit interview.

#### Signature

```http
POST /business-made/offboarding/exit-interviews/{id}/conduct (id: string, body) -> The completed interview
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | EXIT_INTERVIEW_NOT_FOUND | Exit interview not found | No exit interview has that id. | The body carries `code: "EXIT_INTERVIEW_NOT_FOUND"` and the id. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /business-made/offboarding/exit-interviews/{id}/action-items`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `id` | path | string | yes | Record id. |

### Request body

The responses.

```json
{
  "responses": [
    {
      "question": "Primary reason for leaving",
      "answer": "Limited progression"
    }
  ],
  "overallSentiment": "neutral"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The completed interview |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Exit interview not found — No exit interview has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /business-made/offboarding/exit-interviews/{id}/decline

**Record a declined exit interview**

`operationId: OffboardingController_declineExitInterview`

Records that the employee declined to be interviewed. Worth capturing — a declined interview is a data point, and it distinguishes "chose not to" from "was never asked".

#### Signature

```http
POST /business-made/offboarding/exit-interviews/{id}/decline (id: string, body) -> The updated interview
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | EXIT_INTERVIEW_NOT_FOUND | Exit interview not found | No exit interview has that id. | The body carries `code: "EXIT_INTERVIEW_NOT_FOUND"` and the id. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /business-made/offboarding/exit-interviews/{id}/conduct`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `id` | path | string | yes | Record id. |

### Request body

Optional detail.

```json
{
  "reason": "Employee declined"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The updated interview |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Exit interview not found — No exit interview has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /business-made/offboarding/exit-interviews/{id}/action-items

**Add exit interview action items**

`operationId: OffboardingController_addActionItem`

Records actions arising from an exit interview — the step that turns feedback into something that changes. Without it the interview is only a record.

#### Signature

```http
POST /business-made/offboarding/exit-interviews/{id}/action-items (id: string, body) -> The updated interview
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | EXIT_INTERVIEW_NOT_FOUND | Exit interview not found | No exit interview has that id. | The body carries `code: "EXIT_INTERVIEW_NOT_FOUND"` and the id. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /business-made/offboarding/metrics`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `id` | path | string | yes | Record id. |

### Request body

The actions.

```json
{
  "items": [
    {
      "action": "Review progression framework for engineering",
      "owner": "hr@acme.com"
    }
  ]
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The updated interview |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Exit interview not found — No exit interview has that id. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /business-made/offboarding/metrics

**Get offboarding metrics**

`operationId: OffboardingController_getOffboardingMetrics`

Attrition figures and exit-interview themes — why people are leaving, aggregated.

#### Signature

```http
GET /business-made/offboarding/metrics () -> Offboarding metrics
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /business-made/offboarding/exit-interviews`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `startDate` | query | string | yes |  |
| `endDate` | query | string | yes |  |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Offboarding metrics |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

