---
title: "Offboard User"
method: POST
path: "/api/tenants/{tenant_id}/users/{user_id}/offboard"
tags: ["tenants"]
---

# Offboard User

`POST /api/tenants/{tenant_id}/users/{user_id}/offboard`

## Request

- Base URL: `https://pozeidon.ai` (the document declares no server; this is the origin it was published from)
- URL: `https://pozeidon.ai/api/tenants/{tenant_id}/users/{user_id}/offboard`
- Auth: none declared. Required headers: `x-admin-secret`

Offboard a user: LOCK the account, cut its cross-tenant reach, end every
session, and record who did it (G-OFFBOARD, docs/folds/user-offboarding.md).

Distinct from ``revoke-sessions`` above, which is a *kick*: it ends the
sessions that exist, but the same person logs straight back in tomorrow.
This is the *lock*. Four things, in this order, so that no ordering leaves a
usable window:

1. ``users.disabled_at`` — every entry point that turns a users row into a
   credential refuses from this instant (``app/user_active.py`` names them).
   FIRST, so nothing can start a new session while the rest runs.
2. ``cross_tenant_grants`` — the reach into other tenants goes with the
   account (docs/design/2026-06-03-delegated-tenant-access-act-as.md).
3. ``revoke_user_sessions`` — the existing kick, unchanged: bumps
   session_epoch and revokes outstanding refresh families, so live copilot
   sessions die at their next revalidation and meta-copilot's revocation
   mirror picks the user up from ``session_revoked_at``.
4. one ``user_offboardings`` row.

Idempotent. A second call reports ``already_disabled: true``, leaves the
original ``disabled_at`` alone, and STILL re-runs steps 2–4 — a repeat is
what an operator reaches for when they suspect the first one half-landed,
so it must re-close the door rather than report success and do nothing.

## Path parameters

- `tenant_id` string, required
- `user_id` string, uuid, required

## Headers

- `x-admin-secret` string, required

## Request body

- OffboardUserRequest
  - `actor` string, required
  - `reason` string, nullable

## Response `200`

Successful Response

- unknown

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/pozeidon/apis/pozeidon-demo.md) · [All operations](https://skmtc.dev/pozeidon/apis/pozeidon-demo/llms.txt) · [OpenAPI document](https://skmtc.dev/pozeidon/apis/pozeidon-demo/revisions/de288dc26752?raw)
