> ## Documentation Index
> Fetch the complete documentation index at: https://docs.blobhub.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Delete User

Retire a service account: revoke its credentials, drop its memberships, and mark it retired. A human
user can never be deleted through this endpoint.

## **DELETE** `/users/:user_id`

### Path Parameters

| Parameter | Type   | Required | Description                                     |
| :-------- | :----- | :------- | :---------------------------------------------- |
| `user_id` | string | Yes      | The unique ID of the service account to retire. |

### Response

Returns `{"status": "success"}` — no body beyond the status.

### What Retirement Does

1. Deletes every API key the account holds.
2. Deletes every credential stored at `target=user/{user_id}` — the third-party provider secrets held **on
   the account itself**.
3. Removes every membership the account holds.
4. Sets the account's `status` to `retired`.

Step 2 is scoped to the account and nothing else. A credential at `target=org/{org_id}` or
`target=blob/{blob_id}` belongs to that Organization or Blob and **survives** — it outlives every account
that ever read it, and retiring a reader never removes it.

The account **record itself survives**, so historical authorship — an `author_id` on a Revision, a
`user_id` on a thread item — still resolves to a name instead of a dangling ID. Retirement is
**terminal**: there is no reactivation, matching [Lifecycle](/general/service-accounts#lifecycle).

### Errors

| Status | Error                | Cause                                                                          |
| :----- | :------------------- | :----------------------------------------------------------------------------- |
| 400    | `cannot_delete_user` | `user_id` names a human — humans can't be deleted here.                        |
| 400    | `account_retired`    | The account has already been retired.                                          |
| 403    | `forbidden`          | Missing `admin` access to the account's owner, or no human behind the request. |

See [Permissions](#permissions) below for who can call this endpoint at all.

### Example

<CodeGroup>
  ```bash Request theme={null}
  curl -X DELETE https://api.blobhub.io/v1/users/fe827336-3548-429c-a37c-a06d9b689eac \
    -H "X-API-Key: $ORG_API_KEY"
  ```

  ```json Response theme={null}
  {
    "status": "success"
  }
  ```
</CodeGroup>

### Permissions

| Caller                                                               | Access                                    |
| :------------------------------------------------------------------- | :---------------------------------------- |
| The owning user, signed in as themselves                             | Allowed.                                  |
| An admin of the owning organization                                  | Allowed.                                  |
| An org-scoped API key with the `admin` role, for the owning org      | Allowed — the path most CI pipelines use. |
| An [acting token](/rest-api/auth/impersonate) minted for the account | Allowed — for that one account only.      |
| The service account's own key, for itself or anything else           | Forbidden, always.                        |

Retiring an account is a human act: the request fails with `403` whenever there is no human behind
it at all, which is what makes the last row unconditional rather than role-dependent — a service
account's key can never satisfy it, no matter what role that key carries. An acting token satisfies it
because it names the human who minted it, which is why it appears one row above — see
[The Access Perimeter](/general/service-accounts#the-access-perimeter) for the rule across all ten
operations it governs.
