---
title: "Delete organization"
method: DELETE
path: "/organization/{id}"
tags: ["Organizations"]
---

# Delete organization

`DELETE /organization/{id}`

## Request

- Base URL: `https://api.elaichi.ai`
- URL: `https://api.elaichi.ai/organization/{id}`
- Auth: HTTP bearer

**Schedules permanent deletion 30 days out; it does not erase the organization today.** Immediately and irreversibly, every connection is severed and its stored credential deleted (a restore returns the organization but not the connections; each must be re-authorized by hand), every SCIM token and MCP OAuth grant is revoked, and the Stripe subscription is canceled (immediately, not at period end). Everything else (members, roles, teams, toolboxes, templates, restrictions, conversations, audit history, the logo, API tokens) survives and returns on a restore. For the next 30 days the organization is read-only: every GET still works (the paginated read APIs are the export path, and existing API tokens keep reading through them, so an export script needs no new credential), and every other method answers `403 organization_pending_deletion` except `POST /organization/{id}/restore`. MCP, tool execution and new connections are refused outright. On day 30 the full teardown runs. Calling this twice is idempotent: the second call returns the same `purge_after` with an all-zero summary. Requires the `org:delete` permission, which only the Org Owner role holds (an Org Admin is refused with 403 `permission_required`), an interactive browser session (an org API token is refused with 403), and step-up reauthentication in the app: without a valid `X-Step-Up-Token` the call answers `428 step_up_required`. `confirm_slug` must equal the organization's own `slug`; the API re-checks it, so a client that skips its confirmation prompt does not skip the check. Unlike every other mutation here this does not require an active subscription, so a locked or expired organization can still leave. On `200` the `summary` describes only what this call severed: `api_tokens_revoked`, `conversations_purged` and `logo_objects_deleted` are absent and `residue` stays empty because this phase touches none of them (the day-30 purge reports those). A non-empty `failures` means a credential this call promised to revoke may still be live at the provider, so tell the user rather than repeat the promise.

## Path parameters

- `id` string, required

## Request body

- object
  - `confirm_slug` string, required: Must equal this organization’s `slug`. The API re-checks it.
  - `reason` string: Optional note, recorded on the audit entry this deletion writes before it runs.

## Response `200`

OK

- object
  - `deleted` true
  - `organization_id` string
  - `pending_deletion` true: Always `true` here: this route only schedules. The organization is read-only until `purge_after` and can be brought back with `POST /organization/{id}/restore`.
  - `purge_after` string, date-time: When the full teardown will run, 30 days out. The restore window closes at this instant. A repeat call on an already-scheduled organization returns the deadline already set, never a later one.
  - `summary` object: Only what this call severed. Counts are of items successfully removed. The purge-only counts (`api_tokens_revoked`, `conversations_purged`, `logo_objects_deleted`) are absent here, not zero: they appear only on the day-30 purge.
    - `connections_deleted` integer
    - `scim_tokens_revoked` integer
    - `oauth_grants_revoked` integer
    - `stripe_subscription_cancelled` boolean
    - `failures` object[]: Steps that did not come off cleanly on this run, one entry per step. Empty on a clean run; a retry of the same delete may clear them. There are only a handful of possible steps, so the list stays short however large the organization is; a step that walks many items reports a count and a few sample ids in its single entry.
      - `step` string
      - `detail` string
    - `residue` object[]: Stores a deletion cannot reach at all. Empty on this route, because scheduling touches none of them; the day-30 purge reports them, and that list is never a sign that anything went wrong. It is the list an erasure request is answered with.
      - `step` string
      - `detail` string

## Other responses

- `400`: Bad request
- `401`: Unauthorized
- `403`: Forbidden
- `404`: Not found
- `429`: Rate limited

---

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