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

# Account and purge

> The two destructive operations, both behind a ceremony.

## What this family does

`POST /v1/purge` is two-phase. The first call counts exactly what would be deleted and mints a short-lived confirmation token. The second call presents that token and deletes. If the data changed between the two, the confirm is refused and nothing is deleted.

`DELETE /v1/me` deletes the account. For a personal organization that tears down the whole tenant, keys included.

## Routes

| Method   | Path                                           | Scope   | What it does                                   |
| -------- | ---------------------------------------------- | ------- | ---------------------------------------------- |
| `DELETE` | [`/v1/me`](/api-reference/admin/delete-me)     | `write` | Delete account                                 |
| `POST`   | [`/v1/purge`](/api-reference/admin/purge-data) | `admin` | Purge subject or organization data (two-phase) |

## The shape of a call

Dry-run a purge.

<CodeGroup>
  ```bash cURL theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
  curl -X POST https://api.get-exo.com/v1/purge \
    -H "X-Exo-API-Key: $EXO_KEY" \
    -H "Content-Type: application/json" \
    -d '{"scope": "subject", "subjectId": "customer_6412", "dryRun": true}'
  ```

  ```python Python theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
  import httpx

  response = httpx.post(
      "https://api.get-exo.com/v1/purge",
      headers={"X-Exo-API-Key": EXO_KEY},
      json={"scope": "subject", "subjectId": "customer_6412", "dryRun": True},
  )
  token = response.json()["confirmToken"]
  ```

  ```typescript TypeScript theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
  const response = await fetch("https://api.get-exo.com/v1/purge", {
    method: "POST",
    headers: {
      "X-Exo-API-Key": process.env.EXO_KEY!,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ scope: "subject", subjectId: "customer_6412", dryRun: true }),
  });
  const { confirmToken } = await response.json();
  ```
</CodeGroup>

The response:

```json theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
{
  "requestId": "req_4f7b2c9a1d3e6081",
  "scope": "subject",
  "subjectId": "customer_6412",
  "dryRun": true,
  "counts": { "vault_nodes": 128, "memory_chunks": 402, "graph_edges": 341 },
  "totalRows": 871,
  "confirmToken": "pt_9c2a41f8b0e7",
  "expiresAt": "2026-07-14T09:17:03Z",
  "purgedAt": null
}
```

## Traps

**`dryRun` defaults to true.** A purge request without `dryRun: false` and a valid token counts and reports. It does not delete.

**The impact is re-checked at confirm time.** If it changed since the dry run, you get 409 `purge_impact_changed` and nothing is deleted. Re-run the dry run for a fresh token.

**Purge at organization scope keeps the organization.** It empties the knowledge graph but keeps users and keys. To delete the account itself, use `DELETE /v1/me`.

**A confirmed purge also deletes stored files.** Uploaded imports and finished export documents at both scopes, and the trained brain at organization scope, because it is derived from the graph being emptied.

## Related

<Columns cols={2}>
  <Card title="API reference" icon="book-open" href="/api-reference/overview">
    Base URL, authentication, and the conventions every route shares.
  </Card>

  <Card title="Errors" icon="circle-alert" href="/platform/errors">
    The problem envelope and the full code catalogue.
  </Card>
</Columns>
